diff --git a/.github/mergeable.yml b/.github/mergeable.yml index ade6c679a47c8..17688527de561 100644 --- a/.github/mergeable.yml +++ b/.github/mergeable.yml @@ -9,10 +9,10 @@ mergeable: - and: - must_include: regex: 'release notes: yes' - message: 'Please include release notes: yes' + message: 'Include release notes: yes' - must_include: regex: '^(autotools|bazel|c#|c\+\+|cleanup|cmake|conformance tests|integration|go|java|javascript|objective-c|php|protoc|python|ruby|kotlin)' - message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: autotools, bazel, cmake, cleanup, conformance tests, integration, protoc.' + message: 'at least a language label (e.g., c++, java, python). Or apply one of the following labels: autotools, bazel, cmake, cleanup, conformance tests, integration, protoc.' - must_include: regex: 'release notes: no' - message: 'Please include release notes: no' + message: 'Include release notes: no' diff --git a/BUILD b/BUILD index 9fbf69dfca963..df62e9e22bca1 100644 --- a/BUILD +++ b/BUILD @@ -2,11 +2,13 @@ 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_pkg//:pkg.bzl", "pkg_zip") +load("@rules_pkg//:mappings.bzl", "pkg_attributes", "pkg_files") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") load("@rules_python//python:defs.bzl", "py_library") load("@rules_java//java:defs.bzl", "java_binary", "java_lite_proto_library", "java_proto_library") load(":cc_proto_blacklist_test.bzl", "cc_proto_blacklist_test") - +load(":protobuf_release.bzl", "package_naming") licenses(["notice"]) exports_files(["LICENSE"]) @@ -26,7 +28,6 @@ ZLIB_DEPS = ["@zlib//:zlib"] ################################################################################ MSVC_COPTS = [ - "/DHAVE_PTHREAD", "/wd4018", # -Wno-sign-compare "/wd4065", # switch statement contains 'default' but no 'case' labels "/wd4146", # unary minus operator applied to unsigned type, result still unsigned @@ -46,7 +47,6 @@ MSVC_COPTS = [ COPTS = select({ ":msvc": MSVC_COPTS, "//conditions:default": [ - "-DHAVE_PTHREAD", "-DHAVE_ZLIB", "-Wmissing-field-initializers", "-Woverloaded-virtual", @@ -65,6 +65,13 @@ create_compiler_config_setting( ], ) +# Android NDK builds can specify different crosstool_top flags to choose which +# STL they use for C++. We need these multiple variants to catch all of those +# versions of crosstool_top and reliably detect Android. +# +# For more info on the various crosstool_tops used by NDK Bazel builds, see: +# https://docs.bazel.build/versions/master/android-ndk.html#configuring-the-stl + config_setting( name = "android", values = { @@ -76,6 +83,17 @@ config_setting( ], ) +config_setting( + name = "android-stlport", + values = { + "crosstool_top": "@androidndk//:toolchain-stlport", + }, + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], +) + config_setting( name = "android-libcpp", values = { @@ -98,11 +116,24 @@ config_setting( ], ) +config_setting( + name = "android-default", + values = { + "crosstool_top": "@androidndk//:default_crosstool", + }, + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], +) + # Android and MSVC builds do not need to link in a separate pthread library. LINK_OPTS = select({ ":android": [], + ":android-stlport": [], ":android-libcpp": [], ":android-gnu-libstdcpp": [], + ":android-default": [], ":msvc": [ # Suppress linker warnings about files with no symbols defined. "-ignore:4221", @@ -147,6 +178,7 @@ cc_library( "src/google/protobuf/message_lite.cc", "src/google/protobuf/parse_context.cc", "src/google/protobuf/repeated_field.cc", + "src/google/protobuf/repeated_ptr_field.cc", "src/google/protobuf/stubs/bytestream.cc", "src/google/protobuf/stubs/common.cc", "src/google/protobuf/stubs/int128.cc", @@ -488,6 +520,70 @@ cc_binary( deps = [":protoc_lib"], ) + +################################################################################ +# Generates protoc release artifacts. +################################################################################ + +genrule( + name = "protoc_readme", + visibility = ["//visibility:private"], + cmd = """ +echo "Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. +https://developers.google.com/protocol-buffers/ +This package contains a precompiled binary version of the protocol buffer +compiler (protoc). This binary is intended for users who want to use Protocol +Buffers in languages other than C++ but do not want to compile protoc +themselves. To install, simply place this binary somewhere in your PATH. +If you intend to use the included well known types then don't forget to +copy the contents of the 'include' directory somewhere as well, for example +into '/usr/local/include/'. +Please refer to our official github site for more installation instructions: + https://github.com/protocolbuffers/protobuf" > $@ + """, + outs = ["readme.txt"], +) + +# plugin.proto is excluded from this list because it belongs in a nested folder (protobuf/compiler/plugin.proto) +pkg_files( + name = "wkt_protos_files", + srcs = [value[0] for value in WELL_KNOWN_PROTO_MAP.values() if not value[0].endswith("plugin.proto")], + visibility = ["//visibility:private"], + prefix = "include/google/protobuf", +) + +pkg_files( + name = "compiler_plugin_protos_files", + srcs = ["src/google/protobuf/compiler/plugin.proto"], + visibility = ["//visibility:private"], + prefix = "include/google/protobuf/compiler", +) + +pkg_files( + name = "protoc_files", + srcs = [":protoc"], + attributes = pkg_attributes(mode = "0555"), + visibility = ["//visibility:private"], + prefix = "bin/", +) + +package_naming( + name = "protoc_pkg_naming", +) + +pkg_zip( + name = "protoc_release", + package_file_name = "protoc-{version}-{platform}.zip", + package_variables = ":protoc_pkg_naming", + srcs = [ + ":protoc_files", + ":wkt_protos_files", + ":compiler_plugin_protos_files", + "readme.txt", + ], +) + ################################################################################ # Tests ################################################################################ @@ -560,6 +656,8 @@ RELATIVE_TEST_PROTOS = [ TEST_PROTOS = ["src/" + s for s in RELATIVE_TEST_PROTOS] GENERIC_RELATIVE_TEST_PROTOS = [ + "google/protobuf/map_proto2_unittest.proto", + "google/protobuf/map_unittest.proto", "google/protobuf/unittest.proto", "google/protobuf/unittest_arena.proto", "google/protobuf/unittest_custom_options.proto", @@ -953,7 +1051,6 @@ py_proto_library( protoc = ":protoc", py_libs = [ ":python_srcs", - "@six//:six", ], srcs_version = "PY2AND3", visibility = ["//visibility:public"], @@ -1087,7 +1184,7 @@ proto_library( name = "generated_protos_proto", srcs = [ "src/google/protobuf/unittest_import_public.proto", - "unittest_gen.proto", + "unittest_gen_import.proto", ], ) @@ -1095,7 +1192,7 @@ py_proto_library( name = "generated_protos_py", srcs = [ "src/google/protobuf/unittest_import_public.proto", - "unittest_gen.proto", + "unittest_gen_import.proto", ], default_runtime = "", protoc = ":protoc", @@ -1225,6 +1322,19 @@ cc_binary( # ], # ) + +java_proto_library( + name = "java_test_protos", + deps = [":generic_test_protos"], + visibility = ["//java:__subpackages__"], +) + +java_lite_proto_library( + name = "java_lite_test_protos", + deps = [":generic_test_protos"], + visibility = ["//java:__subpackages__"], +) + java_proto_library( name = "test_messages_proto2_java_proto", visibility = [ @@ -1318,3 +1428,146 @@ filegroup( srcs = glob(["**/*.bzl"]), visibility = ["//visibility:public"], ) + +# Kotlin proto rules + +genrule( + name = "gen_kotlin_unittest_lite", + srcs = [ + "src/google/protobuf/unittest_lite.proto", + "src/google/protobuf/unittest_import_lite.proto", + "src/google/protobuf/unittest_import_public_lite.proto", + "src/google/protobuf/map_lite_unittest.proto", + ], + outs = [ + "TestAllTypesLiteKt.kt", + "ForeignMessageLiteKt.kt", + "TestAllExtensionsLiteKt.kt", + "TestEmptyMessageLiteKt.kt", + "TestEmptyMessageWithExtensionsLiteKt.kt", + "TestMapLiteKt.kt", + "OptionalGroup_extension_liteKt.kt", + "RepeatedGroup_extension_liteKt.kt", + ], + visibility = ["//java:__subpackages__"], + cmd = "$(location //:protoc) " + + "--kotlin_out=lite:$(@D) -Isrc/ " + + "$(locations src/google/protobuf/unittest_lite.proto) && " + + "$(location //:protoc) " + + "--kotlin_out=lite:$(@D) -Isrc/ " + + "$(locations src/google/protobuf/map_lite_unittest.proto) && " + + "cp $(@D)/com/google/protobuf/TestAllTypesLiteKt.kt " + + "$(location TestAllTypesLiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/ForeignMessageLiteKt.kt " + + "$(location ForeignMessageLiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/TestAllExtensionsLiteKt.kt " + + "$(location TestAllExtensionsLiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/TestAllTypesLiteKt.kt " + + "$(location TestAllTypesLiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/TestEmptyMessageLiteKt.kt " + + "$(location TestEmptyMessageLiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt.kt " + + "$(location TestEmptyMessageWithExtensionsLiteKt.kt) && " + + "cp $(@D)/protobuf_unittest/TestMapLiteKt.kt " + + "$(location TestMapLiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/OptionalGroup_extension_liteKt.kt " + + "$(location OptionalGroup_extension_liteKt.kt) && " + + "cp $(@D)/com/google/protobuf/RepeatedGroup_extension_liteKt.kt " + + "$(location RepeatedGroup_extension_liteKt.kt)", + tools = [":protoc"], +) + +genrule( + name = "gen_kotlin_unittest", + srcs = [ + "src/google/protobuf/unittest.proto", + "src/google/protobuf/unittest_import.proto", + "src/google/protobuf/unittest_import_public.proto", + "src/google/protobuf/map_proto2_unittest.proto", + ], + outs = [ + "TestAllTypesKt.kt", + "ForeignMessageKt.kt", + "TestAllExtensionsKt.kt", + "TestEmptyMessageKt.kt", + "TestEmptyMessageWithExtensionsKt.kt", + "TestIntIntMapKt.kt", + "TestEnumMapKt.kt", + "TestMapsKt.kt", + "OptionalGroup_extensionKt.kt", + "RepeatedGroup_extensionKt.kt", + ], + visibility = ["//java:__subpackages__"], + cmd = "$(location //:protoc) " + + "--kotlin_out=shared,immutable:$(@D) -Isrc/ " + + "$(location src/google/protobuf/unittest.proto) && " + + "$(location //:protoc) " + + "--kotlin_out=shared,immutable:$(@D) -Isrc/ " + + "$(location src/google/protobuf/map_proto2_unittest.proto) && " + + "cp $(@D)/protobuf_unittest/TestAllTypesKt.kt " + + "$(location TestAllTypesKt.kt) && " + + "cp $(@D)/protobuf_unittest/ForeignMessageKt.kt " + + "$(location ForeignMessageKt.kt) && " + + "cp $(@D)/protobuf_unittest/TestAllExtensionsKt.kt " + + "$(location TestAllExtensionsKt.kt) && " + + "cp $(@D)/protobuf_unittest/TestEmptyMessageKt.kt " + + "$(location TestEmptyMessageKt.kt) && " + + "cp $(@D)/protobuf_unittest/TestEmptyMessageWithExtensionsKt.kt " + + "$(location TestEmptyMessageWithExtensionsKt.kt) && " + + "cp $(@D)/protobuf_unittest/TestIntIntMapKt.kt " + + "$(location TestIntIntMapKt.kt) && " + + "cp $(@D)/protobuf_unittest/TestEnumMapKt.kt " + + "$(location TestEnumMapKt.kt) && " + + "cp $(@D)/protobuf_unittest/TestMapsKt.kt " + + "$(location TestMapsKt.kt) && " + + "cp $(@D)/protobuf_unittest/OptionalGroup_extensionKt.kt " + + "$(location OptionalGroup_extensionKt.kt) && " + + "cp $(@D)/protobuf_unittest/RepeatedGroup_extensionKt.kt " + + "$(location RepeatedGroup_extensionKt.kt)", + tools = ["//:protoc"], +) + +genrule( + name = "gen_kotlin_proto3_unittest_lite", + srcs = [ + "src/google/protobuf/unittest_proto3_lite.proto", + "src/google/protobuf/unittest_import.proto", + "src/google/protobuf/unittest_import_public.proto", + ], + outs = [ + "TestAllTypesProto3LiteKt.kt", + "TestEmptyMessageProto3LiteKt.kt", + ], + visibility = ["//java:__subpackages__"], + cmd = "$(location //:protoc) " + + "--kotlin_out=lite:$(@D) -Isrc/ " + + "$(location src/google/protobuf/unittest_proto3_lite.proto) && " + + "cp $(@D)/proto3_lite_unittest/TestAllTypesKt.kt " + + "$(location TestAllTypesProto3LiteKt.kt) && " + + "cp $(@D)/proto3_lite_unittest/TestEmptyMessageKt.kt " + + "$(location TestEmptyMessageProto3LiteKt.kt)", + tools = ["//:protoc"], +) + +genrule( + name = "gen_kotlin_proto3_unittest", + srcs = [ + "src/google/protobuf/unittest_proto3.proto", + "src/google/protobuf/unittest_import.proto", + "src/google/protobuf/unittest_import_public.proto", + ], + outs = [ + "TestAllTypesProto3Kt.kt", + "TestEmptyMessageProto3Kt.kt", + ], + visibility = ["//java:__subpackages__"], + cmd = "$(location //:protoc) " + + "--kotlin_out=shared,immutable:$(@D) -Isrc/ " + + "$(location src/google/protobuf/unittest_proto3.proto) && " + + "cp $(@D)/proto3_unittest/TestAllTypesKt.kt " + + "$(location TestAllTypesProto3Kt.kt) && " + + "cp $(@D)/proto3_unittest/TestEmptyMessageKt.kt " + + "$(location TestEmptyMessageProto3Kt.kt)", + tools = ["//:protoc"], +) + diff --git a/CHANGES.txt b/CHANGES.txt index 7682fbdd19707..ea9e6afaefbdc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,110 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) - Protocol Compiler + + Ruby + * JSON will now output shorter strings for double and float fields when possible + without losing precision. + * Encoding and decoding of binary format will now work properly on big-endian + systems. + * UTF-8 verification was fixed to properly reject surrogate code points. + * Unknown enums for proto2 protos now properly implement proto2's behavior of + putting such values in unknown fields. + +2022-01-28 version 3.19.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Python + * Make libprotobuf symbols local on OSX to fix issue #9395 (#9435) + + Ruby + * Fixed a data loss bug that could occur when the number of `optional` + fields in a message is an exact multiple of 32. (#9440). + + PHP + * Fixed a data loss bug that could occur when the number of `optional` + fields in a message is an exact multiple of 32. (#9440). + +2022-01-10 version 3.19.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Python + * Fix missing Windows wheel for Python 3.10 on PyPI + +2022-01-05 version 3.19.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Java + * Improve performance characteristics of UnknownFieldSet parsing (#9371) + * This release addresses a Security Advisory for Java users + (https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-wrvw-hg22-4m67) + +2022-01-05 version 3.18.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Java + * Improve performance characteristics of UnknownFieldSet parsing (#9371) + * This release addresses a Security Advisory for Java users + (https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-wrvw-hg22-4m67) + +2022-01-05 version 3.16.1 (Java) + + Java + * Improve performance characteristics of UnknownFieldSet parsing (#9371) + * This release addresses a Security Advisory for Java users + (https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-wrvw-hg22-4m67) + +2021-10-28 version 3.19.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Bazel + * Ensure that release archives contain everything needed for Bazel (#9131) + * Align dependency handling with Bazel best practices (#9165) + + JavaScript + * Fix `ReferenceError: window is not defined` when getting the global object (#9156) + + Ruby + * Fix memory leak in MessageClass.encode (#9150) + +2021-10-15 version 3.19.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ * Make proto2::Message::DiscardUnknownFields() non-virtual + * Separate RepeatedPtrField into its own header file + * For default floating point values of 0, consider all bits significant + * cmake: support `MSVC_RUNTIME_LIBRARY` property (#8851) + * Fix shadowing warnings (#8926) + * Fix for issue #8484, constant initialization doesn't compile in msvc clang-cl environment (#8993) + * Fix build on AIX and SunOS (#8373) (#9065) + * Add Android stlport and default toolchains to BUILD. (#8290) + + Java + * For default floating point values of 0, consider all bits significant + * Annotate `//java/com/google/protobuf/util/...` with nullness annotations + * Use ArrayList copy constructor (#7853) + + Kotlin + * Switch Kotlin proto DSLs to be implemented with inline value classes + * Fix inlining and deprecation for repeated string fields in kotlin (#9120) + + Python + * Proto2 DecodeError now includes message name in error message + * Make MessageToDict convert map keys to strings (#8122) + * Add python-requires in setup.py (#8989) + * Add python 3.10 (#9034) + + JavaScript + * Skip exports if not available by CommonJS (#8856) + * JS: Comply with CSP no-unsafe-eval. (#8864) + + PHP + * Added "object" as a reserved name for PHP (#8962) + + Ruby + * Override Map.clone to use Map's dup method (#7938) + * Ruby: build extensions for arm64-darwin (#8232) + * Add class method Timestamp.from_time to ruby well known types (#8562) + * Adopt pure ruby DSL implementation for JRuby (#9047) + * Add size to Map class (#8068) + * Fix for descriptor_pb.rb: google/protobuf should be required first (#9121) + + C# + * Correctly set ExtensionRegistry when parsing with MessageParser, but using an already existing CodedInputStream (#7246) + * [C#] Make FieldDescriptor propertyName public (#7642) 2021-10-04 version 3.18.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index db1ff31cac6c4..8ef5dd29c85c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,31 @@ # Contributing to Protocol Buffers -We welcome your contributions to protocol buffers. This doc describes the +We welcome some types of contributions to protocol buffers. This doc describes the process to contribute patches to protobuf and the general guidelines we expect contributors to follow. +## What We Accept + +* Bug fixes with unit tests demonstrating the problem are very welcome. + We also appreciate bug reports, even when they don't come with a patch. + Bug fixes without tests are usually not accepted. +* New APIs and features with adequate test coverage and documentation + may be accepted if they do not compromise backwards + compatibility. However there's a fairly high bar of usefulness a new public + method must clear before it will be accepted. Features that are fine in + isolation are often rejected because they don't have enough impact to justify the + conceptual burden and ongoing maintenance cost. It's best to file an issue + and get agreement from maintainers on the value of a new feature before + working on a PR. +* Performance optimizations may be accepted if they have convincing benchmarks that demonstrate + an improvement and they do not significantly increase complexity. +* Changes to existing APIs are almost never accepted. Stability and + backwards compatibility are paramount. In the unlikely event a breaking change + is required, it must usually be implemented in google3 first. +* Changes to the wire and text formats are never accepted. Any breaking change + to these formats would have to be implemented as a completely new format. + We cannot begin generating protos that cannot be parsed by existing code. + ## Before You Start We accept patches in the form of github pull requests. If you are new to @@ -58,7 +80,7 @@ the final release. * Create small PRs that are narrowly focused on addressing a single concern. We often receive PRs that are trying to fix several things at a time, but if only one fix is considered acceptable, nothing gets merged and both author's - & review's time is wasted. Create more PRs to address different concerns and + & reviewer's time is wasted. Create more PRs to address different concerns and everyone will be happy. * For speculative changes, consider opening an issue and discussing it first. If you are suggesting a behavioral or API change, make sure you get explicit diff --git a/Makefile.am b/Makefile.am index 6fb1c84fc54e8..858eedfa7495f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1011,6 +1011,7 @@ python_EXTRA_DIST= \ python/google/protobuf/internal/any_test.proto \ python/google/protobuf/internal/api_implementation.cc \ python/google/protobuf/internal/api_implementation.py \ + python/google/protobuf/internal/builder.py \ python/google/protobuf/internal/containers.py \ python/google/protobuf/internal/decoder.py \ python/google/protobuf/internal/descriptor_database_test.py \ @@ -1426,7 +1427,6 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ examples/pubspec.yaml \ protobuf.bzl \ protobuf_deps.bzl \ - third_party/six.BUILD \ third_party/zlib.BUILD \ util/python/BUILD \ internal.bzl diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec index f285e58af8e3d..9b8fae51a732b 100644 --- a/Protobuf-C++.podspec +++ b/Protobuf-C++.podspec @@ -35,9 +35,6 @@ Pod::Spec.new do |s| # Do not let src/google/protobuf/stubs/time.h override system API 'USE_HEADERMAP' => 'NO', 'ALWAYS_SEARCH_USER_PATHS' => 'NO', - - # Configure tool is not being used for Xcode. When building, assume pthread is supported. - 'GCC_PREPROCESSOR_DEFINITIONS' => '"$(inherited)" "HAVE_PTHREAD=1"', } end diff --git a/Protobuf.podspec b/Protobuf.podspec index 4a5f7dd9c17fd..67c31141ce028 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -5,10 +5,10 @@ # dependent projects use the :git notation to refer to the library. Pod::Spec.new do |s| s.name = 'Protobuf' - s.version = '3.18.1' + s.version = '3.19.4' 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.license = 'BSD-3-Clause' s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' } s.cocoapods_version = '>= 1.0' diff --git a/WORKSPACE b/WORKSPACE index 2174cabf8c8fa..36df3f33714cf 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -27,7 +27,7 @@ http_archive( ) # Load common dependencies. -load("//:protobuf_deps.bzl", "protobuf_deps") +load("//:protobuf_deps.bzl", "PROTOBUF_MAVEN_ARTIFACTS", "protobuf_deps") protobuf_deps() bind( @@ -36,68 +36,33 @@ bind( ) load("@rules_jvm_external//:defs.bzl", "maven_install") + maven_install( - artifacts = [ - "com.google.code.gson:gson:2.8.6", - "com.google.errorprone:error_prone_annotations:2.3.2", - "com.google.j2objc:j2obj_annotations:1.3", - "com.google.guava:guava:30.1.1-jre", - "com.google.truth:truth:1.1.2", - "junit:junit:4.12", - "org.easymock:easymock:3.2", - ], + artifacts = PROTOBUF_MAVEN_ARTIFACTS, + # For updating instructions, see: + # https://github.com/bazelbuild/rules_jvm_external#updating-maven_installjson + maven_install_json = "//:maven_install.json", repositories = [ "https://repo1.maven.org/maven2", "https://repo.maven.apache.org/maven2", ], - # For updating instructions, see: - # https://github.com/bazelbuild/rules_jvm_external#updating-maven_installjson - maven_install_json = "//:maven_install.json", ) load("@maven//:defs.bzl", "pinned_maven_install") -pinned_maven_install() -bind( - name = "guava", - actual = "@maven//:com_google_guava_guava", -) - -bind( - name = "gson", - actual = "@maven//:com_google_code_gson_gson", -) - -bind( - name = "error_prone_annotations", - actual = "@maven//:com_google_errorprone_error_prone_annotations", -) - -bind( - name = "j2objc_annotations", - actual = "@maven//:com_google_j2objc_j2objc_annotations", -) +pinned_maven_install() -bind( - name = "junit", - actual = "@maven//:junit_junit", -) +# For `cc_proto_blacklist_test` and `build_test`. +load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") -bind( - name = "easymock", - actual = "@maven//:org_easymock_easymock", -) +bazel_skylib_workspace() -bind( - name = "easymock_classextension", - actual = "@maven//:org_easymock_easymockclassextension", -) +load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") +rules_pkg_dependencies() -bind( - name = "truth", - actual = "@maven//:com_google_truth_truth", -) +# For `kt_jvm_library` +load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories") +kotlin_repositories() -# For `cc_proto_blacklist_test` and `build_test`. -load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") -bazel_skylib_workspace() +load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") +kt_register_toolchains() diff --git a/appveyor.bat b/appveyor.bat index 7a35ceb4d678e..005fb11f891c5 100644 --- a/appveyor.bat +++ b/appveyor.bat @@ -38,7 +38,7 @@ dotnet restore dotnet build -c %configuration% || goto error echo Testing C# -dotnet test -c %configuration% -f netcoreapp2.1 Google.Protobuf.Test\Google.Protobuf.Test.csproj || goto error +dotnet test -c %configuration% -f netcoreapp3.1 Google.Protobuf.Test\Google.Protobuf.Test.csproj || goto error dotnet test -c %configuration% -f net451 Google.Protobuf.Test\Google.Protobuf.Test.csproj || goto error goto :EOF diff --git a/benchmarks/README.md b/benchmarks/README.md index 9c25c7803d254..f708afd9cb166 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -4,8 +4,8 @@ This directory contains benchmarking schemas and data sets that you can use to test a variety of performance scenarios against your protobuf language runtime. If you are looking for performance -numbers of officially support languages, see [here]( -https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md) +numbers of officially supported languages, see [Protobuf Performance]( +https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md). ## Prerequisite diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index caa92150c7d7b..51e8478f6e211 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -127,9 +127,6 @@ if (protobuf_DISABLE_RTTI) endif() find_package(Threads REQUIRED) -if (CMAKE_USE_PTHREADS_INIT) - add_definitions(-DHAVE_PTHREAD) -endif (CMAKE_USE_PTHREADS_INIT) set(_protobuf_FIND_ZLIB) if (protobuf_WITH_ZLIB) @@ -209,6 +206,8 @@ if (MSVC) # Build with multiple processes add_definitions(/MP) endif() + # Set source file and execution character sets to UTF-8 + add_definitions(/utf-8) # MSVC warning suppressions add_definitions( /wd4018 # 'expression' : signed/unsigned mismatch diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 8e26aedd18355..2f53be0dad3f0 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -41,6 +41,8 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_gene copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_pyi_generator.h" include\google\protobuf\compiler\python\python_pyi_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_helpers.h" include\google\protobuf\compiler\python\python_helpers.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h" include\google\protobuf\descriptor.pb.h @@ -48,6 +50,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor_database.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.pb.h" include\google\protobuf\duration.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h" include\google\protobuf\dynamic_message.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\explicitly_constructed.h" include\google\protobuf\explicitly_constructed.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set_inl.h" include\google\protobuf\extension_set_inl.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_access_listener.h" include\google\protobuf\field_access_listener.h @@ -92,6 +95,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\port_undef.inc" inclu copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h" include\google\protobuf\reflection.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h" include\google\protobuf\reflection_ops.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_ptr_field.h" include\google\protobuf\repeated_ptr_field.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h" include\google\protobuf\service.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h" include\google\protobuf\source_context.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h" include\google\protobuf\struct.pb.h diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index f36a7acf6c04e..0ee65e20f8437 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -2,9 +2,9 @@ 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/arenaz_sampler.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 ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_lite.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_util.cc ${protobuf_source_dir}/src/google/protobuf/implicit_weak_message.cc @@ -38,15 +38,13 @@ set(libprotobuf_lite_includes ${protobuf_source_dir}/src/google/protobuf/arena.h ${protobuf_source_dir}/src/google/protobuf/arena_impl.h ${protobuf_source_dir}/src/google/protobuf/arenastring.h + ${protobuf_source_dir}/src/google/protobuf/arenaz_sampler.h ${protobuf_source_dir}/src/google/protobuf/explicitly_constructed.h ${protobuf_source_dir}/src/google/protobuf/extension_set.h ${protobuf_source_dir}/src/google/protobuf/extension_set_inl.h ${protobuf_source_dir}/src/google/protobuf/generated_enum_util.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.h ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_decl.h ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_impl.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_impl.inc ${protobuf_source_dir}/src/google/protobuf/generated_message_util.h ${protobuf_source_dir}/src/google/protobuf/has_bits.h ${protobuf_source_dir}/src/google/protobuf/implicit_weak_message.h diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index e4b810c66a4f9..1f5ae5ab04550 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -14,7 +14,6 @@ set(libprotobuf_files ${protobuf_source_dir}/src/google/protobuf/field_mask.pb.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_bases.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_reflection.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_full.cc ${protobuf_source_dir}/src/google/protobuf/io/gzip_stream.cc ${protobuf_source_dir}/src/google/protobuf/io/printer.cc diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 505e469d07f0a..ed20f31c75aa1 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -91,6 +91,8 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.cc ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_helpers.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_pyi_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.cc @@ -117,6 +119,7 @@ set(libprotoc_headers ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.h ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.h ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.h + ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_pyi_generator.h ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.h ) diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in index 810256e54cfb4..09b9d29c22123 100644 --- a/cmake/protobuf-module.cmake.in +++ b/cmake/protobuf-module.cmake.in @@ -110,16 +110,6 @@ function(_protobuf_find_libraries name filename) endif() endfunction() -# Internal function: find threads library -function(_protobuf_find_threads) - set(CMAKE_THREAD_PREFER_PTHREAD TRUE) - find_package(Threads) - if(Threads_FOUND) - list(APPEND PROTOBUF_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - set(PROTOBUF_LIBRARIES "${PROTOBUF_LIBRARIES}" PARENT_SCOPE) - endif() -endfunction() - # # Main. # @@ -139,10 +129,6 @@ _protobuf_find_libraries(Protobuf_LITE protobuf-lite) # The Protobuf Protoc Library _protobuf_find_libraries(Protobuf_PROTOC protoc) -if(UNIX) - _protobuf_find_threads() -endif() - # Set the include directory get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 9ede4f328caeb..aa069febd2359 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -131,6 +131,7 @@ set(tests_files ${protobuf_source_dir}/src/google/protobuf/any_test.cc ${protobuf_source_dir}/src/google/protobuf/arena_unittest.cc ${protobuf_source_dir}/src/google/protobuf/arenastring_unittest.cc + ${protobuf_source_dir}/src/google/protobuf/arenaz_sampler_test.cc ${protobuf_source_dir}/src/google/protobuf/compiler/annotation_test_util.cc ${protobuf_source_dir}/src/google/protobuf/compiler/annotation_test_util.h ${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -155,6 +156,7 @@ set(tests_files ${protobuf_source_dir}/src/google/protobuf/dynamic_message_unittest.cc ${protobuf_source_dir}/src/google/protobuf/extension_set_unittest.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_reflection_unittest.cc + ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_lite_test.cc ${protobuf_source_dir}/src/google/protobuf/inlined_string_field_unittest.cc ${protobuf_source_dir}/src/google/protobuf/io/coded_stream_unittest.cc ${protobuf_source_dir}/src/google/protobuf/io/io_win32_unittest.cc diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java index 100bec4b54f09..f724548d7cb6c 100644 --- a/conformance/ConformanceJava.java +++ b/conformance/ConformanceJava.java @@ -361,7 +361,7 @@ private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest re case TEXT_FORMAT: return Conformance.ConformanceResponse.newBuilder() - .setTextPayload(TextFormat.printToString(testMessage)) + .setTextPayload(TextFormat.printer().printToString(testMessage)) .build(); default: diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py index 37ee36e24c51f..f81275244067f 100755 --- a/conformance/conformance_python.py +++ b/conformance/conformance_python.py @@ -39,8 +39,8 @@ import os from google.protobuf import json_format from google.protobuf import message -from google.protobuf import test_messages_proto3_pb2 -from google.protobuf import test_messages_proto2_pb2 +from google3.third_party.protobuf import test_messages_proto3_pb2 +from google3.third_party.protobuf import test_messages_proto2_pb2 from google.protobuf import text_format import conformance_pb2 diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc index 1572ac03b5f49..19222c7a7ceac 100644 --- a/conformance/conformance_test_runner.cc +++ b/conformance/conformance_test_runner.cc @@ -162,7 +162,7 @@ void ForkPipeRunner::RunTest( // We failed to read from the child, assume a crash and try to reap. GOOGLE_LOG(INFO) << "Trying to reap child, pid=" << child_pid_; - int status; + int status = 0; waitpid(child_pid_, &status, WEXITED); string error_msg; diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 8e5786fdbdd46..098d79d09cb7e 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.18.1 + 3.19.4 Google Inc. protobuf-packages https://github.com/protocolbuffers/protobuf/blob/master/LICENSE diff --git a/csharp/NuGet.Config b/csharp/NuGet.Config new file mode 100644 index 0000000000000..b04b00689fcb4 --- /dev/null +++ b/csharp/NuGet.Config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/csharp/build_packages.bat b/csharp/build_packages.bat index d7205659f103a..9e68229037f5a 100644 --- a/csharp/build_packages.bat +++ b/csharp/build_packages.bat @@ -1,7 +1,7 @@ @rem Builds Google.Protobuf NuGet packages dotnet restore src/Google.Protobuf.sln -dotnet pack -c Release src/Google.Protobuf.sln || goto :error +dotnet pack -c Release src/Google.Protobuf.sln -p:ContinuousIntegrationBuild=true || goto :error goto :EOF diff --git a/csharp/buildall.sh b/csharp/buildall.sh index 43b5ac3ffb29a..ab1a6c425aaab 100755 --- a/csharp/buildall.sh +++ b/csharp/buildall.sh @@ -10,8 +10,8 @@ dotnet restore $SRC/Google.Protobuf.sln dotnet build -c $CONFIG $SRC/Google.Protobuf.sln echo Running tests. -# Only test netcoreapp2.1, which uses the .NET Core runtime. +# Only test netcoreapp3.1, which uses the .NET Core runtime. # If we want to test the .NET 4.5 version separately, we could # run Mono explicitly. However, we don't have any differences between # the .NET 4.5 and netstandard2.1 assemblies. -dotnet test -c $CONFIG -f netcoreapp2.1 $SRC/Google.Protobuf.Test/Google.Protobuf.Test.csproj +dotnet test -c $CONFIG -f netcoreapp3.1 $SRC/Google.Protobuf.Test/Google.Protobuf.Test.csproj diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj index cbb6fee5f7d41..0ecdf37abb953 100644 --- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj +++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj @@ -2,7 +2,7 @@ Exe - net451;netcoreapp2.1 + net451;netcoreapp3.1 ../../keys/Google.Protobuf.snk true False diff --git a/csharp/compatibility_tests/v3.0.0/test.sh b/csharp/compatibility_tests/v3.0.0/test.sh index f893d64aba830..459c0798794ca 100755 --- a/csharp/compatibility_tests/v3.0.0/test.sh +++ b/csharp/compatibility_tests/v3.0.0/test.sh @@ -22,7 +22,7 @@ function run_test() { dotnet restore src/Google.Protobuf.Test/Google.Protobuf.Test.csproj dotnet build -c Release src/Google.Protobuf/Google.Protobuf.csproj dotnet build -c Release src/Google.Protobuf.Test/Google.Protobuf.Test.csproj - dotnet run -c Release -f netcoreapp2.1 -p src/Google.Protobuf.Test/Google.Protobuf.Test.csproj + dotnet run -c Release -f netcoreapp3.1 -p src/Google.Protobuf.Test/Google.Protobuf.Test.csproj } set -ex diff --git a/csharp/install_dotnet_sdk.ps1 b/csharp/install_dotnet_sdk.ps1 index c78655cc027ea..f9dc0d9d7ac38 100755 --- a/csharp/install_dotnet_sdk.ps1 +++ b/csharp/install_dotnet_sdk.ps1 @@ -16,5 +16,5 @@ Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath # 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 5.0.102 +&$InstallScriptPath -Version 3.1.415 +&$InstallScriptPath -Version 6.0.100 diff --git a/csharp/src/AddressBook/AddressBook.csproj b/csharp/src/AddressBook/AddressBook.csproj index f3268c0acf3e3..9a527874ce81a 100644 --- a/csharp/src/AddressBook/AddressBook.csproj +++ b/csharp/src/AddressBook/AddressBook.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 Exe Google.Protobuf.Examples.AddressBook.Program False diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index 2e88db9a18abd..484a2296a72b5 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -32,9 +32,10 @@ static AddressbookReflection() { "Eg4KBm51bWJlchgBIAEoCRIoCgR0eXBlGAIgASgOMhoudHV0b3JpYWwuUGVy", "c29uLlBob25lVHlwZSIrCglQaG9uZVR5cGUSCgoGTU9CSUxFEAASCAoESE9N", "RRABEggKBFdPUksQAiIvCgtBZGRyZXNzQm9vaxIgCgZwZW9wbGUYASADKAsy", - "EC50dXRvcmlhbC5QZXJzb25CZgobY29tLmV4YW1wbGUudHV0b3JpYWwucHJv", - "dG9zQhFBZGRyZXNzQm9va1Byb3Rvc1ABWgsuLi90dXRvcmlhbKoCJEdvb2ds", - "ZS5Qcm90b2J1Zi5FeGFtcGxlcy5BZGRyZXNzQm9va2IGcHJvdG8z")); + "EC50dXRvcmlhbC5QZXJzb25ClQEKG2NvbS5leGFtcGxlLnR1dG9yaWFsLnBy", + "b3Rvc0IRQWRkcmVzc0Jvb2tQcm90b3NQAVo6Z2l0aHViLmNvbS9wcm90b2Nv", + "bGJ1ZmZlcnMvcHJvdG9idWYvZXhhbXBsZXMvZ28vdHV0b3JpYWxwYqoCJEdv", + "b2dsZS5Qcm90b2J1Zi5FeGFtcGxlcy5BZGRyZXNzQm9va2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { diff --git a/csharp/src/Google.Protobuf.Benchmarks/Program.cs b/csharp/src/Google.Protobuf.Benchmarks/Program.cs index 1f77a26135eba..037752f6b78ec 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/Program.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/Program.cs @@ -36,7 +36,7 @@ namespace Google.Protobuf.Benchmarks { class Program { - // typical usage: dotnet run -c Release -f netcoreapp2.1 + // typical usage: dotnet run -c Release -f netcoreapp3.1 // (this can profile both .net core and .net framework; for some reason // if you start from "-f net461", it goes horribly wrong) public static void Main(string[] args) diff --git a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj index ec8fb9138947c..6277e6898a584 100644 --- a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj +++ b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 Exe False diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj index fee35be9910d3..b2c4272628a8e 100644 --- a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj +++ b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 Exe False 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 9f2ba6b0deeb9..5030043d760b4 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 @@ -1,4 +1,4 @@ - + - + diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs index d2db53d06ae61..94f089c3f2184 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs @@ -25,7 +25,7 @@ static TestMessagesProto2Reflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "Cipnb29nbGUvcHJvdG9idWYvdGVzdF9tZXNzYWdlc19wcm90bzIucHJvdG8S", - "HXByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8yIqQ+ChJUZXN0QWxsVHlw", + "HXByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8yIsQ+ChJUZXN0QWxsVHlw", "ZXNQcm90bzISFgoOb3B0aW9uYWxfaW50MzIYASABKAUSFgoOb3B0aW9uYWxf", "aW50NjQYAiABKAMSFwoPb3B0aW9uYWxfdWludDMyGAMgASgNEhcKD29wdGlv", "bmFsX3VpbnQ2NBgEIAEoBBIXCg9vcHRpb25hbF9zaW50MzIYBSABKBESFwoP", @@ -148,79 +148,81 @@ static TestMessagesProto2Reflection() { "NTY3ODkxMjM0NTY3ODkSHQoNZGVmYXVsdF9mbG9hdBj7ASABKAI6BTllKzA5", "Eh4KDmRlZmF1bHRfZG91YmxlGPwBIAEoAToFN2UrMjISGwoMZGVmYXVsdF9i", "b29sGP0BIAEoCDoEdHJ1ZRIgCg5kZWZhdWx0X3N0cmluZxj+ASABKAk6B1Jv", - "c2VidWQSEwoKZmllbGRuYW1lMRiRAyABKAUSFAoLZmllbGRfbmFtZTIYkgMg", - "ASgFEhUKDF9maWVsZF9uYW1lMxiTAyABKAUSFgoNZmllbGRfX25hbWU0XxiU", - "AyABKAUSFAoLZmllbGQwbmFtZTUYlQMgASgFEhYKDWZpZWxkXzBfbmFtZTYY", - "lgMgASgFEhMKCmZpZWxkTmFtZTcYlwMgASgFEhMKCkZpZWxkTmFtZTgYmAMg", - "ASgFEhQKC2ZpZWxkX05hbWU5GJkDIAEoBRIVCgxGaWVsZF9OYW1lMTAYmgMg", - "ASgFEhUKDEZJRUxEX05BTUUxMRibAyABKAUSFQoMRklFTERfbmFtZTEyGJwD", - "IAEoBRIXCg5fX2ZpZWxkX25hbWUxMxidAyABKAUSFwoOX19GaWVsZF9uYW1l", - "MTQYngMgASgFEhYKDWZpZWxkX19uYW1lMTUYnwMgASgFEhYKDWZpZWxkX19O", - "YW1lMTYYoAMgASgFEhcKDmZpZWxkX25hbWUxN19fGKEDIAEoBRIXCg5GaWVs", - "ZF9uYW1lMThfXxiiAyABKAUaYgoNTmVzdGVkTWVzc2FnZRIJCgFhGAEgASgF", - "EkYKC2NvcmVjdXJzaXZlGAIgASgLMjEucHJvdG9idWZfdGVzdF9tZXNzYWdl", - "cy5wcm90bzIuVGVzdEFsbFR5cGVzUHJvdG8yGjQKEk1hcEludDMySW50MzJF", - "bnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1hcElu", - "dDY0SW50NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6AjgB", - "GjYKFE1hcFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2YWx1", - "ZRgCIAEoDToCOAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5GAEg", - "ASgEEg0KBXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJFbnRy", - "eRILCgNrZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNpbnQ2", - "NFNpbnQ2NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoCOAEa", - "OAoWTWFwRml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoFdmFs", - "dWUYAiABKAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoDa2V5", - "GAEgASgGEg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNmaXhl", - "ZDMyRW50cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6ChhN", - "YXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZhbHVl", - "GAIgASgQOgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEgASgF", - "Eg0KBXZhbHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5EgsK", - "A2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJvb2xF", - "bnRyeRILCgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1hcFN0", - "cmluZ1N0cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToC", - "OAEaNQoTTWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFs", - "dWUYAiABKAw6AjgBGn4KG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRIL", - "CgNrZXkYASABKAkSTgoFdmFsdWUYAiABKAsyPy5wcm90b2J1Zl90ZXN0X21l", - "c3NhZ2VzLnByb3RvMi5UZXN0QWxsVHlwZXNQcm90bzIuTmVzdGVkTWVzc2Fn", - "ZToCOAEacwocTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VFbnRyeRILCgNrZXkY", - "ASABKAkSQgoFdmFsdWUYAiABKAsyMy5wcm90b2J1Zl90ZXN0X21lc3NhZ2Vz", - "LnByb3RvMi5Gb3JlaWduTWVzc2FnZVByb3RvMjoCOAEaeAoYTWFwU3RyaW5n", - "TmVzdGVkRW51bUVudHJ5EgsKA2tleRgBIAEoCRJLCgV2YWx1ZRgCIAEoDjI8", + "c2VidWQSHgoNZGVmYXVsdF9ieXRlcxj/ASABKAw6Bmpvc2h1YRITCgpmaWVs", + "ZG5hbWUxGJEDIAEoBRIUCgtmaWVsZF9uYW1lMhiSAyABKAUSFQoMX2ZpZWxk", + "X25hbWUzGJMDIAEoBRIWCg1maWVsZF9fbmFtZTRfGJQDIAEoBRIUCgtmaWVs", + "ZDBuYW1lNRiVAyABKAUSFgoNZmllbGRfMF9uYW1lNhiWAyABKAUSEwoKZmll", + "bGROYW1lNxiXAyABKAUSEwoKRmllbGROYW1lOBiYAyABKAUSFAoLZmllbGRf", + "TmFtZTkYmQMgASgFEhUKDEZpZWxkX05hbWUxMBiaAyABKAUSFQoMRklFTERf", + "TkFNRTExGJsDIAEoBRIVCgxGSUVMRF9uYW1lMTIYnAMgASgFEhcKDl9fZmll", + "bGRfbmFtZTEzGJ0DIAEoBRIXCg5fX0ZpZWxkX25hbWUxNBieAyABKAUSFgoN", + "ZmllbGRfX25hbWUxNRifAyABKAUSFgoNZmllbGRfX05hbWUxNhigAyABKAUS", + "FwoOZmllbGRfbmFtZTE3X18YoQMgASgFEhcKDkZpZWxkX25hbWUxOF9fGKID", + "IAEoBRpiCg1OZXN0ZWRNZXNzYWdlEgkKAWEYASABKAUSRgoLY29yZWN1cnNp", + "dmUYAiABKAsyMS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvMi5UZXN0", + "QWxsVHlwZXNQcm90bzIaNAoSTWFwSW50MzJJbnQzMkVudHJ5EgsKA2tleRgB", + "IAEoBRINCgV2YWx1ZRgCIAEoBToCOAEaNAoSTWFwSW50NjRJbnQ2NEVudHJ5", + "EgsKA2tleRgBIAEoAxINCgV2YWx1ZRgCIAEoAzoCOAEaNgoUTWFwVWludDMy", + "VWludDMyRW50cnkSCwoDa2V5GAEgASgNEg0KBXZhbHVlGAIgASgNOgI4ARo2", + "ChRNYXBVaW50NjRVaW50NjRFbnRyeRILCgNrZXkYASABKAQSDQoFdmFsdWUY", + "AiABKAQ6AjgBGjYKFE1hcFNpbnQzMlNpbnQzMkVudHJ5EgsKA2tleRgBIAEo", + "ERINCgV2YWx1ZRgCIAEoEToCOAEaNgoUTWFwU2ludDY0U2ludDY0RW50cnkS", + "CwoDa2V5GAEgASgSEg0KBXZhbHVlGAIgASgSOgI4ARo4ChZNYXBGaXhlZDMy", + "Rml4ZWQzMkVudHJ5EgsKA2tleRgBIAEoBxINCgV2YWx1ZRgCIAEoBzoCOAEa", + "OAoWTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeRILCgNrZXkYASABKAYSDQoFdmFs", + "dWUYAiABKAY6AjgBGjoKGE1hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeRILCgNr", + "ZXkYASABKA8SDQoFdmFsdWUYAiABKA86AjgBGjoKGE1hcFNmaXhlZDY0U2Zp", + "eGVkNjRFbnRyeRILCgNrZXkYASABKBASDQoFdmFsdWUYAiABKBA6AjgBGjQK", + "Ek1hcEludDMyRmxvYXRFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiAB", + "KAI6AjgBGjUKE01hcEludDMyRG91YmxlRW50cnkSCwoDa2V5GAEgASgFEg0K", + "BXZhbHVlGAIgASgBOgI4ARoyChBNYXBCb29sQm9vbEVudHJ5EgsKA2tleRgB", + "IAEoCBINCgV2YWx1ZRgCIAEoCDoCOAEaNgoUTWFwU3RyaW5nU3RyaW5nRW50", + "cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARo1ChNNYXBTdHJp", + "bmdCeXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoCOAEa", + "fgobTWFwU3RyaW5nTmVzdGVkTWVzc2FnZUVudHJ5EgsKA2tleRgBIAEoCRJO", + "CgV2YWx1ZRgCIAEoCzI/LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8y", + "LlRlc3RBbGxUeXBlc1Byb3RvMi5OZXN0ZWRNZXNzYWdlOgI4ARpzChxNYXBT", + "dHJpbmdGb3JlaWduTWVzc2FnZUVudHJ5EgsKA2tleRgBIAEoCRJCCgV2YWx1", + "ZRgCIAEoCzIzLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8yLkZvcmVp", + "Z25NZXNzYWdlUHJvdG8yOgI4ARp4ChhNYXBTdHJpbmdOZXN0ZWRFbnVtRW50", + "cnkSCwoDa2V5GAEgASgJEksKBXZhbHVlGAIgASgOMjwucHJvdG9idWZfdGVz", + "dF9tZXNzYWdlcy5wcm90bzIuVGVzdEFsbFR5cGVzUHJvdG8yLk5lc3RlZEVu", + "dW06AjgBGm0KGU1hcFN0cmluZ0ZvcmVpZ25FbnVtRW50cnkSCwoDa2V5GAEg", + "ASgJEj8KBXZhbHVlGAIgASgOMjAucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5w", + "cm90bzIuRm9yZWlnbkVudW1Qcm90bzI6AjgBGjMKBERhdGESFAoLZ3JvdXBf", + "aW50MzIYygEgASgFEhUKDGdyb3VwX3VpbnQzMhjLASABKA0aIQoRTWVzc2Fn", + "ZVNldENvcnJlY3QqCAgEEP////8HOgIIARrgAQobTWVzc2FnZVNldENvcnJl", + "Y3RFeHRlbnNpb24xEgsKA3N0chgZIAEoCTKzAQoVbWVzc2FnZV9zZXRfZXh0", + "ZW5zaW9uEkMucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzIuVGVzdEFs", + "bFR5cGVzUHJvdG8yLk1lc3NhZ2VTZXRDb3JyZWN0GPm7XiABKAsyTS5wcm90", + "b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvMi5UZXN0QWxsVHlwZXNQcm90bzIu", + "TWVzc2FnZVNldENvcnJlY3RFeHRlbnNpb24xGt8BChtNZXNzYWdlU2V0Q29y", + "cmVjdEV4dGVuc2lvbjISCQoBaRgJIAEoBTK0AQoVbWVzc2FnZV9zZXRfZXh0", + "ZW5zaW9uEkMucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzIuVGVzdEFs", + "bFR5cGVzUHJvdG8yLk1lc3NhZ2VTZXRDb3JyZWN0GJCz/AEgASgLMk0ucHJv", + "dG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzIuVGVzdEFsbFR5cGVzUHJvdG8y", + "Lk1lc3NhZ2VTZXRDb3JyZWN0RXh0ZW5zaW9uMiI5CgpOZXN0ZWRFbnVtEgcK", + "A0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8BKgUI", + "eBDJAUINCgtvbmVvZl9maWVsZEoGCOgHEJBOIiEKFEZvcmVpZ25NZXNzYWdl", + "UHJvdG8yEgkKAWMYASABKAUiwQIKFVVua25vd25Ub1Rlc3RBbGxUeXBlcxIX", + "Cg5vcHRpb25hbF9pbnQzMhjpByABKAUSGAoPb3B0aW9uYWxfc3RyaW5nGOoH", + "IAEoCRJMCg5uZXN0ZWRfbWVzc2FnZRjrByABKAsyMy5wcm90b2J1Zl90ZXN0", + "X21lc3NhZ2VzLnByb3RvMi5Gb3JlaWduTWVzc2FnZVByb3RvMhJaCg1vcHRp", + "b25hbGdyb3VwGOwHIAEoCjJCLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJv", + "dG8yLlVua25vd25Ub1Rlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwEhYKDW9w", + "dGlvbmFsX2Jvb2wY7gcgASgIEhcKDnJlcGVhdGVkX2ludDMyGPMHIAMoBRoa", + "Cg1PcHRpb25hbEdyb3VwEgkKAWEYASABKAUiFgoUTnVsbEh5cG90aGVzaXNQ", + "cm90bzIiLwoORW51bU9ubHlQcm90bzIiHQoEQm9vbBIKCgZrRmFsc2UQABIJ", + "CgVrVHJ1ZRABIh8KD09uZVN0cmluZ1Byb3RvMhIMCgRkYXRhGAEgASgJKkYK", + "EUZvcmVpZ25FbnVtUHJvdG8yEg8KC0ZPUkVJR05fRk9PEAASDwoLRk9SRUlH", + "Tl9CQVIQARIPCgtGT1JFSUdOX0JBWhACOkoKD2V4dGVuc2lvbl9pbnQzMhIx", "LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8yLlRlc3RBbGxUeXBlc1By", - "b3RvMi5OZXN0ZWRFbnVtOgI4ARptChlNYXBTdHJpbmdGb3JlaWduRW51bUVu", - "dHJ5EgsKA2tleRgBIAEoCRI/CgV2YWx1ZRgCIAEoDjIwLnByb3RvYnVmX3Rl", - "c3RfbWVzc2FnZXMucHJvdG8yLkZvcmVpZ25FbnVtUHJvdG8yOgI4ARozCgRE", - "YXRhEhQKC2dyb3VwX2ludDMyGMoBIAEoBRIVCgxncm91cF91aW50MzIYywEg", - "ASgNGiEKEU1lc3NhZ2VTZXRDb3JyZWN0KggIBBD/////BzoCCAEa4AEKG01l", - "c3NhZ2VTZXRDb3JyZWN0RXh0ZW5zaW9uMRILCgNzdHIYGSABKAkyswEKFW1l", - "c3NhZ2Vfc2V0X2V4dGVuc2lvbhJDLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMu", - "cHJvdG8yLlRlc3RBbGxUeXBlc1Byb3RvMi5NZXNzYWdlU2V0Q29ycmVjdBj5", - "u14gASgLMk0ucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzIuVGVzdEFs", - "bFR5cGVzUHJvdG8yLk1lc3NhZ2VTZXRDb3JyZWN0RXh0ZW5zaW9uMRrfAQob", - "TWVzc2FnZVNldENvcnJlY3RFeHRlbnNpb24yEgkKAWkYCSABKAUytAEKFW1l", - "c3NhZ2Vfc2V0X2V4dGVuc2lvbhJDLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMu", - "cHJvdG8yLlRlc3RBbGxUeXBlc1Byb3RvMi5NZXNzYWdlU2V0Q29ycmVjdBiQ", - "s/wBIAEoCzJNLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8yLlRlc3RB", - "bGxUeXBlc1Byb3RvMi5NZXNzYWdlU2V0Q29ycmVjdEV4dGVuc2lvbjIiOQoK", - "TmVzdGVkRW51bRIHCgNGT08QABIHCgNCQVIQARIHCgNCQVoQAhIQCgNORUcQ", - "////////////ASoFCHgQyQFCDQoLb25lb2ZfZmllbGRKBgjoBxCQTiIhChRG", - "b3JlaWduTWVzc2FnZVByb3RvMhIJCgFjGAEgASgFIsECChVVbmtub3duVG9U", - "ZXN0QWxsVHlwZXMSFwoOb3B0aW9uYWxfaW50MzIY6QcgASgFEhgKD29wdGlv", - "bmFsX3N0cmluZxjqByABKAkSTAoObmVzdGVkX21lc3NhZ2UY6wcgASgLMjMu", - "cHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzIuRm9yZWlnbk1lc3NhZ2VQ", - "cm90bzISWgoNb3B0aW9uYWxncm91cBjsByABKAoyQi5wcm90b2J1Zl90ZXN0", - "X21lc3NhZ2VzLnByb3RvMi5Vbmtub3duVG9UZXN0QWxsVHlwZXMuT3B0aW9u", - "YWxHcm91cBIWCg1vcHRpb25hbF9ib29sGO4HIAEoCBIXCg5yZXBlYXRlZF9p", - "bnQzMhjzByADKAUaGgoNT3B0aW9uYWxHcm91cBIJCgFhGAEgASgFIhYKFE51", - "bGxIeXBvdGhlc2lzUHJvdG8yIi8KDkVudW1Pbmx5UHJvdG8yIh0KBEJvb2wS", - "CgoGa0ZhbHNlEAASCQoFa1RydWUQASpGChFGb3JlaWduRW51bVByb3RvMhIP", - "CgtGT1JFSUdOX0ZPTxAAEg8KC0ZPUkVJR05fQkFSEAESDwoLRk9SRUlHTl9C", - "QVoQAjpKCg9leHRlbnNpb25faW50MzISMS5wcm90b2J1Zl90ZXN0X21lc3Nh", - "Z2VzLnByb3RvMi5UZXN0QWxsVHlwZXNQcm90bzIYeCABKAVCLwooY29tLmdv", - "b2dsZS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvMkgB+AEB")); + "b3RvMhh4IAEoBUIvCihjb20uZ29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVzc2Fn", + "ZXMucHJvdG8ySAH4AQE=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto2.ForeignEnumProto2), }, new pb::Extension[] { TestMessagesProto2Extensions.ExtensionInt32 }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "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", "Data", "DefaultInt32", "DefaultInt64", "DefaultUint32", "DefaultUint64", "DefaultSint32", "DefaultSint64", "DefaultFixed32", "DefaultFixed64", "DefaultSfixed32", "DefaultSfixed64", "DefaultFloat", "DefaultDouble", "DefaultBool", "DefaultString", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "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", "Data", "DefaultInt32", "DefaultInt64", "DefaultUint32", "DefaultUint64", "DefaultSint32", "DefaultSint64", "DefaultFixed32", "DefaultFixed64", "DefaultSfixed32", "DefaultSfixed64", "DefaultFloat", "DefaultDouble", "DefaultBool", "DefaultString", "DefaultBytes", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.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.Proto2.TestAllTypesProto2.Types.Data), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.Data.Parser, new[]{ "GroupInt32", "GroupUint32" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrect), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrect.Parser, null, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1.Parser, new[]{ "Str" }, null, null, new pb::Extension[] { global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1.Extensions.MessageSetExtension }, null), @@ -228,7 +230,8 @@ static TestMessagesProto2Reflection() { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.ForeignMessageProto2), global::ProtobufTestMessages.Proto2.ForeignMessageProto2.Parser, new[]{ "C" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalString", "NestedMessage", "OptionalGroup", "OptionalBool", "RepeatedInt32" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup.Parser, new[]{ "A" }, null, null, null, null)}), new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.NullHypothesisProto2), global::ProtobufTestMessages.Proto2.NullHypothesisProto2.Parser, null, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2), global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Parser, null, null, new[]{ typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Types.Bool) }, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2), global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Parser, null, null, new[]{ typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Types.Bool) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.OneStringProto2), global::ProtobufTestMessages.Proto2.OneStringProto2.Parser, new[]{ "Data" }, null, null, null, null) })); } #endregion @@ -404,6 +407,7 @@ public TestAllTypesProto2(TestAllTypesProto2 other) : this() { defaultDouble_ = other.defaultDouble_; defaultBool_ = other.defaultBool_; defaultString_ = other.defaultString_; + defaultBytes_ = other.defaultBytes_; fieldname1_ = other.fieldname1_; fieldName2_ = other.fieldName2_; FieldName3_ = other.FieldName3_; @@ -2394,6 +2398,32 @@ public void ClearDefaultString() { defaultString_ = null; } + /// Field number for the "default_bytes" field. + public const int DefaultBytesFieldNumber = 255; + private readonly static pb::ByteString DefaultBytesDefaultValue = pb::ByteString.FromBase64("am9zaHVh"); + + private pb::ByteString defaultBytes_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pb::ByteString DefaultBytes { + get { return defaultBytes_ ?? DefaultBytesDefaultValue; } + set { + defaultBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "default_bytes" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool HasDefaultBytes { + get { return defaultBytes_ != null; } + } + /// Clears the value of the "default_bytes" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void ClearDefaultBytes() { + defaultBytes_ = null; + } + /// Field number for the "fieldname1" field. public const int Fieldname1FieldNumber = 401; private readonly static int Fieldname1DefaultValue = 0; @@ -3041,6 +3071,7 @@ public bool Equals(TestAllTypesProto2 other) { if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DefaultDouble, other.DefaultDouble)) return false; if (DefaultBool != other.DefaultBool) return false; if (DefaultString != other.DefaultString) return false; + if (DefaultBytes != other.DefaultBytes) return false; if (Fieldname1 != other.Fieldname1) return false; if (FieldName2 != other.FieldName2) return false; if (FieldName3 != other.FieldName3) return false; @@ -3184,6 +3215,7 @@ public override int GetHashCode() { if (HasDefaultDouble) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DefaultDouble); if (HasDefaultBool) hash ^= DefaultBool.GetHashCode(); if (HasDefaultString) hash ^= DefaultString.GetHashCode(); + if (HasDefaultBytes) hash ^= DefaultBytes.GetHashCode(); if (HasFieldname1) hash ^= Fieldname1.GetHashCode(); if (HasFieldName2) hash ^= FieldName2.GetHashCode(); if (HasFieldName3) hash ^= FieldName3.GetHashCode(); @@ -3477,6 +3509,10 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(242, 15); output.WriteString(DefaultString); } + if (HasDefaultBytes) { + output.WriteRawTag(250, 15); + output.WriteBytes(DefaultBytes); + } if (HasFieldname1) { output.WriteRawTag(136, 25); output.WriteInt32(Fieldname1); @@ -3815,6 +3851,10 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(242, 15); output.WriteString(DefaultString); } + if (HasDefaultBytes) { + output.WriteRawTag(250, 15); + output.WriteBytes(DefaultBytes); + } if (HasFieldname1) { output.WriteRawTag(136, 25); output.WriteInt32(Fieldname1); @@ -4106,6 +4146,9 @@ public int CalculateSize() { if (HasDefaultString) { size += 2 + pb::CodedOutputStream.ComputeStringSize(DefaultString); } + if (HasDefaultBytes) { + size += 2 + pb::CodedOutputStream.ComputeBytesSize(DefaultBytes); + } if (HasFieldname1) { size += 2 + pb::CodedOutputStream.ComputeInt32Size(Fieldname1); } @@ -4366,6 +4409,9 @@ public void MergeFrom(TestAllTypesProto2 other) { if (other.HasDefaultString) { DefaultString = other.DefaultString; } + if (other.HasDefaultBytes) { + DefaultBytes = other.DefaultBytes; + } if (other.HasFieldname1) { Fieldname1 = other.Fieldname1; } @@ -4988,6 +5034,10 @@ public void MergeFrom(pb::CodedInputStream input) { DefaultString = input.ReadString(); break; } + case 2042: { + DefaultBytes = input.ReadBytes(); + break; + } case 3208: { Fieldname1 = input.ReadInt32(); break; @@ -5594,6 +5644,10 @@ public void MergeFrom(pb::CodedInputStream input) { DefaultString = input.ReadString(); break; } + case 2042: { + DefaultBytes = input.ReadBytes(); + break; + } case 3208: { Fieldname1 = input.ReadInt32(); break; @@ -8043,6 +8097,209 @@ public enum Bool { } + public sealed partial class OneStringProto2 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneStringProto2()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufTestMessages.Proto2.TestMessagesProto2Reflection.Descriptor.MessageTypes[5]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public OneStringProto2() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public OneStringProto2(OneStringProto2 other) : this() { + data_ = other.data_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public OneStringProto2 Clone() { + return new OneStringProto2(this); + } + + /// Field number for the "data" field. + public const int DataFieldNumber = 1; + private readonly static string DataDefaultValue = ""; + + private string data_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Data { + get { return data_ ?? DataDefaultValue; } + set { + data_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "data" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool HasData { + get { return data_ != null; } + } + /// Clears the value of the "data" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void ClearData() { + data_ = null; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as OneStringProto2); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(OneStringProto2 other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Data != other.Data) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (HasData) hash ^= Data.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasData) { + output.WriteRawTag(10); + output.WriteString(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + 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] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (HasData) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Data); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(OneStringProto2 other) { + if (other == null) { + return; + } + if (other.HasData) { + Data = other.Data; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + 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: { + Data = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + 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 + + } + #endregion } diff --git a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs index 61453e5ab2e6d..ff8f5cc6b1181 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs @@ -840,7 +840,7 @@ public void NaNValuesComparedBitwise() var list2 = new RepeatedField { SampleNaNs.Regular, SampleNaNs.PayloadFlipped }; var list3 = new RepeatedField { SampleNaNs.Regular, SampleNaNs.SignallingFlipped }; - // All SampleNaNs have the same hashcode under certain targets (e.g. netcoreapp2.1) + // All SampleNaNs have the same hashcode under certain targets (e.g. netcoreapp3.1) EqualityTester.AssertInequality(list1, list2, checkHashcode: false); EqualityTester.AssertEquality(list1, list3); Assert.True(list1.Contains(SampleNaNs.SignallingFlipped)); diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs index 1abed60563c86..894d914124939 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs @@ -380,5 +380,18 @@ public void RoundTrip_NestedExtensionGroup() TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }), message); } + + [Test] + public void RoundTrip_ParseUsingCodedInput() + { + var message = new TestAllExtensions(); + message.SetExtension(UnittestExtensions.OptionalBoolExtension, true); + byte[] bytes = message.ToByteArray(); + using (CodedInputStream input = new CodedInputStream(bytes)) + { + var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input); + Assert.AreEqual(message, parsed); + } + } } } diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj index cdfa98e09874c..deb17e9f52e47 100644 --- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj +++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj @@ -1,7 +1,7 @@  - net451;netcoreapp2.1;net50 + net451;netcoreapp3.1;net60 ../../keys/Google.Protobuf.snk true False @@ -21,7 +21,7 @@ - + diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs index 69c9eb6e998b5..eb8996e620f65 100644 --- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs @@ -35,6 +35,7 @@ using Google.Protobuf.WellKnownTypes; using NUnit.Framework; using ProtobufTestMessages.Proto2; +using ProtobufTestMessages.Proto3; using System; using UnitTest.Issues.TestProtos; @@ -551,13 +552,9 @@ public void NumberToDouble_Valid(string jsonValue, double expectedParsedValue) } [Test] - // Skip these test cases in .NET 5 because floating point parsing supports bigger values. - // These big values won't throw an error in the test. -#if !NET5_0 [TestCase("1.7977e308")] [TestCase("-1.7977e308")] [TestCase("1e309")] -#endif [TestCase("1,0")] [TestCase("1.0.0")] [TestCase("+1")] @@ -922,10 +919,10 @@ public void Bytes_InvalidBase64(string badBase64) } [Test] - [TestCase("\"FOREIGN_BAR\"", ForeignEnum.ForeignBar)] - [TestCase("5", ForeignEnum.ForeignBar)] - [TestCase("100", (ForeignEnum)100)] - public void EnumValid(string value, ForeignEnum expectedValue) + [TestCase("\"FOREIGN_BAR\"", TestProtos.ForeignEnum.ForeignBar)] + [TestCase("5", TestProtos.ForeignEnum.ForeignBar)] + [TestCase("100", (TestProtos.ForeignEnum)100)] + public void EnumValid(string value, TestProtos.ForeignEnum expectedValue) { string json = "{ \"singleForeignEnum\": " + value + " }"; var parsed = TestAllTypes.Parser.ParseJson(json); @@ -1025,5 +1022,128 @@ internal static string WrapInQuotes(string text) { return '"' + text + '"'; } + + [Test] + public void ParseAllNullValues() + { + string json = @"{ + ""optionalInt32"": null, + ""optionalInt64"": null, + ""optionalUint32"": null, + ""optionalUint64"": null, + ""optionalSint32"": null, + ""optionalSint64"": null, + ""optionalFixed32"": null, + ""optionalFixed64"": null, + ""optionalSfixed32"": null, + ""optionalSfixed64"": null, + ""optionalFloat"": null, + ""optionalDouble"": null, + ""optionalBool"": null, + ""optionalString"": null, + ""optionalBytes"": null, + ""optionalNestedEnum"": null, + ""optionalNestedMessage"": null, + ""repeatedInt32"": null, + ""repeatedInt64"": null, + ""repeatedUint32"": null, + ""repeatedUint64"": null, + ""repeatedSint32"": null, + ""repeatedSint64"": null, + ""repeatedFixed32"": null, + ""repeatedFixed64"": null, + ""repeatedSfixed32"": null, + ""repeatedSfixed64"": null, + ""repeatedFloat"": null, + ""repeatedDouble"": null, + ""repeatedBool"": null, + ""repeatedString"": null, + ""repeatedBytes"": null, + ""repeatedNestedEnum"": null, + ""repeatedNestedMessage"": null, + ""mapInt32Int32"": null, + ""mapBoolBool"": null, + ""mapStringNestedMessage"": null +}"; + + TestAllTypesProto3 message = new TestAllTypesProto3(); + + message.OptionalInt32 = 1; + message.OptionalInt64 = 1; + message.OptionalUint32 = 1; + message.OptionalUint64 = 1; + message.OptionalSint32 = 1; + message.OptionalSint64 = 1; + message.OptionalFixed32 = 1; + message.OptionalFixed64 = 1; + message.OptionalSfixed32 = 1; + message.OptionalSfixed64 = 1; + message.OptionalFloat = 1; + message.OptionalDouble = 1; + message.OptionalBool = true; + message.OptionalString = "1"; + message.OptionalBytes = ByteString.CopyFrom(new byte[] { 1 }); + message.OptionalNestedEnum = TestAllTypesProto3.Types.NestedEnum.Bar; + message.OptionalNestedMessage = new TestAllTypesProto3.Types.NestedMessage(); + message.RepeatedInt32.Add(1); + message.RepeatedInt64.Add(1); + message.RepeatedUint32.Add(1); + message.RepeatedUint64.Add(1); + message.RepeatedSint32.Add(1); + message.RepeatedSint64.Add(1); + message.RepeatedFixed32.Add(1); + message.RepeatedFixed64.Add(1); + message.RepeatedSfixed32.Add(1); + message.RepeatedSfixed64.Add(1); + message.RepeatedFloat.Add(1); + message.RepeatedDouble.Add(1); + message.RepeatedBool.Add(true); + message.RepeatedString.Add("1"); + message.RepeatedBytes.Add(ByteString.CopyFrom(new byte[] { 1 })); + message.RepeatedNestedEnum.Add(TestAllTypesProto3.Types.NestedEnum.Bar); + message.RepeatedNestedMessage.Add(new TestAllTypesProto3.Types.NestedMessage()); + message.MapInt32Int32.Add(1, 1); + message.MapBoolBool.Add(true, true); + message.MapStringNestedMessage.Add(" ", new TestAllTypesProto3.Types.NestedMessage()); + + JsonParser.Default.Merge(message, json); + + Assert.AreEqual(0, message.OptionalInt32); + Assert.AreEqual(0, message.OptionalInt64); + Assert.AreEqual(0, message.OptionalUint32); + Assert.AreEqual(0, message.OptionalUint64); + Assert.AreEqual(0, message.OptionalSint32); + Assert.AreEqual(0, message.OptionalSint64); + Assert.AreEqual(0, message.OptionalFixed32); + Assert.AreEqual(0, message.OptionalFixed64); + Assert.AreEqual(0, message.OptionalSfixed32); + Assert.AreEqual(0, message.OptionalSfixed64); + Assert.AreEqual(0, message.OptionalFloat); + Assert.AreEqual(0, message.OptionalDouble); + Assert.AreEqual(false, message.OptionalBool); + Assert.AreEqual("", message.OptionalString); + Assert.AreEqual(ByteString.Empty, message.OptionalBytes); + Assert.AreEqual(TestAllTypesProto3.Types.NestedEnum.Foo, message.OptionalNestedEnum); + Assert.AreEqual(null, message.OptionalNestedMessage); + Assert.AreEqual(0, message.RepeatedInt32.Count); + Assert.AreEqual(0, message.RepeatedInt64.Count); + Assert.AreEqual(0, message.RepeatedUint32.Count); + Assert.AreEqual(0, message.RepeatedUint64.Count); + Assert.AreEqual(0, message.RepeatedSint32.Count); + Assert.AreEqual(0, message.RepeatedSint64.Count); + Assert.AreEqual(0, message.RepeatedFixed32.Count); + Assert.AreEqual(0, message.RepeatedFixed64.Count); + Assert.AreEqual(0, message.RepeatedSfixed32.Count); + Assert.AreEqual(0, message.RepeatedFloat.Count); + Assert.AreEqual(0, message.RepeatedDouble.Count); + Assert.AreEqual(0, message.RepeatedBool.Count); + Assert.AreEqual(0, message.RepeatedString.Count); + Assert.AreEqual(0, message.RepeatedBytes.Count); + Assert.AreEqual(0, message.RepeatedNestedEnum.Count); + Assert.AreEqual(0, message.RepeatedNestedMessage.Count); + Assert.AreEqual(0, message.MapInt32Int32.Count); + Assert.AreEqual(0, message.MapBoolBool.Count); + Assert.AreEqual(0, message.MapStringNestedMessage.Count); + } } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs index 0cbc0a4ff8ec8..df43effd4ff0f 100644 --- a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs @@ -199,12 +199,8 @@ public void NumberValue(string json, double expectedValue) [TestCase("1e-")] [TestCase("--")] [TestCase("--1")] - // Skip these test cases in .NET 5 because floating point parsing supports bigger values. - // These big values won't throw an error in the test. -#if !NET5_0 [TestCase("-1.7977e308")] [TestCase("1.7977e308")] -#endif public void InvalidNumberValue(string json) { AssertThrowsAfter(json); diff --git a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs index fab983d463517..65c8b8267fbd5 100644 --- a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs @@ -124,6 +124,7 @@ private void TestFileDescriptor(FileDescriptor file, FileDescriptor importedFile } Assert.AreEqual(10, file.SerializedData[0]); + TestDescriptorToProto(file.ToProto, file.Proto); } [Test] @@ -231,6 +232,7 @@ public void MessageDescriptor() { Assert.AreEqual(i, messageType.EnumTypes[i].Index); } + TestDescriptorToProto(messageType.ToProto, messageType.Proto); } [Test] @@ -294,6 +296,11 @@ public void TestFieldDescriptor( // 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); + + TestDescriptorToProto(primitiveField.ToProto, primitiveField.Proto); + TestDescriptorToProto(enumField.ToProto, enumField.Proto); + TestDescriptorToProto(foreignMessageField.ToProto, foreignMessageField.Proto); + TestDescriptorToProto(fieldInOneof.ToProto, fieldInOneof.Proto); } [Test] @@ -338,6 +345,8 @@ public void EnumDescriptor() { Assert.AreEqual(i, enumType.Values[i].Index); } + TestDescriptorToProto(enumType.ToProto, enumType.Proto); + TestDescriptorToProto(nestedType.ToProto, nestedType.Proto); } [Test] @@ -361,6 +370,7 @@ public void OneofDescriptor() } CollectionAssert.AreEquivalent(expectedFields, descriptor.Fields); + TestDescriptorToProto(descriptor.ToProto, descriptor.Proto); } [Test] @@ -370,6 +380,7 @@ public void MapEntryMessageDescriptor() Assert.IsNull(descriptor.Parser); Assert.IsNull(descriptor.ClrType); Assert.IsNull(descriptor.Fields[1].Accessor); + TestDescriptorToProto(descriptor.ToProto, descriptor.Proto); } // From TestFieldOrdering: @@ -391,6 +402,7 @@ public void DescriptorProtoFileDescriptor() { var descriptor = Google.Protobuf.Reflection.FileDescriptor.DescriptorProtoFileDescriptor; Assert.AreEqual("google/protobuf/descriptor.proto", descriptor.Name); + TestDescriptorToProto(descriptor.ToProto, descriptor.Proto); } [Test] @@ -453,5 +465,17 @@ public void SyntheticOneofReflection() } } } + + private static void TestDescriptorToProto(Func toProtoFunction, IMessage expectedProto) + { + var clone1 = toProtoFunction(); + var clone2 = toProtoFunction(); + Assert.AreNotSame(clone1, clone2); + Assert.AreNotSame(clone1, expectedProto); + Assert.AreNotSame(clone2, expectedProto); + + Assert.AreEqual(clone1, clone2); + Assert.AreEqual(clone1, expectedProto); + } } } diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index f1f44f1c54670..2fc4b53029fe3 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/Compatibility/DynamicallyAccessedMemberTypes.cs b/csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs new file mode 100644 index 0000000000000..a4d739d80298a --- /dev/null +++ b/csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs @@ -0,0 +1,127 @@ +#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 + +#if !NET5_0_OR_GREATER +// Copied with permission from https://github.com/dotnet/runtime/tree/8fbf206d0e518b45ca855832e8bfb391afa85972/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Specifies the types of members that are dynamically accessed. + /// + /// This enumeration has a attribute that allows a + /// bitwise combination of its member values. + /// + [Flags] + internal enum DynamicallyAccessedMemberTypes + { + /// + /// Specifies no members. + /// + None = 0, + + /// + /// Specifies the default, parameterless public constructor. + /// + PublicParameterlessConstructor = 0x0001, + + /// + /// Specifies all public constructors. + /// + PublicConstructors = 0x0002 | PublicParameterlessConstructor, + + /// + /// Specifies all non-public constructors. + /// + NonPublicConstructors = 0x0004, + + /// + /// Specifies all public methods. + /// + PublicMethods = 0x0008, + + /// + /// Specifies all non-public methods. + /// + NonPublicMethods = 0x0010, + + /// + /// Specifies all public fields. + /// + PublicFields = 0x0020, + + /// + /// Specifies all non-public fields. + /// + NonPublicFields = 0x0040, + + /// + /// Specifies all public nested types. + /// + PublicNestedTypes = 0x0080, + + /// + /// Specifies all non-public nested types. + /// + NonPublicNestedTypes = 0x0100, + + /// + /// Specifies all public properties. + /// + PublicProperties = 0x0200, + + /// + /// Specifies all non-public properties. + /// + NonPublicProperties = 0x0400, + + /// + /// Specifies all public events. + /// + PublicEvents = 0x0800, + + /// + /// Specifies all non-public events. + /// + NonPublicEvents = 0x1000, + + /// + /// Specifies all interfaces implemented by the type. + /// + Interfaces = 0x2000, + + /// + /// Specifies all members. + /// + All = ~None + } +} +#endif diff --git a/csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs b/csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs new file mode 100644 index 0000000000000..ae0927623474d --- /dev/null +++ b/csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs @@ -0,0 +1,83 @@ +#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 + +#if !NET5_0_OR_GREATER +// Copied with permission from https://github.com/dotnet/runtime/tree/8fbf206d0e518b45ca855832e8bfb391afa85972/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that certain members on a specified are accessed dynamically, + /// for example through . + /// + /// + /// This allows tools to understand which members are being accessed during the execution + /// of a program. + /// + /// This attribute is valid on members whose type is or . + /// + /// When this attribute is applied to a location of type , the assumption is + /// that the string represents a fully qualified type name. + /// + /// When this attribute is applied to a class, interface, or struct, the members specified + /// can be accessed dynamically on instances returned from calling + /// on instances of that class, interface, or struct. + /// + /// If the attribute is applied to a method it's treated as a special case and it implies + /// the attribute should be applied to the "this" parameter of the method. As such the attribute + /// should only be used on instance methods of types assignable to System.Type (or string, but no methods + /// will use it there). + /// + [AttributeUsage( + AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter | + AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method | + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct, + Inherited = false)] + internal sealed class DynamicallyAccessedMembersAttribute : Attribute + { + /// + /// Initializes a new instance of the class + /// with the specified member types. + /// + /// The types of members dynamically accessed. + public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) + { + MemberTypes = memberTypes; + } + + /// + /// Gets the which specifies the type + /// of members dynamically accessed. + /// + public DynamicallyAccessedMemberTypes MemberTypes { get; } + } +} +#endif diff --git a/csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs b/csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs new file mode 100644 index 0000000000000..1fc8e66d49b16 --- /dev/null +++ b/csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs @@ -0,0 +1,72 @@ +#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 + +#if !NET5_0_OR_GREATER +// Copied with permission from https://github.com/dotnet/runtime/tree/8fbf206d0e518b45ca855832e8bfb391afa85972/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that the specified method requires dynamic access to code that is not referenced + /// statically, for example through . + /// + /// + /// This allows tools to understand which methods are unsafe to call when removing unreferenced + /// code from an application. + /// + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)] + internal sealed class RequiresUnreferencedCodeAttribute : Attribute + { + /// + /// Initializes a new instance of the class + /// with the specified message. + /// + /// + /// A message that contains information about the usage of unreferenced code. + /// + public RequiresUnreferencedCodeAttribute(string message) + { + Message = message; + } + + /// + /// Gets a message that contains information about the usage of unreferenced code. + /// + public string Message { get; } + + /// + /// Gets or sets an optional URL that contains more information about the method, + /// why it requires unreferenced code, and what options a consumer has to deal with it. + /// + public string Url { get; set; } + } +} +#endif diff --git a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs index 2f23713819f6a..b3acda2da7667 100644 --- a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs +++ b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs @@ -31,6 +31,7 @@ #endregion using System; +using System.Diagnostics.CodeAnalysis; using System.Reflection; #if !NET35 @@ -59,7 +60,11 @@ internal static bool IsAssignableFrom(this Type target, Type c) /// including inherited properties or null if there is no such public property. /// Here, "public property" means a property where either the getter, or the setter, or both, is public. /// - internal static PropertyInfo GetProperty(this Type target, string name) + [UnconditionalSuppressMessage("Trimming", "IL2072", + Justification = "The BaseType of the target will have all properties because of the annotation.")] + internal static PropertyInfo GetProperty( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] + this Type target, string name) { // GetDeclaredProperty only returns properties declared in the given type, so we need to recurse. while (target != null) @@ -86,7 +91,11 @@ internal static PropertyInfo GetProperty(this Type target, string name) /// class Child : Base declares public void Foo(long)). /// /// One type in the hierarchy declared more than one method with the same name - internal static MethodInfo GetMethod(this Type target, string name) + [UnconditionalSuppressMessage("Trimming", "IL2072", + Justification = "The BaseType of the target will have all properties because of the annotation.")] + internal static MethodInfo GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] + this Type target, string name) { // GetDeclaredMethod only returns methods declared in the given type, so we need to recurse. while (target != null) diff --git a/csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs b/csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs new file mode 100644 index 0000000000000..a02a1453ebb3e --- /dev/null +++ b/csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs @@ -0,0 +1,117 @@ +#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 + +#if !NET5_0_OR_GREATER +// Copied with permission from https://github.com/dotnet/runtime/tree/8fbf206d0e518b45ca855832e8bfb391afa85972/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Suppresses reporting of a specific rule violation, allowing multiple suppressions on a + /// single code artifact. + /// + /// + /// is different than + /// in that it doesn't have a + /// . So it is always preserved in the compiled assembly. + /// + [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] + internal sealed class UnconditionalSuppressMessageAttribute : Attribute + { + /// + /// Initializes a new instance of the + /// class, specifying the category of the tool and the identifier for an analysis rule. + /// + /// The category for the attribute. + /// The identifier of the analysis rule the attribute applies to. + public UnconditionalSuppressMessageAttribute(string category, string checkId) + { + Category = category; + CheckId = checkId; + } + + /// + /// Gets the category identifying the classification of the attribute. + /// + /// + /// The property describes the tool or tool analysis category + /// for which a message suppression attribute applies. + /// + public string Category { get; } + + /// + /// Gets the identifier of the analysis tool rule to be suppressed. + /// + /// + /// Concatenated together, the and + /// properties form a unique check identifier. + /// + public string CheckId { get; } + + /// + /// Gets or sets the scope of the code that is relevant for the attribute. + /// + /// + /// The Scope property is an optional argument that specifies the metadata scope for which + /// the attribute is relevant. + /// + public string Scope { get; set; } + + /// + /// Gets or sets a fully qualified path that represents the target of the attribute. + /// + /// + /// The property is an optional argument identifying the analysis target + /// of the attribute. An example value is "System.IO.Stream.ctor():System.Void". + /// Because it is fully qualified, it can be long, particularly for targets such as parameters. + /// The analysis tool user interface should be capable of automatically formatting the parameter. + /// + public string Target { get; set; } + + /// + /// Gets or sets an optional argument expanding on exclusion criteria. + /// + /// + /// The property is an optional argument that specifies additional + /// exclusion where the literal metadata target is not sufficiently precise. For example, + /// the cannot be applied within a method, + /// and it may be desirable to suppress a violation against a statement in the method that will + /// give a rule violation, but not against all statements in the method. + /// + public string MessageId { get; set; } + + /// + /// Gets or sets the justification for suppressing the code analysis message. + /// + public string Justification { get; set; } + } +} +#endif diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index f6d6069102ef7..8c2a68a1cd856 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -1,10 +1,10 @@ - + C# runtime library for Protocol Buffers - Google's data interchange format. Copyright 2015, Google Inc. Google Protocol Buffers - 3.18.1 + 3.19.4 7.2 Google Inc. @@ -15,12 +15,14 @@ Protocol;Buffers;Binary;Serialization;Format;Google;proto;proto3 C# proto3 support https://github.com/protocolbuffers/protobuf - https://github.com/protocolbuffers/protobuf/blob/master/LICENSE + BSD-3-Clause git https://github.com/protocolbuffers/protobuf.git - True + true + true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + true @@ -43,7 +45,7 @@ - + diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs index 4bffd58c1f406..17fdc7f738664 100644 --- a/csharp/src/Google.Protobuf/JsonFormatter.cs +++ b/csharp/src/Google.Protobuf/JsonFormatter.cs @@ -40,6 +40,7 @@ using System.Linq; using System.Collections.Generic; using System.Reflection; +using System.Diagnostics.CodeAnalysis; namespace Google.Protobuf { @@ -879,6 +880,8 @@ private static class OriginalEnumValueHelper private static readonly Dictionary> dictionaries = new Dictionary>(); + [UnconditionalSuppressMessage("Trimming", "IL2072", + Justification = "The field for the value must still be present. It will be returned by reflection, will be in this collection, and its name can be resolved.")] internal static string GetOriginalName(object value) { var enumType = value.GetType(); @@ -898,21 +901,13 @@ internal static string GetOriginalName(object value) return originalName; } -#if NET35 - // TODO: Consider adding functionality to TypeExtensions to avoid this difference. - private static Dictionary GetNameMapping(System.Type enumType) => - enumType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static) - .Where(f => (f.GetCustomAttributes(typeof(OriginalNameAttribute), false) - .FirstOrDefault() as OriginalNameAttribute) - ?.PreferredAlias ?? true) - .ToDictionary(f => f.GetValue(null), - f => (f.GetCustomAttributes(typeof(OriginalNameAttribute), false) - .FirstOrDefault() as OriginalNameAttribute) - // If the attribute hasn't been applied, fall back to the name of the field. - ?.Name ?? f.Name); -#else - private static Dictionary GetNameMapping(System.Type enumType) => - enumType.GetTypeInfo().DeclaredFields + private static Dictionary GetNameMapping( + [DynamicallyAccessedMembers( + DynamicallyAccessedMemberTypes.PublicFields | + DynamicallyAccessedMemberTypes.NonPublicFields)] + System.Type enumType) + { + return enumType.GetTypeInfo().DeclaredFields .Where(f => f.IsStatic) .Where(f => f.GetCustomAttributes() .FirstOrDefault()?.PreferredAlias ?? true) @@ -921,7 +916,7 @@ private static Dictionary GetNameMapping(System.Type enumType) = .FirstOrDefault() // If the attribute hasn't been applied, fall back to the name of the field. ?.Name ?? f.Name); -#endif + } } } } diff --git a/csharp/src/Google.Protobuf/JsonTokenizer.cs b/csharp/src/Google.Protobuf/JsonTokenizer.cs index 4725e7cc51197..13a12c05dd44c 100644 --- a/csharp/src/Google.Protobuf/JsonTokenizer.cs +++ b/csharp/src/Google.Protobuf/JsonTokenizer.cs @@ -471,9 +471,18 @@ private double ReadNumber(char initialCharacter) // TODO: What exception should we throw if the value can't be represented as a double? try { - return double.Parse(builder.ToString(), + double result = double.Parse(builder.ToString(), NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); + + // .NET Core 3.0 and later returns infinity if the number is too large or small to be represented. + // For compatibility with other Protobuf implementations the tokenizer should still throw. + if (double.IsInfinity(result)) + { + throw reader.CreateException("Numeric value out of range: " + builder); + } + + return result; } catch (OverflowException) { diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs index 30a25a8698d38..a10c908916408 100644 --- a/csharp/src/Google.Protobuf/MessageParser.cs +++ b/csharp/src/Google.Protobuf/MessageParser.cs @@ -187,14 +187,17 @@ public IMessage ParseJson(string json) internal void MergeFrom(IMessage message, CodedInputStream codedInput) { bool originalDiscard = codedInput.DiscardUnknownFields; + ExtensionRegistry originalRegistry = codedInput.ExtensionRegistry; try { codedInput.DiscardUnknownFields = DiscardUnknownFields; + codedInput.ExtensionRegistry = Extensions; message.MergeFrom(codedInput); } finally { codedInput.DiscardUnknownFields = originalDiscard; + codedInput.ExtensionRegistry = originalRegistry; } } diff --git a/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs b/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs index 9fc3766889b80..f6fa1522ba6ca 100644 --- a/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs +++ b/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs @@ -34,6 +34,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; @@ -63,6 +64,8 @@ namespace Google.Protobuf.Reflection /// public sealed class CustomOptions { + private const string UnreferencedCodeMessage = "CustomOptions is incompatible with trimming."; + private static readonly object[] EmptyParameters = new object[0]; private readonly IDictionary values; @@ -77,6 +80,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetBool(int field, out bool value) => TryGetPrimitiveValue(field, out value); /// @@ -85,6 +89,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetInt32(int field, out int value) => TryGetPrimitiveValue(field, out value); /// @@ -93,6 +98,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetInt64(int field, out long value) => TryGetPrimitiveValue(field, out value); /// @@ -102,6 +108,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetFixed32(int field, out uint value) => TryGetUInt32(field, out value); /// @@ -111,6 +118,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetFixed64(int field, out ulong value) => TryGetUInt64(field, out value); /// @@ -120,6 +128,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetSFixed32(int field, out int value) => TryGetInt32(field, out value); /// @@ -129,6 +138,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetSFixed64(int field, out long value) => TryGetInt64(field, out value); /// @@ -138,6 +148,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetSInt32(int field, out int value) => TryGetPrimitiveValue(field, out value); /// @@ -147,6 +158,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetSInt64(int field, out long value) => TryGetPrimitiveValue(field, out value); /// @@ -155,6 +167,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetUInt32(int field, out uint value) => TryGetPrimitiveValue(field, out value); /// @@ -163,6 +176,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetUInt64(int field, out ulong value) => TryGetPrimitiveValue(field, out value); /// @@ -171,6 +185,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetFloat(int field, out float value) => TryGetPrimitiveValue(field, out value); /// @@ -179,6 +194,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetDouble(int field, out double value) => TryGetPrimitiveValue(field, out value); /// @@ -187,6 +203,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetString(int field, out string value) => TryGetPrimitiveValue(field, out value); /// @@ -195,6 +212,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetBytes(int field, out ByteString value) => TryGetPrimitiveValue(field, out value); /// @@ -203,6 +221,7 @@ internal CustomOptions(IDictionary values) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. + [RequiresUnreferencedCode(UnreferencedCodeMessage)] public bool TryGetMessage(int field, out T value) where T : class, IMessage, new() { if (values == null) @@ -240,6 +259,7 @@ internal CustomOptions(IDictionary values) return false; } + [RequiresUnreferencedCode(UnreferencedCodeMessage)] private bool TryGetPrimitiveValue(int field, out T value) { if (values == null) diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index 5cae6ac9b22ba..1a9fade56635a 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -113,52 +113,53 @@ static DescriptorReflection() { "CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIRCgltYXBfZW50cnkYByABKAgS", "QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv", "YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAQQBUoECAUQ", - "BkoECAYQB0oECAgQCUoECAkQCiKeAwoMRmllbGRPcHRpb25zEjoKBWN0eXBl", + "BkoECAYQB0oECAgQCUoECAkQCiK+AwoMRmllbGRPcHRpb25zEjoKBWN0eXBl", "GAEgASgOMiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToG", "U1RSSU5HEg4KBnBhY2tlZBgCIAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29n", "bGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMK", - "BGxhenkYBSABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNl", - "EhMKBHdlYWsYCiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u", - "GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u", - "Ii8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElF", - "Q0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAES", - "DQoJSlNfTlVNQkVSEAIqCQjoBxCAgICAAkoECAQQBSJeCgxPbmVvZk9wdGlv", - "bnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy", - "b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoLRW51", - "bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMYAiABKAgSGQoKZGVwcmVjYXRlZBgD", - "IAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQu", - "Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICA", - "AkoECAUQBiJ9ChBFbnVtVmFsdWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASAB", - "KAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv", - "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi", - "ewoOU2VydmljZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2US", - "QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv", - "YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKtAgoNTWV0aG9k", - "T3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJfChFpZGVtcG90", - "ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRp", - "b25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV04SQwoU", + "BGxhenkYBSABKAg6BWZhbHNlEh4KD3VudmVyaWZpZWRfbGF6eRgPIAEoCDoF", + "ZmFsc2USGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEwoEd2VhaxgKIAEo", + "CDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29v", + "Z2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iLwoFQ1R5cGUSCgoG", + "U1RSSU5HEAASCAoEQ09SRBABEhAKDFNUUklOR19QSUVDRRACIjUKBkpTVHlw", + "ZRINCglKU19OT1JNQUwQABINCglKU19TVFJJTkcQARINCglKU19OVU1CRVIQ", + "AioJCOgHEICAgIACSgQIBBAFIl4KDE9uZW9mT3B0aW9ucxJDChR1bmludGVy", + "cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl", + "cnByZXRlZE9wdGlvbioJCOgHEICAgIACIpMBCgtFbnVtT3B0aW9ucxITCgth", + "bGxvd19hbGlhcxgCIAEoCBIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRJD", + "ChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9i", + "dWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACSgQIBRAGIn0KEEVu", + "dW1WYWx1ZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2USQwoU", "dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm", - "LlVuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJ", - "REVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoK", - "SURFTVBPVEVOVBACKgkI6AcQgICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRp", - "b24SOwoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJl", - "dGVkT3B0aW9uLk5hbWVQYXJ0EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkS", - "GgoScG9zaXRpdmVfaW50X3ZhbHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92", - "YWx1ZRgFIAEoAxIUCgxkb3VibGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3Zh", - "bHVlGAcgASgMEhcKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFy", - "dBIRCgluYW1lX3BhcnQYASACKAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIItUB", - "Cg5Tb3VyY2VDb2RlSW5mbxI6Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5w", - "cm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24S", - "EAoEcGF0aBgBIAMoBUICEAESEAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGlu", - "Z19jb21tZW50cxgDIAEoCRIZChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIh", - "ChlsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzGAYgAygJIqcBChFHZW5lcmF0", - "ZWRDb2RlSW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3Rv", - "YnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24aTwoKQW5ub3RhdGlv", - "bhIQCgRwYXRoGAEgAygFQgIQARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgVi", - "ZWdpbhgDIAEoBRILCgNlbmQYBCABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1", - "ZkIQRGVzY3JpcHRvclByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90", - "b2J1Zi90eXBlcy9kZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJv", - "dG9idWYuUmVmbGVjdGlvbg==")); + "LlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiJ7Cg5TZXJ2aWNlT3B0", + "aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJl", + "dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy", + "ZXRlZE9wdGlvbioJCOgHEICAgIACIq0CCg1NZXRob2RPcHRpb25zEhkKCmRl", + "cHJlY2F0ZWQYISABKAg6BWZhbHNlEl8KEWlkZW1wb3RlbmN5X2xldmVsGCIg", + "ASgOMi8uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVu", + "Y3lMZXZlbDoTSURFTVBPVEVOQ1lfVU5LTk9XThJDChR1bmludGVycHJldGVk", + "X29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRl", + "ZE9wdGlvbiJQChBJZGVtcG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VO", + "S05PV04QABITCg9OT19TSURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIq", + "CQjoBxCAgICAAiKeAgoTVW5pbnRlcnByZXRlZE9wdGlvbhI7CgRuYW1lGAIg", + "AygLMi0uZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFt", + "ZVBhcnQSGAoQaWRlbnRpZmllcl92YWx1ZRgDIAEoCRIaChJwb3NpdGl2ZV9p", + "bnRfdmFsdWUYBCABKAQSGgoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDEhQK", + "DGRvdWJsZV92YWx1ZRgGIAEoARIUCgxzdHJpbmdfdmFsdWUYByABKAwSFwoP", + "YWdncmVnYXRlX3ZhbHVlGAggASgJGjMKCE5hbWVQYXJ0EhEKCW5hbWVfcGFy", + "dBgBIAIoCRIUCgxpc19leHRlbnNpb24YAiACKAgi1QEKDlNvdXJjZUNvZGVJ", + "bmZvEjoKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnByb3RvYnVmLlNvdXJj", + "ZUNvZGVJbmZvLkxvY2F0aW9uGoYBCghMb2NhdGlvbhIQCgRwYXRoGAEgAygF", + "QgIQARIQCgRzcGFuGAIgAygFQgIQARIYChBsZWFkaW5nX2NvbW1lbnRzGAMg", + "ASgJEhkKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJEiEKGWxlYWRpbmdfZGV0", + "YWNoZWRfY29tbWVudHMYBiADKAkipwEKEUdlbmVyYXRlZENvZGVJbmZvEkEK", + "CmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVk", + "Q29kZUluZm8uQW5ub3RhdGlvbhpPCgpBbm5vdGF0aW9uEhAKBHBhdGgYASAD", + "KAVCAhABEhMKC3NvdXJjZV9maWxlGAIgASgJEg0KBWJlZ2luGAMgASgFEgsK", + "A2VuZBgEIAEoBUJ+ChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9y", + "UHJvdG9zSAFaLWdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2Rl", + "c2NyaXB0b3JwYvgBAaICA0dQQqoCGkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0", + "aW9u")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -175,7 +176,7 @@ static DescriptorReflection() { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "PhpGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "PhpMetadataNamespace", "RubyPackage", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "UnverifiedLazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null, null), @@ -2507,7 +2508,6 @@ public void ClearExtendee() { /// For booleans, "true" or "false". /// For strings, contains the default text contents (not escaped in any way). /// For bytes, contains the C escaped value. All bytes >= 128 are escaped. - /// TODO(kenton): Base-64 encode? /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -6943,6 +6943,7 @@ public FieldOptions(FieldOptions other) : this() { packed_ = other.packed_; jstype_ = other.jstype_; lazy_ = other.lazy_; + unverifiedLazy_ = other.unverifiedLazy_; deprecated_ = other.deprecated_; weak_ = other.weak_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); @@ -7096,6 +7097,12 @@ public void ClearJstype() { /// implementation must either *always* check its required fields, or *never* /// check its required fields, regardless of whether or not the message has /// been parsed. + /// + /// As of 2021, lazy does no correctness checks on the byte stream during + /// parsing. This may lead to crashes if and when an invalid byte stream is + /// finally parsed upon access. + /// + /// TODO(b/211906113): Enable validation on lazy fields. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -7119,6 +7126,38 @@ public void ClearLazy() { _hasBits0 &= ~8; } + /// Field number for the "unverified_lazy" field. + public const int UnverifiedLazyFieldNumber = 15; + private readonly static bool UnverifiedLazyDefaultValue = false; + + private bool unverifiedLazy_; + /// + /// unverified_lazy does no correctness checks on the byte stream. This should + /// only be used where lazy with verification is prohibitive for performance + /// reasons. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool UnverifiedLazy { + get { if ((_hasBits0 & 64) != 0) { return unverifiedLazy_; } else { return UnverifiedLazyDefaultValue; } } + set { + _hasBits0 |= 64; + unverifiedLazy_ = value; + } + } + /// Gets whether the "unverified_lazy" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool HasUnverifiedLazy { + get { return (_hasBits0 & 64) != 0; } + } + /// Clears the value of the "unverified_lazy" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void ClearUnverifiedLazy() { + _hasBits0 &= ~64; + } + /// Field number for the "deprecated" field. public const int DeprecatedFieldNumber = 3; private readonly static bool DeprecatedDefaultValue = false; @@ -7215,6 +7254,7 @@ public bool Equals(FieldOptions other) { if (Packed != other.Packed) return false; if (Jstype != other.Jstype) return false; if (Lazy != other.Lazy) return false; + if (UnverifiedLazy != other.UnverifiedLazy) return false; if (Deprecated != other.Deprecated) return false; if (Weak != other.Weak) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; @@ -7232,6 +7272,7 @@ public override int GetHashCode() { if (HasPacked) hash ^= Packed.GetHashCode(); if (HasJstype) hash ^= Jstype.GetHashCode(); if (HasLazy) hash ^= Lazy.GetHashCode(); + if (HasUnverifiedLazy) hash ^= UnverifiedLazy.GetHashCode(); if (HasDeprecated) hash ^= Deprecated.GetHashCode(); if (HasWeak) hash ^= Weak.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); @@ -7280,6 +7321,10 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(80); output.WriteBool(Weak); } + if (HasUnverifiedLazy) { + output.WriteRawTag(120); + output.WriteBool(UnverifiedLazy); + } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); if (_extensions != null) { _extensions.WriteTo(output); @@ -7318,6 +7363,10 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(80); output.WriteBool(Weak); } + if (HasUnverifiedLazy) { + output.WriteRawTag(120); + output.WriteBool(UnverifiedLazy); + } uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec); if (_extensions != null) { _extensions.WriteTo(ref output); @@ -7344,6 +7393,9 @@ public int CalculateSize() { if (HasLazy) { size += 1 + 1; } + if (HasUnverifiedLazy) { + size += 1 + 1; + } if (HasDeprecated) { size += 1 + 1; } @@ -7378,6 +7430,9 @@ public void MergeFrom(FieldOptions other) { if (other.HasLazy) { Lazy = other.Lazy; } + if (other.HasUnverifiedLazy) { + UnverifiedLazy = other.UnverifiedLazy; + } if (other.HasDeprecated) { Deprecated = other.Deprecated; } @@ -7427,6 +7482,10 @@ public void MergeFrom(pb::CodedInputStream input) { Weak = input.ReadBool(); break; } + case 120: { + UnverifiedLazy = input.ReadBool(); + break; + } case 7994: { uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; @@ -7472,6 +7531,10 @@ public void MergeFrom(pb::CodedInputStream input) { Weak = input.ReadBool(); break; } + case 120: { + UnverifiedLazy = input.ReadBool(); + break; + } case 7994: { uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec); break; diff --git a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs index f7e8b5b5f28db..3f2e1c41f5754 100644 --- a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs @@ -68,6 +68,14 @@ internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageD internal EnumDescriptorProto Proto { get { return proto; } } + /// + /// Returns a clone of the underlying describing this enum. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this enum descriptor. + public EnumDescriptorProto ToProto() => Proto.Clone(); + /// /// The brief name of the descriptor's target. /// diff --git a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs index 05097bd1da3d7..50b26a46bb4d7 100644 --- a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs @@ -55,6 +55,14 @@ internal EnumValueDescriptor(EnumValueDescriptorProto proto, FileDescriptor file internal EnumValueDescriptorProto Proto { get { return proto; } } + /// + /// Returns a clone of the underlying describing this enum value. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this enum value descriptor. + public EnumValueDescriptorProto ToProto() => Proto.Clone(); + /// /// Returns the name of the enum value described by this object. /// diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs index 7324e3dfc6381..84ad49d276380 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs @@ -45,7 +45,6 @@ public sealed class FieldDescriptor : DescriptorBase, IComparable @@ -70,6 +69,11 @@ public sealed class FieldDescriptor : DescriptorBase, IComparable public string JsonName { get; } + /// + /// The name of the property in the ContainingType.ClrType class. + /// + public string PropertyName { 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 @@ -87,6 +91,14 @@ public sealed class FieldDescriptor : DescriptorBase, IComparable + /// Returns a clone of the underlying describing this field. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this field descriptor. + public FieldDescriptorProto ToProto() => Proto.Clone(); + /// /// An extension identifier for this field, or null if this field isn't an extension. /// @@ -123,7 +135,7 @@ internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file, // for later. // We could trust the generated code and check whether the type of the property is // a MapField, but that feels a tad nasty. - this.propertyName = propertyName; + PropertyName = propertyName; Extension = extension; JsonName = Proto.JsonName == "" ? JsonFormatter.ToJsonName(Proto.Name) : Proto.JsonName; } @@ -235,7 +247,8 @@ public bool IsPacked } else { - return !Proto.Options.HasPacked || Proto.Options.Packed; + // Packed by default with proto3 + return Proto.Options == null || !Proto.Options.HasPacked || Proto.Options.Packed; } } } @@ -436,19 +449,19 @@ private IFieldAccessor CreateAccessor() // If we're given no property name, that's because we really don't want an accessor. // This could be because it's a map message, or it could be that we're loading a FileDescriptor dynamically. // TODO: Support dynamic messages. - if (propertyName == null) + if (PropertyName == null) { return null; } - var property = ContainingType.ClrType.GetProperty(propertyName); + var property = ContainingType.ClrType.GetProperty(PropertyName); if (property == null) { - throw new DescriptorValidationException(this, $"Property {propertyName} not found in {ContainingType.ClrType}"); + throw new DescriptorValidationException(this, $"Property {PropertyName} not found in {ContainingType.ClrType}"); } return IsMap ? new MapFieldAccessor(property, this) : IsRepeated ? new RepeatedFieldAccessor(property, this) - : (IFieldAccessor) new SingleFieldAccessor(property, this); + : (IFieldAccessor) new SingleFieldAccessor(ContainingType.ClrType, property, this); } } } diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs index 724bb3a04dad3..d7701da92e9c1 100644 --- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs @@ -249,6 +249,14 @@ private static IList DeterminePublicDependencies(FileDescriptor /// internal FileDescriptorProto Proto { get; } + /// + /// Returns a clone of the underlying describing this file. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this file descriptor. + public FileDescriptorProto ToProto() => Proto.Clone(); + /// /// The syntax of the file /// diff --git a/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs index 479e177130fce..d0a495b851b54 100644 --- a/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs +++ b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs @@ -30,6 +30,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion using System; +using System.Diagnostics.CodeAnalysis; namespace Google.Protobuf.Reflection { @@ -43,10 +44,19 @@ public sealed class GeneratedClrTypeInfo private static readonly string[] EmptyNames = new string[0]; private static readonly GeneratedClrTypeInfo[] EmptyCodeInfo = new GeneratedClrTypeInfo[0]; private static readonly Extension[] EmptyExtensions = new Extension[0]; + internal const DynamicallyAccessedMemberTypes MessageAccessibility = + // Creating types + DynamicallyAccessedMemberTypes.PublicConstructors | + // Getting and setting properties + DynamicallyAccessedMemberTypes.PublicProperties | + DynamicallyAccessedMemberTypes.NonPublicProperties | + // Calling presence methods + DynamicallyAccessedMemberTypes.PublicMethods; /// /// Irrelevant for file descriptors; the CLR type for the message for message descriptors. /// + [DynamicallyAccessedMembers(MessageAccessibility)] public Type ClrType { get; private set; } /// @@ -88,7 +98,11 @@ public sealed class GeneratedClrTypeInfo /// Each array parameter may be null, to indicate a lack of values. /// The parameter order is designed to make it feasible to format the generated code readably. /// - public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, Extension[] extensions, GeneratedClrTypeInfo[] nestedTypes) + public GeneratedClrTypeInfo( + // Preserve all public members on message types when trimming is enabled. + // This ensures that members used by reflection, e.g. JSON serialization, are preserved. + [DynamicallyAccessedMembers(MessageAccessibility)] + Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, Extension[] extensions, GeneratedClrTypeInfo[] nestedTypes) { NestedTypes = nestedTypes ?? EmptyCodeInfo; NestedEnums = nestedEnums ?? ReflectionUtil.EmptyTypes; @@ -104,7 +118,11 @@ public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propert /// Each array parameter may be null, to indicate a lack of values. /// The parameter order is designed to make it feasible to format the generated code readably. /// - public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes) + public GeneratedClrTypeInfo( + // Preserve all public members on message types when trimming is enabled. + // This ensures that members used by reflection, e.g. JSON serialization, are preserved. + [DynamicallyAccessedMembers(MessageAccessibility)] + Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes) : this(clrType, parser, propertyNames, oneofNames, nestedEnums, null, nestedTypes) { } diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs index 7b5ab2fb48e78..40a6ff832b1ae 100644 --- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; #if NET35 @@ -150,6 +151,14 @@ internal override IReadOnlyList GetNestedDescriptorListForField( internal DescriptorProto Proto { get; } + /// + /// Returns a clone of the underlying describing this message. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this message descriptor. + public DescriptorProto ToProto() => Proto.Clone(); + internal bool IsExtensionsInitialized(IMessage message) { if (Proto.ExtensionRange.Count == 0) @@ -182,6 +191,7 @@ internal bool IsExtensionsInitialized(IMessage message) /// a wrapper type, and handle the result appropriately. /// /// + [DynamicallyAccessedMembers(GeneratedClrTypeInfo.MessageAccessibility)] public Type ClrType { get; } /// diff --git a/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs index 8e1503767bd76..f5ecf2ea83cfd 100644 --- a/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs @@ -114,6 +114,14 @@ internal MethodDescriptor(MethodDescriptorProto proto, FileDescriptor file, internal MethodDescriptorProto Proto { get { return proto; } } + /// + /// Returns a clone of the underlying describing this method. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this method descriptor. + public MethodDescriptorProto ToProto() => Proto.Clone(); + /// /// The brief name of the descriptor's target. /// diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs index b41d5205158c8..ae29ded6473bf 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs @@ -45,7 +45,6 @@ namespace Google.Protobuf.Reflection /// public sealed class OneofDescriptor : DescriptorBase { - private readonly OneofDescriptorProto proto; private MessageDescriptor containingType; private IList fields; private readonly OneofAccessor accessor; @@ -53,7 +52,7 @@ public sealed class OneofDescriptor : DescriptorBase internal OneofDescriptor(OneofDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, string clrName) : base(file, file.ComputeFullName(parent, proto.Name), index) { - this.proto = proto; + this.Proto = proto; containingType = parent; file.DescriptorPool.AddSymbol(this); @@ -68,7 +67,18 @@ internal OneofDescriptor(OneofDescriptorProto proto, FileDescriptor file, Messag /// /// The brief name of the descriptor's target. /// - public override string Name { get { return proto.Name; } } + public override string Name => Proto.Name; + + // Visible for testing + internal OneofDescriptorProto Proto { get; } + + /// + /// Returns a clone of the underlying describing this oneof. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this oneof descriptor. + public OneofDescriptorProto ToProto() => Proto.Clone(); /// /// Gets the message type containing this oneof. @@ -118,7 +128,7 @@ public MessageDescriptor ContainingType /// The (possibly empty) set of custom options for this oneof. /// [Obsolete("CustomOptions are obsolete. Use the GetOptions method.")] - public CustomOptions CustomOptions => new CustomOptions(proto.Options?._extensions?.ValuesByNumber); + public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); /// /// The OneofOptions, defined in descriptor.proto. @@ -126,7 +136,7 @@ public MessageDescriptor ContainingType /// 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(); + public OneofOptions GetOptions() => Proto.Options?.Clone(); /// /// Gets a single value oneof option for this descriptor @@ -134,7 +144,7 @@ public MessageDescriptor ContainingType [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { - var value = proto.Options.GetExtension(extension); + var value = Proto.Options.GetExtension(extension); return value is IDeepCloneable ? (value as IDeepCloneable).Clone() : value; } @@ -144,7 +154,7 @@ public T GetOption(Extension extension) [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { - return proto.Options.GetExtension(extension).Clone(); + return Proto.Options.GetExtension(extension).Clone(); } internal void CrossLink() diff --git a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs index fd1ad4e3e0864..73efcc2566217 100644 --- a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs +++ b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs @@ -32,6 +32,7 @@ using Google.Protobuf.Compatibility; using System; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace Google.Protobuf.Reflection @@ -115,13 +116,15 @@ internal static Action CreateActionIMessage(MethodInfo method) => internal static Func CreateFuncIMessageBool(MethodInfo method) => GetReflectionHelper(method.DeclaringType, method.ReturnType).CreateFuncIMessageBool(method); - internal static Func CreateIsInitializedCaller(Type msg) => + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")] + internal static Func CreateIsInitializedCaller([DynamicallyAccessedMembers(GeneratedClrTypeInfo.MessageAccessibility)]Type msg) => ((IExtensionSetReflector)Activator.CreateInstance(typeof(ExtensionSetReflector<>).MakeGenericType(msg))).CreateIsInitializedCaller(); /// /// Creates a delegate which will execute the given method after casting the first argument to /// the type that declares the method, and the second argument to the first parameter type of the method. /// + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")] internal static IExtensionReflectionHelper CreateExtensionHelper(Extension extension) => (IExtensionReflectionHelper)Activator.CreateInstance(typeof(ExtensionReflectionHelper<,>).MakeGenericType(extension.TargetType, extension.GetType().GenericTypeArguments[1]), extension); @@ -131,6 +134,7 @@ internal static IExtensionReflectionHelper CreateExtensionHelper(Extension exten /// they can be garbage collected. We could cache them by type if that proves to be important, but creating /// an object is pretty cheap. /// + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")] private static IReflectionHelper GetReflectionHelper(Type t1, Type t2) => (IReflectionHelper) Activator.CreateInstance(typeof(ReflectionHelper<,>).MakeGenericType(t1, t2)); @@ -308,16 +312,14 @@ public void ClearExtension(IMessage message) } } - private class ExtensionSetReflector : IExtensionSetReflector where T1 : IExtendableMessage + private class ExtensionSetReflector< + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] + T1> : IExtensionSetReflector where T1 : IExtendableMessage { public Func CreateIsInitializedCaller() { var prop = typeof(T1).GetTypeInfo().GetDeclaredProperty("_Extensions"); -#if NET35 - var getFunc = (Func>)prop.GetGetMethod(true).CreateDelegate(typeof(Func>)); -#else var getFunc = (Func>)prop.GetMethod.CreateDelegate(typeof(Func>)); -#endif var initializedFunc = (Func, bool>) typeof(ExtensionSet) .GetTypeInfo() diff --git a/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs index dab348b6f8ec6..944ea11de14b5 100644 --- a/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs @@ -73,6 +73,14 @@ internal override IReadOnlyList GetNestedDescriptorListForField( internal ServiceDescriptorProto Proto { get { return proto; } } + /// + /// Returns a clone of the underlying describing this service. + /// Note that a copy is taken every time this method is called, so clients using it frequently + /// (and not modifying it) may want to cache the returned value. + /// + /// A protobuf representation of this service descriptor. + public ServiceDescriptorProto ToProto() => Proto.Clone(); + /// /// An unmodifiable list of methods in this service. /// diff --git a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs index 07d84d7fb914d..ac35e729f7b3e 100644 --- a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs +++ b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs @@ -31,6 +31,8 @@ #endregion using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using Google.Protobuf.Compatibility; @@ -50,7 +52,9 @@ internal sealed class SingleFieldAccessor : FieldAccessorBase private readonly Action clearDelegate; private readonly Func hasDelegate; - internal SingleFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) : base(property, descriptor) + internal SingleFieldAccessor( + [DynamicallyAccessedMembers(GeneratedClrTypeInfo.MessageAccessibility)] + Type messageType, PropertyInfo property, FieldDescriptor descriptor) : base(property, descriptor) { if (!property.CanWrite) { @@ -87,13 +91,13 @@ internal SingleFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) // 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; + MethodInfo hasMethod = messageType.GetRuntimeProperty("Has" + property.Name).GetMethod; 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); + MethodInfo clearMethod = messageType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes); if (clearMethod == null) { throw new ArgumentException("Not all required properties/methods are available"); @@ -107,16 +111,48 @@ internal SingleFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) hasDelegate = message => { throw new InvalidOperationException("Presence is not implemented for this field"); }; // While presence isn't supported, clearing still is; it's just setting to a default value. - var clrType = property.PropertyType; - - object defaultValue = - clrType == typeof(string) ? "" - : clrType == typeof(ByteString) ? ByteString.Empty - : Activator.CreateInstance(clrType); + object defaultValue = GetDefaultValue(descriptor); clearDelegate = message => SetValue(message, defaultValue); } } + private static object GetDefaultValue(FieldDescriptor descriptor) + { + switch (descriptor.FieldType) + { + case FieldType.Bool: + return false; + case FieldType.Bytes: + return ByteString.Empty; + case FieldType.String: + return ""; + case FieldType.Double: + return 0.0; + case FieldType.SInt32: + case FieldType.Int32: + case FieldType.SFixed32: + case FieldType.Enum: + return 0; + case FieldType.Fixed32: + case FieldType.UInt32: + return (uint)0; + case FieldType.Fixed64: + case FieldType.UInt64: + return 0UL; + case FieldType.SFixed64: + case FieldType.Int64: + case FieldType.SInt64: + return 0L; + case FieldType.Float: + return 0f; + case FieldType.Message: + case FieldType.Group: // Never expect to get this, but... + return null; + default: + throw new ArgumentException("Invalid field type"); + } + } + 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/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs index 91d2ee9094ab3..58a33cb6d44fe 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs @@ -33,6 +33,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using Google.Protobuf.Reflection; @@ -115,7 +116,7 @@ public static FieldMask FromString(string value) /// Parses from a string to a FieldMask and validates all field paths. /// /// The type to validate the field paths against. - public static FieldMask FromString(string value) where T : IMessage + public static FieldMask FromString<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(string value) where T : IMessage { return FromStringEnumerable(new List(value.Split(FIELD_PATH_SEPARATOR))); } @@ -124,7 +125,7 @@ public static FieldMask FromString(string value) where T : IMessage /// Constructs a FieldMask for a list of field paths in a certain type. /// /// The type to validate the field paths against. - public static FieldMask FromStringEnumerable(IEnumerable paths) where T : IMessage + public static FieldMask FromStringEnumerable<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(IEnumerable paths) where T : IMessage { var mask = new FieldMask(); foreach (var path in paths) @@ -151,7 +152,7 @@ public static FieldMask FromStringEnumerable(IEnumerable paths) where /// Constructs a FieldMask from the passed field numbers. /// /// The type to validate the field paths against. - public static FieldMask FromFieldNumbers(params int[] fieldNumbers) where T : IMessage + public static FieldMask FromFieldNumbers<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(params int[] fieldNumbers) where T : IMessage { return FromFieldNumbers((IEnumerable)fieldNumbers); } @@ -160,7 +161,7 @@ public static FieldMask FromFieldNumbers(params int[] fieldNumbers) where T : /// Constructs a FieldMask from the passed field numbers. /// /// The type to validate the field paths against. - public static FieldMask FromFieldNumbers(IEnumerable fieldNumbers) where T : IMessage + public static FieldMask FromFieldNumbers<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(IEnumerable fieldNumbers) where T : IMessage { var descriptor = Activator.CreateInstance().Descriptor; @@ -208,7 +209,7 @@ private static bool IsPathValid(string input) /// Checks whether paths in a given fields mask are valid. /// /// The type to validate the field paths against. - public static bool IsValid(FieldMask fieldMask) where T : IMessage + public static bool IsValid<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(FieldMask fieldMask) where T : IMessage { var descriptor = Activator.CreateInstance().Descriptor; @@ -235,7 +236,7 @@ public static bool IsValid(MessageDescriptor descriptor, FieldMask fieldMask) /// Checks whether a given field path is valid. /// /// The type to validate the field paths against. - public static bool IsValid(string path) where T : IMessage + public static bool IsValid<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(string path) where T : IMessage { var descriptor = Activator.CreateInstance().Descriptor; diff --git a/docs/options.md b/docs/options.md index 159951ac3c3eb..e4ca729c0af01 100644 --- a/docs/options.md +++ b/docs/options.md @@ -292,3 +292,11 @@ with info about your project (name and website) so we can add an entry for you. 1. Protoc-gen-jsonschema * Website: https://github.com/chrusty/protoc-gen-jsonschema * Extension: 1125-1129 + +1. Protoc-gen-checker + * Website: https://github.com/Intrinsec/protoc-gen-checker + * Extension: 1130-1139 + +1. Protoc-gen-go-svc + * Website: https://github.com/dane/protoc-gen-go-svc + * Extension: 1140 diff --git a/docs/third_party.md b/docs/third_party.md index 06b31b1d25dae..1bf36a8a9f4db 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -2,31 +2,32 @@ This page lists code related to Protocol Buffers which is developed and maintained by third parties. You may find this code useful, but note that **these projects are not affiliated with or endorsed by Google (unless explicitly marked)**; try them at your own risk. Also note that many projects here are in the early stages of development and not production-ready. -If you have a project that should be listed here, please [send us a pull request](https://github.com/google/protobuf/pulls) to update this page. +If you have a project that should be listed here, please +[send us a pull request](https://github.com/protocolbuffers/protobuf/pulls) to update this page. ## Programming Languages These are projects we know about implementing Protocol Buffers for other programming languages: -* Action Script: http://code.google.com/p/protobuf-actionscript3/ +* Action Script: https://code.google.com/p/protobuf-actionscript3/ * Action Script: https://code.google.com/p/protoc-gen-as3/ * Action Script: https://github.com/matrix3d/JProtoc * Action Script: https://github.com/zhongfq/protobuf-as3/ * Ada: https://github.com/reznikmm/protobuf * C: https://github.com/protobuf-c/protobuf-c -* C: http://koti.kapsi.fi/jpa/nanopb/ +* C: https://koti.kapsi.fi/jpa/nanopb/ * C: https://github.com/cloudwu/pbc/ * C: https://github.com/haberman/upb/wiki * C: https://github.com/squidfunk/protobluff * C: https://github.com/eerimoq/pbtools -* C++: https://github.com/google/protobuf (Google-official implementation) +* C++: https://github.com/protocolbuffers/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://code.google.com/p/protobuf-csharp-port * C#: https://silentorbit.com/protobuf/ -* C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/ +* C#/.NET/WCF/VB: https://code.google.com/p/protobuf-net/ * Clojure: http://github.com/ninjudd/clojure-protobuf * Clojure: https://github.com/clojusc/protobuf -* Clojure: https://protojure.github.io +* Clojure: https://protojure.readthedocs.io * Common Lisp: http://github.com/brown/protobuf * Common Lisp: http://github.com/qitab/cl-protobuf * D: https://github.com/dcarp/protobuf-d @@ -48,21 +49,20 @@ These are projects we know about implementing Protocol Buffers for other program * Go: https://github.com/akunspy/gopbuf * Go: https://github.com/gogo/protobuf * GopherJS: https://github.com/johanbrandhorst/protobuf -* Haskell: http://hackage.haskell.org/package/hprotoc +* Haskell: https://hackage.haskell.org/package/hprotoc * Haskell: https://github.com/google/proto-lens (Google-unofficial implementation) * Haskell: https://github.com/awakesecurity/proto3-suite (code generator) https://github.com/awakesecurity/proto3-wire (binary serializer/deserializer) * Haxe: https://github.com/Atry/protoc-gen-haxe -* Java: https://github.com/google/protobuf (Google-official implementation) +* Java: https://github.com/protocolbuffers/protobuf (Google-official implementation) * Java/Android: https://github.com/square/wire * Java: https://github.com/HebiRobotics/QuickBuffers/ -* Java ME: http://code.google.com/p/protobuf-javame/ +* Java ME: https://code.google.com/p/protobuf-javame/ * Java ME: http://swingme.sourceforge.net/encode.shtml -* Java ME: http://code.google.com/p/protobuf-j2me/ -* Javascript: http://code.google.com/p/protobuf-js/ +* Javascript: https://code.google.com/p/protobuf-js/ * Javascript: http://github.com/sirikata/protojs * 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://code.google.com/p/protobuf-for-node/ +* Javascript: https://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) * Javascript: https://github.com/ButterCam/sisyphus-js @@ -71,43 +71,45 @@ These are projects we know about implementing Protocol Buffers for other program * Kotlin: https://github.com/Kotlin/kotlinx.serialization * Kotlin: https://github.com/ButterCam/sisyphus * Kotlin: https://github.com/open-toast/protokt -* Lua: http://code.google.com/p/protoc-gen-lua/ +* Lua: https://code.google.com/p/protoc-gen-lua/ * Lua: http://github.com/indygreg/lua-protobuf * Lua: https://github.com/Neopallium/lua-pb -* Matlab: http://code.google.com/p/protobuf-matlab/ -* Mercury: http://code.google.com/p/protobuf-mercury/ -* Objective C: http://code.google.com/p/protobuf-objc/ +* Matlab: https://code.google.com/p/protobuf-matlab/ +* Mercury: https://code.google.com/p/protobuf-mercury/ +* Objective C: https://code.google.com/p/protobuf-objc/ * Objective C: https://github.com/alexeyxo/protobuf-objc * OCaml: http://piqi.org/ * Perl: http://groups.google.com/group/protobuf-perl -* Perl: http://search.cpan.org/perldoc?Google::ProtocolBuffers +* Perl: https://metacpan.org/pod/Google::ProtocolBuffers * Perl: https://metacpan.org/pod/Google::ProtocolBuffers::Dynamic -* Perl/XS: http://code.google.com/p/protobuf-perlxs/ -* PHP: http://code.google.com/p/pb4php/ +* Perl/XS: https://code.google.com/p/protobuf-perlxs/ +* PHP: https://code.google.com/p/pb4php/ * PHP: https://github.com/allegro/php-protobuf/ * 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/protocolbuffers/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: https://code.google.com/p/ruby-protobuf/ * Ruby: http://github.com/mozy/ruby-protocol-buffers * Ruby: https://github.com/bmizerany/beefcake/tree/master/lib/beefcake * Ruby: https://github.com/localshred/protobuf +* Rust: https://github.com/tokio-rs/prost * Rust: https://github.com/stepancheg/rust-protobuf/ +* Rust: https://github.com/tafia/quick-protobuf * Scala: http://github.com/jeffplaisance/scala-protobuf -* Scala: http://code.google.com/p/protobuf-scala +* Scala: https://code.google.com/p/protobuf-scala * Scala: https://github.com/SandroGrzicic/ScalaBuff * Scala: https://scalapb.github.io * Solidity: https://github.com/celer-network/pb3-gen-sol * Swift: https://github.com/alexeyxo/protobuf-swift * Swift: https://github.com/apple/swift-protobuf/ * Typescript: https://github.com/thesayyn/protoc-gen-ts +* Typescript: https://github.com/pbkit/pbkit * Vala: https://launchpad.net/protobuf-vala -* Visual Basic: http://code.google.com/p/protobuf-net/ +* Visual Basic: https://code.google.com/p/protobuf-net/ ## RPC Implementations @@ -128,6 +130,7 @@ GRPC (http://www.grpc.io/) is Google's RPC implementation for Protocol Buffers. * https://github.com/awakesecurity/gRPC-haskell (Haskell) * https://github.com/Yeolar/raster (C++) * https://github.com/jnordberg/wsrpc (JavaScript Node.js/Browser) +* https://github.com/pbkit/npm-packages/blob/main/frpc-test/src/index.spec.ts (TypeScript Node.js/Browser) * https://github.com/ppissias/xsrpcj (Java) * https://github.com/twitchtv/twirp (Multiple languages) @@ -157,24 +160,23 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [rules_closure](https://github.com/bazelbuild/rules_closure) `js-closure` * [rules_go](https://github.com/bazelbuild/rules_go) `go` * [rules_protobuf](https://github.com/pubref/rules_protobuf) `java` `c++` `c#` `go` `js-closure` `js-node` `python` `ruby` -* [NetBeans IDE plugin](http://code.google.com/p/protobuf-netbeans-plugin/) -* [Wireshark/Ethereal packet sniffer plugin](http://code.google.com/p/protobuf-wireshark/) -* [Alternate encodings (JSON, XML, HTML) for Java protobufs](http://code.google.com/p/protobuf-java-format/) +* [NetBeans IDE plugin](https://code.google.com/p/protobuf-netbeans-plugin/) +* [Wireshark/Ethereal packet sniffer plugin](https://code.google.com/p/protobuf-wireshark/) +* [Alternate encodings (JSON, XML, HTML) for Java protobufs](https://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/) +* [Editor for serialized protobufs](https://code.google.com/p/protobufeditor/) * [IntelliJ IDEA plugin](http://github.com/jvolkman/intellij-protobuf-editor) * [IntelliJ Protobuf Plugin](https://github.com/devkanro/intellij-protobuf-plugin) * [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/) +* [Oracle PL SQL plugin](https://code.google.com/p/protocol-buffer-plsql/) +* [Eclipse editor for protobuf (from Google)](https://code.google.com/p/protobuf-dt/) * [C++ Builder compatible protobuf](https://github.com/saadware/protobuf-cppbuilder) * Maven Protobuf Compiler Plugin * By xolstice.org ([Documentation](https://www.xolstice.org/protobuf-maven-plugin/)) ([Source](https://github.com/xolstice/protobuf-maven-plugin/)) [![Maven Central](https://img.shields.io/maven-central/v/org.xolstice.maven.plugins/protobuf-maven-plugin.svg)](https://repo1.maven.org/maven2/org/xolstice/maven/plugins/protobuf-maven-plugin/) - * http://igor-petruk.github.com/protobuf-maven-plugin/ - * http://code.google.com/p/maven-protoc-plugin/ + * https://code.google.com/p/maven-protoc-plugin/ * https://github.com/os72/protoc-jar-maven-plugin * [Documentation generator plugin (Markdown/HTML/DocBook/...)](https://github.com/pseudomuto/protoc-gen-doc) -* [DocBook generator for .proto files](http://code.google.com/p/protoc-gen-docbook/) +* [DocBook generator for .proto files](https://code.google.com/p/protoc-gen-docbook/) * [Protobuf for nginx module](https://github.com/dbcode/protobuf-nginx/) * [RSpec matchers and Cucumber step defs for testing Protocol Buffers](https://github.com/connamara/protobuf_spec) * [Sbt plugin for Protocol Buffers](https://github.com/Atry/sbt-cppp) diff --git a/editors/protobuf-mode.el b/editors/protobuf-mode.el index aa31bd0c44566..bbb82b7f4bda7 100644 --- a/editors/protobuf-mode.el +++ b/editors/protobuf-mode.el @@ -193,7 +193,7 @@ ;;;###autoload (add-to-list 'auto-mode-alist '("\\.proto\\'" . protobuf-mode)) ;;;###autoload -(defun protobuf-mode () +(define-derived-mode protobuf-mode prog-mode "Protobuf" "Major mode for editing Protocol Buffers description language. The hook `c-mode-common-hook' is run with no argument at mode diff --git a/examples/Makefile b/examples/Makefile index 8ed2492cd82d0..1c7ec8d632df3 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -16,7 +16,7 @@ clean: rm -f javac_middleman AddPerson*.class ListPeople*.class com/example/tutorial/*.class rm -f protoc_middleman addressbook.pb.cc addressbook.pb.h addressbook_pb2.py com/example/tutorial/AddressBookProtos.java rm -f *.pyc - rm -f protoc_middleman_go tutorial/*.pb.go add_person_go list_people_go go.mod go.sum + rm -f go/tutorialpb/*.pb.go add_person_go list_people_go rm -f protoc_middleman_dart dart_tutorial/*.pb*.dart rmdir dart_tutorial 2>/dev/null || true rmdir tutorial 2>/dev/null || true @@ -28,10 +28,9 @@ protoc_middleman: addressbook.proto protoc $$PROTO_PATH --cpp_out=. --java_out=. --python_out=. addressbook.proto @touch protoc_middleman -protoc_middleman_go: addressbook.proto - mkdir -p tutorial # make directory for go package - protoc $$PROTO_PATH --go_out=tutorial addressbook.proto - @touch protoc_middleman_go +go/tutorialpb/addressbook.pb.go: addressbook.proto + mkdir -p go/tutorialpb # make directory for go package + protoc $$PROTO_PATH --go_opt=paths=source_relative --go_out=go/tutorialpb addressbook.proto protoc_middleman_dart: addressbook.proto mkdir -p dart_tutorial # make directory for the dart package @@ -51,21 +50,17 @@ add_person_dart: add_person.dart protoc_middleman_dart list_people_dart: list_people.dart protoc_middleman_dart -go_mod: - go mod init github.com/protocolbuffers/protobuf/examples - go mod tidy +add_person_go: go/cmd/add_person/add_person.go go/tutorialpb/addressbook.pb.go + cd go && go build -o ../add_person_go ./cmd/add_person -add_person_go: add_person.go protoc_middleman_go go_mod - go build -o add_person_go add_person.go +add_person_gotest: go/tutorialpb/addressbook.pb.go + cd go && go test ./cmd/add_person -add_person_gotest: add_person_test.go add_person_go go_mod - go test add_person.go add_person_test.go +list_people_go: go/cmd/list_people/list_people.go go/tutorialpb/addressbook.pb.go + cd go && go build -o ../list_people_go ./cmd/list_people -list_people_go: list_people.go protoc_middleman_go go_mod - go build -o list_people_go list_people.go - -list_people_gotest: list_people.go list_people_go go_mod - go test list_people.go list_people_test.go +list_people_gotest: go/tutorialpb/addressbook.pb.go + cd go && go test ./cmd/list_people javac_middleman: AddPerson.java ListPeople.java protoc_middleman javac -cp $$CLASSPATH AddPerson.java ListPeople.java com/example/tutorial/AddressBookProtos.java diff --git a/examples/README.md b/examples/README.md index 4bf7c17cccf60..a99883e0660ec 100644 --- a/examples/README.md +++ b/examples/README.md @@ -91,22 +91,18 @@ scripts) and can be used to create/display an address book data file. ### Go -The Go example requires a plugin to the protocol buffer compiler, so it is not -build with all the other examples. See: +Follow instructions in [../README.md](../README.md) to install protoc. Then +install the Go protoc plugin (protoc-gen-go): - https://github.com/golang/protobuf + $ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest -for more information about Go protocol buffer support. +The "go install" command will install protoc-gen-go into the GOBIN +directory. You can set the $GOBIN environment variable before +running "go install" to change the install location. Make sure the +install directory is in your shell $PATH. -First, install the Protocol Buffers compiler (protoc). - -Then, install the Go Protocol Buffers plugin ($GOPATH/bin must be in your $PATH -for protoc to find it): - - go get github.com/golang/protobuf/protoc-gen-go - -Build the Go samples in this directory with "make go". This creates the -following executable files in the current directory: +Build the Go samples with "make go". This creates the following +executable files in the current directory: add_person_go list_people_go diff --git a/examples/addressbook.proto b/examples/addressbook.proto index 5bb35772d5430..1bff4ad3bd647 100644 --- a/examples/addressbook.proto +++ b/examples/addressbook.proto @@ -24,7 +24,7 @@ option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; // [END csharp_declaration] // [START go_declaration] -option go_package = "../tutorial"; +option go_package = "github.com/protocolbuffers/protobuf/examples/go/tutorialpb"; // [END go_declaration] // [START messages] diff --git a/examples/add_person.go b/examples/go/cmd/add_person/add_person.go similarity index 96% rename from examples/add_person.go rename to examples/go/cmd/add_person/add_person.go index 7ffb0ab095cc9..5d2f21c1f3f74 100644 --- a/examples/add_person.go +++ b/examples/go/cmd/add_person/add_person.go @@ -9,8 +9,8 @@ import ( "os" "strings" - "github.com/golang/protobuf/proto" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" + "google.golang.org/protobuf/proto" ) func promptForAddress(r io.Reader) (*pb.Person, error) { diff --git a/examples/add_person_test.go b/examples/go/cmd/add_person/add_person_test.go similarity index 88% rename from examples/add_person_test.go rename to examples/go/cmd/add_person/add_person_test.go index d35f10ece9ca5..f10c355a68101 100644 --- a/examples/add_person_test.go +++ b/examples/go/cmd/add_person/add_person_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" - "github.com/golang/protobuf/proto" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" + "google.golang.org/protobuf/proto" ) func TestPromptForAddressReturnsAddress(t *testing.T) { @@ -51,7 +51,7 @@ unknown } for i := 0; i < phones; i++ { if !proto.Equal(got.Phones[i], want[i]) { - t.Errorf("want phone %q, got %q", *want[i], *got.Phones[i]) + t.Errorf("want phone %q, got %q", want[i], got.Phones[i]) } } diff --git a/examples/list_people.go b/examples/go/cmd/list_people/list_people.go similarity index 92% rename from examples/list_people.go rename to examples/go/cmd/list_people/list_people.go index 6c2c34ac332a9..5ca0dcf31b9a5 100644 --- a/examples/list_people.go +++ b/examples/go/cmd/list_people/list_people.go @@ -7,8 +7,8 @@ import ( "log" "os" - "github.com/golang/protobuf/proto" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" + "google.golang.org/protobuf/proto" ) func writePerson(w io.Writer, p *pb.Person) { diff --git a/examples/list_people_test.go b/examples/go/cmd/list_people/list_people_test.go similarity index 97% rename from examples/list_people_test.go rename to examples/go/cmd/list_people/list_people_test.go index aceabd4a61089..b116c16a95325 100644 --- a/examples/list_people_test.go +++ b/examples/go/cmd/list_people/list_people_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" ) func TestWritePersonWritesPerson(t *testing.T) { diff --git a/examples/go/go.mod b/examples/go/go.mod new file mode 100644 index 0000000000000..ed43328d78f0d --- /dev/null +++ b/examples/go/go.mod @@ -0,0 +1,5 @@ +module github.com/protocolbuffers/protobuf/examples/go + +go 1.14 + +require google.golang.org/protobuf v1.27.1 diff --git a/examples/go/go.sum b/examples/go/go.sum new file mode 100644 index 0000000000000..9f8c06439826e --- /dev/null +++ b/examples/go/go.sum @@ -0,0 +1,6 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/global.json b/global.json index d29e29a3ea9dd..ade0252834d84 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "5.0.102", + "version": "6.0.100", "rollForward": "latestMinor" } } diff --git a/java/BUILD b/java/BUILD index e12d472d8c4c7..3e57ab6d7bf50 100644 --- a/java/BUILD +++ b/java/BUILD @@ -2,6 +2,8 @@ test_suite( name = "tests", tests = [ "//java/core:tests", + "//java/kotlin:tests", + "//java/kotlin-lite:tests", "//java/lite:tests", "//java/util:tests", ], @@ -13,4 +15,4 @@ filegroup( "//java/core:release", # contains lite. "//java/util:release", ] -) \ No newline at end of file +) diff --git a/java/README.md b/java/README.md index 849f9b0bb0ce5..0170b9d77269f 100644 --- a/java/README.md +++ b/java/README.md @@ -23,7 +23,7 @@ If you are using Maven, use the following: com.google.protobuf protobuf-java - 3.18.0 + 3.19.4 ``` @@ -37,7 +37,7 @@ protobuf-java-util package: com.google.protobuf protobuf-java-util - 3.18.0 + 3.19.4 ``` @@ -45,7 +45,7 @@ protobuf-java-util package: If you are using Gradle, add the following to your `build.gradle` file's dependencies: ``` - implementation 'com.google.protobuf:protobuf-java:3.18.0' + implementation 'com.google.protobuf:protobuf-java:3.19.4' ``` Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using. diff --git a/java/bom/pom.xml b/java/bom/pom.xml index c4ec6855370f4..f12aa0bc4b95f 100644 --- a/java/bom/pom.xml +++ b/java/bom/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-bom - 3.18.1 + 3.19.4 pom Protocol Buffers [BOM] @@ -29,7 +29,7 @@ - 3-Clause BSD License + BSD-3-Clause https://opensource.org/licenses/BSD-3-Clause diff --git a/java/core/BUILD b/java/core/BUILD index 42124bb4f011e..a698fc8e364f2 100644 --- a/java/core/BUILD +++ b/java/core/BUILD @@ -1,5 +1,5 @@ load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("@rules_java//java:defs.bzl", "java_library", "java_proto_library", "java_lite_proto_library") +load("@rules_java//java:defs.bzl", "java_library", "java_lite_proto_library", "java_proto_library") load("@rules_jvm_external//:defs.bzl", "java_export") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") load("//:internal.bzl", "conformance_test") @@ -103,7 +103,7 @@ LITE_SRCS = [ java_library( name = "lite", srcs = LITE_SRCS + [ - "//:gen_well_known_protos_javalite" + "//:gen_well_known_protos_javalite", ], visibility = [ "//java/lite:__pkg__", @@ -115,10 +115,10 @@ java_export( name = "lite_mvn", maven_coordinates = "com.google.protobuf:protobuf-javalite:%s" % PROTOBUF_VERSION, pom_template = "//java/lite:pom_template.xml", - runtime_deps = [":lite"], resources = [ "//:lite_well_known_protos", ], + runtime_deps = [":lite"], ) java_library( @@ -150,25 +150,25 @@ java_export( name = "core_mvn", maven_coordinates = "com.google.protobuf:protobuf-java:%s" % PROTOBUF_VERSION, pom_template = "pom_template.xml", - runtime_deps = [":core"], resources = [ "//:well_known_protos", ], + runtime_deps = [":core"], ) filegroup( name = "release", - visibility = ["//java:__pkg__"], srcs = [ - ":core_mvn-pom", - ":core_mvn-maven-source", ":core_mvn-docs", + ":core_mvn-maven-source", + ":core_mvn-pom", ":core_mvn-project", - ":lite_mvn-pom", - ":lite_mvn-maven-source", ":lite_mvn-docs", + ":lite_mvn-maven-source", + ":lite_mvn-pom", ":lite_mvn-project", - ] + ], + visibility = ["//java:__pkg__"], ) proto_lang_toolchain( @@ -176,6 +176,21 @@ proto_lang_toolchain( command_line = "--java_out=$(OUT)", runtime = ":core", visibility = ["//visibility:public"], + # keep this in sync w/ WELL_KNOWN_PROTO_MAP in //:BUILD + blacklisted_protos = [ + "//:any_proto", + "//:api_proto", + "//:compiler_plugin_proto", + "//:descriptor_proto", + "//:duration_proto", + "//:empty_proto", + "//:field_mask_proto", + "//:source_context_proto", + "//:struct_proto", + "//:timestamp_proto", + "//:type_proto", + "//:wrappers_proto", + ], ) proto_library( @@ -207,23 +222,25 @@ java_library( name = "test_util", srcs = [ "src/test/java/com/google/protobuf/TestUtil.java", - "src/test/java/com/google/protobuf/TestUtilLite.java" + "src/test/java/com/google/protobuf/TestUtilLite.java", ], deps = [ ":core", ":generic_test_protos_java_proto", ":java_test_protos_java_proto", - "//external:guava", - "//external:junit", + "@maven//:com_google_guava_guava", + "@maven//:junit_junit", ], + visibility = ["//java:__subpackages__"], ) test_suite( name = "tests", tests = [ - "core_build_test", "conformance_test", + "core_build_test", "core_tests", + "utf8_tests", ], ) @@ -236,30 +253,52 @@ build_test( conformance_test( name = "conformance_test", - testee = "//:conformance_java", failure_list = "//:conformance/failure_list_java.txt", + testee = "//:conformance_java", text_format_failure_list = "//:conformance/text_format_failure_list_java.txt", ) junit_tests( name = "core_tests", - srcs = glob(["src/test/java/**/*.java"], exclude = [ - "src/test/java/com/google/protobuf/TestUtil.java", - "src/test/java/com/google/protobuf/TestUtilLite.java", - ]), + size = "small", + srcs = glob( + ["src/test/java/**/*.java"], + exclude = [ + "src/test/java/com/google/protobuf/DecodeUtf8Test.java", + "src/test/java/com/google/protobuf/IsValidUtf8Test.java", + "src/test/java/com/google/protobuf/TestUtil.java", + "src/test/java/com/google/protobuf/TestUtilLite.java", + ], + ), data = ["//:testdata"], - size = "large", deps = [ ":core", ":generic_test_protos_java_proto", ":java_test_protos_java_proto", ":test_util", - "//external:easymock", - "//external:easymock_classextension", - "//external:guava", - "//external:junit", - "//external:truth", - ] + "@maven//:com_google_guava_guava", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + "@maven//:org_easymock_easymock", + ], +) + +# The UTF-8 validation tests are much slower than the other tests, so they get +# their own test target with a longer timeout. +junit_tests( + name = "utf8_tests", + size = "large", + srcs = [ + "src/test/java/com/google/protobuf/DecodeUtf8Test.java", + "src/test/java/com/google/protobuf/IsValidUtf8Test.java", + "src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java", + ], + deps = [ + ":core", + "@maven//:com_google_guava_guava", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], ) java_lite_proto_library( @@ -282,27 +321,28 @@ genrule( name = "rewrite_javalite_test_util", srcs = [ "//java/lite:lite.awk", - "src/test/java/com/google/protobuf/TestUtil.java" + "src/test/java/com/google/protobuf/TestUtil.java", ], outs = ["TestUtil.java"], - cmd = "awk -f $(location //java/lite:lite.awk) $(location src/test/java/com/google/protobuf/TestUtil.java) > $@" + cmd = "awk -f $(location //java/lite:lite.awk) $(location src/test/java/com/google/protobuf/TestUtil.java) > $@", ) java_library( name = "test_util_lite", srcs = [ + "src/test/java/com/google/protobuf/TestUtilLite.java", ":rewrite_javalite_test_util", - "src/test/java/com/google/protobuf/TestUtilLite.java" ], visibility = [ "//java/lite:__pkg__", + "//java/kotlin-lite:__pkg__", ], deps = [ ":generic_test_protos_java_proto_lite", ":java_test_protos_java_proto_lite", ":lite_runtime_only", - "//external:guava", - "//external:junit", + "@maven//:com_google_guava_guava", + "@maven//:junit_junit", ], ) @@ -344,6 +384,7 @@ LITE_TEST_EXCLUSIONS = [ "src/test/java/com/google/protobuf/TypeRegistryTest.java", "src/test/java/com/google/protobuf/UnknownEnumValueTest.java", "src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java", + "src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java", "src/test/java/com/google/protobuf/UnknownFieldSetTest.java", "src/test/java/com/google/protobuf/WellKnownTypesTest.java", "src/test/java/com/google/protobuf/WireFormatTest.java", @@ -351,18 +392,20 @@ LITE_TEST_EXCLUSIONS = [ junit_tests( name = "lite_tests", - srcs = glob(["src/test/java/**/*.java"], exclude = LITE_TEST_EXCLUSIONS), + size = "large", + srcs = glob( + ["src/test/java/**/*.java"], + exclude = LITE_TEST_EXCLUSIONS, + ), data = ["//:testdata"], test_prefix = "Lite", - size = "large", deps = [ - ":lite", ":generic_test_protos_java_proto_lite", ":java_test_protos_java_proto_lite", + ":lite", ":test_util_lite", - "//external:easymock", - "//external:junit", - "//external:truth", - ] + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + "@maven//:org_easymock_easymock", + ], ) - diff --git a/java/core/generate-test-sources-build.xml b/java/core/generate-test-sources-build.xml index 71a88d07b33b3..db44a15ab2ed9 100644 --- a/java/core/generate-test-sources-build.xml +++ b/java/core/generate-test-sources-build.xml @@ -30,7 +30,6 @@ - diff --git a/java/core/pom.xml b/java/core/pom.xml index 3b56150e1cc95..ce068ee684037 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.18.1 + 3.19.4 protobuf-java diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java index 1364fce41ec40..b36c94f9c6d49 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java @@ -224,7 +224,7 @@ private static boolean compareMapField(Object a, Object b) { } /** - * Compares two set of fields. This method is used to implement {@link + * Compares two sets of fields. This method is used to implement {@link * AbstractMessage#equals(Object)} and {@link AbstractMutableMessage#equals(Object)}. It takes * special care of bytes fields because immutable messages and mutable messages use different Java * type to represent a bytes field and this method should be able to compare immutable messages, @@ -242,8 +242,8 @@ static boolean compareFields(Map a, Map list1 = (List) value1; + List list2 = (List) value2; if (list1.size() != list2.size()) { return false; } @@ -383,8 +383,6 @@ BuilderType mergeFrom(final Message other, Map allField // them to insure that they don't change after verification (since // the Message interface itself cannot enforce immutability of // implementations). - // TODO(kenton): Provide a function somewhere called makeDeepCopy() - // which allows people to make secure deep copies of messages. for (final Map.Entry entry : allFields.entrySet()) { final FieldDescriptor field = entry.getKey(); @@ -568,17 +566,6 @@ public BuilderType mergeFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException { return (BuilderType) super.mergeFrom(input, extensionRegistry); } - - @Override - public boolean mergeDelimitedFrom(final InputStream input) throws IOException { - return super.mergeDelimitedFrom(input); - } - - @Override - public boolean mergeDelimitedFrom( - final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException { - return super.mergeDelimitedFrom(input, extensionRegistry); - } } /** diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java index 4e3cf427184a1..7ad2a85cf013e 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java @@ -89,9 +89,9 @@ public void writeDelimitedTo(final OutputStream output) throws IOException { final int serialized = getSerializedSize(); final int bufferSize = CodedOutputStream.computePreferredBufferSize( - CodedOutputStream.computeRawVarint32Size(serialized) + serialized); + CodedOutputStream.computeUInt32SizeNoTag(serialized) + serialized); final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output, bufferSize); - codedOutput.writeRawVarint32(serialized); + codedOutput.writeUInt32NoTag(serialized); writeTo(codedOutput); codedOutput.flush(); } @@ -316,8 +316,11 @@ public int read(final byte[] b, final int off, int len) throws IOException { @Override public long skip(final long n) throws IOException { - final long result = super.skip(Math.min(n, limit)); + // because we take the minimum of an int and a long, result is guaranteed to be + // less than or equal to Integer.MAX_INT so this cast is safe + int result = (int) super.skip(Math.min(n, limit)); if (result >= 0) { + // if the superclass adheres to the contract for skip, this condition is always true limit -= result; } return result; diff --git a/java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java b/java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java index a01a6c1a8b75f..94b09944d1a84 100644 --- a/java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java +++ b/java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java @@ -38,6 +38,7 @@ * A buffer that was allocated by a {@link BufferAllocator}. For every buffer, it is guaranteed that * at least one of {@link #hasArray()} or {@link #hasNioBuffer()} will be {@code true}. */ +@CheckReturnValue @ExperimentalApi abstract class AllocatedBuffer { /** @@ -106,6 +107,7 @@ abstract class AllocatedBuffer { * @return This buffer * @throws IllegalArgumentException If the preconditions on {@code position} do not hold */ + @CanIgnoreReturnValue public abstract AllocatedBuffer position(int position); /** diff --git a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java index 1217e112e0cef..65bbfd1186189 100644 --- a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java +++ b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java @@ -43,6 +43,7 @@ * IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when * crossing protobuf public API boundaries. */ +@CheckReturnValue final class ArrayDecoders { /** * A helper used to return multiple values in a Java function. Java doesn't natively support @@ -548,7 +549,6 @@ static int decodePackedSInt32List( } /** Decodes a packed sint64 field. Returns the position after all read values. */ - @SuppressWarnings("unchecked") static int decodePackedSInt64List( byte[] data, int position, ProtobufList list, Registers registers) throws IOException { final LongArrayList output = (LongArrayList) list; diff --git a/java/core/src/main/java/com/google/protobuf/BinaryReader.java b/java/core/src/main/java/com/google/protobuf/BinaryReader.java index d64574c2a581e..85e8616a9c4a5 100644 --- a/java/core/src/main/java/com/google/protobuf/BinaryReader.java +++ b/java/core/src/main/java/com/google/protobuf/BinaryReader.java @@ -48,6 +48,7 @@ * A {@link Reader} that reads from a buffer containing a message serialized with the binary * protocol. */ +@CheckReturnValue @ExperimentalApi abstract class BinaryReader implements Reader { private static final int FIXED32_MULTIPLE_MASK = FIXED32_SIZE - 1; @@ -271,6 +272,7 @@ private T readMessage(Schema schema, ExtensionRegistryLite extensionRegis } } + @Deprecated @Override public T readGroup(Class clazz, ExtensionRegistryLite extensionRegistry) throws IOException { @@ -278,6 +280,7 @@ public T readGroup(Class clazz, ExtensionRegistryLite extensionRegistry) return readGroup(Protobuf.getInstance().schemaFor(clazz), extensionRegistry); } + @Deprecated @Override public T readGroupBySchemaWithCheck( Schema schema, ExtensionRegistryLite extensionRegistry) throws IOException { @@ -956,6 +959,7 @@ public void readMessageList( } } + @Deprecated @Override public void readGroupList( List target, Class targetType, ExtensionRegistryLite extensionRegistry) @@ -964,6 +968,7 @@ public void readGroupList( readGroupList(target, schema, extensionRegistry); } + @Deprecated @Override public void readGroupList( List target, Schema schema, ExtensionRegistryLite extensionRegistry) diff --git a/java/core/src/main/java/com/google/protobuf/BinaryWriter.java b/java/core/src/main/java/com/google/protobuf/BinaryWriter.java index 94259ecd32bba..cf394e337167f 100644 --- a/java/core/src/main/java/com/google/protobuf/BinaryWriter.java +++ b/java/core/src/main/java/com/google/protobuf/BinaryWriter.java @@ -65,6 +65,7 @@ * The {@link #getTotalBytesWritten()} will continue to reflect the total of the write and will not * be reset. */ +@CheckReturnValue @ExperimentalApi abstract class BinaryWriter extends ByteOutput implements Writer { public static final int DEFAULT_CHUNK_SIZE = 4096; @@ -162,6 +163,7 @@ public final FieldOrder fieldOrder() { *

After calling this method, the writer can not be reused. Create a new writer for future * writes. */ + @CanIgnoreReturnValue public final Queue complete() { finishCurrentBuffer(); return buffers; @@ -808,6 +810,7 @@ public final void writeMessageList(int fieldNumber, List list, Schema schema) } } + @Deprecated @Override public final void writeGroupList(int fieldNumber, List list) throws IOException { for (int i = list.size() - 1; i >= 0; i--) { @@ -815,6 +818,7 @@ public final void writeGroupList(int fieldNumber, List list) throws IOExcepti } } + @Deprecated @Override public final void writeGroupList(int fieldNumber, List list, Schema schema) throws IOException { @@ -1080,6 +1084,7 @@ public void writeMessage(int fieldNumber, Object value, Schema schema) throws IO writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); } + @Deprecated @Override public void writeGroup(int fieldNumber, Object value) throws IOException { writeTag(fieldNumber, WIRETYPE_END_GROUP); @@ -1497,8 +1502,8 @@ private void nextBuffer(AllocatedBuffer allocatedBuffer) { this.allocatedBuffer = allocatedBuffer; this.buffer = allocatedBuffer.array(); int arrayOffset = allocatedBuffer.arrayOffset(); - this.limit = arrayOffset + allocatedBuffer.limit(); - this.offset = arrayOffset + allocatedBuffer.position(); + this.limit = (long) arrayOffset + allocatedBuffer.limit(); + this.offset = (long) arrayOffset + allocatedBuffer.position(); this.offsetMinusOne = offset - 1; this.limitMinusOne = limit - 1; this.pos = limitMinusOne; @@ -2148,6 +2153,7 @@ public void writeMessage(int fieldNumber, Object value, Schema schema) throws IO writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); } + @Deprecated @Override public void writeGroup(int fieldNumber, Object value) throws IOException { writeTag(fieldNumber, WIRETYPE_END_GROUP); @@ -2162,11 +2168,13 @@ public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOEx writeTag(fieldNumber, WIRETYPE_START_GROUP); } + @Deprecated @Override public void writeStartGroup(int fieldNumber) { writeTag(fieldNumber, WIRETYPE_START_GROUP); } + @Deprecated @Override public void writeEndGroup(int fieldNumber) { writeTag(fieldNumber, WIRETYPE_END_GROUP); @@ -2719,11 +2727,13 @@ public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOEx writeTag(fieldNumber, WIRETYPE_START_GROUP); } + @Deprecated @Override public void writeStartGroup(int fieldNumber) { writeTag(fieldNumber, WIRETYPE_START_GROUP); } + @Deprecated @Override public void writeEndGroup(int fieldNumber) { writeTag(fieldNumber, WIRETYPE_END_GROUP); diff --git a/java/core/src/main/java/com/google/protobuf/BufferAllocator.java b/java/core/src/main/java/com/google/protobuf/BufferAllocator.java index bfd9c7237c0e2..a2295399e895f 100644 --- a/java/core/src/main/java/com/google/protobuf/BufferAllocator.java +++ b/java/core/src/main/java/com/google/protobuf/BufferAllocator.java @@ -36,6 +36,7 @@ * An object responsible for allocation of buffers. This is an extension point to enable buffer * pooling within an application. */ +@CheckReturnValue @ExperimentalApi abstract class BufferAllocator { private static final BufferAllocator UNPOOLED = diff --git a/java/core/src/main/java/com/google/protobuf/ByteString.java b/java/core/src/main/java/com/google/protobuf/ByteString.java index a4beaeb4cffb3..f9e8efd40499a 100644 --- a/java/core/src/main/java/com/google/protobuf/ByteString.java +++ b/java/core/src/main/java/com/google/protobuf/ByteString.java @@ -236,6 +236,11 @@ public final boolean isEmpty() { return size() == 0; } + /** Returns an empty {@code ByteString} of size {@code 0}. */ + public static final ByteString empty() { + return EMPTY; + } + // ================================================================= // Comparison @@ -253,6 +258,38 @@ private static int toInt(byte value) { return value & UNSIGNED_BYTE_MASK; } + /** Returns the numeric value of the given character in hex, or -1 if invalid. */ + private static int hexDigit(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } else if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } else { + return -1; + } + } + + /** + * Returns the numeric value of the given character at index in hexString. + * + * @throws NumberFormatException if the hexString character is invalid. + */ + private static int extractHexDigit(String hexString, int index) { + int digit = hexDigit(hexString.charAt(index)); + if (digit == -1) { + throw new NumberFormatException( + "Invalid hexString " + + hexString + + " must only contain [0-9a-fA-F] but contained " + + hexString.charAt(index) + + " at index " + + index); + } + return digit; + } + /** * Compares two {@link ByteString}s lexicographically, treating their contents as unsigned byte * values between 0 and 255 (inclusive). @@ -282,8 +319,8 @@ public int compare(ByteString former, ByteString latter) { }; /** - * Returns a {@link Comparator} which compares {@link ByteString}-s lexicographically - * as sequences of unsigned bytes (i.e. values between 0 and 255, inclusive). + * Returns a {@link Comparator} which compares {@link ByteString}-s lexicographically as sequences + * of unsigned bytes (i.e. values between 0 and 255, inclusive). * *

For example, {@code (byte) -1} is considered to be greater than {@code (byte) 1} because it * is interpreted as an unsigned value, {@code 255}: @@ -346,6 +383,30 @@ public final boolean endsWith(ByteString suffix) { return size() >= suffix.size() && substring(size() - suffix.size()).equals(suffix); } + // ================================================================= + // String -> ByteString + + /** + * Returns a {@code ByteString} from a hexadecimal String. Alternative CharSequences should use + * {@link ByteStrings#decode(CharSequence, BaseEncoding)} + * + * @param hexString String of hexadecimal digits to create {@code ByteString} from. + * @throws NumberFormatException if the hexString does not contain a parsable hex String. + */ + public static ByteString fromHex(@CompileTimeConstant String hexString) { + if (hexString.length() % 2 != 0) { + throw new NumberFormatException( + "Invalid hexString " + hexString + " of length " + hexString.length() + " must be even."); + } + byte[] bytes = new byte[hexString.length() / 2]; + for (int i = 0; i < bytes.length; i++) { + int d1 = extractHexDigit(hexString, 2 * i); + int d2 = extractHexDigit(hexString, 2 * i + 1); + bytes[i] = (byte) (d1 << 4 | d2); + } + return new LiteralByteString(bytes); + } + // ================================================================= // byte[] -> ByteString 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 6e9c0f62091af..b3074b5b55f4f 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -680,33 +680,33 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_VARINT: { long value = readInt64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeUInt64NoTag(value); return true; } case WireFormat.WIRETYPE_FIXED64: { long value = readRawLittleEndian64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed64NoTag(value); return true; } case WireFormat.WIRETYPE_LENGTH_DELIMITED: { ByteString value = readBytes(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeBytesNoTag(value); return true; } case WireFormat.WIRETYPE_START_GROUP: { - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); skipMessage(output); int endtag = WireFormat.makeTag( WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP); checkLastTagWas(endtag); - output.writeRawVarint32(endtag); + output.writeUInt32NoTag(endtag); return true; } case WireFormat.WIRETYPE_END_GROUP: @@ -716,7 +716,7 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_FIXED32: { int value = readRawLittleEndian32(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed32NoTag(value); return true; } @@ -1395,33 +1395,33 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_VARINT: { long value = readInt64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeUInt64NoTag(value); return true; } case WireFormat.WIRETYPE_FIXED64: { long value = readRawLittleEndian64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed64NoTag(value); return true; } case WireFormat.WIRETYPE_LENGTH_DELIMITED: { ByteString value = readBytes(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeBytesNoTag(value); return true; } case WireFormat.WIRETYPE_START_GROUP: { - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); skipMessage(output); int endtag = WireFormat.makeTag( WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP); checkLastTagWas(endtag); - output.writeRawVarint32(endtag); + output.writeUInt32NoTag(endtag); return true; } case WireFormat.WIRETYPE_END_GROUP: @@ -1431,7 +1431,7 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_FIXED32: { int value = readRawLittleEndian32(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed32NoTag(value); return true; } @@ -2163,33 +2163,33 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_VARINT: { long value = readInt64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeUInt64NoTag(value); return true; } case WireFormat.WIRETYPE_FIXED64: { long value = readRawLittleEndian64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed64NoTag(value); return true; } case WireFormat.WIRETYPE_LENGTH_DELIMITED: { ByteString value = readBytes(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeBytesNoTag(value); return true; } case WireFormat.WIRETYPE_START_GROUP: { - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); skipMessage(output); int endtag = WireFormat.makeTag( WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP); checkLastTagWas(endtag); - output.writeRawVarint32(endtag); + output.writeUInt32NoTag(endtag); return true; } case WireFormat.WIRETYPE_END_GROUP: @@ -2199,7 +2199,7 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_FIXED32: { int value = readRawLittleEndian32(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed32NoTag(value); return true; } @@ -3284,33 +3284,33 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_VARINT: { long value = readInt64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeUInt64NoTag(value); return true; } case WireFormat.WIRETYPE_FIXED64: { long value = readRawLittleEndian64(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed64NoTag(value); return true; } case WireFormat.WIRETYPE_LENGTH_DELIMITED: { ByteString value = readBytes(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeBytesNoTag(value); return true; } case WireFormat.WIRETYPE_START_GROUP: { - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); skipMessage(output); int endtag = WireFormat.makeTag( WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP); checkLastTagWas(endtag); - output.writeRawVarint32(endtag); + output.writeUInt32NoTag(endtag); return true; } case WireFormat.WIRETYPE_END_GROUP: @@ -3320,7 +3320,7 @@ public boolean skipField(final int tag, final CodedOutputStream output) throws I case WireFormat.WIRETYPE_FIXED32: { int value = readRawLittleEndian32(); - output.writeRawVarint32(tag); + output.writeUInt32NoTag(tag); output.writeFixed32NoTag(value); return true; } diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java b/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java index 7658f629d3717..9736034cf3c1d 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java @@ -44,6 +44,7 @@ import java.util.Map; /** An adapter between the {@link Reader} interface and {@link CodedInputStream}. */ +@CheckReturnValue @ExperimentalApi final class CodedInputStreamReader implements Reader { private static final int FIXED32_MULTIPLE_MASK = FIXED32_SIZE - 1; @@ -165,7 +166,6 @@ public String readStringRequireUtf8() throws IOException { return input.readStringRequireUtf8(); } - @SuppressWarnings("unchecked") @Override public T readMessage(Class clazz, ExtensionRegistryLite extensionRegistry) throws IOException { @@ -181,7 +181,7 @@ public T readMessageBySchemaWithCheck( return readMessage(schema, extensionRegistry); } - @SuppressWarnings("unchecked") + @Deprecated @Override public T readGroup(Class clazz, ExtensionRegistryLite extensionRegistry) throws IOException { @@ -189,7 +189,7 @@ public T readGroup(Class clazz, ExtensionRegistryLite extensionRegistry) return readGroup(Protobuf.getInstance().schemaFor(clazz), extensionRegistry); } - @SuppressWarnings("unchecked") + @Deprecated @Override public T readGroupBySchemaWithCheck(Schema schema, ExtensionRegistryLite extensionRegistry) throws IOException { @@ -821,6 +821,7 @@ public void readMessageList( } } + @Deprecated @Override public void readGroupList( List target, Class targetType, ExtensionRegistryLite extensionRegistry) @@ -829,6 +830,7 @@ public void readGroupList( readGroupList(target, schema, extensionRegistry); } + @Deprecated @Override public void readGroupList( List target, Schema schema, ExtensionRegistryLite extensionRegistry) @@ -1314,7 +1316,7 @@ private Object readField( case UINT64: return readUInt64(); default: - throw new RuntimeException("unsupported field type."); + throw new IllegalArgumentException("unsupported field type."); } } diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java index 12f2097a8f50d..a05c50451bbe9 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -1056,7 +1056,7 @@ final void writeGroupNoTag(final MessageLite value, Schema schema) throws IOExce */ @Deprecated public static int computeGroupSize(final int fieldNumber, final MessageLite value) { - return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value); + return computeTagSize(fieldNumber) * 2 + value.getSerializedSize(); } /** @@ -1072,6 +1072,7 @@ static int computeGroupSize(final int fieldNumber, final MessageLite value, Sche /** Compute the number of bytes that would be needed to encode a {@code group} field. */ @Deprecated + @InlineMe(replacement = "value.getSerializedSize()") public static int computeGroupSizeNoTag(final MessageLite value) { return value.getSerializedSize(); } @@ -1089,6 +1090,7 @@ static int computeGroupSizeNoTag(final MessageLite value, Schema schema) { * @deprecated use {@link #writeUInt32NoTag} instead. */ @Deprecated + @InlineMe(replacement = "this.writeUInt32NoTag(value)") public final void writeRawVarint32(int value) throws IOException { writeUInt32NoTag(value); } @@ -1099,6 +1101,7 @@ public final void writeRawVarint32(int value) throws IOException { * @deprecated use {@link #writeUInt64NoTag} instead. */ @Deprecated + @InlineMe(replacement = "this.writeUInt64NoTag(value)") public final void writeRawVarint64(long value) throws IOException { writeUInt64NoTag(value); } @@ -1110,6 +1113,9 @@ public final void writeRawVarint64(long value) throws IOException { * @deprecated use {@link #computeUInt32SizeNoTag(int)} instead. */ @Deprecated + @InlineMe( + replacement = "CodedOutputStream.computeUInt32SizeNoTag(value)", + imports = "com.google.protobuf.CodedOutputStream") public static int computeRawVarint32Size(final int value) { return computeUInt32SizeNoTag(value); } @@ -1120,6 +1126,9 @@ public static int computeRawVarint32Size(final int value) { * @deprecated use {@link #computeUInt64SizeNoTag(long)} instead. */ @Deprecated + @InlineMe( + replacement = "CodedOutputStream.computeUInt64SizeNoTag(value)", + imports = "com.google.protobuf.CodedOutputStream") public static int computeRawVarint64Size(long value) { return computeUInt64SizeNoTag(value); } @@ -1130,6 +1139,7 @@ public static int computeRawVarint64Size(long value) { * @deprecated Use {@link #writeFixed32NoTag} instead. */ @Deprecated + @InlineMe(replacement = "this.writeFixed32NoTag(value)") public final void writeRawLittleEndian32(final int value) throws IOException { writeFixed32NoTag(value); } @@ -1140,6 +1150,7 @@ public final void writeRawLittleEndian32(final int value) throws IOException { * @deprecated Use {@link #writeFixed64NoTag} instead. */ @Deprecated + @InlineMe(replacement = "this.writeFixed64NoTag(value)") public final void writeRawLittleEndian64(final long value) throws IOException { writeFixed64NoTag(value); } diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java index 0d1983cb07b1c..3f796fa1f0569 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java +++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java @@ -39,6 +39,7 @@ import java.util.Map; /** An adapter between the {@link Writer} interface and {@link CodedOutputStream}. */ +@CheckReturnValue @ExperimentalApi final class CodedOutputStreamWriter implements Writer { private final CodedOutputStream output; @@ -154,6 +155,7 @@ public void writeMessage(int fieldNumber, Object value, Schema schema) throws IO output.writeMessage(fieldNumber, (MessageLite) value, schema); } + @Deprecated @Override public void writeGroup(int fieldNumber, Object value) throws IOException { output.writeGroup(fieldNumber, (MessageLite) value); @@ -164,11 +166,13 @@ public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOEx output.writeGroup(fieldNumber, (MessageLite) value, schema); } + @Deprecated @Override public void writeStartGroup(int fieldNumber) throws IOException { output.writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP); } + @Deprecated @Override public void writeEndGroup(int fieldNumber) throws IOException { output.writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP); @@ -561,6 +565,7 @@ public void writeMessageList(int fieldNumber, List value, Schema schema) thro } } + @Deprecated @Override public void writeGroupList(int fieldNumber, List value) throws IOException { for (int i = 0; i < value.size(); ++i) { diff --git a/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/java/core/src/main/java/com/google/protobuf/CompileTimeConstant.java similarity index 75% rename from java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java rename to java/core/src/main/java/com/google/protobuf/CompileTimeConstant.java index baa6d0867012c..dde7cf1ec307c 100644 --- a/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java +++ b/java/core/src/main/java/com/google/protobuf/CompileTimeConstant.java @@ -30,18 +30,18 @@ package com.google.protobuf; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** - * A prerun for a test suite that allows running the full protocol buffer tests in a mode that - * disables the optimization for not using {@link RepeatedFieldBuilder} and {@link - * SingleFieldBuilder} until they are requested. This allows us to run all the tests through both - * code paths and ensures that both code paths produce identical results. - * - * @author jonp@google.com (Jon Perlow) + * Annotation for method parameter and class field declarations, which denotes that corresponding + * actual values must be compile-time constant expressions. */ -public class ForceFieldBuildersPreRun implements Runnable { - - @Override - public void run() { - GeneratedMessage.enableAlwaysUseFieldBuildersForTesting(); - } -} +@Documented +@Retention(CLASS) +@Target({ElementType.PARAMETER, ElementType.FIELD}) +@interface CompileTimeConstant {} 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 f36d033327731..1722ba54b0202 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -278,14 +278,13 @@ public FieldDescriptor findExtensionByName(String name) { /** * Construct a {@code FileDescriptor}. * - * @param proto The protocol message form of the FileDescriptor. - * @param dependencies {@code FileDescriptor}s corresponding to all of the file's dependencies. + * @param proto the protocol message form of the FileDescriptort + * @param dependencies {@code FileDescriptor}s corresponding to all of the file's dependencies * @throws DescriptorValidationException {@code proto} is not a valid descriptor. This can occur - * for a number of reasons, e.g. because a field has an undefined type or because two - * messages were defined with the same name. + * for a number of reasons; for instance, because a field has an undefined type or because + * two messages were defined with the same name. */ - public static FileDescriptor buildFrom( - final FileDescriptorProto proto, final FileDescriptor[] dependencies) + public static FileDescriptor buildFrom(FileDescriptorProto proto, FileDescriptor[] dependencies) throws DescriptorValidationException { return buildFrom(proto, dependencies, false); } @@ -293,18 +292,19 @@ public static FileDescriptor buildFrom( /** * Construct a {@code FileDescriptor}. * - * @param proto The protocol message form of the FileDescriptor. - * @param dependencies {@code FileDescriptor}s corresponding to all of the file's dependencies. - * @param allowUnknownDependencies If true, non-exist dependenncies will be ignored and - * undefined message types will be replaced with a placeholder type. + * @param proto the protocol message form of the FileDescriptor + * @param dependencies {@code FileDescriptor}s corresponding to all of the file's dependencies + * @param allowUnknownDependencies if true, non-existing dependencies will be ignored and + * undefined message types will be replaced with a placeholder type. Undefined enum types + * still cause a DescriptorValidationException. * @throws DescriptorValidationException {@code proto} is not a valid descriptor. This can occur - * for a number of reasons, e.g. because a field has an undefined type or because two - * messages were defined with the same name. + * for a number of reasons; for instance, because a field has an undefined type or because + * two messages were defined with the same name. */ public static FileDescriptor buildFrom( - final FileDescriptorProto proto, - final FileDescriptor[] dependencies, - final boolean allowUnknownDependencies) + FileDescriptorProto proto, + FileDescriptor[] dependencies, + boolean allowUnknownDependencies) throws DescriptorValidationException { // Building descriptors involves two steps: translating and linking. // In the translation step (implemented by FileDescriptor's @@ -315,8 +315,8 @@ public static FileDescriptor buildFrom( // FieldDescriptor for an embedded message contains a pointer directly // to the Descriptor for that message's type. We also detect undefined // types in the linking step. - final DescriptorPool pool = new DescriptorPool(dependencies, allowUnknownDependencies); - final FileDescriptor result = + DescriptorPool pool = new DescriptorPool(dependencies, allowUnknownDependencies); + FileDescriptor result = new FileDescriptor(proto, dependencies, pool, allowUnknownDependencies); result.crossLink(); return result; @@ -1837,8 +1837,8 @@ public EnumValueDescriptor findValueByNumberCreatingIfUnknown(final int number) // The number represents an unknown enum value. synchronized (this) { if (cleanupQueue == null) { - cleanupQueue = new ReferenceQueue(); - unknownValues = new HashMap>(); + cleanupQueue = new ReferenceQueue<>(); + unknownValues = new HashMap<>(); } else { while (true) { UnknownEnumValueReference toClean = (UnknownEnumValueReference) cleanupQueue.poll(); @@ -2415,7 +2415,7 @@ private void importPublicDependencies(final FileDescriptor file) { } private final Set dependencies; - private boolean allowUnknownDependencies; + private final boolean allowUnknownDependencies; private final Map descriptorsByName = new HashMap<>(); @@ -2475,7 +2475,6 @@ GenericDescriptor lookupSymbol( final GenericDescriptor relativeTo, final DescriptorPool.SearchFilter filter) throws DescriptorValidationException { - // TODO(kenton): This could be optimized in a number of ways. GenericDescriptor result; String fullname; @@ -2547,11 +2546,11 @@ GenericDescriptor lookupSymbol( logger.warning( "The descriptor for message type \"" + name - + "\" can not be found and a placeholder is created for it"); + + "\" cannot be found and a placeholder is created for it"); // We create a dummy message descriptor here regardless of the // expected type. If the type should be message, this dummy // descriptor will work well and if the type should be enum, a - // DescriptorValidationException will be thrown latter. In either + // DescriptorValidationException will be thrown later. In either // case, the code works as expected: we allow unknown message types // but not unknown enum types. result = new Descriptor(fullname); @@ -2766,8 +2765,7 @@ private OneofDescriptor( final OneofDescriptorProto proto, final FileDescriptor file, final Descriptor parent, - final int index) - throws DescriptorValidationException { + final int index) { this.proto = proto; fullName = computeFullName(file, parent, proto.getName()); this.file = file; 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 8beebba24d65b..fee643f807a06 100644 --- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java +++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java @@ -38,6 +38,7 @@ import com.google.protobuf.Descriptors.OneofDescriptor; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -318,14 +319,14 @@ private void verifyOneofContainingType(OneofDescriptor oneof) { /** Builder for {@link DynamicMessage}s. */ public static final class Builder extends AbstractMessage.Builder { private final Descriptor type; - private FieldSet fields; + private FieldSet.Builder fields; private final FieldDescriptor[] oneofCases; private UnknownFieldSet unknownFields; /** Construct a {@code Builder} for the given type. */ private Builder(Descriptor type) { this.type = type; - this.fields = FieldSet.newFieldSet(); + this.fields = FieldSet.newBuilder(); this.unknownFields = UnknownFieldSet.getDefaultInstance(); this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()]; } @@ -335,11 +336,7 @@ private Builder(Descriptor type) { @Override public Builder clear() { - if (fields.isImmutable()) { - fields = FieldSet.newFieldSet(); - } else { - fields.clear(); - } + fields = FieldSet.newBuilder(); unknownFields = UnknownFieldSet.getDefaultInstance(); return this; } @@ -353,7 +350,6 @@ public Builder mergeFrom(Message other) { throw new IllegalArgumentException( "mergeFrom(Message) can only merge messages of the same type."); } - ensureIsMutable(); fields.mergeFrom(otherDynamicMessage.fields); mergeUnknownFields(otherDynamicMessage.unknownFields); for (int i = 0; i < oneofCases.length; i++) { @@ -378,10 +374,7 @@ public DynamicMessage build() { if (!isInitialized()) { throw newUninitializedMessageException( new DynamicMessage( - type, - fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), - unknownFields)); + type, fields.build(), Arrays.copyOf(oneofCases, oneofCases.length), unknownFields)); } return buildPartial(); } @@ -395,8 +388,8 @@ private DynamicMessage buildParsed() throws InvalidProtocolBufferException { throw newUninitializedMessageException( new DynamicMessage( type, - fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), + fields.build(), + Arrays.copyOf(oneofCases, oneofCases.length), unknownFields)) .asInvalidProtocolBufferException(); } @@ -418,17 +411,16 @@ public DynamicMessage buildPartial() { } } - fields.makeImmutable(); DynamicMessage result = new DynamicMessage( - type, fields, java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields); + type, fields.build(), Arrays.copyOf(oneofCases, oneofCases.length), unknownFields); return result; } @Override public Builder clone() { Builder result = new Builder(type); - result.fields.mergeFrom(fields); + result.fields.mergeFrom(fields.build()); result.mergeUnknownFields(unknownFields); System.arraycopy(oneofCases, 0, result.oneofCases, 0, oneofCases.length); return result; @@ -436,7 +428,17 @@ public Builder clone() { @Override public boolean isInitialized() { - return DynamicMessage.isInitialized(type, fields); + // Check that all required fields are present. + for (FieldDescriptor field : type.getFields()) { + if (field.isRequired()) { + if (!fields.hasField(field)) { + return false; + } + } + } + + // Check that embedded messages are initialized. + return fields.isInitialized(); } @Override @@ -517,15 +519,12 @@ public Object getField(FieldDescriptor field) { @Override public Builder setField(FieldDescriptor field, Object value) { verifyContainingType(field); - ensureIsMutable(); // TODO(xiaofeng): This check should really be put in FieldSet.setField() // where all other such checks are done. However, currently // FieldSet.setField() permits Integer value for enum fields probably // because of some internal features we support. Should figure it out // and move this check to a more appropriate place. - if (field.getType() == FieldDescriptor.Type.ENUM) { - ensureEnumValueDescriptor(field, value); - } + verifyType(field, value); OneofDescriptor oneofDescriptor = field.getContainingOneof(); if (oneofDescriptor != null) { int index = oneofDescriptor.getIndex(); @@ -550,7 +549,6 @@ public Builder setField(FieldDescriptor field, Object value) { @Override public Builder clearField(FieldDescriptor field) { verifyContainingType(field); - ensureIsMutable(); OneofDescriptor oneofDescriptor = field.getContainingOneof(); if (oneofDescriptor != null) { int index = oneofDescriptor.getIndex(); @@ -577,7 +575,7 @@ public Object getRepeatedField(FieldDescriptor field, int index) { @Override public Builder setRepeatedField(FieldDescriptor field, int index, Object value) { verifyContainingType(field); - ensureIsMutable(); + verifySingularValueType(field, value); fields.setRepeatedField(field, index, value); return this; } @@ -585,7 +583,7 @@ public Builder setRepeatedField(FieldDescriptor field, int index, Object value) @Override public Builder addRepeatedField(FieldDescriptor field, Object value) { verifyContainingType(field); - ensureIsMutable(); + verifySingularValueType(field, value); fields.addRepeatedField(field, value); return this; } @@ -622,53 +620,116 @@ private void verifyOneofContainingType(OneofDescriptor oneof) { } } - /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */ - private void ensureSingularEnumValueDescriptor(FieldDescriptor field, Object value) { - checkNotNull(value); - if (!(value instanceof EnumValueDescriptor)) { - throw new IllegalArgumentException( - "DynamicMessage should use EnumValueDescriptor to set Enum Value."); + /** + * Verifies that {@code value} is of the appropriate type, in addition to the checks already + * performed by {@link FieldSet.Builder}. + */ + private void verifySingularValueType(FieldDescriptor field, Object value) { + // Most type checks are performed by FieldSet.Builder, but FieldSet.Builder is more permissive + // than generated Message.Builder subclasses, so we perform extra checks in this class so that + // DynamicMessage.Builder's semantics more closely match the semantics of generated builders. + switch (field.getType()) { + case ENUM: + checkNotNull(value); + // FieldSet.Builder accepts Integer values for enum fields. + if (!(value instanceof EnumValueDescriptor)) { + throw new IllegalArgumentException( + "DynamicMessage should use EnumValueDescriptor to set Enum Value."); + } + // TODO(xiaofeng): Re-enable this check after Orgstore is fixed to not + // set incorrect EnumValueDescriptors. + // EnumDescriptor fieldType = field.getEnumType(); + // EnumDescriptor fieldValueType = ((EnumValueDescriptor) value).getType(); + // if (fieldType != fieldValueType) { + // throw new IllegalArgumentException(String.format( + // "EnumDescriptor %s of field doesn't match EnumDescriptor %s of field value", + // fieldType.getFullName(), fieldValueType.getFullName())); + // } + break; + case MESSAGE: + // FieldSet.Builder accepts Message.Builder values for message fields. + if (value instanceof Message.Builder) { + throw new IllegalArgumentException( + String.format( + "Wrong object type used with protocol message reflection.\n" + + "Field number: %d, field java type: %s, value type: %s\n", + field.getNumber(), + field.getLiteType().getJavaType(), + value.getClass().getName())); + } + break; + default: + break; } - // TODO(xiaofeng): Re-enable this check after Orgstore is fixed to not - // set incorrect EnumValueDescriptors. - // EnumDescriptor fieldType = field.getEnumType(); - // EnumDescriptor fieldValueType = ((EnumValueDescriptor) value).getType(); - // if (fieldType != fieldValueType) { - // throw new IllegalArgumentException(String.format( - // "EnumDescriptor %s of field doesn't match EnumDescriptor %s of field value", - // fieldType.getFullName(), fieldValueType.getFullName())); - // } - } - - /** Verifies the value for an enum field. */ - private void ensureEnumValueDescriptor(FieldDescriptor field, Object value) { + } + + /** + * Verifies that {@code value} is of the appropriate type, in addition to the checks already + * performed by {@link FieldSet.Builder}. + */ + private void verifyType(FieldDescriptor field, Object value) { if (field.isRepeated()) { - for (Object item : (List) value) { - ensureSingularEnumValueDescriptor(field, item); + for (Object item : (List) value) { + verifySingularValueType(field, item); } } else { - ensureSingularEnumValueDescriptor(field, value); - } - } - - private void ensureIsMutable() { - if (fields.isImmutable()) { - fields = fields.clone(); + verifySingularValueType(field, value); } } @Override public com.google.protobuf.Message.Builder getFieldBuilder(FieldDescriptor field) { - // TODO(xiangl): need implementation for dynamic message - throw new UnsupportedOperationException( - "getFieldBuilder() called on a dynamic message type."); + verifyContainingType(field); + // Error messages chosen for parity with GeneratedMessage.getFieldBuilder. + if (field.isMapField()) { + throw new UnsupportedOperationException("Nested builder not supported for map fields."); + } + if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { + throw new UnsupportedOperationException("getFieldBuilder() called on a non-Message type."); + } + + Object existingValue = fields.getFieldAllowBuilders(field); + Message.Builder builder = + existingValue == null + ? new Builder(field.getMessageType()) + : toMessageBuilder(existingValue); + fields.setField(field, builder); + return builder; } @Override public com.google.protobuf.Message.Builder getRepeatedFieldBuilder( FieldDescriptor field, int index) { - throw new UnsupportedOperationException( - "getRepeatedFieldBuilder() called on a dynamic message type."); + verifyContainingType(field); + // Error messages chosen for parity with GeneratedMessage.getRepeatedFieldBuilder. + if (field.isMapField()) { + throw new UnsupportedOperationException("Map fields cannot be repeated"); + } + if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { + throw new UnsupportedOperationException( + "getRepeatedFieldBuilder() called on a non-Message type."); + } + + Message.Builder builder = + toMessageBuilder(fields.getRepeatedFieldAllowBuilders(field, index)); + fields.setRepeatedField(field, index, builder); + return builder; + } + + private static Message.Builder toMessageBuilder(Object o) { + if (o instanceof Message.Builder) { + return (Message.Builder) o; + } + + if (o instanceof LazyField) { + o = ((LazyField) o).getValue(); + } + if (o instanceof Message) { + return ((Message) o).toBuilder(); + } + + throw new IllegalArgumentException( + String.format("Cannot convert %s to Message.Builder", o.getClass())); } } } diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java index aeeaee53e2112..f0f15641f1146 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java @@ -154,7 +154,7 @@ public ExtensionInfo findMutableExtensionByName(final String fullName) { return mutableExtensionsByName.get(fullName); } - /** Deprecated. Use {@link #findImmutableExtensionByNumber( Descriptors.Descriptor, int)} */ + /** Deprecated. Use {@link #findImmutableExtensionByNumber(Descriptors.Descriptor, int)} */ @Deprecated public ExtensionInfo findExtensionByNumber( final Descriptor containingType, final int fieldNumber) { diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java index 2eae22d26a078..296d5583ff2f0 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.util.Map; +@CheckReturnValue abstract class ExtensionSchema> { /** Returns true for messages that support extensions. */ diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java index 90558518b9961..698fc0e4fdbe3 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java @@ -497,7 +497,7 @@ void serializeExtension(Writer writer, Map.Entry extension) throws IOExcep Object findExtensionByNumber( ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number) { return ((ExtensionRegistry) extensionRegistry) - .findExtensionByNumber(((Message) defaultInstance).getDescriptorForType(), number); + .findImmutableExtensionByNumber(((Message) defaultInstance).getDescriptorForType(), number); } @Override diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java index 437cca2d96bdc..e199ed46fa41e 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java @@ -37,6 +37,7 @@ import java.util.List; import java.util.Map; +@CheckReturnValue @SuppressWarnings("unchecked") final class ExtensionSchemaLite extends ExtensionSchema { diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java index 46ce327d133e3..2652fa5213441 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java @@ -30,6 +30,7 @@ package com.google.protobuf; +@CheckReturnValue final class ExtensionSchemas { private static final ExtensionSchema LITE_SCHEMA = new ExtensionSchemaLite(); private static final ExtensionSchema FULL_SCHEMA = loadSchemaForFullRuntime(); diff --git a/java/core/src/main/java/com/google/protobuf/FieldInfo.java b/java/core/src/main/java/com/google/protobuf/FieldInfo.java index 71a307a895b60..59472dfaa14db 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldInfo.java +++ b/java/core/src/main/java/com/google/protobuf/FieldInfo.java @@ -36,6 +36,7 @@ import java.lang.reflect.Field; /** Information for a single field in a protobuf message class. */ +@CheckReturnValue @ExperimentalApi final class FieldInfo implements Comparable { private final Field field; 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 4853df28371d4..0597ef758b781 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java @@ -387,17 +387,10 @@ public void addRepeatedField(final T descriptor, final Object value) { * (For repeated fields, this checks if the object is the right type to be one element of the * field.) * - * @throws IllegalArgumentException The value is not of the right type. + * @throws IllegalArgumentException the value is not of the right type */ 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 - // more information here, e.g. naming the field. We used to do that. - // But we can't now that FieldSet doesn't use descriptors. Maybe this - // 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( String.format( "Wrong object type used with protocol message reflection.\n" @@ -427,10 +420,8 @@ private static boolean isValidType(final WireFormat.FieldType type, final Object case BYTE_STRING: return value instanceof ByteString || value instanceof byte[]; case ENUM: - // TODO(kenton): Caller must do type checking here, I guess. return (value instanceof Integer || value instanceof Internal.EnumLite); case MESSAGE: - // TODO(kenton): Caller must do type checking here, I guess. return (value instanceof MessageLite) || (value instanceof LazyField); } return false; @@ -458,34 +449,36 @@ public boolean isInitialized() { return true; } - @SuppressWarnings("unchecked") private static > boolean isInitialized( final Map.Entry entry) { final T descriptor = entry.getKey(); if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { if (descriptor.isRepeated()) { - for (final MessageLite element : (List) entry.getValue()) { - if (!element.isInitialized()) { + for (final Object element : (List) entry.getValue()) { + if (!isMessageFieldValueInitialized(element)) { return false; } } } else { - Object value = entry.getValue(); - if (value instanceof MessageLite) { - if (!((MessageLite) value).isInitialized()) { - return false; - } - } else if (value instanceof LazyField) { - return true; - } else { - throw new IllegalArgumentException( - "Wrong object type used with protocol message reflection."); - } + return isMessageFieldValueInitialized(entry.getValue()); } } return true; } + private static boolean isMessageFieldValueInitialized(Object value) { + if (value instanceof MessageLiteOrBuilder) { + // Message fields cannot have builder values in FieldSet, but can in FieldSet.Builder, and + // this method is used by FieldSet.Builder.isInitialized. + return ((MessageLiteOrBuilder) value).isInitialized(); + } else if (value instanceof LazyField) { + return true; + } else { + throw new IllegalArgumentException( + "Wrong object type used with protocol message reflection."); + } + } + /** * Given a field type, return the wire type. * @@ -554,18 +547,15 @@ private void mergeFromField(final Map.Entry entry) { } } - // TODO(kenton): Move static parsing and serialization methods into some - // other class. Probably WireFormat. - /** * Read a field of any primitive type for immutable messages from a CodedInputStream. Enums, * groups, and embedded messages are not handled by this method. * - * @param input The stream from which to read. - * @param type Declared type of the field. - * @param checkUtf8 When true, check that the input is valid utf8. - * @return An object representing the field's value, of the exact type which would be returned by - * {@link Message#getField(Descriptors.FieldDescriptor)} for this field. + * @param input the stream from which to read + * @param type declared type of the field + * @param checkUtf8 When true, check that the input is valid UTF-8 + * @return an object representing the field's value, of the exact type which would be returned by + * {@link Message#getField(Descriptors.FieldDescriptor)} for this field */ public static Object readPrimitiveField( CodedInputStream input, final WireFormat.FieldType type, boolean checkUtf8) @@ -737,7 +727,7 @@ public static void writeField( for (final Object element : valueList) { dataSize += computeElementSizeNoTag(type, element); } - output.writeRawVarint32(dataSize); + output.writeUInt32NoTag(dataSize); // Write the data itself, without any tags. for (final Object element : valueList) { writeElementNoTag(output, type, element); @@ -903,7 +893,7 @@ public static int computeFieldSize(final FieldDescriptorLite descriptor, fina } return dataSize + CodedOutputStream.computeTagSize(number) - + CodedOutputStream.computeRawVarint32Size(dataSize); + + CodedOutputStream.computeUInt32SizeNoTag(dataSize); } else { int size = 0; for (final Object element : (List) value) { @@ -1081,8 +1071,7 @@ public void setField(final T descriptor, Object value) { // Wrap the contents in a new list so that the caller cannot change // the list's contents after setting it. - final List newList = new ArrayList(); - newList.addAll((List) value); + final List newList = new ArrayList((List) value); for (final Object element : newList) { verifyType(descriptor, element); hasNestedBuilders = hasNestedBuilders || element instanceof MessageLite.Builder; @@ -1115,10 +1104,10 @@ public void clearField(final T descriptor) { public int getRepeatedFieldCount(final T descriptor) { if (!descriptor.isRepeated()) { throw new IllegalArgumentException( - "getRepeatedField() can only be called on repeated fields."); + "getRepeatedFieldCount() can only be called on repeated fields."); } - final Object value = getField(descriptor); + final Object value = getFieldAllowBuilders(descriptor); if (value == null) { return 0; } else { @@ -1170,7 +1159,7 @@ public void setRepeatedField(final T descriptor, final int index, final Object v hasNestedBuilders = hasNestedBuilders || value instanceof MessageLite.Builder; - final Object list = getField(descriptor); + final Object list = getFieldAllowBuilders(descriptor); if (list == null) { throw new IndexOutOfBoundsException(); } @@ -1195,7 +1184,7 @@ public void addRepeatedField(final T descriptor, final Object value) { verifyType(descriptor, value); - final Object existingValue = getField(descriptor); + final Object existingValue = getFieldAllowBuilders(descriptor); List list; if (existingValue == null) { list = new ArrayList<>(); @@ -1263,7 +1252,7 @@ public void mergeFrom(final FieldSet other) { } } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings("unchecked") private void mergeFromField(final Map.Entry entry) { final T descriptor = entry.getKey(); Object otherValue = entry.getValue(); @@ -1272,16 +1261,16 @@ private void mergeFromField(final Map.Entry entry) { } if (descriptor.isRepeated()) { - Object value = getField(descriptor); + List value = (List) getFieldAllowBuilders(descriptor); if (value == null) { value = new ArrayList<>(); + fields.put(descriptor, value); } - for (Object element : (List) otherValue) { - ((List) value).add(FieldSet.cloneIfMutable(element)); + for (Object element : (List) otherValue) { + value.add(FieldSet.cloneIfMutable(element)); } - fields.put(descriptor, value); } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { - Object value = getField(descriptor); + Object value = getFieldAllowBuilders(descriptor); if (value == null) { fields.put(descriptor, FieldSet.cloneIfMutable(otherValue)); } else { 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 7db8f32ee019a..f5cf885041dd3 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -985,7 +985,6 @@ public final Type getExtension(final ExtensionLite ext /** Get one element of a repeated extension. */ @Override - @SuppressWarnings("unchecked") public final Type getExtension( final ExtensionLite> extension, final int index) { return instance.getExtension(extension, index); @@ -1342,7 +1341,6 @@ public static SerializedForm of(MessageLite message) { * * @return a GeneratedMessage of the type that was serialized */ - @SuppressWarnings("unchecked") protected Object readResolve() throws ObjectStreamException { try { Class messageClass = resolveMessageClass(); @@ -1542,6 +1540,8 @@ public T parsePartialFrom( e = new InvalidProtocolBufferException(e); } throw e.setUnfinishedMessage(result); + } catch (UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(result); } catch (IOException e) { if (e.getCause() instanceof InvalidProtocolBufferException) { throw (InvalidProtocolBufferException) e.getCause(); @@ -1557,7 +1557,7 @@ public T parsePartialFrom( } /** A static helper method for parsing a partial from byte array. */ - static > T parsePartialFrom( + private static > T parsePartialFrom( T instance, byte[] input, int offset, int length, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { @SuppressWarnings("unchecked") // Guaranteed by protoc @@ -1575,6 +1575,8 @@ public T parsePartialFrom( e = new InvalidProtocolBufferException(e); } throw e.setUnfinishedMessage(result); + } catch (UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(result); } catch (IOException e) { if (e.getCause() instanceof InvalidProtocolBufferException) { throw (InvalidProtocolBufferException) e.getCause(); @@ -1641,28 +1643,14 @@ public T parsePartialFrom( private static > T parsePartialFrom( T defaultInstance, ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { - T message; + CodedInputStream input = data.newCodedInput(); + T message = parsePartialFrom(defaultInstance, input, extensionRegistry); try { - CodedInputStream input = data.newCodedInput(); - message = parsePartialFrom(defaultInstance, input, extensionRegistry); - try { - input.checkLastTagWas(0); - } catch (InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(message); - } - return message; + input.checkLastTagWas(0); } catch (InvalidProtocolBufferException e) { - throw e; + throw e.setUnfinishedMessage(message); } - } - - // This is a special case since we want to verify that the last tag is 0. We assume we exhaust the - // ByteString. - private static > T parsePartialFrom( - T defaultInstance, byte[] data, ExtensionRegistryLite extensionRegistry) - throws InvalidProtocolBufferException { - return checkMessageInitialized( - parsePartialFrom(defaultInstance, data, 0, data.length, extensionRegistry)); + return message; } // Validates last tag. 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 46427b3ddf8ab..4bad7e8e1d2f6 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -2726,8 +2726,7 @@ public com.google.protobuf.Message.Builder getBuilder(Builder builder) { @Override public com.google.protobuf.Message.Builder getRepeatedBuilder(Builder builder, int index) { - throw new UnsupportedOperationException( - "Nested builder not supported for map fields."); + throw new UnsupportedOperationException("Map fields cannot be repeated"); } } diff --git a/java/core/src/main/java/com/google/protobuf/InlineMe.java b/java/core/src/main/java/com/google/protobuf/InlineMe.java new file mode 100644 index 0000000000000..6c81d18227ecd --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/InlineMe.java @@ -0,0 +1,59 @@ +// 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. + +package com.google.protobuf; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; + +import java.lang.annotation.Documented; +import java.lang.annotation.Target; + +/** + * Indicates that callers of this API should be inlined. That is, this API is trivially expressible + * in terms of another API, for example a method that just calls another method. + */ +@Documented +@Target({METHOD, CONSTRUCTOR}) +@interface InlineMe { + /** + * What the caller should be replaced with. Local parameter names can be used in the replacement + * string. If you are invoking an instance method or constructor, you must include the implicit + * {@code this} in the replacement body. If you are invoking a static method, you must include the + * implicit {@code ClassName} in the replacement body. + */ + String replacement(); + + /** The new imports to (optionally) add to the caller. */ + String[] imports() default {}; + + /** The new static imports to (optionally) add to the caller. */ + String[] staticImports() default {}; +} 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 07e8dd1322576..f2f194f9bd999 100644 --- a/java/core/src/main/java/com/google/protobuf/Internal.java +++ b/java/core/src/main/java/com/google/protobuf/Internal.java @@ -31,6 +31,7 @@ package com.google.protobuf; import java.lang.reflect.Method; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.AbstractList; @@ -139,10 +140,12 @@ public static ByteBuffer copyByteBuffer(ByteBuffer source) { ByteBuffer temp = source.duplicate(); // We want to copy all the data in the source ByteBuffer, not just the // remaining bytes. - temp.clear(); + // View ByteBuffer as Buffer to avoid issue with covariant return types + // See https://issues.apache.org/jira/browse/MRESOLVER-85 + ((Buffer) temp).clear(); ByteBuffer result = ByteBuffer.allocate(temp.capacity()); result.put(temp); - result.clear(); + ((Buffer) result).clear(); return result; } @@ -450,7 +453,6 @@ public MapAdapter(Map realMap, Converter valueConver this.valueConverter = valueConverter; } - @SuppressWarnings("unchecked") @Override public V get(Object key) { RealValue result = realMap.get(key); @@ -549,7 +551,6 @@ public boolean equals(Object o) { if (!(o instanceof Map.Entry)) { return false; } - @SuppressWarnings("unchecked") Map.Entry other = (Map.Entry) o; return getKey().equals(other.getKey()) && getValue().equals(getValue()); } diff --git a/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java index 118a1e8392b1a..71ccb14b13c93 100644 --- a/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java +++ b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java @@ -33,8 +33,8 @@ import java.io.IOException; /** - * Thrown when a protocol message being parsed is invalid in some way, e.g. it contains a malformed - * varint or a negative byte length. + * Thrown when a protocol message being parsed is invalid in some way. For instance, + * it contains a malformed varint or a negative byte length. * * @author kenton@google.com Kenton Varda */ @@ -43,15 +43,15 @@ public class InvalidProtocolBufferException extends IOException { private MessageLite unfinishedMessage = null; private boolean wasThrownFromInputStream; - public InvalidProtocolBufferException(final String description) { + public InvalidProtocolBufferException(String description) { super(description); } - public InvalidProtocolBufferException(IOException e) { + public InvalidProtocolBufferException(Exception e) { super(e.getMessage(), e); } - public InvalidProtocolBufferException(final String description, IOException e) { + public InvalidProtocolBufferException(String description, Exception e) { super(description, e); } diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java index ebc8561a7261d..651e5fdc160b5 100644 --- a/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java +++ b/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java @@ -38,6 +38,7 @@ /** * Utility class that aids in properly manipulating list fields for either the lite or full runtime. */ +@CheckReturnValue abstract class ListFieldSchema { // Disallow construction. private ListFieldSchema() {} diff --git a/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java b/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java index 84ca9ae0f7576..cbd39f51f8ca5 100644 --- a/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java +++ b/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java @@ -35,6 +35,7 @@ /** * Dynamically generates a manifest-based (i.e. table-based) schema for a given protobuf message. */ +@CheckReturnValue @ExperimentalApi final class ManifestSchemaFactory implements SchemaFactory { diff --git a/java/core/src/main/java/com/google/protobuf/MapEntry.java b/java/core/src/main/java/com/google/protobuf/MapEntry.java index ca0678e2f128f..d528e1a21663c 100644 --- a/java/core/src/main/java/com/google/protobuf/MapEntry.java +++ b/java/core/src/main/java/com/google/protobuf/MapEntry.java @@ -437,7 +437,6 @@ public UnknownFieldSet getUnknownFields() { } @Override - @SuppressWarnings("unchecked") public Builder clone() { return new Builder<>(metadata, key, value, hasKey, hasValue); } diff --git a/java/core/src/main/java/com/google/protobuf/MapField.java b/java/core/src/main/java/com/google/protobuf/MapField.java index f487736065f2f..2fe8867a7471c 100644 --- a/java/core/src/main/java/com/google/protobuf/MapField.java +++ b/java/core/src/main/java/com/google/protobuf/MapField.java @@ -85,7 +85,7 @@ private enum StorageMode { private volatile boolean isMutable; private volatile StorageMode mode; - private MutatabilityAwareMap mapData; + private MutabilityAwareMap mapData; private List listData; // Convert between a map entry Message and a key-value pair. @@ -129,7 +129,7 @@ private MapField(Converter converter, StorageMode mode, Map mapData) this.converter = converter; this.isMutable = true; this.mode = mode; - this.mapData = new MutatabilityAwareMap(this, mapData); + this.mapData = new MutabilityAwareMap(this, mapData); this.listData = null; } @@ -154,12 +154,11 @@ private Message convertKeyAndValueToMessage(K key, V value) { return converter.convertKeyAndValueToMessage(key, value); } - @SuppressWarnings("unchecked") private void convertMessageToKeyAndValue(Message message, Map map) { converter.convertMessageToKeyAndValue(message, map); } - private List convertMapToList(MutatabilityAwareMap mapData) { + private List convertMapToList(MutabilityAwareMap mapData) { List listData = new ArrayList(); for (Map.Entry entry : mapData.entrySet()) { listData.add(convertKeyAndValueToMessage(entry.getKey(), entry.getValue())); @@ -167,12 +166,12 @@ private List convertMapToList(MutatabilityAwareMap mapData) { return listData; } - private MutatabilityAwareMap convertListToMap(List listData) { + private MutabilityAwareMap convertListToMap(List listData) { Map mapData = new LinkedHashMap(); for (Message item : listData) { convertMessageToKeyAndValue(item, mapData); } - return new MutatabilityAwareMap(this, mapData); + return new MutabilityAwareMap(this, mapData); } /** Returns the content of this MapField as a read-only Map. */ @@ -205,7 +204,7 @@ public void mergeFrom(MapField other) { } public void clear() { - mapData = new MutatabilityAwareMap(this, new LinkedHashMap()); + mapData = new MutabilityAwareMap(this, new LinkedHashMap()); mode = StorageMode.MAP; } @@ -283,11 +282,11 @@ public void ensureMutable() { } /** An internal map that checks for mutability before delegating. */ - private static class MutatabilityAwareMap implements Map { + private static class MutabilityAwareMap implements Map { private final MutabilityOracle mutabilityOracle; private final Map delegate; - MutatabilityAwareMap(MutabilityOracle mutabilityOracle, Map delegate) { + MutabilityAwareMap(MutabilityOracle mutabilityOracle, Map delegate) { this.mutabilityOracle = mutabilityOracle; this.delegate = delegate; } @@ -349,17 +348,17 @@ public void clear() { @Override public Set keySet() { - return new MutatabilityAwareSet(mutabilityOracle, delegate.keySet()); + return new MutabilityAwareSet(mutabilityOracle, delegate.keySet()); } @Override public Collection values() { - return new MutatabilityAwareCollection(mutabilityOracle, delegate.values()); + return new MutabilityAwareCollection(mutabilityOracle, delegate.values()); } @Override public Set> entrySet() { - return new MutatabilityAwareSet>(mutabilityOracle, delegate.entrySet()); + return new MutabilityAwareSet>(mutabilityOracle, delegate.entrySet()); } @Override @@ -378,11 +377,11 @@ public String toString() { } /** An internal collection that checks for mutability before delegating. */ - private static class MutatabilityAwareCollection implements Collection { + private static class MutabilityAwareCollection implements Collection { private final MutabilityOracle mutabilityOracle; private final Collection delegate; - MutatabilityAwareCollection(MutabilityOracle mutabilityOracle, Collection delegate) { + MutabilityAwareCollection(MutabilityOracle mutabilityOracle, Collection delegate) { this.mutabilityOracle = mutabilityOracle; this.delegate = delegate; } @@ -404,7 +403,7 @@ public boolean contains(Object o) { @Override public Iterator iterator() { - return new MutatabilityAwareIterator(mutabilityOracle, delegate.iterator()); + return new MutabilityAwareIterator(mutabilityOracle, delegate.iterator()); } @Override @@ -475,11 +474,11 @@ public String toString() { } /** An internal set that checks for mutability before delegating. */ - private static class MutatabilityAwareSet implements Set { + private static class MutabilityAwareSet implements Set { private final MutabilityOracle mutabilityOracle; private final Set delegate; - MutatabilityAwareSet(MutabilityOracle mutabilityOracle, Set delegate) { + MutabilityAwareSet(MutabilityOracle mutabilityOracle, Set delegate) { this.mutabilityOracle = mutabilityOracle; this.delegate = delegate; } @@ -501,7 +500,7 @@ public boolean contains(Object o) { @Override public Iterator iterator() { - return new MutatabilityAwareIterator(mutabilityOracle, delegate.iterator()); + return new MutabilityAwareIterator(mutabilityOracle, delegate.iterator()); } @Override @@ -572,11 +571,11 @@ public String toString() { } /** An internal iterator that checks for mutability before delegating. */ - private static class MutatabilityAwareIterator implements Iterator { + private static class MutabilityAwareIterator implements Iterator { private final MutabilityOracle mutabilityOracle; private final Iterator delegate; - MutatabilityAwareIterator(MutabilityOracle mutabilityOracle, Iterator delegate) { + MutabilityAwareIterator(MutabilityOracle mutabilityOracle, Iterator delegate) { this.mutabilityOracle = mutabilityOracle; this.delegate = delegate; } diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java index f792ae9fc7549..72e03d16b23b9 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java @@ -57,15 +57,14 @@ private MapFieldLite(Map mapData) { this.isMutable = true; } - @SuppressWarnings({"rawtypes", "unchecked"}) - private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite<>(); + private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite<>(); static { EMPTY_MAP_FIELD.makeImmutable(); } /** Returns a singleton immutable empty MapFieldLite instance. */ - @SuppressWarnings({"unchecked", "cast"}) + @SuppressWarnings("unchecked") public static MapFieldLite emptyMapField() { return (MapFieldLite) EMPTY_MAP_FIELD; } @@ -77,7 +76,6 @@ public void mergeFrom(MapFieldLite other) { } } - @SuppressWarnings({"unchecked", "cast"}) @Override public Set> entrySet() { return isEmpty() ? Collections.>emptySet() : super.entrySet(); diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java index 195126e51435f..d92a3bb2c8440 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java @@ -32,6 +32,7 @@ import java.util.Map; +@CheckReturnValue interface MapFieldSchema { /** Returns the map data for mutation. */ Map forMutableMapData(Object mapField); @@ -56,6 +57,7 @@ interface MapFieldSchema { MapEntryLite.Metadata forMapMetadata(Object mapDefaultEntry); /** Merges {@code srcMapField} into {@code destMapField}, and returns the merged instance. */ + @CanIgnoreReturnValue Object mergeFrom(Object destMapField, Object srcMapField); /** Compute the serialized size for the map with a given field number. */ diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java index 8a8c78de8aaa6..aef8ad2346c14 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java @@ -33,6 +33,7 @@ import com.google.protobuf.MapEntryLite.Metadata; import java.util.Map; +@CheckReturnValue class MapFieldSchemaLite implements MapFieldSchema { @Override diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java index b398c61022149..835f95c414c66 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java @@ -30,6 +30,7 @@ package com.google.protobuf; +@CheckReturnValue final class MapFieldSchemas { private static final MapFieldSchema FULL_SCHEMA = loadSchemaForFullRuntime(); private static final MapFieldSchema LITE_SCHEMA = new MapFieldSchemaLite(); diff --git a/java/core/src/main/java/com/google/protobuf/Message.java b/java/core/src/main/java/com/google/protobuf/Message.java index 9b3a015ba9825..3db1c771e6c18 100644 --- a/java/core/src/main/java/com/google/protobuf/Message.java +++ b/java/core/src/main/java/com/google/protobuf/Message.java @@ -28,9 +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. -// TODO(kenton): Use generics? E.g. Builder, then -// mergeFrom*() could return BuilderType for better type-safety. - package com.google.protobuf; import java.io.IOException; @@ -41,8 +38,8 @@ * Abstract interface implemented by Protocol Message objects. * *

See also {@link MessageLite}, which defines most of the methods that typical users care about. - * {@link Message} adds to it methods that are not available in the "lite" runtime. The biggest - * added features are introspection and reflection -- i.e., getting descriptors for the message type + * {@link Message} adds methods that are not available in the "lite" runtime. The biggest added + * features are introspection and reflection; that is, getting descriptors for the message type * and accessing the field values dynamically. * * @author kenton@google.com Kenton Varda @@ -165,16 +162,13 @@ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistr * Get a nested builder instance for the given field. * *

Normally, we hold a reference to the immutable message object for the message type field. - * Some implementations(the generated message builders), however, can also hold a reference to + * Some implementations (the generated message builders) can also hold a reference to * the builder object (a nested builder) for the field. * - *

If the field is already backed up by a nested builder, the nested builder will be - * returned. Otherwise, a new field builder will be created and returned. The original message - * field (if exist) will be merged into the field builder, which will then be nested into its + *

If the field is already backed up by a nested builder, the nested builder is + * returned. Otherwise, a new field builder is created and returned. The original message + * field (if one exists) is merged into the field builder, which is then nested into its * parent builder. - * - *

NOTE: implementations that do not support nested builders will throw - * UnsupportedOperationException. */ Builder getFieldBuilder(Descriptors.FieldDescriptor field); @@ -182,22 +176,19 @@ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistr * Get a nested builder instance for the given repeated field instance. * *

Normally, we hold a reference to the immutable message object for the message type field. - * Some implementations(the generated message builders), however, can also hold a reference to + * Some implementations (the generated message builders) can also hold a reference to * the builder object (a nested builder) for the field. * - *

If the field is already backed up by a nested builder, the nested builder will be - * returned. Otherwise, a new field builder will be created and returned. The original message - * field (if exist) will be merged into the field builder, which will then be nested into its + *

If the field is already backed up by a nested builder, the nested builder is + * returned. Otherwise, a new field builder is created and returned. The original message + * field (if one exists) is merged into the field builder, which is then nested into its * parent builder. - * - *

NOTE: implementations that do not support nested builders will throw - * UnsupportedOperationException. */ Builder getRepeatedFieldBuilder(Descriptors.FieldDescriptor field, int index); /** - * Sets a field to the given value. The value must be of the correct type for this field, i.e. - * the same type that {@link Message#getField(Descriptors.FieldDescriptor)} would return. + * Sets a field to the given value. The value must be of the correct type for this field, that + * is, the same type that {@link Message#getField(Descriptors.FieldDescriptor)} returns. */ Builder setField(Descriptors.FieldDescriptor field, Object value); @@ -215,10 +206,10 @@ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistr /** * Sets an element of a repeated field to the given value. The value must be of the correct type - * for this field, i.e. the same type that {@link - * Message#getRepeatedField(Descriptors.FieldDescriptor,int)} would return. + * for this field; that is, the same type that {@link + * Message#getRepeatedField(Descriptors.FieldDescriptor,int)} returns. * - * @throws IllegalArgumentException The field is not a repeated field, or {@code + * @throws IllegalArgumentException if the field is not a repeated field, or {@code * field.getContainingType() != getDescriptorForType()}. */ Builder setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value); @@ -226,8 +217,8 @@ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistr /** * Like {@code setRepeatedField}, but appends the value as a new element. * - * @throws IllegalArgumentException The field is not a repeated field, or {@code - * field.getContainingType() != getDescriptorForType()}. + * @throws IllegalArgumentException if the field is not a repeated field, or {@code + * field.getContainingType() != getDescriptorForType()} */ Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value); diff --git a/java/core/src/main/java/com/google/protobuf/MessageInfo.java b/java/core/src/main/java/com/google/protobuf/MessageInfo.java index 69e318696aa33..399ca621611b4 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/MessageInfo.java @@ -30,7 +30,8 @@ package com.google.protobuf; -/** A MesageInfo object describes a proto message type. */ +/** A MessageInfo object describes a proto message type. */ +@CheckReturnValue interface MessageInfo { /** Gets syntax for this type. */ ProtoSyntax getSyntax(); diff --git a/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java b/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java index 005c26d05f7d4..3732b8ee4a0f8 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java +++ b/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java @@ -32,6 +32,7 @@ /** A factory that creates {@link MessageInfo} instances for message types. */ @ExperimentalApi +@CheckReturnValue interface MessageInfoFactory { /** Whether the message class is supported by this factory. */ boolean isSupported(Class clazz); diff --git a/java/core/src/main/java/com/google/protobuf/MessageLite.java b/java/core/src/main/java/com/google/protobuf/MessageLite.java index bbf30364b2353..f9b2f6653f830 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/MessageLite.java @@ -28,9 +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. -// TODO(kenton): Use generics? E.g. Builder, then -// mergeFrom*() could return BuilderType for better type-safety. - package com.google.protobuf; import java.io.IOException; @@ -109,10 +106,10 @@ public interface MessageLite extends MessageLiteOrBuilder { * *

NOTE: Protocol Buffers are not self-delimiting. Therefore, if you write any more data to the * stream after the message, you must somehow ensure that the parser on the receiving end does not - * interpret this as being part of the protocol message. This can be done e.g. by writing the size - * of the message before the data, then making sure to limit the input to that size on the - * receiving end (e.g. by wrapping the InputStream in one which limits the input). Alternatively, - * just use {@link #writeDelimitedTo(OutputStream)}. + * interpret this as being part of the protocol message. This can be done, for instance, by + * writing the size of the message before the data, then making sure to limit the input to that + * size on the receiving end by wrapping the InputStream in one which limits the input. + * Alternatively, just use {@link #writeDelimitedTo(OutputStream)}. */ void writeTo(OutputStream output) throws IOException; @@ -183,6 +180,11 @@ interface Builder extends MessageLiteOrBuilder, Cloneable { * *

Note: The caller should call {@link CodedInputStream#checkLastTagWas(int)} after calling * this to verify that the last tag seen was the appropriate end-group tag, or zero for EOF. + * + * @throws InvalidProtocolBufferException the bytes read are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. + * @throws IOException an I/O error reading from the stream */ Builder mergeFrom(CodedInputStream input) throws IOException; @@ -190,6 +192,11 @@ interface Builder extends MessageLiteOrBuilder, Cloneable { * Like {@link Builder#mergeFrom(CodedInputStream)}, but also parses extensions. The extensions * that you want to be able to parse must be registered in {@code extensionRegistry}. Extensions * not in the registry will be treated as unknown fields. + * + * @throws InvalidProtocolBufferException the bytes read are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. + * @throws IOException an I/O error reading from the stream */ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; @@ -201,6 +208,9 @@ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistr * Parse {@code data} as a message of this type and merge it with the message being built. This * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. * + * @throws InvalidProtocolBufferException the bytes in data are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. * @return this */ Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException; @@ -209,6 +219,9 @@ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistr * Parse {@code data} as a message of this type and merge it with the message being built. This * is just a small wrapper around {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}. * + * @throws InvalidProtocolBufferException the bytes in data are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. * @return this */ Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry) @@ -218,6 +231,9 @@ Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry) * Parse {@code data} as a message of this type and merge it with the message being built. This * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. * + * @throws InvalidProtocolBufferException the bytes in data are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. * @return this */ Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException; @@ -226,6 +242,9 @@ Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry) * Parse {@code data} as a message of this type and merge it with the message being built. This * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. * + * @throws InvalidProtocolBufferException the bytes in data are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. * @return this */ Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException; @@ -234,6 +253,9 @@ Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry) * Parse {@code data} as a message of this type and merge it with the message being built. This * is just a small wrapper around {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}. * + * @throws InvalidProtocolBufferException the bytes in data are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. * @return this */ Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry) @@ -243,6 +265,9 @@ Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry) * Parse {@code data} as a message of this type and merge it with the message being built. This * is just a small wrapper around {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}. * + * @throws InvalidProtocolBufferException the bytes in data are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. * @return this */ Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry) @@ -258,6 +283,10 @@ Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extension * *

Despite usually reading the entire input, this does not close the stream. * + * @throws InvalidProtocolBufferException the bytes read are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. + * @throws IOException an I/O error reading from the stream * @return this */ Builder mergeFrom(InputStream input) throws IOException; @@ -295,12 +324,25 @@ Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry) * message (encoded as a varint) is read first, then the message data. Use {@link * MessageLite#writeDelimitedTo(OutputStream)} to write messages in this format. * - * @return True if successful, or false if the stream is at EOF when the method starts. Any - * other error (including reaching EOF during parsing) will cause an exception to be thrown. + * @return true if successful, or false if the stream is at EOF when the method starts. Any + * other error (including reaching EOF during parsing) causes an exception to be thrown. + * @throws InvalidProtocolBufferException the bytes read are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. + * @throws IOException an I/O error reading from the stream */ boolean mergeDelimitedFrom(InputStream input) throws IOException; - /** Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions. */ + /** + * Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions. + * + * @return true if successful, or false if the stream is at EOF when the method starts. Any + * other error (including reaching EOF during parsing) causes an exception to be thrown. + * @throws InvalidProtocolBufferException the bytes read are not syntactically correct + * according to the protobuf wire format specification. The data is corrupt, incomplete, + * or was never a protobuf in the first place. + * @throws IOException an I/O error reading from the stream + */ boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; } diff --git a/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java index 9ad681679fbe8..23be61475e8db 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java +++ b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java @@ -47,13 +47,16 @@ final class MessageLiteToString { private static final String MAP_SUFFIX = "Map"; private static final String BYTES_SUFFIX = "Bytes"; + private MessageLiteToString() { + // Classes which are not intended to be instantiated should be made non-instantiable with a + // private constructor. This includes utility classes (classes with only static members). + } + /** * Returns a {@link String} representation of the {@link MessageLite} object. The first line of - * the {@code String} representation representation includes a comment string to uniquely identify + * the {@code String} representation includes a comment string to uniquely identify * the object instance. This acts as an indicator that this should not be relied on for * comparisons. - * - *

For use by generated code only. */ static String toString(MessageLite messageLite, String commentString) { StringBuilder buffer = new StringBuilder(); @@ -73,9 +76,9 @@ private static void reflectivePrintWithIndent( // Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(), // getFooList() and getFooMap() which might be useful for building an object's string // representation. - Map nameToNoArgMethod = new HashMap(); - Map nameToMethod = new HashMap(); - Set getters = new TreeSet(); + Map nameToNoArgMethod = new HashMap<>(); + Map nameToMethod = new HashMap<>(); + Set getters = new TreeSet<>(); for (Method method : messageLite.getClass().getDeclaredMethods()) { nameToMethod.put(method.getName(), method); if (method.getParameterTypes().length == 0) { @@ -263,7 +266,7 @@ static final void printField(StringBuilder buffer, int indent, String name, Obje } buffer.append("}"); } else { - buffer.append(": ").append(object.toString()); + buffer.append(": ").append(object); } } diff --git a/java/core/src/main/java/com/google/protobuf/MessageSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSchema.java index 4170f4fbe499b..53548c8fc8e20 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java @@ -82,6 +82,7 @@ import java.util.Map; /** Schema used for standard messages. */ +@CheckReturnValue final class MessageSchema implements Schema { private static final int INTS_PER_FIELD = 3; private static final int OFFSET_BITS = 20; @@ -2533,7 +2534,6 @@ private static List listAt(Object message, long offset) { return (List) UnsafeUtil.getObject(message, offset); } - @SuppressWarnings("unchecked") @Override // TODO(nathanmittler): Consider serializing oneof fields last so that only one entry per // oneof is actually serialized. This would mean that we would violate the serialization order @@ -4875,6 +4875,7 @@ private EnumVerifier getEnumFieldVerifier(int pos) { * group (endGroup != 0), parsing ends when a tag == endGroup is encountered and the position * after that tag is returned. */ + @CanIgnoreReturnValue int parseProto2Message( T message, byte[] data, int position, int limit, int endGroup, Registers registers) throws IOException { @@ -5184,6 +5185,7 @@ int parseProto2Message( } /** Parses a proto3 message and returns the limit if parsing is successful. */ + @CanIgnoreReturnValue private int parseProto3Message( T message, byte[] data, int position, int limit, Registers registers) throws IOException { final sun.misc.Unsafe unsafe = UNSAFE; diff --git a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java index 187dc8b8a5e13..71ad7507674d3 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java @@ -35,6 +35,7 @@ import java.util.Map.Entry; /** Schema used for proto2 messages using message_set_wireformat. */ +@CheckReturnValue final class MessageSetSchema implements Schema { private final MessageLite defaultInstance; private final UnknownFieldSchema unknownFieldSchema; @@ -231,7 +232,6 @@ public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionR * A helper method for wildcard capture of {@code unknownFieldSchema}. See: * https://docs.oracle.com/javase/tutorial/java/generics/capture.html */ - @SuppressWarnings("unchecked") private > void mergeFromHelper( UnknownFieldSchema unknownFieldSchema, ExtensionSchema extensionSchema, diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java index f2dbb8ef9cc11..9bffd8e953e2e 100644 --- a/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java +++ b/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java @@ -30,6 +30,7 @@ package com.google.protobuf; +@CheckReturnValue interface NewInstanceSchema { /** Create a new message instance given the default instance of the message type. */ Object newInstance(Object defaultInstance); diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java index 9b922667638d2..7ee92852e1c3c 100644 --- a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java @@ -30,6 +30,7 @@ package com.google.protobuf; +@CheckReturnValue final class NewInstanceSchemaLite implements NewInstanceSchema { @Override public Object newInstance(Object defaultInstance) { diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java index eff45f67b9c04..6e9031a551c0b 100644 --- a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java +++ b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java @@ -30,6 +30,7 @@ package com.google.protobuf; +@CheckReturnValue final class NewInstanceSchemas { private static final NewInstanceSchema FULL_SCHEMA = loadSchemaForFullRuntime(); private static final NewInstanceSchema LITE_SCHEMA = new NewInstanceSchemaLite(); diff --git a/java/core/src/main/java/com/google/protobuf/OneofInfo.java b/java/core/src/main/java/com/google/protobuf/OneofInfo.java index bc518fcadd93f..4301055d6bb0a 100644 --- a/java/core/src/main/java/com/google/protobuf/OneofInfo.java +++ b/java/core/src/main/java/com/google/protobuf/OneofInfo.java @@ -35,6 +35,7 @@ /** Information for a oneof within a protobuf message. */ // TODO(nathanmittler): make this private once all of experimental code is migrated to protobuf. @ExperimentalApi +@CheckReturnValue final class OneofInfo { private final int id; private final Field caseField; diff --git a/java/core/src/main/java/com/google/protobuf/Protobuf.java b/java/core/src/main/java/com/google/protobuf/Protobuf.java index 0affac5f0a40c..74624c33464d1 100644 --- a/java/core/src/main/java/com/google/protobuf/Protobuf.java +++ b/java/core/src/main/java/com/google/protobuf/Protobuf.java @@ -41,6 +41,7 @@ * than directly accessing internal APIs) in order to perform operations on protobuf messages. */ @ExperimentalApi +@CheckReturnValue final class Protobuf { private static final Protobuf INSTANCE = new Protobuf(); @@ -127,6 +128,7 @@ public Schema registerSchema(Class messageType, Schema schema) { * @return the previously registered schema, or {@code null} if no schema was registered * previously. */ + @CanIgnoreReturnValue public Schema registerSchemaOverride(Class messageType, Schema schema) { checkNotNull(messageType, "messageType"); checkNotNull(schema, "schema"); diff --git a/java/core/src/main/java/com/google/protobuf/ProtobufLists.java b/java/core/src/main/java/com/google/protobuf/ProtobufLists.java index 271c849b4d41e..018c9118c0fab 100644 --- a/java/core/src/main/java/com/google/protobuf/ProtobufLists.java +++ b/java/core/src/main/java/com/google/protobuf/ProtobufLists.java @@ -39,6 +39,7 @@ /** Utility class for construction of lists that extend {@link ProtobufList}. */ @ExperimentalApi +@CheckReturnValue final class ProtobufLists { private ProtobufLists() {} diff --git a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java index 1735a08924cfd..2e585748e1221 100644 --- a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java @@ -34,6 +34,7 @@ * RawMessageInfo stores the same amount of information as {@link MessageInfo} but in a more compact * format. */ +@CheckReturnValue final class RawMessageInfo implements MessageInfo { private final MessageLite defaultInstance; diff --git a/java/core/src/main/java/com/google/protobuf/Reader.java b/java/core/src/main/java/com/google/protobuf/Reader.java index 705096f2d80e2..7497eeacd50d5 100644 --- a/java/core/src/main/java/com/google/protobuf/Reader.java +++ b/java/core/src/main/java/com/google/protobuf/Reader.java @@ -37,6 +37,7 @@ /** A reader of fields from a serialized protobuf message. */ // TODO(nathanmittler): Refactor to allow the reader to allocate properly sized lists. @ExperimentalApi +@CheckReturnValue interface Reader { /** Value used to indicate that the end of input has been reached. */ int READ_DONE = Integer.MAX_VALUE; diff --git a/java/core/src/main/java/com/google/protobuf/Schema.java b/java/core/src/main/java/com/google/protobuf/Schema.java index d0e1e26e5bf78..efb3c1ef449c2 100644 --- a/java/core/src/main/java/com/google/protobuf/Schema.java +++ b/java/core/src/main/java/com/google/protobuf/Schema.java @@ -38,6 +38,7 @@ * such as serialization/deserialization. */ @ExperimentalApi +@CheckReturnValue interface Schema { /** Writes the given message to the target {@link Writer}. */ void writeTo(T message, Writer writer) throws IOException; diff --git a/java/core/src/main/java/com/google/protobuf/SchemaFactory.java b/java/core/src/main/java/com/google/protobuf/SchemaFactory.java index cf38dd69945f7..33d9c9d21a123 100644 --- a/java/core/src/main/java/com/google/protobuf/SchemaFactory.java +++ b/java/core/src/main/java/com/google/protobuf/SchemaFactory.java @@ -32,6 +32,7 @@ /** A factory that manufactures {@link Schema} instances for protobuf messages. */ @ExperimentalApi +@CheckReturnValue interface SchemaFactory { /** Creates a schema instance for the given protobuf message type. */ Schema createSchema(Class messageType); diff --git a/java/core/src/main/java/com/google/protobuf/SchemaUtil.java b/java/core/src/main/java/com/google/protobuf/SchemaUtil.java index 1d5e6ba69c175..06f3ab79f3d32 100644 --- a/java/core/src/main/java/com/google/protobuf/SchemaUtil.java +++ b/java/core/src/main/java/com/google/protobuf/SchemaUtil.java @@ -41,6 +41,7 @@ /** Helper methods used by schemas. */ @ExperimentalApi +@CheckReturnValue final class SchemaUtil { private static final Class GENERATED_MESSAGE_CLASS = getGeneratedMessageClass(); private static final UnknownFieldSchema PROTO2_UNKNOWN_FIELD_SET_SCHEMA = @@ -980,6 +981,7 @@ static UB filterUnknownEnumList( } /** Stores an unrecognized enum value as an unknown value. */ + @CanIgnoreReturnValue static UB storeUnknownEnum( int number, int enumValue, UB unknownFields, UnknownFieldSchema unknownFieldSchema) { if (unknownFields == null) { diff --git a/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java b/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java index 546e56e856130..db6353452e718 100644 --- a/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java +++ b/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java @@ -374,7 +374,6 @@ private void checkMutable() { * @return a {@link SortedMap} to which overflow entries mappings can be added or removed. * @throws UnsupportedOperationException if {@link #makeImmutable()} has been called. */ - @SuppressWarnings("unchecked") private SortedMap getOverflowEntriesMutable() { checkMutable(); if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) { @@ -441,7 +440,6 @@ public boolean equals(Object o) { if (!(o instanceof Map.Entry)) { return false; } - @SuppressWarnings("unchecked") Map.Entry other = (Map.Entry) o; return equals(key, other.getKey()) && equals(value, other.getValue()); } diff --git a/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java b/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java index a32b1430ee115..defb53ebd0c1b 100644 --- a/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java @@ -41,6 +41,7 @@ * contained within a message. */ @ExperimentalApi +@CheckReturnValue final class StructuralMessageInfo implements MessageInfo { private final ProtoSyntax syntax; private final boolean messageSetWireFormat; 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 21f1ff09d4699..6aeb56556316d 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -70,6 +70,9 @@ private TextFormat() {} * @deprecated Use {@code printer().print(MessageOrBuilder, Appendable)} */ @Deprecated + @InlineMe( + replacement = "TextFormat.printer().print(message, output)", + imports = "com.google.protobuf.TextFormat") public static void print(final MessageOrBuilder message, final Appendable output) throws IOException { printer().print(message, output); @@ -92,6 +95,9 @@ public static void print(final UnknownFieldSet fields, final Appendable output) * @deprecated Use {@code printer().escapingNonAscii(false).print(MessageOrBuilder, Appendable)} */ @Deprecated + @InlineMe( + replacement = "TextFormat.printer().escapingNonAscii(false).print(message, output)", + imports = "com.google.protobuf.TextFormat") public static void printUnicode(final MessageOrBuilder message, final Appendable output) throws IOException { printer().escapingNonAscii(false).print(message, output); @@ -145,6 +151,9 @@ public static String shortDebugString(final UnknownFieldSet fields) { * @deprecated Use {@code message.toString()} */ @Deprecated + @InlineMe( + replacement = "TextFormat.printer().printToString(message)", + imports = "com.google.protobuf.TextFormat") public static String printToString(final MessageOrBuilder message) { return printer().printToString(message); } @@ -166,6 +175,9 @@ public static String printToString(final UnknownFieldSet fields) { * @deprecated Use {@code printer().escapingNonAscii(false).printToString(MessageOrBuilder)} */ @Deprecated + @InlineMe( + replacement = "TextFormat.printer().escapingNonAscii(false).printToString(message)", + imports = "com.google.protobuf.TextFormat") public static String printToUnicodeString(final MessageOrBuilder message) { return printer().escapingNonAscii(false).printToString(message); } @@ -227,6 +239,9 @@ public static void printUnicodeFieldValue( * @throws IOException if there is an exception writing to the output */ @Deprecated + @InlineMe( + replacement = "TextFormat.printer().printFieldValue(field, value, output)", + imports = "com.google.protobuf.TextFormat") public static void printFieldValue( final FieldDescriptor field, final Object value, final Appendable output) throws IOException { printer().printFieldValue(field, value, output); diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java index e736d5ce9cdca..681b824d8dd94 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java @@ -33,6 +33,7 @@ import java.io.IOException; @ExperimentalApi +@CheckReturnValue abstract class UnknownFieldSchema { /** Whether unknown fields should be dropped. */ diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java index ba2f9df08e675..5c482d62dab52 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java @@ -43,13 +43,13 @@ import java.util.TreeMap; /** - * {@code UnknownFieldSet} is used to keep track of fields which were seen when parsing a protocol + * {@code UnknownFieldSet} keeps track of fields which were seen when parsing a protocol * message but whose field numbers or types are unrecognized. This most frequently occurs when new * fields are added to a message type and then messages containing those fields are read by old * software that was compiled before the new types were added. * *

Every {@link Message} contains an {@code UnknownFieldSet} (and every {@link Message.Builder} - * contains an {@link Builder}). + * contains a {@link Builder}). * *

Most users will never need to use this class. * @@ -57,9 +57,13 @@ */ public final class UnknownFieldSet implements MessageLite { - private UnknownFieldSet() { - fields = null; - fieldsDescending = null; + private final TreeMap fields; + + /** + * Construct an {@code UnknownFieldSet} around the given map. + */ + UnknownFieldSet(TreeMap fields) { + this.fields = fields; } /** Create a new {@link Builder}. */ @@ -68,7 +72,7 @@ public static Builder newBuilder() { } /** Create a new {@link Builder} and initialize it to be a copy of {@code copyFrom}. */ - public static Builder newBuilder(final UnknownFieldSet copyFrom) { + public static Builder newBuilder(UnknownFieldSet copyFrom) { return newBuilder().mergeFrom(copyFrom); } @@ -83,25 +87,11 @@ public UnknownFieldSet getDefaultInstanceForType() { } private static final UnknownFieldSet defaultInstance = - new UnknownFieldSet( - Collections.emptyMap(), Collections.emptyMap()); - - /** - * Construct an {@code UnknownFieldSet} around the given map. The map is expected to be immutable. - */ - UnknownFieldSet(final Map fields, final Map fieldsDescending) { - this.fields = fields; - this.fieldsDescending = fieldsDescending; - } - - private final Map fields; - - /** A copy of {@link #fields} who's iterator order is reversed. */ - private final Map fieldsDescending; + new UnknownFieldSet(new TreeMap()); @Override - public boolean equals(final Object other) { + public boolean equals(Object other) { if (this == other) { return true; } @@ -110,29 +100,33 @@ public boolean equals(final Object other) { @Override public int hashCode() { + if (fields.isEmpty()) { // avoid allocation of iterator. + // This optimization may not be helpful but it is needed for the allocation tests to pass. + return 0; + } return fields.hashCode(); } /** Get a map of fields in the set by number. */ public Map asMap() { - return fields; + return (Map) fields.clone(); } /** Check if the given field number is present in the set. */ - public boolean hasField(final int number) { + public boolean hasField(int number) { return fields.containsKey(number); } /** Get a field by number. Returns an empty field if not present. Never returns {@code null}. */ - public Field getField(final int number) { - final Field result = fields.get(number); + public Field getField(int number) { + Field result = fields.get(number); return (result == null) ? Field.getDefaultInstance() : result; } /** Serializes the set and writes it to {@code output}. */ @Override - public void writeTo(final CodedOutputStream output) throws IOException { - for (final Map.Entry entry : fields.entrySet()) { + public void writeTo(CodedOutputStream output) throws IOException { + for (Map.Entry entry : fields.entrySet()) { Field field = entry.getValue(); field.writeTo(entry.getKey(), output); } @@ -154,10 +148,10 @@ public String toString() { @Override public ByteString toByteString() { try { - final ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize()); + ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize()); writeTo(out.getCodedOutput()); return out.build(); - } catch (final IOException e) { + } catch (IOException e) { throw new RuntimeException( "Serializing to a ByteString threw an IOException (should never happen).", e); } @@ -170,12 +164,12 @@ public ByteString toByteString() { @Override public byte[] toByteArray() { try { - final byte[] result = new byte[getSerializedSize()]; - final CodedOutputStream output = CodedOutputStream.newInstance(result); + byte[] result = new byte[getSerializedSize()]; + CodedOutputStream output = CodedOutputStream.newInstance(result); writeTo(output); output.checkNoSpaceLeft(); return result; - } catch (final IOException e) { + } catch (IOException e) { throw new RuntimeException( "Serializing to a byte array threw an IOException (should never happen).", e); } @@ -186,16 +180,16 @@ public byte[] toByteArray() { * {@link #writeTo(CodedOutputStream)}. */ @Override - public void writeTo(final OutputStream output) throws IOException { - final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); + public void writeTo(OutputStream output) throws IOException { + CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); writeTo(codedOutput); codedOutput.flush(); } @Override public void writeDelimitedTo(OutputStream output) throws IOException { - final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); - codedOutput.writeRawVarint32(getSerializedSize()); + CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); + codedOutput.writeUInt32NoTag(getSerializedSize()); writeTo(codedOutput); codedOutput.flush(); } @@ -204,15 +198,17 @@ public void writeDelimitedTo(OutputStream output) throws IOException { @Override public int getSerializedSize() { int result = 0; - for (final Map.Entry entry : fields.entrySet()) { - result += entry.getValue().getSerializedSize(entry.getKey()); + if (!fields.isEmpty()) { + for (Map.Entry entry : fields.entrySet()) { + result += entry.getValue().getSerializedSize(entry.getKey()); + } } return result; } /** Serializes the set and writes it to {@code output} using {@code MessageSet} wire format. */ - public void writeAsMessageSetTo(final CodedOutputStream output) throws IOException { - for (final Map.Entry entry : fields.entrySet()) { + public void writeAsMessageSetTo(CodedOutputStream output) throws IOException { + for (Map.Entry entry : fields.entrySet()) { entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), output); } } @@ -221,7 +217,7 @@ public void writeAsMessageSetTo(final CodedOutputStream output) throws IOExcepti void writeTo(Writer writer) throws IOException { if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) { // Write fields in descending order. - for (Map.Entry entry : fieldsDescending.entrySet()) { + for (Map.Entry entry : fields.descendingMap().entrySet()) { entry.getValue().writeTo(entry.getKey(), writer); } } else { @@ -233,15 +229,15 @@ void writeTo(Writer writer) throws IOException { } /** Serializes the set and writes it to {@code writer} using {@code MessageSet} wire format. */ - void writeAsMessageSetTo(final Writer writer) throws IOException { + void writeAsMessageSetTo(Writer writer) throws IOException { if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) { // Write fields in descending order. - for (final Map.Entry entry : fieldsDescending.entrySet()) { + for (Map.Entry entry : fields.descendingMap().entrySet()) { entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer); } } else { // Write fields in ascending order. - for (final Map.Entry entry : fields.entrySet()) { + for (Map.Entry entry : fields.entrySet()) { entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer); } } @@ -250,7 +246,7 @@ void writeAsMessageSetTo(final Writer writer) throws IOException { /** Get the number of bytes required to encode this set using {@code MessageSet} wire format. */ public int getSerializedSizeAsMessageSet() { int result = 0; - for (final Map.Entry entry : fields.entrySet()) { + for (Map.Entry entry : fields.entrySet()) { result += entry.getValue().getSerializedSizeAsMessageSetExtension(entry.getKey()); } return result; @@ -264,23 +260,23 @@ public boolean isInitialized() { } /** Parse an {@code UnknownFieldSet} from the given input stream. */ - public static UnknownFieldSet parseFrom(final CodedInputStream input) throws IOException { + public static UnknownFieldSet parseFrom(CodedInputStream input) throws IOException { return newBuilder().mergeFrom(input).build(); } /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */ - public static UnknownFieldSet parseFrom(final ByteString data) + public static UnknownFieldSet parseFrom(ByteString data) throws InvalidProtocolBufferException { return newBuilder().mergeFrom(data).build(); } /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */ - public static UnknownFieldSet parseFrom(final byte[] data) throws InvalidProtocolBufferException { + public static UnknownFieldSet parseFrom(byte[] data) throws InvalidProtocolBufferException { return newBuilder().mergeFrom(data).build(); } /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */ - public static UnknownFieldSet parseFrom(final InputStream input) throws IOException { + public static UnknownFieldSet parseFrom(InputStream input) throws IOException { return newBuilder().mergeFrom(input).build(); } @@ -309,64 +305,43 @@ public static final class Builder implements MessageLite.Builder { // This constructor should never be called directly (except from 'create'). private Builder() {} - private Map fields; - - // Optimization: We keep around a builder for the last field that was - // modified so that we can efficiently add to it multiple times in a - // row (important when parsing an unknown repeated field). - private int lastFieldNumber; - private Field.Builder lastField; + private TreeMap fieldBuilders = new TreeMap<>(); private static Builder create() { - Builder builder = new Builder(); - builder.reinitialize(); - return builder; + return new Builder(); } /** * Get a field builder for the given field number which includes any values that already exist. */ - private Field.Builder getFieldBuilder(final int number) { - if (lastField != null) { - if (number == lastFieldNumber) { - return lastField; - } - // Note: addField() will reset lastField and lastFieldNumber. - addField(lastFieldNumber, lastField.build()); - } + private Field.Builder getFieldBuilder(int number) { if (number == 0) { return null; } else { - final Field existing = fields.get(number); - lastFieldNumber = number; - lastField = Field.newBuilder(); - if (existing != null) { - lastField.mergeFrom(existing); + Field.Builder builder = fieldBuilders.get(number); + if (builder == null) { + builder = Field.newBuilder(); + fieldBuilders.put(number, builder); } - return lastField; + return builder; } } /** * Build the {@link UnknownFieldSet} and return it. - * - *

Once {@code build()} has been called, the {@code Builder} will no longer be usable. - * Calling any method after {@code build()} will result in undefined behavior and can cause a - * {@code NullPointerException} to be thrown. */ @Override public UnknownFieldSet build() { - getFieldBuilder(0); // Force lastField to be built. - final UnknownFieldSet result; - if (fields.isEmpty()) { + UnknownFieldSet result; + if (fieldBuilders.isEmpty()) { result = getDefaultInstance(); } else { - Map descendingFields = null; - descendingFields = - Collections.unmodifiableMap(((TreeMap) fields).descendingMap()); - result = new UnknownFieldSet(Collections.unmodifiableMap(fields), descendingFields); + TreeMap fields = new TreeMap<>(); + for (Map.Entry entry : fieldBuilders.entrySet()) { + fields.put(entry.getKey(), entry.getValue().build()); + } + result = new UnknownFieldSet(fields); } - fields = null; return result; } @@ -378,11 +353,13 @@ public UnknownFieldSet buildPartial() { @Override public Builder clone() { - getFieldBuilder(0); // Force lastField to be built. - Map descendingFields = null; - descendingFields = - Collections.unmodifiableMap(((TreeMap) fields).descendingMap()); - return UnknownFieldSet.newBuilder().mergeFrom(new UnknownFieldSet(fields, descendingFields)); + Builder clone = UnknownFieldSet.newBuilder(); + for (Map.Entry entry : fieldBuilders.entrySet()) { + Integer key = entry.getKey(); + Field.Builder value = entry.getValue(); + clone.fieldBuilders.put(key, value.clone()); + } + return clone; } @Override @@ -390,31 +367,24 @@ public UnknownFieldSet getDefaultInstanceForType() { return UnknownFieldSet.getDefaultInstance(); } - private void reinitialize() { - fields = Collections.emptyMap(); - lastFieldNumber = 0; - lastField = null; - } - /** Reset the builder to an empty set. */ @Override public Builder clear() { - reinitialize(); + fieldBuilders = new TreeMap<>(); return this; } - /** Clear fields from the set with a given field number. */ - public Builder clearField(final int number) { - if (number == 0) { - throw new IllegalArgumentException("Zero is not a valid field number."); - } - if (lastField != null && lastFieldNumber == number) { - // Discard this. - lastField = null; - lastFieldNumber = 0; + /** + * Clear fields from the set with a given field number. + * + * @throws IllegalArgumentException if number is not positive + */ + public Builder clearField(int number) { + if (number <= 0) { + throw new IllegalArgumentException(number + " is not a valid field number."); } - if (fields.containsKey(number)) { - fields.remove(number); + if (fieldBuilders.containsKey(number)) { + fieldBuilders.remove(number); } return this; } @@ -423,9 +393,9 @@ public Builder clearField(final int number) { * Merge the fields from {@code other} into this set. If a field number exists in both sets, * {@code other}'s values for that field will be appended to the values in this set. */ - public Builder mergeFrom(final UnknownFieldSet other) { + public Builder mergeFrom(UnknownFieldSet other) { if (other != getDefaultInstance()) { - for (final Map.Entry entry : other.fields.entrySet()) { + for (Map.Entry entry : other.fields.entrySet()) { mergeField(entry.getKey(), entry.getValue()); } } @@ -435,10 +405,12 @@ public Builder mergeFrom(final UnknownFieldSet other) { /** * Add a field to the {@code UnknownFieldSet}. If a field with the same number already exists, * the two are merged. + * + * @throws IllegalArgumentException if number is not positive */ - public Builder mergeField(final int number, final Field field) { - if (number == 0) { - throw new IllegalArgumentException("Zero is not a valid field number."); + public Builder mergeField(int number, final Field field) { + if (number <= 0) { + throw new IllegalArgumentException(number + " is not a valid field number."); } if (hasField(number)) { getFieldBuilder(number).mergeFrom(field); @@ -454,10 +426,12 @@ public Builder mergeField(final int number, final Field field) { /** * Convenience method for merging a new field containing a single varint value. This is used in * particular when an unknown enum value is encountered. + * + * @throws IllegalArgumentException if number is not positive */ - public Builder mergeVarintField(final int number, final int value) { - if (number == 0) { - throw new IllegalArgumentException("Zero is not a valid field number."); + public Builder mergeVarintField(int number, int value) { + if (number <= 0) { + throw new IllegalArgumentException(number + " is not a valid field number."); } getFieldBuilder(number).addVarint(value); return this; @@ -467,40 +441,33 @@ public Builder mergeVarintField(final int number, final int value) { * Convenience method for merging a length-delimited field. * *

For use by generated code only. + * + * @throws IllegalArgumentException if number is not positive */ - public Builder mergeLengthDelimitedField(final int number, final ByteString value) { - if (number == 0) { - throw new IllegalArgumentException("Zero is not a valid field number."); + public Builder mergeLengthDelimitedField(int number, ByteString value) { + if (number <= 0) { + throw new IllegalArgumentException(number + " is not a valid field number."); } getFieldBuilder(number).addLengthDelimited(value); return this; } /** Check if the given field number is present in the set. */ - public boolean hasField(final int number) { - if (number == 0) { - throw new IllegalArgumentException("Zero is not a valid field number."); - } - return number == lastFieldNumber || fields.containsKey(number); + public boolean hasField(int number) { + return fieldBuilders.containsKey(number); } /** * Add a field to the {@code UnknownFieldSet}. If a field with the same number already exists, * it is removed. + * + * @throws IllegalArgumentException if number is not positive */ - public Builder addField(final int number, final Field field) { - if (number == 0) { - throw new IllegalArgumentException("Zero is not a valid field number."); - } - if (lastField != null && lastFieldNumber == number) { - // Discard this. - lastField = null; - lastFieldNumber = 0; + public Builder addField(int number, Field field) { + if (number <= 0) { + throw new IllegalArgumentException(number + " is not a valid field number."); } - if (fields.isEmpty()) { - fields = new TreeMap(); - } - fields.put(number, field); + fieldBuilders.put(number, Field.newBuilder(field)); return this; } @@ -509,15 +476,18 @@ public Builder addField(final int number, final Field field) { * changes may or may not be reflected in this map. */ public Map asMap() { - getFieldBuilder(0); // Force lastField to be built. + TreeMap fields = new TreeMap<>(); + for (Map.Entry entry : fieldBuilders.entrySet()) { + fields.put(entry.getKey(), entry.getValue().build()); + } return Collections.unmodifiableMap(fields); } /** Parse an entire message from {@code input} and merge its fields into this set. */ @Override - public Builder mergeFrom(final CodedInputStream input) throws IOException { + public Builder mergeFrom(CodedInputStream input) throws IOException { while (true) { - final int tag = input.readTag(); + int tag = input.readTag(); if (tag == 0 || !mergeFieldFrom(tag, input)) { break; } @@ -531,8 +501,8 @@ public Builder mergeFrom(final CodedInputStream input) throws IOException { * @param tag The field's tag number, which was already parsed. * @return {@code false} if the tag is an end group tag. */ - public boolean mergeFieldFrom(final int tag, final CodedInputStream input) throws IOException { - final int number = WireFormat.getTagFieldNumber(tag); + public boolean mergeFieldFrom(int tag, CodedInputStream input) throws IOException { + int number = WireFormat.getTagFieldNumber(tag); switch (WireFormat.getTagWireType(tag)) { case WireFormat.WIRETYPE_VARINT: getFieldBuilder(number).addVarint(input.readInt64()); @@ -544,7 +514,7 @@ public boolean mergeFieldFrom(final int tag, final CodedInputStream input) throw getFieldBuilder(number).addLengthDelimited(input.readBytes()); return true; case WireFormat.WIRETYPE_START_GROUP: - final Builder subBuilder = newBuilder(); + Builder subBuilder = newBuilder(); input.readGroup(number, subBuilder, ExtensionRegistry.getEmptyRegistry()); getFieldBuilder(number).addGroup(subBuilder.build()); return true; @@ -563,15 +533,15 @@ public boolean mergeFieldFrom(final int tag, final CodedInputStream input) throw * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. */ @Override - public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException { + public Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException { try { - final CodedInputStream input = data.newCodedInput(); + CodedInputStream input = data.newCodedInput(); mergeFrom(input); input.checkLastTagWas(0); return this; - } catch (final InvalidProtocolBufferException e) { + } catch (InvalidProtocolBufferException e) { throw e; - } catch (final IOException e) { + } catch (IOException e) { throw new RuntimeException( "Reading from a ByteString threw an IOException (should never happen).", e); } @@ -582,15 +552,15 @@ public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferExce * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. */ @Override - public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException { + public Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException { try { - final CodedInputStream input = CodedInputStream.newInstance(data); + CodedInputStream input = CodedInputStream.newInstance(data); mergeFrom(input); input.checkLastTagWas(0); return this; - } catch (final InvalidProtocolBufferException e) { + } catch (InvalidProtocolBufferException e) { throw e; - } catch (final IOException e) { + } catch (IOException e) { throw new RuntimeException( "Reading from a byte array threw an IOException (should never happen).", e); } @@ -601,8 +571,8 @@ public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferExceptio * This is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. */ @Override - public Builder mergeFrom(final InputStream input) throws IOException { - final CodedInputStream codedInput = CodedInputStream.newInstance(input); + public Builder mergeFrom(InputStream input) throws IOException { + CodedInputStream codedInput = CodedInputStream.newInstance(input); mergeFrom(codedInput); codedInput.checkLastTagWas(0); return this; @@ -610,12 +580,12 @@ public Builder mergeFrom(final InputStream input) throws IOException { @Override public boolean mergeDelimitedFrom(InputStream input) throws IOException { - final int firstByte = input.read(); + int firstByte = input.read(); if (firstByte == -1) { return false; } - final int size = CodedInputStream.readRawVarint32(firstByte, input); - final InputStream limitedInput = new LimitedInputStream(input, size); + int size = CodedInputStream.readRawVarint32(firstByte, input); + InputStream limitedInput = new LimitedInputStream(input, size); mergeFrom(limitedInput); return true; } @@ -644,7 +614,7 @@ public Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistr @Override public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException { try { - final CodedInputStream input = CodedInputStream.newInstance(data, off, len); + CodedInputStream input = CodedInputStream.newInstance(data, off, len); mergeFrom(input); input.checkLastTagWas(0); return this; @@ -718,7 +688,7 @@ public static Builder newBuilder() { } /** Construct a new {@link Builder} and initialize it to a copy of {@code copyFrom}. */ - public static Builder newBuilder(final Field copyFrom) { + public static Builder newBuilder(Field copyFrom) { return newBuilder().mergeFrom(copyFrom); } @@ -758,7 +728,7 @@ public List getGroupList() { } @Override - public boolean equals(final Object other) { + public boolean equals(Object other) { if (this == other) { return true; } @@ -785,7 +755,7 @@ private Object[] getIdentityArray() { public ByteString toByteString(int fieldNumber) { try { // TODO(lukes): consider caching serialized size in a volatile long - final ByteString.CodedBuilder out = + ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize(fieldNumber)); writeTo(fieldNumber, out.getCodedOutput()); return out.build(); @@ -796,40 +766,40 @@ public ByteString toByteString(int fieldNumber) { } /** Serializes the field, including field number, and writes it to {@code output}. */ - public void writeTo(final int fieldNumber, final CodedOutputStream output) throws IOException { - for (final long value : varint) { + public void writeTo(int fieldNumber, CodedOutputStream output) throws IOException { + for (long value : varint) { output.writeUInt64(fieldNumber, value); } - for (final int value : fixed32) { + for (int value : fixed32) { output.writeFixed32(fieldNumber, value); } - for (final long value : fixed64) { + for (long value : fixed64) { output.writeFixed64(fieldNumber, value); } - for (final ByteString value : lengthDelimited) { + for (ByteString value : lengthDelimited) { output.writeBytes(fieldNumber, value); } - for (final UnknownFieldSet value : group) { + for (UnknownFieldSet value : group) { output.writeGroup(fieldNumber, value); } } /** Get the number of bytes required to encode this field, including field number. */ - public int getSerializedSize(final int fieldNumber) { + public int getSerializedSize(int fieldNumber) { int result = 0; - for (final long value : varint) { + for (long value : varint) { result += CodedOutputStream.computeUInt64Size(fieldNumber, value); } - for (final int value : fixed32) { + for (int value : fixed32) { result += CodedOutputStream.computeFixed32Size(fieldNumber, value); } - for (final long value : fixed64) { + for (long value : fixed64) { result += CodedOutputStream.computeFixed64Size(fieldNumber, value); } - for (final ByteString value : lengthDelimited) { + for (ByteString value : lengthDelimited) { result += CodedOutputStream.computeBytesSize(fieldNumber, value); } - for (final UnknownFieldSet value : group) { + for (UnknownFieldSet value : group) { result += CodedOutputStream.computeGroupSize(fieldNumber, value); } return result; @@ -839,15 +809,15 @@ public int getSerializedSize(final int fieldNumber) { * Serializes the field, including field number, and writes it to {@code output}, using {@code * MessageSet} wire format. */ - public void writeAsMessageSetExtensionTo(final int fieldNumber, final CodedOutputStream output) + public void writeAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) throws IOException { - for (final ByteString value : lengthDelimited) { + for (ByteString value : lengthDelimited) { output.writeRawMessageSetExtension(fieldNumber, value); } } /** Serializes the field, including field number, and writes it to {@code writer}. */ - void writeTo(final int fieldNumber, final Writer writer) throws IOException { + void writeTo(int fieldNumber, Writer writer) throws IOException { writer.writeInt64List(fieldNumber, varint, false); writer.writeFixed32List(fieldNumber, fixed32, false); writer.writeFixed64List(fieldNumber, fixed64, false); @@ -872,7 +842,7 @@ void writeTo(final int fieldNumber, final Writer writer) throws IOException { * Serializes the field, including field number, and writes it to {@code writer}, using {@code * MessageSet} wire format. */ - private void writeAsMessageSetExtensionTo(final int fieldNumber, final Writer writer) + private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer) throws IOException { if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) { // Write in descending field order. @@ -882,7 +852,7 @@ private void writeAsMessageSetExtensionTo(final int fieldNumber, final Writer wr } } else { // Write in ascending field order. - for (final ByteString value : lengthDelimited) { + for (ByteString value : lengthDelimited) { writer.writeMessageSetItem(fieldNumber, value); } } @@ -892,9 +862,9 @@ private void writeAsMessageSetExtensionTo(final int fieldNumber, final Writer wr * Get the number of bytes required to encode this field, including field number, using {@code * MessageSet} wire format. */ - public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) { + public int getSerializedSizeAsMessageSetExtension(int fieldNumber) { int result = 0; - for (final ByteString value : lengthDelimited) { + for (ByteString value : lengthDelimited) { result += CodedOutputStream.computeRawMessageSetExtensionSize(fieldNumber, value); } return result; @@ -912,52 +882,85 @@ public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) { *

Use {@link Field#newBuilder()} to construct a {@code Builder}. */ public static final class Builder { - // This constructor should never be called directly (except from 'create'). - private Builder() {} + // This constructor should only be called directly from 'create' and 'clone'. + private Builder() { + result = new Field(); + } private static Builder create() { Builder builder = new Builder(); - builder.result = new Field(); return builder; } private Field result; + @Override + public Builder clone() { + Field copy = new Field(); + if (result.varint == null) { + copy.varint = null; + } else { + copy.varint = new ArrayList<>(result.varint); + } + if (result.fixed32 == null) { + copy.fixed32 = null; + } else { + copy.fixed32 = new ArrayList<>(result.fixed32); + } + if (result.fixed64 == null) { + copy.fixed64 = null; + } else { + copy.fixed64 = new ArrayList<>(result.fixed64); + } + if (result.lengthDelimited == null) { + copy.lengthDelimited = null; + } else { + copy.lengthDelimited = new ArrayList<>(result.lengthDelimited); + } + if (result.group == null) { + copy.group = null; + } else { + copy.group = new ArrayList<>(result.group); + } + + Builder clone = new Builder(); + clone.result = copy; + return clone; + } + /** - * Build the field. After {@code build()} has been called, the {@code Builder} is no longer - * usable. Calling any other method will result in undefined behavior and can cause a {@code - * NullPointerException} to be thrown. + * Build the field. */ public Field build() { + Field built = new Field(); if (result.varint == null) { - result.varint = Collections.emptyList(); + built.varint = Collections.emptyList(); } else { - result.varint = Collections.unmodifiableList(result.varint); + built.varint = Collections.unmodifiableList(new ArrayList<>(result.varint)); } if (result.fixed32 == null) { - result.fixed32 = Collections.emptyList(); + built.fixed32 = Collections.emptyList(); } else { - result.fixed32 = Collections.unmodifiableList(result.fixed32); + built.fixed32 = Collections.unmodifiableList(new ArrayList<>(result.fixed32)); } if (result.fixed64 == null) { - result.fixed64 = Collections.emptyList(); + built.fixed64 = Collections.emptyList(); } else { - result.fixed64 = Collections.unmodifiableList(result.fixed64); + built.fixed64 = Collections.unmodifiableList(new ArrayList<>(result.fixed64)); } if (result.lengthDelimited == null) { - result.lengthDelimited = Collections.emptyList(); + built.lengthDelimited = Collections.emptyList(); } else { - result.lengthDelimited = Collections.unmodifiableList(result.lengthDelimited); + built.lengthDelimited = Collections.unmodifiableList( + new ArrayList<>(result.lengthDelimited)); } if (result.group == null) { - result.group = Collections.emptyList(); + built.group = Collections.emptyList(); } else { - result.group = Collections.unmodifiableList(result.group); + built.group = Collections.unmodifiableList(new ArrayList<>(result.group)); } - final Field returnMe = result; - result = null; - return returnMe; + return built; } /** Discard the field's contents. */ @@ -970,7 +973,7 @@ public Builder clear() { * Merge the values in {@code other} into this field. For each list of values, {@code other}'s * values are append to the ones in this field. */ - public Builder mergeFrom(final Field other) { + public Builder mergeFrom(Field other) { if (!other.varint.isEmpty()) { if (result.varint == null) { result.varint = new ArrayList(); @@ -985,19 +988,19 @@ public Builder mergeFrom(final Field other) { } if (!other.fixed64.isEmpty()) { if (result.fixed64 == null) { - result.fixed64 = new ArrayList(); + result.fixed64 = new ArrayList<>(); } result.fixed64.addAll(other.fixed64); } if (!other.lengthDelimited.isEmpty()) { if (result.lengthDelimited == null) { - result.lengthDelimited = new ArrayList(); + result.lengthDelimited = new ArrayList<>(); } result.lengthDelimited.addAll(other.lengthDelimited); } if (!other.group.isEmpty()) { if (result.group == null) { - result.group = new ArrayList(); + result.group = new ArrayList<>(); } result.group.addAll(other.group); } @@ -1005,45 +1008,45 @@ public Builder mergeFrom(final Field other) { } /** Add a varint value. */ - public Builder addVarint(final long value) { + public Builder addVarint(long value) { if (result.varint == null) { - result.varint = new ArrayList(); + result.varint = new ArrayList<>(); } result.varint.add(value); return this; } /** Add a fixed32 value. */ - public Builder addFixed32(final int value) { + public Builder addFixed32(int value) { if (result.fixed32 == null) { - result.fixed32 = new ArrayList(); + result.fixed32 = new ArrayList<>(); } result.fixed32.add(value); return this; } /** Add a fixed64 value. */ - public Builder addFixed64(final long value) { + public Builder addFixed64(long value) { if (result.fixed64 == null) { - result.fixed64 = new ArrayList(); + result.fixed64 = new ArrayList<>(); } result.fixed64.add(value); return this; } /** Add a length-delimited value. */ - public Builder addLengthDelimited(final ByteString value) { + public Builder addLengthDelimited(ByteString value) { if (result.lengthDelimited == null) { - result.lengthDelimited = new ArrayList(); + result.lengthDelimited = new ArrayList<>(); } result.lengthDelimited.add(value); return this; } /** Add an embedded group. */ - public Builder addGroup(final UnknownFieldSet value) { + public Builder addGroup(UnknownFieldSet value) { if (result.group == null) { - result.group = new ArrayList(); + result.group = new ArrayList<>(); } result.group.add(value); return this; diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java index ffd7232308c4a..7b70fca841e56 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java @@ -32,6 +32,7 @@ import java.io.IOException; +@CheckReturnValue class UnknownFieldSetLiteSchema extends UnknownFieldSchema { diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java b/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java index bcaf1d2f33d83..16521e1bdd900 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java @@ -35,7 +35,7 @@ /** * 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 + * performance requirements. These methods are referred to as "unsafe" because they * potentially expose the backing buffer of a {@link ByteString} to the application. * *

DISCLAIMER: The methods in this class should only be called if it is diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java index 7c9133e16b323..c878751c8da70 100644 --- a/java/core/src/main/java/com/google/protobuf/Utf8.java +++ b/java/core/src/main/java/com/google/protobuf/Utf8.java @@ -102,10 +102,10 @@ final class Utf8 { * State value indicating that the byte sequence is well-formed and complete (no further bytes are * needed to complete a character). */ - public static final int COMPLETE = 0; + static final int COMPLETE = 0; /** State value indicating that the byte sequence is definitely not well-formed. */ - public static final int MALFORMED = -1; + static final int MALFORMED = -1; /** * Used by {@code Unsafe} UTF-8 string validation logic to determine the minimum string length @@ -143,7 +143,7 @@ final class Utf8 { *

This is a convenience method, equivalent to a call to {@code isValidUtf8(bytes, 0, * bytes.length)}. */ - public static boolean isValidUtf8(byte[] bytes) { + static boolean isValidUtf8(byte[] bytes) { return processor.isValidUtf8(bytes, 0, bytes.length); } @@ -155,7 +155,7 @@ public static boolean isValidUtf8(byte[] bytes) { *

This is a convenience method, equivalent to {@code partialIsValidUtf8(bytes, index, limit) * == Utf8.COMPLETE}. */ - public static boolean isValidUtf8(byte[] bytes, int index, int limit) { + static boolean isValidUtf8(byte[] bytes, int index, int limit) { return processor.isValidUtf8(bytes, index, limit); } @@ -172,7 +172,7 @@ public static boolean isValidUtf8(byte[] bytes, int index, int limit) { * "state" value containing enough information to decode the character when passed to a * subsequent invocation of a partial decoding method. */ - public static int partialIsValidUtf8(int state, byte[] bytes, int index, int limit) { + static int partialIsValidUtf8(int state, byte[] bytes, int index, int limit) { return processor.partialIsValidUtf8(state, bytes, index, limit); } @@ -572,7 +572,7 @@ private static int partialIsValidUtf8(final ByteBuffer buffer, int index, final return incompleteStateFor(buffer, byte1, index, limit - index); } - final byte byte2 = buffer.get(index++); + byte byte2 = buffer.get(index++); if (byte2 > (byte) 0xBF // overlong? 5 most significant bits must not all be zero || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) @@ -591,7 +591,7 @@ private static int partialIsValidUtf8(final ByteBuffer buffer, int index, final } // TODO(nathanmittler): Consider using getInt() to improve performance. - final int byte2 = buffer.get(index++); + int byte2 = buffer.get(index++); if (byte2 > (byte) 0xBF // Check that 1 <= plane <= 16. Tricky optimized form of: // if (byte1 > (byte) 0xF4 || @@ -611,7 +611,7 @@ private static int partialIsValidUtf8(final ByteBuffer buffer, int index, final /** * Decodes the given byte array slice into a {@link String}. * - * @throws InvalidProtocolBufferException if the byte array slice is not valid UTF-8. + * @throws InvalidProtocolBufferException if the byte array slice is not valid UTF-8 */ abstract String decodeUtf8(byte[] bytes, int index, int size) throws InvalidProtocolBufferException; @@ -619,7 +619,7 @@ abstract String decodeUtf8(byte[] bytes, int index, int size) /** * Decodes the given portion of the {@link ByteBuffer} into a {@link String}. * - * @throws InvalidProtocolBufferException if the portion of the buffer is not valid UTF-8. + * @throws InvalidProtocolBufferException if the portion of the buffer is not valid UTF-8 */ final String decodeUtf8(ByteBuffer buffer, int index, int size) throws InvalidProtocolBufferException { @@ -649,7 +649,7 @@ final String decodeUtf8Default(ByteBuffer buffer, int index, int size) } int offset = index; - final int limit = offset + size; + int limit = offset + size; // The longest possible resulting String is the same as the number of input bytes, when it is // all ASCII. For other cases, this over-allocates and we will truncate in the end. @@ -1907,12 +1907,24 @@ private static boolean isOneByte(byte b) { return b >= 0; } - /** Returns whether this is a two-byte codepoint with the form '10XXXXXX'. */ + /** + * Returns whether this is a two-byte codepoint with the form '10XXXXXX' iff + * {@link #isOneByte(byte)} is false. This private method works in the limited use in + * this class where this method is only called when {@link #isOneByte(byte)} has already + * returned false. It is not suitable for general or public use. + */ private static boolean isTwoBytes(byte b) { return b < (byte) 0xE0; } - /** Returns whether this is a three-byte codepoint with the form '110XXXXX'. */ + /** + * Returns whether this is a three-byte codepoint with the form '110XXXXX' iff + * {@link #isOneByte(byte)} and {@link #isTwoBytes(byte)} are false. + * This private method works in the limited use in + * this class where this method is only called when {@link #isOneByte(byte)} an + * {@link #isTwoBytes(byte)} have already returned false. It is not suitable for general + * or public use. + */ private static boolean isThreeBytes(byte b) { return b < (byte) 0xF0; } diff --git a/java/core/src/main/java/com/google/protobuf/Writer.java b/java/core/src/main/java/com/google/protobuf/Writer.java index 3f95c325de46e..3550058806601 100644 --- a/java/core/src/main/java/com/google/protobuf/Writer.java +++ b/java/core/src/main/java/com/google/protobuf/Writer.java @@ -36,6 +36,7 @@ /** A writer that performs serialization of protobuf message fields. */ @ExperimentalApi +@CheckReturnValue interface Writer { /** The order in which the fields are written by a {@link Writer}. */ diff --git a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java index 3f97e3174ffe1..f0035bea9b9e1 100644 --- a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java @@ -69,16 +69,16 @@ static byte[] getTestBytes(int size, long seed) { return result; } - private byte[] getTestBytes(int size) { + private static byte[] getTestBytes(int size) { return getTestBytes(size, 445566L); } - private byte[] getTestBytes() { + private static byte[] getTestBytes() { return getTestBytes(1000); } // Compare the entire left array with a subset of the right array. - private boolean isArrayRange(byte[] left, byte[] right, int rightOffset, int length) { + private static boolean isArrayRange(byte[] left, byte[] right, int rightOffset, int length) { boolean stillEqual = (left.length == length); for (int i = 0; (stillEqual && i < length); ++i) { stillEqual = (left[i] == right[rightOffset + i]); @@ -87,7 +87,7 @@ private boolean isArrayRange(byte[] left, byte[] right, int rightOffset, int len } // Returns true only if the given two arrays have identical contents. - private boolean isArray(byte[] left, byte[] right) { + private static boolean isArray(byte[] left, byte[] right) { return left.length == right.length && isArrayRange(left, right, 0, left.length); } @@ -134,7 +134,7 @@ public void testCompare_interpretsByteValuesAsUnsigned() throws Exception { } @Test - public void testSubstring_BeginIndex() { + public void testSubstring_beginIndex() { byte[] bytes = getTestBytes(); ByteString substring = ByteString.copyFrom(bytes).substring(500); assertWithMessage("substring must contain the tail of the string") @@ -143,7 +143,66 @@ public void testSubstring_BeginIndex() { } @Test - public void testCopyFrom_BytesOffsetSize() { + public void testEmpty_isEmpty() { + ByteString byteString = ByteString.empty(); + assertThat(byteString.isEmpty()).isTrue(); + assertWithMessage("ByteString.empty() must return empty byte array") + .that(isArray(byteString.toByteArray(), new byte[] {})) + .isTrue(); + } + + @Test + public void testEmpty_referenceEquality() { + assertThat(ByteString.empty()).isSameInstanceAs(ByteString.EMPTY); + assertThat(ByteString.empty()).isSameInstanceAs(ByteString.empty()); + } + + @Test + public void testFromHex_hexString() { + ByteString byteString; + byteString = ByteString.fromHex("0a0b0c"); + assertWithMessage("fromHex must contain the expected bytes") + .that(isArray(byteString.toByteArray(), new byte[] {0x0a, 0x0b, 0x0c})) + .isTrue(); + + byteString = ByteString.fromHex("0A0B0C"); + assertWithMessage("fromHex must contain the expected bytes") + .that(isArray(byteString.toByteArray(), new byte[] {0x0a, 0x0b, 0x0c})) + .isTrue(); + + byteString = ByteString.fromHex("0a0b0c0d0e0f"); + assertWithMessage("fromHex must contain the expected bytes") + .that(isArray(byteString.toByteArray(), new byte[] {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f})) + .isTrue(); + } + + @Test + @SuppressWarnings("AlwaysThrows") // Verifying that indeed these calls do throw. + public void testFromHex_invalidHexString() { + try { + ByteString.fromHex("a0b0c"); + assertWithMessage("Should throw").fail(); + } catch (NumberFormatException expected) { + assertThat(expected).hasMessageThat().contains("even"); + } + + try { + ByteString.fromHex("0x0y0z"); + assertWithMessage("Should throw").fail(); + } catch (NumberFormatException expected) { + assertThat(expected).hasMessageThat().contains("[0-9a-fA-F]"); + } + + try { + ByteString.fromHex("0૫"); + assertWithMessage("Should throw").fail(); + } catch (NumberFormatException expected) { + assertThat(expected).hasMessageThat().contains("[0-9a-fA-F]"); + } + } + + @Test + public void testCopyFrom_bytesOffsetSize() { byte[] bytes = getTestBytes(); ByteString byteString = ByteString.copyFrom(bytes, 500, 200); assertWithMessage("copyFrom sub-range must contain the expected bytes") @@ -152,7 +211,7 @@ public void testCopyFrom_BytesOffsetSize() { } @Test - public void testCopyFrom_Bytes() { + public void testCopyFrom_bytes() { byte[] bytes = getTestBytes(); ByteString byteString = ByteString.copyFrom(bytes); assertWithMessage("copyFrom must contain the expected bytes") @@ -161,7 +220,7 @@ public void testCopyFrom_Bytes() { } @Test - public void testCopyFrom_ByteBufferSize() { + public void testCopyFrom_byteBufferSize() { byte[] bytes = getTestBytes(); ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); byteBuffer.put(bytes); @@ -173,7 +232,7 @@ public void testCopyFrom_ByteBufferSize() { } @Test - public void testCopyFrom_ByteBuffer() { + public void testCopyFrom_byteBuffer() { byte[] bytes = getTestBytes(); ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); byteBuffer.put(bytes); @@ -185,7 +244,7 @@ public void testCopyFrom_ByteBuffer() { } @Test - public void testCopyFrom_StringEncoding() { + public void testCopyFrom_stringEncoding() { String testString = "I love unicode \u1234\u5678 characters"; ByteString byteString = ByteString.copyFrom(testString, UTF_16); byte[] testBytes = testString.getBytes(UTF_16); @@ -195,7 +254,7 @@ public void testCopyFrom_StringEncoding() { } @Test - public void testCopyFrom_Utf8() { + public void testCopyFrom_utf8() { String testString = "I love unicode \u1234\u5678 characters"; ByteString byteString = ByteString.copyFromUtf8(testString); byte[] testBytes = testString.getBytes(Internal.UTF_8); @@ -205,7 +264,7 @@ public void testCopyFrom_Utf8() { } @Test - public void testCopyFrom_Iterable() { + public void testCopyFrom_iterable() { byte[] testBytes = getTestBytes(77777, 113344L); final List pieces = makeConcretePieces(testBytes); // Call copyFrom() on a Collection @@ -228,7 +287,7 @@ public Iterator iterator() { } @Test - public void testCopyFrom_LengthTooBig() { + public void testCopyFrom_lengthTooBig() { byte[] testBytes = getTestBytes(100); try { ByteString.copyFrom(testBytes, 0, 200); @@ -257,7 +316,7 @@ public void testCopyFrom_LengthTooBig() { } @Test - public void testCopyTo_TargetOffset() { + public void testCopyTo_targetOffset() { byte[] bytes = getTestBytes(); ByteString byteString = ByteString.copyFrom(bytes); byte[] target = new byte[bytes.length + 1000]; @@ -353,7 +412,7 @@ public void testReadFrom_byteBoundaries() throws IOException { // Tests that IOExceptions propagate through ByteString.readFrom(). @Test - public void testReadFrom_IOExceptions() { + public void testReadFrom_iOExceptions() { try { ByteString.readFrom(new FailStream()); assertWithMessage("readFrom must throw the underlying IOException").fail(); @@ -547,7 +606,7 @@ public void testToString_long() { } @Test - public void testNewOutput_InitialCapacity() throws IOException { + public void testNewOutput_initialCapacity() throws IOException { byte[] bytes = getTestBytes(); ByteString.Output output = ByteString.newOutput(bytes.length + 100); output.write(bytes); @@ -560,7 +619,7 @@ public void testNewOutput_InitialCapacity() throws IOException { // Test newOutput() using a variety of buffer sizes and a variety of (fixed) // write sizes @Test - public void testNewOutput_ArrayWrite() { + public void testNewOutput_arrayWrite() { byte[] bytes = getTestBytes(); int length = bytes.length; int[] bufferSizes = { @@ -586,7 +645,7 @@ public void testNewOutput_ArrayWrite() { // Test newOutput() using a variety of buffer sizes, but writing all the // characters using write(byte); @Test - public void testNewOutput_WriteChar() { + public void testNewOutput_writeChar() { byte[] bytes = getTestBytes(); int length = bytes.length; int[] bufferSizes = { @@ -607,7 +666,7 @@ public void testNewOutput_WriteChar() { // Test newOutput() in which we write the bytes using a variety of methods // and sizes, and in which we repeatedly call toByteString() in the middle. @Test - public void testNewOutput_Mixed() { + public void testNewOutput_mixed() { Random rng = new Random(1); byte[] bytes = getTestBytes(); int length = bytes.length; @@ -649,7 +708,7 @@ public void testNewOutputEmpty() { } @Test - public void testNewOutput_Mutating() throws IOException { + public void testNewOutput_mutating() throws IOException { Output os = ByteString.newOutput(5); os.write(new byte[] {1, 2, 3, 4, 5}); EvilOutputStream eos = new EvilOutputStream(); diff --git a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java index f5bb31fdf4e56..1ebf457a6bed7 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java @@ -540,8 +540,8 @@ public void testReadMaliciouslyLargeBlob() throws Exception { CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); - output.writeRawVarint32(tag); - output.writeRawVarint32(0x7FFFFFFF); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(0x7FFFFFFF); output.writeRawBytes(new byte[32]); // Pad with a few random bytes. output.flush(); @@ -747,11 +747,11 @@ public void testRefillBufferWithCorrectSize() throws Exception { CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length); int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); - output.writeRawVarint32(tag); - output.writeRawVarint32(bytes.length); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(bytes.length); output.writeRawBytes(bytes); - output.writeRawVarint32(tag); - output.writeRawVarint32(bytes.length); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(bytes.length); output.writeRawBytes(bytes); output.writeRawByte(4); output.flush(); @@ -796,8 +796,8 @@ public void testCurrentLimitExceeded() throws Exception { CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length); int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); - output.writeRawVarint32(tag); - output.writeRawVarint32(bytes.length); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(bytes.length); output.writeRawBytes(bytes); output.flush(); @@ -851,8 +851,8 @@ public void testReadString() throws Exception { CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length); int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); - output.writeRawVarint32(tag); - output.writeRawVarint32(bytes.length); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(bytes.length); output.writeRawBytes(bytes); output.flush(); @@ -878,8 +878,8 @@ public void testReadStringRequireUtf8() throws Exception { CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length); int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); - output.writeRawVarint32(tag); - output.writeRawVarint32(bytes.length); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(bytes.length); output.writeRawBytes(bytes); output.flush(); @@ -902,8 +902,8 @@ public void testReadStringInvalidUtf8() throws Exception { CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); - output.writeRawVarint32(tag); - output.writeRawVarint32(1); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 0x80}); output.flush(); @@ -926,8 +926,8 @@ public void testReadStringRequireUtf8InvalidUtf8() throws Exception { CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); - output.writeRawVarint32(tag); - output.writeRawVarint32(1); + output.writeUInt32NoTag(tag); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 0x80}); output.flush(); @@ -985,19 +985,19 @@ public void testReadByteArray() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); // Zero-sized bytes field. - output.writeRawVarint32(0); + output.writeUInt32NoTag(0); // One one-byte bytes field - output.writeRawVarint32(1); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 23}); // Another one-byte bytes field - output.writeRawVarint32(1); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 45}); // A bytes field large enough that won't fit into the 4K buffer. final int bytesLength = 16 * 1024; byte[] bytes = new byte[bytesLength]; bytes[0] = (byte) 67; bytes[bytesLength - 1] = (byte) 89; - output.writeRawVarint32(bytesLength); + output.writeUInt32NoTag(bytesLength); output.writeRawBytes(bytes); output.flush(); @@ -1029,7 +1029,7 @@ public void testReadLargeByteStringFromInputStream() throws Exception { } ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); - output.writeRawVarint32(bytes.length); + output.writeUInt32NoTag(bytes.length); output.writeRawBytes(bytes); output.flush(); byte[] data = rawOutput.toByteString().toByteArray(); @@ -1054,7 +1054,7 @@ public void testReadLargeByteArrayFromInputStream() throws Exception { } ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); - output.writeRawVarint32(bytes.length); + output.writeUInt32NoTag(bytes.length); output.writeRawBytes(bytes); output.flush(); byte[] data = rawOutput.toByteString().toByteArray(); @@ -1076,19 +1076,19 @@ public void testReadByteBuffer() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); // Zero-sized bytes field. - output.writeRawVarint32(0); + output.writeUInt32NoTag(0); // One one-byte bytes field - output.writeRawVarint32(1); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 23}); // Another one-byte bytes field - output.writeRawVarint32(1); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 45}); // A bytes field large enough that won't fit into the 4K buffer. final int bytesLength = 16 * 1024; byte[] bytes = new byte[bytesLength]; bytes[0] = (byte) 67; bytes[bytesLength - 1] = (byte) 89; - output.writeRawVarint32(bytesLength); + output.writeUInt32NoTag(bytesLength); output.writeRawBytes(bytes); output.flush(); @@ -1118,19 +1118,19 @@ public void testReadByteBufferAliasing() throws Exception { ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream(); CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream); // Zero-sized bytes field. - output.writeRawVarint32(0); + output.writeUInt32NoTag(0); // One one-byte bytes field - output.writeRawVarint32(1); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 23}); // Another one-byte bytes field - output.writeRawVarint32(1); + output.writeUInt32NoTag(1); output.writeRawBytes(new byte[] {(byte) 45}); // A bytes field large enough that won't fit into the 4K buffer. final int bytesLength = 16 * 1024; byte[] bytes = new byte[bytesLength]; bytes[0] = (byte) 67; bytes[bytesLength - 1] = (byte) 89; - output.writeRawVarint32(bytesLength); + output.writeUInt32NoTag(bytesLength); output.writeRawBytes(bytes); output.flush(); diff --git a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java index 9934ca19ff96c..eb24dded51be9 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java @@ -399,7 +399,7 @@ public void testWriteWholePackedFieldsMessage() throws Exception { public void testWriteMessageWithNegativeEnumValue() throws Exception { SparseEnumMessage message = SparseEnumMessage.newBuilder().setSparseEnum(TestSparseEnum.SPARSE_E).build(); - assertThat(message.getSparseEnum().getNumber() < 0).isTrue(); + assertThat(message.getSparseEnum().getNumber()).isLessThan(0); for (OutputType outputType : OutputType.values()) { Coder coder = outputType.newCoder(message.getSerializedSize()); message.writeTo(coder.stream()); @@ -427,11 +427,9 @@ public void testGetTotalBytesWritten() throws Exception { String string = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; // Ensure we take the slower fast path. - assertThat( - CodedOutputStream.computeUInt32SizeNoTag(string.length()) - != CodedOutputStream.computeUInt32SizeNoTag( - string.length() * Utf8.MAX_BYTES_PER_CHAR)) - .isTrue(); + assertThat(CodedOutputStream.computeUInt32SizeNoTag(string.length())) + .isNotEqualTo( + CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR)); coder.stream().writeStringNoTag(string); coder.stream().flush(); diff --git a/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java index 6cb0baebedb55..a88baca61c7c2 100644 --- a/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java +++ b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java @@ -460,6 +460,33 @@ public void testDescriptorValidatorException() throws Exception { } } + /** Tests that parsing an unknown enum throws an exception */ + @Test + public void testParseUnknownEnum() { + FieldDescriptorProto.Builder field = FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setTypeName("UnknownEnum") + .setType(FieldDescriptorProto.Type.TYPE_ENUM) + .setName("bar") + .setNumber(1); + DescriptorProto.Builder messageType = DescriptorProto.newBuilder() + .setName("Foo") + .addField(field); + FileDescriptorProto fooProto = + FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addDependency("bar.proto") + .addMessageType(messageType) + .build(); + try { + Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[0], true); + assertWithMessage("DescriptorValidationException expected").fail(); + } catch (DescriptorValidationException expected) { + assertThat(expected.getMessage()).contains("\"UnknownEnum\" is not an enum type."); + } + } + + /** * Tests the translate/crosslink for an example where a message field's name and type name are the * same. diff --git a/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java index 3aacdccfb4ffd..8e1abc0450774 100644 --- a/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java @@ -31,10 +31,13 @@ package com.google.protobuf; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; +import dynamicmessagetest.DynamicMessageTestProto.EmptyMessage; +import dynamicmessagetest.DynamicMessageTestProto.MessageWithMapFields; import protobuf_unittest.UnittestProto; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; @@ -42,6 +45,7 @@ import protobuf_unittest.UnittestProto.TestEmptyMessage; import protobuf_unittest.UnittestProto.TestPackedTypes; import org.junit.Test; +import org.junit.function.ThrowingRunnable; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -335,4 +339,52 @@ public void testSettersForRepeatedEnumField() throws Exception { DynamicMessage message = builder.build(); assertThat(message.getField(repeatedEnumField)).isEqualTo(enumDescriptor.getValues()); } + + @Test + public void testBuilderGetFieldBuilder_mapField_throwsUnsupportedOperationException() { + final DynamicMessage.Builder builder = + DynamicMessage.newBuilder(MessageWithMapFields.getDescriptor()); + final FieldDescriptor mapField = + MessageWithMapFields.getDescriptor().findFieldByName("string_message_map"); + + Message.Builder entryBuilder = builder.newBuilderForField(mapField); + entryBuilder.setField(entryBuilder.getDescriptorForType().findFieldByNumber(1), "foo"); + entryBuilder.setField( + entryBuilder.getDescriptorForType().findFieldByNumber(2), + EmptyMessage.getDefaultInstance()); + builder.addRepeatedField(mapField, entryBuilder.build()); + + assertThrows( + UnsupportedOperationException.class, + new ThrowingRunnable() { + @Override + public void run() throws Throwable { + builder.getFieldBuilder(mapField); + } + }); + } + + @Test + public void testBuilderGetRepeatedFieldBuilder_mapField_throwsUnsupportedOperationException() { + final DynamicMessage.Builder builder = + DynamicMessage.newBuilder(MessageWithMapFields.getDescriptor()); + final FieldDescriptor mapField = + MessageWithMapFields.getDescriptor().findFieldByName("string_message_map"); + + Message.Builder entryBuilder = builder.newBuilderForField(mapField); + entryBuilder.setField(entryBuilder.getDescriptorForType().findFieldByNumber(1), "foo"); + entryBuilder.setField( + entryBuilder.getDescriptorForType().findFieldByNumber(2), + EmptyMessage.getDefaultInstance()); + builder.addRepeatedField(mapField, entryBuilder.build()); + + assertThrows( + UnsupportedOperationException.class, + new ThrowingRunnable() { + @Override + public void run() throws Throwable { + builder.getFieldBuilder(mapField); + } + }); + } } diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java index e5047661dd26d..eb5b7396c9ad2 100644 --- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -85,6 +85,20 @@ @SuppressWarnings({"ProtoBuilderReturnValueIgnored", "ReturnValueIgnored"}) @RunWith(JUnit4.class) public class GeneratedMessageTest { + + private static final TestOneof2 EXPECTED_MERGED_MESSAGE = + TestOneof2.newBuilder() + .setFooMessage(TestOneof2.NestedMessage.newBuilder().addCorgeInt(1).addCorgeInt(2)) + .build(); + + private static final TestOneof2 MESSAGE_TO_MERGE_FROM = + TestOneof2.newBuilder() + .setFooMessage(TestOneof2.NestedMessage.newBuilder().addCorgeInt(2)) + .build(); + + private static final FieldDescriptor NESTED_MESSAGE_BB_FIELD = + UnittestProto.TestAllTypes.NestedMessage.getDescriptor().findFieldByName("bb"); + TestUtil.ReflectionTester reflectionTester = new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); @@ -1036,9 +1050,8 @@ public void testExtensionConstantValues() throws Exception { public void testRecursiveMessageDefaultInstance() throws Exception { UnittestProto.TestRecursiveMessage message = UnittestProto.TestRecursiveMessage.getDefaultInstance(); - assertThat(message != null).isTrue(); - assertThat(message.getA()).isNotNull(); - assertThat(message.getA().equals(message)).isTrue(); + assertThat(message).isNotNull(); + assertThat(message.getA()).isEqualTo(message); } @Test @@ -1047,11 +1060,8 @@ public void testSerialize() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); TestAllTypes expected = builder.build(); - ObjectOutputStream out = new ObjectOutputStream(baos); - try { + try (ObjectOutputStream out = new ObjectOutputStream(baos)) { out.writeObject(expected); - } finally { - out.close(); } ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bais); @@ -1317,9 +1327,7 @@ public void testGetFieldBuilder() { builder1 .newBuilderForField(fieldDescriptor) .mergeFrom((Message) builder1.getField(fieldDescriptor)); - FieldDescriptor subFieldDescriptor1 = - fieldBuilder1.getDescriptorForType().findFieldByName("bb"); - fieldBuilder1.setField(subFieldDescriptor1, 1); + fieldBuilder1.setField(NESTED_MESSAGE_BB_FIELD, 1); builder1.setField(fieldDescriptor, fieldBuilder1.build()); // Mutate foreign message @@ -1348,9 +1356,7 @@ public void testGetFieldBuilder() { // Mutate nested message TestAllTypes.Builder builder2 = TestAllTypes.newBuilder(); Message.Builder fieldBuilder2 = builder2.getFieldBuilder(fieldDescriptor); - FieldDescriptor subFieldDescriptor2 = - fieldBuilder2.getDescriptorForType().findFieldByName("bb"); - fieldBuilder2.setField(subFieldDescriptor2, 1); + fieldBuilder2.setField(NESTED_MESSAGE_BB_FIELD, 1); builder2.setField(fieldDescriptor, fieldBuilder2.build()); // Mutate foreign message @@ -1650,7 +1656,7 @@ public void testOneofTypes() throws Exception { } @Test - public void testOneofMerge() throws Exception { + public void testOneofMergeNonMessage() throws Exception { // Primitive Type { TestOneof2.Builder builder = TestOneof2.newBuilder(); @@ -1677,18 +1683,39 @@ public void testOneofMerge() throws Exception { assertThat(message2.hasFooEnum()).isTrue(); assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); } + } - // Message - { - TestOneof2.Builder builder = TestOneof2.newBuilder(); - TestOneof2 message = - builder - .setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()) - .build(); - TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); - assertThat(message2.hasFooMessage()).isTrue(); - assertThat(message2.getFooMessage().getQuxInt()).isEqualTo(234); - } + @Test + public void testOneofMergeMessage_mergeIntoNewBuilder() { + TestOneof2.Builder builder = TestOneof2.newBuilder(); + TestOneof2 message = + builder.setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build(); + TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); + assertThat(message2.hasFooMessage()).isTrue(); + assertThat(message2.getFooMessage().getQuxInt()).isEqualTo(234); + } + + @Test + public void testOneofMergeMessage_mergeWithGetMessageBuilder() { + TestOneof2.Builder builder = TestOneof2.newBuilder(); + builder.getFooMessageBuilder().addCorgeInt(1); + assertThat(builder.mergeFrom(MESSAGE_TO_MERGE_FROM).build()).isEqualTo(EXPECTED_MERGED_MESSAGE); + } + + @Test + public void testOneofMergeMessage_mergeIntoMessageBuiltWithGetMessageBuilder() { + TestOneof2.Builder builder = TestOneof2.newBuilder(); + builder.getFooMessageBuilder().addCorgeInt(1); + TestOneof2 message = builder.build(); + assertThat(message.toBuilder().mergeFrom(MESSAGE_TO_MERGE_FROM).build()) + .isEqualTo(EXPECTED_MERGED_MESSAGE); + } + + @Test + public void testOneofMergeMessage_mergeWithoutGetMessageBuilder() { + TestOneof2.Builder builder = + TestOneof2.newBuilder().setFooMessage(TestOneof2.NestedMessage.newBuilder().addCorgeInt(1)); + assertThat(builder.mergeFrom(MESSAGE_TO_MERGE_FROM).build()).isEqualTo(EXPECTED_MERGED_MESSAGE); } @Test @@ -1796,9 +1823,7 @@ public void testGetRepeatedFieldBuilder() { // Mutate nested message TestAllTypes.Builder builder1 = TestAllTypes.newBuilder(); Message.Builder fieldBuilder1 = builder1.newBuilderForField(fieldDescriptor); - FieldDescriptor subFieldDescriptor1 = - fieldBuilder1.getDescriptorForType().findFieldByName("bb"); - fieldBuilder1.setField(subFieldDescriptor1, 1); + fieldBuilder1.setField(NESTED_MESSAGE_BB_FIELD, 1); builder1.addRepeatedField(fieldDescriptor, fieldBuilder1.build()); // Mutate foreign message @@ -1822,9 +1847,7 @@ public void testGetRepeatedFieldBuilder() { TestAllTypes.Builder builder2 = TestAllTypes.newBuilder(); builder2.addRepeatedNestedMessageBuilder(); Message.Builder fieldBuilder2 = builder2.getRepeatedFieldBuilder(fieldDescriptor, 0); - FieldDescriptor subFieldDescriptor2 = - fieldBuilder2.getDescriptorForType().findFieldByName("bb"); - fieldBuilder2.setField(subFieldDescriptor2, 1); + fieldBuilder2.setField(NESTED_MESSAGE_BB_FIELD, 1); // Mutate foreign message Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField(foreignFieldDescriptor); @@ -1905,4 +1928,99 @@ public void testGetRepeatedFieldBuilderNotSupportedException() { // We expect this exception. } } + + private static final FieldDescriptor OPTIONAL_NESTED_MESSAGE_EXTENSION = + UnittestProto.getDescriptor().findExtensionByName("optional_nested_message_extension"); + private static final FieldDescriptor REPEATED_NESTED_MESSAGE_EXTENSION = + UnittestProto.getDescriptor().findExtensionByName("repeated_nested_message_extension"); + // A compile-time check that TestAllExtensions.Builder does in fact extend + // GeneratedMessageV3.ExtendableBuilder. The tests below assume that it does. + static { + @SuppressWarnings("unused") + Class> ignored = + TestAllExtensions.Builder.class; + } + + @Test + public void + extendableBuilder_extensionFieldContainingBuilder_setRepeatedFieldOverwritesElement() { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance()); + // Calling getRepeatedFieldBuilder and ignoring the returned Builder should have no + // externally-visible effect, but internally it sets the stored field element to a builder. + builder.getRepeatedFieldBuilder(REPEATED_NESTED_MESSAGE_EXTENSION, 0); + + NestedMessage setNestedMessage = NestedMessage.newBuilder().setBb(100).build(); + builder.setRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, 0, setNestedMessage); + + assertThat(builder.getRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, 0)) + .isEqualTo(setNestedMessage); + } + + @Test + public void extendableBuilder_extensionFieldContainingBuilder_addRepeatedFieldAppendsToField() { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance()); + // Calling getRepeatedFieldBuilder and ignoring the returned Builder should have no + // externally-visible effect, but internally it sets the stored field element to a builder. + builder.getRepeatedFieldBuilder(REPEATED_NESTED_MESSAGE_EXTENSION, 0); + + builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance()); + + assertThat((List) builder.getField(REPEATED_NESTED_MESSAGE_EXTENSION)).hasSize(2); + } + + @Test + public void extendableBuilder_mergeFrom_optionalField_changesReflectedInExistingBuilder() { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + Message.Builder nestedMessageBuilder = + builder.getFieldBuilder(OPTIONAL_NESTED_MESSAGE_EXTENSION); + + builder.mergeFrom( + TestAllExtensions.newBuilder() + .setField(OPTIONAL_NESTED_MESSAGE_EXTENSION, NestedMessage.newBuilder().setBb(100)) + .build()); + + assertThat(nestedMessageBuilder.getField(NESTED_MESSAGE_BB_FIELD)).isEqualTo(100); + } + + @Test + public void extendableBuilder_mergeFrom_optionalField_doesNotInvalidateExistingBuilder() { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + Message.Builder nestedMessageBuilder = + builder.getFieldBuilder(OPTIONAL_NESTED_MESSAGE_EXTENSION); + + builder.mergeFrom( + TestAllExtensions.newBuilder() + .setField(OPTIONAL_NESTED_MESSAGE_EXTENSION, NestedMessage.newBuilder().setBb(100)) + .build()); + + // Changes to nestedMessageBuilder should still be reflected in the parent builder. + nestedMessageBuilder.setField(NESTED_MESSAGE_BB_FIELD, 200); + + assertThat(builder.build()) + .isEqualTo( + TestAllExtensions.newBuilder() + .setField(OPTIONAL_NESTED_MESSAGE_EXTENSION, NestedMessage.newBuilder().setBb(200)) + .build()); + } + + @Test + public void extendableBuilder_mergeFrom_repeatedField_doesNotInvalidateExistingBuilder() { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance()); + Message.Builder nestedMessageBuilder = + builder.getRepeatedFieldBuilder(REPEATED_NESTED_MESSAGE_EXTENSION, 0); + + builder.mergeFrom( + TestAllExtensions.newBuilder() + .addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance()) + .build()); + + // Changes to nestedMessageBuilder should still be reflected in the parent builder. + nestedMessageBuilder.setField(NESTED_MESSAGE_BB_FIELD, 100); + + assertThat(builder.getRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, 0)) + .isEqualTo(NestedMessage.newBuilder().setBb(100).build()); + } } diff --git a/java/core/src/test/java/com/google/protobuf/InvalidProtocolBufferExceptionTest.java b/java/core/src/test/java/com/google/protobuf/InvalidProtocolBufferExceptionTest.java new file mode 100644 index 0000000000000..564b8c2b7e61a --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/InvalidProtocolBufferExceptionTest.java @@ -0,0 +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. + +package com.google.protobuf; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class InvalidProtocolBufferExceptionTest { + + @Test + public void testWrapRuntimeException() { + ArrayIndexOutOfBoundsException root = new ArrayIndexOutOfBoundsException(); + InvalidProtocolBufferException wrapper = new InvalidProtocolBufferException(root); + assertThat(wrapper).hasCauseThat().isEqualTo(root); + } + +} diff --git a/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java b/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java index 576feea6d04a6..7d6b0d645e997 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java @@ -254,7 +254,7 @@ public void testMergeOneofMessages() throws Exception { ByteString data1 = outer.toByteString(); // The following should not alter the content of the 'outer' message. - LazyMessageLite.Builder merged = LazyMessageLite.newBuilder().mergeFrom(outer); + LazyMessageLite.Builder merged = outer.toBuilder(); LazyInnerMessageLite anotherInner = LazyInnerMessageLite.newBuilder().setNum(12345).build(); merged.setOneofInner(anotherInner); diff --git a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java index 5f39893d7b8e8..349d576ff7683 100644 --- a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java @@ -537,6 +537,7 @@ public void testEqualsAndHashCode() throws Exception { } @Test + @SuppressWarnings("ProtoNewBuilderMergeFrom") public void testUnknownEnumValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder() 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 34df94523dbb6..587ebbb5cc5ef 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -992,6 +992,7 @@ public void testReflectionEqualsAndHashCode() throws Exception { } @Test + @SuppressWarnings("ProtoNewBuilderMergeFrom") public void testUnknownEnumValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder() diff --git a/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java index c1660a80d09fc..81ced78accdfe 100644 --- a/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java @@ -218,11 +218,11 @@ public DescriptorProto parse(InputStream in) throws IOException { public void messageBuilder_mergeDelimitedFrom_InputStream_malformed() throws Exception { byte[] body = new byte[80]; CodedOutputStream cos = CodedOutputStream.newInstance(body); - cos.writeRawVarint32(90); // Greater than bytes in stream + cos.writeUInt32NoTag(90); // Greater than bytes in stream cos.writeTag(DescriptorProto.ENUM_TYPE_FIELD_NUMBER, WireFormat.WIRETYPE_LENGTH_DELIMITED); - cos.writeRawVarint32(98); // Nested message with size larger than parent + cos.writeUInt32NoTag(98); // Nested message with size larger than parent cos.writeTag(1000, WireFormat.WIRETYPE_LENGTH_DELIMITED); - cos.writeRawVarint32(100); // Unknown field with size larger than parent + cos.writeUInt32NoTag(100); // Unknown field with size larger than parent ByteArrayInputStream bais = new ByteArrayInputStream(body); try { DescriptorProto.parseDelimitedFrom(bais); diff --git a/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java b/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java index fd0bf45a93739..6f6d26b1ca13c 100644 --- a/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java @@ -31,10 +31,15 @@ package com.google.protobuf; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import com.google.protobuf.UnittestLite.TestAllExtensionsLite; import com.google.protobuf.UnittestLite.TestAllTypesLite; +import com.google.protobuf.UnittestLite.TestMergeExceptionLite; import com.google.protobuf.UnittestLite.TestPackedExtensionsLite; import com.google.protobuf.UnittestLite.TestParsingMergeLite; +import protobuf_unittest.MapLiteUnittest; +import protobuf_unittest.MapLiteUnittest.TestRequiredLite; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -200,4 +205,70 @@ public void testParsingMergeLite() throws Exception { assertThat(parsingMerge.getRepeatedGroupCount()).isEqualTo(3); assertThat(parsingMerge.getExtensionCount(TestParsingMergeLite.repeatedExt)).isEqualTo(3); } + + @Test + public void testExceptionWhenMergingExtendedMessagesMissingRequiredFieldsLite() { + // create a TestMergeExceptionLite message (missing required fields) that looks like + // all_extensions { + // [TestRequiredLite.single] { + // } + // } + TestMergeExceptionLite.Builder message = TestMergeExceptionLite.newBuilder(); + message.setAllExtensions( + TestAllExtensionsLite.newBuilder() + .setExtension(TestRequiredLite.single, TestRequiredLite.newBuilder().buildPartial()) + .buildPartial()); + ByteString byteString = message.buildPartial().toByteString(); + + // duplicate the bytestring to make the `all_extensions` field repeat twice, so that it will + // need merging when parsing back + ByteString duplicatedByteString = byteString.concat(byteString); + + byte[] bytes = duplicatedByteString.toByteArray(); + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + MapLiteUnittest.registerAllExtensions(registry); + + // `parseFrom` should throw InvalidProtocolBufferException, not UninitializedMessageException, + // for each of the 5 possible input types: + + // parseFrom(ByteString) + try { + TestMergeExceptionLite.parseFrom(duplicatedByteString, registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(ByteArray) + try { + TestMergeExceptionLite.parseFrom(bytes, registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(InputStream) + try { + TestMergeExceptionLite.parseFrom(new ByteArrayInputStream(bytes), registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(CodedInputStream) + try { + TestMergeExceptionLite.parseFrom(CodedInputStream.newInstance(bytes), registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(ByteBuffer) + try { + TestMergeExceptionLite.parseFrom(duplicatedByteString.asReadOnlyByteBuffer(), registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + } } diff --git a/java/core/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java index e78c671c0ee71..f4cf529e9083b 100644 --- a/java/core/src/test/java/com/google/protobuf/ParserTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java @@ -40,6 +40,7 @@ import protobuf_unittest.UnittestProto.ForeignMessage; import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestEmptyMessage; +import protobuf_unittest.UnittestProto.TestMergeException; import protobuf_unittest.UnittestProto.TestParsingMerge; import protobuf_unittest.UnittestProto.TestRequired; import java.io.ByteArrayInputStream; @@ -291,6 +292,71 @@ public void testParsingMerge() throws Exception { assertThat(parsingMerge.getExtensionCount(TestParsingMerge.repeatedExt)).isEqualTo(3); } + @Test + public void testExceptionWhenMergingExtendedMessagesMissingRequiredFields() { + // create a TestMergeException message (missing required fields) that looks like + // all_extensions { + // [TestRequired.single] { + // } + // } + TestMergeException.Builder message = TestMergeException.newBuilder(); + message + .getAllExtensionsBuilder() + .setExtension(TestRequired.single, TestRequired.newBuilder().buildPartial()); + ByteString byteString = message.buildPartial().toByteString(); + + // duplicate the bytestring to make the `all_extensions` field repeat twice, so that it will + // need merging when parsing back + ByteString duplicatedByteString = byteString.concat(byteString); + + byte[] bytes = duplicatedByteString.toByteArray(); + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + UnittestProto.registerAllExtensions(registry); + + // `parseFrom` should throw InvalidProtocolBufferException, not UninitializedMessageException, + // for each of the 5 possible input types: + + // parseFrom(ByteString) + try { + TestMergeException.parseFrom(duplicatedByteString, registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(ByteArray) + try { + TestMergeException.parseFrom(bytes, registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(InputStream) + try { + TestMergeException.parseFrom(new ByteArrayInputStream(bytes), registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(CodedInputStream) + try { + TestMergeException.parseFrom(CodedInputStream.newInstance(bytes), registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + + // parseFrom(ByteBuffer) + try { + TestMergeException.parseFrom(duplicatedByteString.asReadOnlyByteBuffer(), registry); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); + } catch (Exception e) { + assertThat(e.getClass()).isEqualTo(InvalidProtocolBufferException.class); + } + } + @Test public void testParseDelimitedFrom_firstByteInterrupted_preservesCause() { try { diff --git a/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java b/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java index 07864a93718c3..15097a09b9842 100644 --- a/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java +++ b/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java @@ -52,7 +52,6 @@ public class Proto2ExtensionLookupSchemaTest { public void setup() { TestSchemas.registerGenericProto2Schemas(); - Protobuf.getInstance().schemaFor(Proto2MessageWithExtensions.class); data = new Proto2MessageFactory(10, 20, 1, 1).newMessage().toByteArray(); extensionRegistry = ExtensionRegistry.newInstance(); Proto2Testing.registerAllExtensions(extensionRegistry); diff --git a/java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java b/java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java deleted file mode 100644 index af671b22e47b8..0000000000000 --- a/java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java +++ /dev/null @@ -1,892 +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. - -package com.google.protobuf; - -import static com.google.protobuf.FieldInfo.forField; -import static com.google.protobuf.FieldInfo.forFieldWithEnumVerifier; -import static com.google.protobuf.FieldInfo.forMapField; -import static com.google.protobuf.FieldInfo.forOneofMemberField; -import static com.google.protobuf.FieldInfo.forProto2OptionalField; -import static com.google.protobuf.FieldInfo.forProto2RequiredField; -import static com.google.protobuf.FieldInfo.forRepeatedMessageField; - -import com.google.protobuf.testing.Proto2Testing; -import com.google.protobuf.testing.Proto2Testing.Proto2Empty; -import com.google.protobuf.testing.Proto2Testing.Proto2Message; -import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldGroup49; -import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldGroup69; -import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldGroupList51; -import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldRequiredGroup88; -import com.google.protobuf.testing.Proto2Testing.Proto2Message.RequiredNestedMessage; -import com.google.protobuf.testing.Proto2Testing.Proto2Message.TestEnum; -import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithExtensions; -import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithMaps; -import java.lang.reflect.Field; - -/** A factory that generates a hard-coded message info for {@link Proto2Message}. */ -public final class Proto2MessageInfoFactory implements MessageInfoFactory { - private static final Proto2MessageInfoFactory INSTANCE = new Proto2MessageInfoFactory(); - - private Proto2MessageInfoFactory() {} - - public static Proto2MessageInfoFactory getInstance() { - return INSTANCE; - } - - @Override - public boolean isSupported(Class clazz) { - return true; - } - - @Override - public MessageInfo messageInfoFor(Class clazz) { - if (Proto2Message.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2Message(); - } else if (FieldGroup49.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldGroup49(); - } else if (FieldGroupList51.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldGroupList51(); - } else if (FieldGroup69.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldGroup69(); - } else if (FieldRequiredGroup88.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldRequiredGroup88(); - } else if (RequiredNestedMessage.class.isAssignableFrom(clazz)) { - return newMessageInfoForRequiredNestedMessage(); - } else if (Proto2Empty.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2Empty(); - } else if (Proto2MessageWithExtensions.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2MessageWithExtensions(); - } else if (Proto2Testing.FieldGroup49.class.isAssignableFrom(clazz)) { - return newMessageInfoForExtensionFieldGroup49(); - } else if (Proto2Testing.FieldGroupList51.class.isAssignableFrom(clazz)) { - return newMessageInfoForExtensionFieldGroupList51(); - } else if (Proto2Testing.Proto2MessageWithMaps.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2MessageWithMaps(); - } else { - throw new IllegalArgumentException("Unsupported class: " + clazz.getName()); - } - } - - /** - * Creates a new hard-coded info for {@link Proto2Message}. Each time this is called, we manually - * go through the entire process of what a message would do if it self-registered its own info, - * including looking up each field by name. This is done for benchmarking purposes, so that we get - * a more accurate representation of the time it takes to perform this process. - */ - private static StructuralMessageInfo newMessageInfoForProto2Message() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(50); - builder.withCheckInitialized( - new int[] { - 10, 27, 62, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - }); - lookupFieldsByName(builder); - return builder.build(); - } - - private static void lookupFieldsByName(StructuralMessageInfo.Builder builder) { - Field bitField0 = field("bitField0_"); - - builder.withDefaultInstance(Proto2Message.getDefaultInstance()); - builder.withSyntax(ProtoSyntax.PROTO2); - builder.withField( - forProto2OptionalField( - field("fieldDouble1_"), 1, FieldType.DOUBLE, bitField0, 0x00000001, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldFloat2_"), 2, FieldType.FLOAT, bitField0, 0x00000002, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldInt643_"), 3, FieldType.INT64, bitField0, 0x00000004, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldUint644_"), 4, FieldType.UINT64, bitField0, 0x00000008, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldInt325_"), 5, FieldType.INT32, bitField0, 0x00000010, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldFixed646_"), 6, FieldType.FIXED64, bitField0, 0x00000020, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldFixed327_"), 7, FieldType.FIXED32, bitField0, 0x00000040, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldBool8_"), 8, FieldType.BOOL, bitField0, 0x00000080, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldString9_"), 9, FieldType.STRING, bitField0, 0x00000100, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldMessage10_"), 10, FieldType.MESSAGE, bitField0, 0x00000200, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldBytes11_"), 11, FieldType.BYTES, bitField0, 0x00000400, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldUint3212_"), 12, FieldType.UINT32, bitField0, 0x00000800, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldEnum13_"), - 13, - FieldType.ENUM, - bitField0, - 0x00001000, - false, - asVerifier(TestEnum.internalGetValueMap()))); - builder.withField( - forProto2OptionalField( - field("fieldSfixed3214_"), 14, FieldType.SFIXED32, bitField0, 0x00002000, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldSfixed6415_"), 15, FieldType.SFIXED64, bitField0, 0x00004000, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldSint3216_"), 16, FieldType.SINT32, bitField0, 0x00008000, false, null)); - builder.withField( - forProto2OptionalField( - field("fieldSint6417_"), 17, FieldType.SINT64, bitField0, 0x00010000, false, null)); - builder.withField(forField(field("fieldDoubleList18_"), 18, FieldType.DOUBLE_LIST, false)); - builder.withField(forField(field("fieldFloatList19_"), 19, FieldType.FLOAT_LIST, false)); - builder.withField(forField(field("fieldInt64List20_"), 20, FieldType.INT64_LIST, false)); - builder.withField(forField(field("fieldUint64List21_"), 21, FieldType.UINT64_LIST, false)); - builder.withField(forField(field("fieldInt32List22_"), 22, FieldType.INT32_LIST, false)); - builder.withField(forField(field("fieldFixed64List23_"), 23, FieldType.FIXED64_LIST, false)); - builder.withField(forField(field("fieldFixed32List24_"), 24, FieldType.FIXED32_LIST, false)); - builder.withField(forField(field("fieldBoolList25_"), 25, FieldType.BOOL_LIST, false)); - builder.withField(forField(field("fieldStringList26_"), 26, FieldType.STRING_LIST, false)); - builder.withField( - forRepeatedMessageField( - field("fieldMessageList27_"), 27, FieldType.MESSAGE_LIST, Proto2Message.class)); - builder.withField(forField(field("fieldBytesList28_"), 28, FieldType.BYTES_LIST, false)); - builder.withField(forField(field("fieldUint32List29_"), 29, FieldType.UINT32_LIST, false)); - builder.withField( - forFieldWithEnumVerifier( - field("fieldEnumList30_"), - 30, - FieldType.ENUM_LIST, - asVerifier(TestEnum.internalGetValueMap()))); - builder.withField(forField(field("fieldSfixed32List31_"), 31, FieldType.SFIXED32_LIST, false)); - builder.withField(forField(field("fieldSfixed64List32_"), 32, FieldType.SFIXED64_LIST, false)); - builder.withField(forField(field("fieldSint32List33_"), 33, FieldType.SINT32_LIST, false)); - builder.withField(forField(field("fieldSint64List34_"), 34, FieldType.SINT64_LIST, false)); - builder.withField( - forField(field("fieldDoubleListPacked35_"), 35, FieldType.DOUBLE_LIST_PACKED, false)); - builder.withField( - forField(field("fieldFloatListPacked36_"), 36, FieldType.FLOAT_LIST_PACKED, false)); - builder.withField( - forField(field("fieldInt64ListPacked37_"), 37, FieldType.INT64_LIST_PACKED, false)); - builder.withField( - forField(field("fieldUint64ListPacked38_"), 38, FieldType.UINT64_LIST_PACKED, false)); - builder.withField( - forField(field("fieldInt32ListPacked39_"), 39, FieldType.INT32_LIST_PACKED, false)); - builder.withField( - forField(field("fieldFixed64ListPacked40_"), 40, FieldType.FIXED64_LIST_PACKED, false)); - builder.withField( - forField(field("fieldFixed32ListPacked41_"), 41, FieldType.FIXED32_LIST_PACKED, false)); - builder.withField( - forField(field("fieldBoolListPacked42_"), 42, FieldType.BOOL_LIST_PACKED, false)); - builder.withField( - forField(field("fieldUint32ListPacked43_"), 43, FieldType.UINT32_LIST_PACKED, false)); - builder.withField( - forFieldWithEnumVerifier( - field("fieldEnumListPacked44_"), - 44, - FieldType.ENUM_LIST_PACKED, - asVerifier(TestEnum.internalGetValueMap()))); - builder.withField( - forField(field("fieldSfixed32ListPacked45_"), 45, FieldType.SFIXED32_LIST_PACKED, false)); - builder.withField( - forField(field("fieldSfixed64ListPacked46_"), 46, FieldType.SFIXED64_LIST_PACKED, false)); - builder.withField( - forField(field("fieldSint32ListPacked47_"), 47, FieldType.SINT32_LIST_PACKED, false)); - builder.withField( - forField(field("fieldSint64ListPacked48_"), 48, FieldType.SINT64_LIST_PACKED, false)); - - builder.withField( - forProto2OptionalField( - field("fieldGroup49_"), 49, FieldType.GROUP, bitField0, 0x00020000, false, null)); - builder.withField( - forRepeatedMessageField( - field("fieldGroupList51_"), - 51, - FieldType.GROUP_LIST, - Proto2Message.FieldGroupList51.class)); - - OneofInfo oneof = new OneofInfo(0, field("testOneofCase_"), field("testOneof_")); - builder.withField(forOneofMemberField(53, FieldType.DOUBLE, oneof, Double.class, false, null)); - builder.withField(forOneofMemberField(54, FieldType.FLOAT, oneof, Float.class, false, null)); - builder.withField(forOneofMemberField(55, FieldType.INT64, oneof, Long.class, false, null)); - builder.withField(forOneofMemberField(56, FieldType.UINT64, oneof, Long.class, false, null)); - builder.withField(forOneofMemberField(57, FieldType.INT32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(58, FieldType.FIXED64, oneof, Long.class, false, null)); - builder.withField( - forOneofMemberField(59, FieldType.FIXED32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(60, FieldType.BOOL, oneof, Boolean.class, false, null)); - builder.withField(forOneofMemberField(61, FieldType.STRING, oneof, String.class, false, null)); - builder.withField( - forOneofMemberField(62, FieldType.MESSAGE, oneof, Proto2Message.class, false, null)); - builder.withField( - forOneofMemberField(63, FieldType.BYTES, oneof, ByteString.class, false, null)); - builder.withField(forOneofMemberField(64, FieldType.UINT32, oneof, Integer.class, false, null)); - builder.withField( - forOneofMemberField(65, FieldType.SFIXED32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(66, FieldType.SFIXED64, oneof, Long.class, false, null)); - builder.withField(forOneofMemberField(67, FieldType.SINT32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(68, FieldType.SINT64, oneof, Long.class, false, null)); - builder.withField( - forOneofMemberField( - 69, FieldType.GROUP, oneof, Proto2Message.FieldGroup69.class, false, null)); - - Field bitField1 = field("bitField1_"); - builder.withField( - forProto2RequiredField( - field("fieldRequiredDouble71_"), - 71, - FieldType.DOUBLE, - bitField1, - 0x00000008, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredFloat72_"), - 72, - FieldType.FLOAT, - bitField1, - 0x00000010, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredInt6473_"), - 73, - FieldType.INT64, - bitField1, - 0x00000020, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredUint6474_"), - 74, - FieldType.UINT64, - bitField1, - 0x00000040, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredInt3275_"), - 75, - FieldType.INT32, - bitField1, - 0x00000080, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredFixed6476_"), - 76, - FieldType.FIXED64, - bitField1, - 0x00000100, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredFixed3277_"), - 77, - FieldType.FIXED32, - bitField1, - 0x00000200, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredBool78_"), 78, FieldType.BOOL, bitField1, 0x00000400, false, null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredString79_"), - 79, - FieldType.STRING, - bitField1, - 0x00000800, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredMessage80_"), - 80, - FieldType.MESSAGE, - bitField1, - 0x00001000, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredBytes81_"), - 81, - FieldType.BYTES, - bitField1, - 0x00002000, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredUint3282_"), - 82, - FieldType.UINT32, - bitField1, - 0x00004000, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredEnum83_"), - 83, - FieldType.ENUM, - bitField1, - 0x00008000, - false, - asVerifier(TestEnum.internalGetValueMap()))); - builder.withField( - forProto2RequiredField( - field("fieldRequiredSfixed3284_"), - 84, - FieldType.SFIXED32, - bitField1, - 0x00010000, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredSfixed6485_"), - 85, - FieldType.SFIXED64, - bitField1, - 0x00020000, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredSint3286_"), - 86, - FieldType.SINT32, - bitField1, - 0x00040000, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredSint6487_"), - 87, - FieldType.SINT64, - bitField1, - 0x00080000, - false, - null)); - builder.withField( - forProto2RequiredField( - field("fieldRequiredGroup88_"), - 88, - FieldType.GROUP, - bitField1, - 0x00100000, - false, - null)); - } - - private static StructuralMessageInfo newMessageInfoForFieldGroup49() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldGroup49.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldGroup49.class, "fieldInt3250_"), - 50, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForFieldGroupList51() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldGroupList51.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldGroupList51.class, "fieldInt3252_"), - 52, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForFieldGroup69() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldGroup69.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldGroup69.class, "fieldInt3270_"), - 70, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForRequiredNestedMessage() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(RequiredNestedMessage.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(RequiredNestedMessage.class, "value_"), - 1, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForFieldRequiredGroup88() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldRequiredGroup88.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldRequiredGroup88.class, "fieldInt3289_"), - 89, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForProto2Empty() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForProto2MessageWithExtensions() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(0); - builder.withSyntax(ProtoSyntax.PROTO2); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForExtensionFieldGroup49() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(Proto2Testing.FieldGroup49.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(Proto2Testing.FieldGroup49.class, "fieldInt3250_"), - 50, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForExtensionFieldGroupList51() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(Proto2Testing.FieldGroupList51.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(Proto2Testing.FieldGroupList51.class, "fieldInt3252_"), - 52, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForProto2MessageWithMaps() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(); - builder.withCheckInitialized( - new int[] { - 10, 27, 44, 61, 78, 95, 112, 129, 146, 163, 180, 197, - }); - builder.withSyntax(ProtoSyntax.PROTO2); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_bool_1", 1)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_bytes_2", 2)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_double_3", 3)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_enum_4", 4)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_fixed32_5", 5)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_fixed64_6", 6)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_float_7", 7)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_int32_8", 8)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_int64_9", 9)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_message_10", 10)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sfixed32_11", 11)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sfixed64_12", 12)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sint32_13", 13)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sint64_14", 14)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_string_15", 15)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_uint32_16", 16)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_uint64_17", 17)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_bool_18", 18)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_bytes_19", 19)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_double_20", 20)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_enum_21", 21)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_fixed32_22", 22)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_fixed64_23", 23)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_float_24", 24)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_int32_25", 25)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_int64_26", 26)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_message_27", 27)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sfixed32_28", 28)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sfixed64_29", 29)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sint32_30", 30)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sint64_31", 31)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_string_32", 32)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_uint32_33", 33)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_uint64_34", 34)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_bool_35", 35)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_bytes_36", 36)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_double_37", 37)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_enum_38", 38)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_fixed32_39", 39)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_fixed64_40", 40)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_float_41", 41)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_int32_42", 42)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_int64_43", 43)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_message_44", 44)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sfixed32_45", 45)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sfixed64_46", 46)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sint32_47", 47)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sint64_48", 48)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_string_49", 49)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_uint32_50", 50)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_uint64_51", 51)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_bool_52", 52)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_bytes_53", 53)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_double_54", 54)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_enum_55", 55)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_fixed32_56", 56)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_fixed64_57", 57)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_float_58", 58)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_int32_59", 59)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_int64_60", 60)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_message_61", 61)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sfixed32_62", 62)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sfixed64_63", 63)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sint32_64", 64)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sint64_65", 65)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_string_66", 66)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_uint32_67", 67)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_uint64_68", 68)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_bool_69", 69)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_bytes_70", 70)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_double_71", 71)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_enum_72", 72)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_fixed32_73", 73)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_fixed64_74", 74)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_float_75", 75)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_int32_76", 76)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_int64_77", 77)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_message_78", 78)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sfixed32_79", 79)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sfixed64_80", 80)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sint32_81", 81)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sint64_82", 82)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_string_83", 83)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_uint32_84", 84)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_uint64_85", 85)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_bool_86", 86)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_bytes_87", 87)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_double_88", 88)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_enum_89", 89)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_fixed32_90", 90)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_fixed64_91", 91)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_float_92", 92)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_int32_93", 93)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_int64_94", 94)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_message_95", 95)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sfixed32_96", 96)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sfixed64_97", 97)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sint32_98", 98)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sint64_99", 99)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_string_100", 100)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_uint32_101", 101)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_uint64_102", 102)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_bool_103", 103)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_bytes_104", 104)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_double_105", 105)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_enum_106", 106)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_fixed32_107", 107)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_fixed64_108", 108)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_float_109", 109)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_int32_110", 110)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_int64_111", 111)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_message_112", 112)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sfixed32_113", 113)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sfixed64_114", 114)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sint32_115", 115)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sint64_116", 116)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_string_117", 117)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_uint32_118", 118)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_uint64_119", 119)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_bool_120", 120)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_bytes_121", 121)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_double_122", 122)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_enum_123", 123)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_fixed32_124", 124)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_fixed64_125", 125)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_float_126", 126)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_int32_127", 127)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_int64_128", 128)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_message_129", 129)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sfixed32_130", 130)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sfixed64_131", 131)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sint32_132", 132)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sint64_133", 133)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_string_134", 134)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_uint32_135", 135)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_uint64_136", 136)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_bool_137", 137)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_bytes_138", 138)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_double_139", 139)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_enum_140", 140)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_fixed32_141", 141)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_fixed64_142", 142)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_float_143", 143)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_int32_144", 144)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_int64_145", 145)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_message_146", 146)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sfixed32_147", 147)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sfixed64_148", 148)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sint32_149", 149)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sint64_150", 150)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_string_151", 151)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_uint32_152", 152)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_uint64_153", 153)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_bool_154", 154)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_bytes_155", 155)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_double_156", 156)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_enum_157", 157)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_fixed32_158", 158)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_fixed64_159", 159)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_float_160", 160)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_int32_161", 161)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_int64_162", 162)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_message_163", 163)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sfixed32_164", 164)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sfixed64_165", 165)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sint32_166", 166)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sint64_167", 167)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_string_168", 168)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_uint32_169", 169)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_uint64_170", 170)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_bool_171", 171)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_bytes_172", 172)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_double_173", 173)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_enum_174", 174)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_fixed32_175", 175)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_fixed64_176", 176)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_float_177", 177)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_int32_178", 178)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_int64_179", 179)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_message_180", 180)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sfixed32_181", 181)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sfixed64_182", 182)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sint32_183", 183)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sint64_184", 184)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_string_185", 185)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_uint32_186", 186)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_uint64_187", 187)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_bool_188", 188)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_bytes_189", 189)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_double_190", 190)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_enum_191", 191)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_fixed32_192", 192)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_fixed64_193", 193)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_float_194", 194)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_int32_195", 195)); - builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_int64_196", 196)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_message_197", 197)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sfixed32_198", 198)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sfixed64_199", 199)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sint32_200", 200)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sint64_201", 201)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_string_202", 202)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint32_203", 203)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint64_204", 204)); - - return builder.build(); - } - - private static FieldInfo mapFieldInfo(Class clazz, String fieldName, int fieldNumber) { - try { - return forMapField( - field(clazz, SchemaUtil.toCamelCase(fieldName, false) + "_"), - fieldNumber, - SchemaUtil.getMapDefaultEntry(clazz, fieldName), - fieldName.contains("_enum_") ? asVerifier(TestEnum.internalGetValueMap()) : null); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } - - - private static Field field(String name) { - return field(Proto2Message.class, name); - } - - private static Field field(Class clazz, String name) { - try { - return clazz.getDeclaredField(name); - } catch (NoSuchFieldException | SecurityException e) { - throw new RuntimeException(e); - } - } - - private static Internal.EnumVerifier asVerifier(final Internal.EnumLiteMap map) { - return new Internal.EnumVerifier() { - @Override - public boolean isInRange(int number) { - return map.findValueByNumber(number) != null; - } - }; - } -} diff --git a/java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java b/java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java deleted file mode 100644 index 364071b35da00..0000000000000 --- a/java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java +++ /dev/null @@ -1,506 +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. - -package com.google.protobuf; - -import static com.google.protobuf.FieldInfo.forField; -import static com.google.protobuf.FieldInfo.forMapField; -import static com.google.protobuf.FieldInfo.forOneofMemberField; -import static com.google.protobuf.FieldInfo.forRepeatedMessageField; - -import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithMaps; -import com.google.protobuf.testing.Proto3Testing.Proto3Empty; -import com.google.protobuf.testing.Proto3Testing.Proto3Message; -import com.google.protobuf.testing.Proto3Testing.Proto3MessageWithMaps; -import java.lang.reflect.Field; - -/** A factory that generates a hard-coded info for {@link Proto3Message}. */ -public final class Proto3MessageInfoFactory implements MessageInfoFactory { - private static final Proto3MessageInfoFactory INSTANCE = new Proto3MessageInfoFactory(); - - private Proto3MessageInfoFactory() {} - - public static Proto3MessageInfoFactory getInstance() { - return INSTANCE; - } - - @Override - public boolean isSupported(Class clazz) { - return true; - } - - @Override - public MessageInfo messageInfoFor(Class clazz) { - if (Proto3Message.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto3Message(); - } else if (Proto3Empty.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto3Empty(); - } else if (Proto3MessageWithMaps.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto3MessageWithMaps(); - } else { - throw new IllegalArgumentException("Unsupported class: " + clazz.getName()); - } - } - - /** - * Creates a new hard-coded info for {@link Proto3Message}. Each time this is called, we manually - * go through the entire process of what a message would do if it self-registered its own info, - * including looking up each field by name. This is done for benchmarking purposes, so that we get - * a more accurate representation of the time it takes to perform this process. - */ - private static StructuralMessageInfo newMessageInfoForProto3Message() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(48); - lookupFieldsByName(builder); - return builder.build(); - } - - private static void lookupFieldsByName(StructuralMessageInfo.Builder builder) { - builder.withDefaultInstance(Proto3Message.getDefaultInstance()); - builder.withSyntax(ProtoSyntax.PROTO3); - builder.withField(forField(field("fieldDouble1_"), 1, FieldType.DOUBLE, true)); - builder.withField(forField(field("fieldFloat2_"), 2, FieldType.FLOAT, true)); - builder.withField(forField(field("fieldInt643_"), 3, FieldType.INT64, true)); - builder.withField(forField(field("fieldUint644_"), 4, FieldType.UINT64, true)); - builder.withField(forField(field("fieldInt325_"), 5, FieldType.INT32, true)); - builder.withField(forField(field("fieldFixed646_"), 6, FieldType.FIXED64, true)); - builder.withField(forField(field("fieldFixed327_"), 7, FieldType.FIXED32, true)); - builder.withField(forField(field("fieldBool8_"), 8, FieldType.BOOL, true)); - builder.withField(forField(field("fieldString9_"), 9, FieldType.STRING, true)); - builder.withField(forField(field("fieldMessage10_"), 10, FieldType.MESSAGE, true)); - builder.withField(forField(field("fieldBytes11_"), 11, FieldType.BYTES, true)); - builder.withField(forField(field("fieldUint3212_"), 12, FieldType.UINT32, true)); - builder.withField(forField(field("fieldEnum13_"), 13, FieldType.ENUM, true)); - builder.withField(forField(field("fieldSfixed3214_"), 14, FieldType.SFIXED32, true)); - builder.withField(forField(field("fieldSfixed6415_"), 15, FieldType.SFIXED64, true)); - builder.withField(forField(field("fieldSint3216_"), 16, FieldType.SINT32, true)); - builder.withField(forField(field("fieldSint6417_"), 17, FieldType.SINT64, true)); - builder.withField(forField(field("fieldDoubleList18_"), 18, FieldType.DOUBLE_LIST, true)); - builder.withField(forField(field("fieldFloatList19_"), 19, FieldType.FLOAT_LIST, true)); - builder.withField(forField(field("fieldInt64List20_"), 20, FieldType.INT64_LIST, true)); - builder.withField(forField(field("fieldUint64List21_"), 21, FieldType.UINT64_LIST, true)); - builder.withField(forField(field("fieldInt32List22_"), 22, FieldType.INT32_LIST, true)); - builder.withField(forField(field("fieldFixed64List23_"), 23, FieldType.FIXED64_LIST, true)); - builder.withField(forField(field("fieldFixed32List24_"), 24, FieldType.FIXED32_LIST, true)); - builder.withField(forField(field("fieldBoolList25_"), 25, FieldType.BOOL_LIST, true)); - builder.withField(forField(field("fieldStringList26_"), 26, FieldType.STRING_LIST, true)); - builder.withField( - forRepeatedMessageField( - field("fieldMessageList27_"), 27, FieldType.MESSAGE_LIST, Proto3Message.class)); - builder.withField(forField(field("fieldBytesList28_"), 28, FieldType.BYTES_LIST, true)); - builder.withField(forField(field("fieldUint32List29_"), 29, FieldType.UINT32_LIST, true)); - builder.withField(forField(field("fieldEnumList30_"), 30, FieldType.ENUM_LIST, true)); - builder.withField(forField(field("fieldSfixed32List31_"), 31, FieldType.SFIXED32_LIST, true)); - builder.withField(forField(field("fieldSfixed64List32_"), 32, FieldType.SFIXED64_LIST, true)); - builder.withField(forField(field("fieldSint32List33_"), 33, FieldType.SINT32_LIST, true)); - builder.withField(forField(field("fieldSint64List34_"), 34, FieldType.SINT64_LIST, true)); - builder.withField( - forField(field("fieldDoubleListPacked35_"), 35, FieldType.DOUBLE_LIST_PACKED, true)); - builder.withField( - forField(field("fieldFloatListPacked36_"), 36, FieldType.FLOAT_LIST_PACKED, true)); - builder.withField( - forField(field("fieldInt64ListPacked37_"), 37, FieldType.INT64_LIST_PACKED, true)); - builder.withField( - forField(field("fieldUint64ListPacked38_"), 38, FieldType.UINT64_LIST_PACKED, true)); - builder.withField( - forField(field("fieldInt32ListPacked39_"), 39, FieldType.INT32_LIST_PACKED, true)); - builder.withField( - forField(field("fieldFixed64ListPacked40_"), 40, FieldType.FIXED64_LIST_PACKED, true)); - builder.withField( - forField(field("fieldFixed32ListPacked41_"), 41, FieldType.FIXED32_LIST_PACKED, true)); - builder.withField( - forField(field("fieldBoolListPacked42_"), 42, FieldType.BOOL_LIST_PACKED, true)); - builder.withField( - forField(field("fieldUint32ListPacked43_"), 43, FieldType.UINT32_LIST_PACKED, true)); - builder.withField( - forField(field("fieldEnumListPacked44_"), 44, FieldType.ENUM_LIST_PACKED, true)); - builder.withField( - forField(field("fieldSfixed32ListPacked45_"), 45, FieldType.SFIXED32_LIST_PACKED, true)); - builder.withField( - forField(field("fieldSfixed64ListPacked46_"), 46, FieldType.SFIXED64_LIST_PACKED, true)); - builder.withField( - forField(field("fieldSint32ListPacked47_"), 47, FieldType.SINT32_LIST_PACKED, true)); - builder.withField( - forField(field("fieldSint64ListPacked48_"), 48, FieldType.SINT64_LIST_PACKED, true)); - - OneofInfo oneof = new OneofInfo(0, field("testOneofCase_"), field("testOneof_")); - builder.withField(forOneofMemberField(53, FieldType.DOUBLE, oneof, Double.class, true, null)); - builder.withField(forOneofMemberField(54, FieldType.FLOAT, oneof, Float.class, true, null)); - builder.withField(forOneofMemberField(55, FieldType.INT64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(56, FieldType.UINT64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(57, FieldType.INT32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(58, FieldType.FIXED64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(59, FieldType.FIXED32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(60, FieldType.BOOL, oneof, Boolean.class, true, null)); - builder.withField(forOneofMemberField(61, FieldType.STRING, oneof, String.class, true, null)); - builder.withField( - forOneofMemberField(62, FieldType.MESSAGE, oneof, Proto3Message.class, true, null)); - builder.withField( - forOneofMemberField(63, FieldType.BYTES, oneof, ByteString.class, true, null)); - builder.withField(forOneofMemberField(64, FieldType.UINT32, oneof, Integer.class, true, null)); - builder.withField( - forOneofMemberField(65, FieldType.SFIXED32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(66, FieldType.SFIXED64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(67, FieldType.SINT32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(68, FieldType.SINT64, oneof, Long.class, true, null)); - } - - private StructuralMessageInfo newMessageInfoForProto3Empty() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO3); - return builder.build(); - } - - private StructuralMessageInfo newMessageInfoForProto3MessageWithMaps() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(); - builder.withSyntax(ProtoSyntax.PROTO3); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_bool_1", 1)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_bytes_2", 2)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_double_3", 3)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_enum_4", 4)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_fixed32_5", 5)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_fixed64_6", 6)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_float_7", 7)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_int32_8", 8)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_int64_9", 9)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_message_10", 10)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sfixed32_11", 11)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sfixed64_12", 12)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sint32_13", 13)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sint64_14", 14)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_string_15", 15)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_uint32_16", 16)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_uint64_17", 17)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_bool_18", 18)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_bytes_19", 19)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_double_20", 20)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_enum_21", 21)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_fixed32_22", 22)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_fixed64_23", 23)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_float_24", 24)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_int32_25", 25)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_int64_26", 26)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_message_27", 27)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sfixed32_28", 28)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sfixed64_29", 29)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sint32_30", 30)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sint64_31", 31)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_string_32", 32)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_uint32_33", 33)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_uint64_34", 34)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_bool_35", 35)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_bytes_36", 36)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_double_37", 37)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_enum_38", 38)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_fixed32_39", 39)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_fixed64_40", 40)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_float_41", 41)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_int32_42", 42)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_int64_43", 43)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_message_44", 44)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sfixed32_45", 45)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sfixed64_46", 46)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sint32_47", 47)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sint64_48", 48)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_string_49", 49)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_uint32_50", 50)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_uint64_51", 51)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_bool_52", 52)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_bytes_53", 53)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_double_54", 54)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_enum_55", 55)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_fixed32_56", 56)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_fixed64_57", 57)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_float_58", 58)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_int32_59", 59)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_int64_60", 60)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_message_61", 61)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sfixed32_62", 62)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sfixed64_63", 63)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sint32_64", 64)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sint64_65", 65)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_string_66", 66)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_uint32_67", 67)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_uint64_68", 68)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_bool_69", 69)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_bytes_70", 70)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_double_71", 71)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_enum_72", 72)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_fixed32_73", 73)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_fixed64_74", 74)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_float_75", 75)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_int32_76", 76)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_int64_77", 77)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_message_78", 78)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sfixed32_79", 79)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sfixed64_80", 80)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sint32_81", 81)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sint64_82", 82)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_string_83", 83)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_uint32_84", 84)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_uint64_85", 85)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_bool_86", 86)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_bytes_87", 87)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_double_88", 88)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_enum_89", 89)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_fixed32_90", 90)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_fixed64_91", 91)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_float_92", 92)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_int32_93", 93)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_int64_94", 94)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_message_95", 95)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sfixed32_96", 96)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sfixed64_97", 97)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sint32_98", 98)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sint64_99", 99)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_string_100", 100)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_uint32_101", 101)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_uint64_102", 102)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_bool_103", 103)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_bytes_104", 104)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_double_105", 105)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_enum_106", 106)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_fixed32_107", 107)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_fixed64_108", 108)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_float_109", 109)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_int32_110", 110)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_int64_111", 111)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_message_112", 112)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sfixed32_113", 113)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sfixed64_114", 114)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sint32_115", 115)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sint64_116", 116)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_string_117", 117)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_uint32_118", 118)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_uint64_119", 119)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_bool_120", 120)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_bytes_121", 121)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_double_122", 122)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_enum_123", 123)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_fixed32_124", 124)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_fixed64_125", 125)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_float_126", 126)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_int32_127", 127)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_int64_128", 128)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_message_129", 129)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sfixed32_130", 130)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sfixed64_131", 131)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sint32_132", 132)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sint64_133", 133)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_string_134", 134)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_uint32_135", 135)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_uint64_136", 136)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_bool_137", 137)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_bytes_138", 138)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_double_139", 139)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_enum_140", 140)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_fixed32_141", 141)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_fixed64_142", 142)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_float_143", 143)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_int32_144", 144)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_int64_145", 145)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_message_146", 146)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sfixed32_147", 147)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sfixed64_148", 148)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sint32_149", 149)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sint64_150", 150)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_string_151", 151)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_uint32_152", 152)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_uint64_153", 153)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_bool_154", 154)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_bytes_155", 155)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_double_156", 156)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_enum_157", 157)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_fixed32_158", 158)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_fixed64_159", 159)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_float_160", 160)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_int32_161", 161)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_int64_162", 162)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_message_163", 163)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sfixed32_164", 164)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sfixed64_165", 165)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sint32_166", 166)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sint64_167", 167)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_string_168", 168)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_uint32_169", 169)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_uint64_170", 170)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_bool_171", 171)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_bytes_172", 172)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_double_173", 173)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_enum_174", 174)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_fixed32_175", 175)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_fixed64_176", 176)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_float_177", 177)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_int32_178", 178)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_int64_179", 179)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_message_180", 180)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sfixed32_181", 181)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sfixed64_182", 182)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sint32_183", 183)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sint64_184", 184)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_string_185", 185)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_uint32_186", 186)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_uint64_187", 187)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_bool_188", 188)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_bytes_189", 189)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_double_190", 190)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_enum_191", 191)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_fixed32_192", 192)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_fixed64_193", 193)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_float_194", 194)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_int32_195", 195)); - builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_int64_196", 196)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_message_197", 197)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sfixed32_198", 198)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sfixed64_199", 199)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sint32_200", 200)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sint64_201", 201)); - builder.withField( - mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_string_202", 202)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint32_203", 203)); - builder.withField( - mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint64_204", 204)); - return builder.build(); - } - - private static Field field(String name) { - return field(Proto3Message.class, name); - } - - private static Field field(Class clazz, String name) { - try { - return clazz.getDeclaredField(name); - } catch (NoSuchFieldException | SecurityException e) { - throw new RuntimeException(e); - } - } - - private static FieldInfo mapFieldInfo(Class clazz, String fieldName, int fieldNumber) { - try { - return forMapField( - field(clazz, SchemaUtil.toCamelCase(fieldName, false) + "_"), - fieldNumber, - SchemaUtil.getMapDefaultEntry(clazz, fieldName), - null); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } -} diff --git a/java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java b/java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java deleted file mode 100644 index 3c0c629c20dec..0000000000000 --- a/java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java +++ /dev/null @@ -1,816 +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. - -package com.google.protobuf; - -import static com.google.protobuf.FieldInfo.forField; -import static com.google.protobuf.FieldInfo.forMapField; -import static com.google.protobuf.FieldInfo.forOneofMemberField; -import static com.google.protobuf.FieldInfo.forRepeatedMessageField; - -import com.google.protobuf.testing.Proto3TestingLite.Proto3EmptyLite; -import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLite; -import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLiteWithMaps; -import java.lang.reflect.Field; - -/** A factory that generates a hard-coded info for {@link Proto3MessageLite}. */ -public final class Proto3MessageLiteInfoFactory implements MessageInfoFactory { - private static final Proto3MessageLiteInfoFactory instanceForRawMessageInfo = - new Proto3MessageLiteInfoFactory(true); - private static final Proto3MessageLiteInfoFactory instanceForStructuralMessageInfo = - new Proto3MessageLiteInfoFactory(false); - - public static Proto3MessageLiteInfoFactory getInstanceForRawMessageInfo() { - return instanceForRawMessageInfo; - } - - public static Proto3MessageLiteInfoFactory getInstanceForStructuralMessageInfo() { - return instanceForStructuralMessageInfo; - } - - private final boolean produceRawMessageInfo; - - private Proto3MessageLiteInfoFactory(boolean produceRawMessageInfo) { - this.produceRawMessageInfo = produceRawMessageInfo; - } - - @Override - public boolean isSupported(Class clazz) { - return true; - } - - @Override - public MessageInfo messageInfoFor(Class clazz) { - return produceRawMessageInfo ? rawMessageInfoFor(clazz) : structuralMessageInfoFor(clazz); - } - - private MessageInfo rawMessageInfoFor(Class clazz) { - if (Proto3MessageLite.class.isAssignableFrom(clazz)) { - return newRawMessageInfoForProto3MessageLite(); - } else { - throw new IllegalArgumentException("Unsupported class: " + clazz.getName()); - } - } - - private MessageInfo newRawMessageInfoForProto3MessageLite() { - java.lang.Object[] objects = - new java.lang.Object[] { - "testOneof_", - "testOneofCase_", - "fieldDouble1_", - "fieldFloat2_", - "fieldInt643_", - "fieldUint644_", - "fieldInt325_", - "fieldFixed646_", - "fieldFixed327_", - "fieldBool8_", - "fieldString9_", - "fieldMessage10_", - "fieldBytes11_", - "fieldUint3212_", - "fieldEnum13_", - "fieldSfixed3214_", - "fieldSfixed6415_", - "fieldSint3216_", - "fieldSint6417_", - "fieldDoubleList18_", - "fieldFloatList19_", - "fieldInt64List20_", - "fieldUint64List21_", - "fieldInt32List22_", - "fieldFixed64List23_", - "fieldFixed32List24_", - "fieldBoolList25_", - "fieldStringList26_", - "fieldMessageList27_", - Proto3MessageLite.class, - "fieldBytesList28_", - "fieldUint32List29_", - "fieldEnumList30_", - "fieldSfixed32List31_", - "fieldSfixed64List32_", - "fieldSint32List33_", - "fieldSint64List34_", - "fieldDoubleListPacked35_", - "fieldFloatListPacked36_", - "fieldInt64ListPacked37_", - "fieldUint64ListPacked38_", - "fieldInt32ListPacked39_", - "fieldFixed64ListPacked40_", - "fieldFixed32ListPacked41_", - "fieldBoolListPacked42_", - "fieldUint32ListPacked43_", - "fieldEnumListPacked44_", - "fieldSfixed32ListPacked45_", - "fieldSfixed64ListPacked46_", - "fieldSint32ListPacked47_", - "fieldSint64ListPacked48_", - Proto3MessageLite.class, - }; - // To update this after a proto change, run protoc on proto3_message_lite.proto and copy over - // the content of the generated buildMessageInfo() method here. - java.lang.String info = - "\u0000@\u0001\u0000\u0001D@\u0000\u001f\u0000\u0001\u0000\u0002\u0001\u0003\u0002" - + "\u0004\u0003\u0005\u0004\u0006\u0005\u0007\u0006\b\u0007\t\u0208\n\t\u000b\n\f\u000b" - + "\r\f\u000e\r\u000f\u000e\u0010\u000f\u0011\u0010\u0012\u0012\u0013\u0013\u0014\u0014" - + "\u0015\u0015\u0016\u0016\u0017\u0017\u0018\u0018\u0019\u0019\u001a\u021a\u001b\u001b" - + "\u001c\u001c\u001d\u001d\u001e\u001e\u001f\u001f !!\"\"##$$%%&&\'\'(())**++,,--" - + "..//0053\u000064\u000075\u000086\u000097\u0000:8\u0000;9\u0000<:\u0000=\u023b\u0000" - + "><\u0000?=\u0000@>\u0000A@\u0000BA\u0000CB\u0000DC\u0000"; - return new RawMessageInfo(Proto3MessageLite.getDefaultInstance(), info, objects); - } - - private MessageInfo structuralMessageInfoFor(Class clazz) { - if (Proto3MessageLite.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto3MessageLite(); - } else if (Proto3EmptyLite.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto3EmptyLite(); - } else if (Proto3MessageLiteWithMaps.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto3MessageLiteWithMaps(); - } else { - throw new IllegalArgumentException("Unsupported class: " + clazz.getName()); - } - } - - /** - * Creates a new hard-coded info for {@link Proto3MessageLite}. Each time this is called, we - * manually go through the entire process of what a message would do if it self-registered its own - * info, including looking up each field by name. This is done for benchmarking purposes, so that - * we get a more accurate representation of the time it takes to perform this process. - */ - private static StructuralMessageInfo newMessageInfoForProto3MessageLite() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(48); - lookupFieldsByName(builder); - return builder.build(); - } - - private static void lookupFieldsByName(StructuralMessageInfo.Builder builder) { - builder.withDefaultInstance(Proto3MessageLite.getDefaultInstance()); - builder.withSyntax(ProtoSyntax.PROTO3); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldDouble1_"), 1, FieldType.DOUBLE, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldFloat2_"), 2, FieldType.FLOAT, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldInt643_"), 3, FieldType.INT64, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldUint644_"), 4, FieldType.UINT64, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldInt325_"), 5, FieldType.INT32, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldFixed646_"), 6, FieldType.FIXED64, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldFixed327_"), 7, FieldType.FIXED32, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldBool8_"), 8, FieldType.BOOL, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldString9_"), 9, FieldType.STRING, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldMessage10_"), 10, FieldType.MESSAGE, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldBytes11_"), 11, FieldType.BYTES, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldUint3212_"), 12, FieldType.UINT32, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldEnum13_"), 13, FieldType.ENUM, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldSfixed3214_"), 14, FieldType.SFIXED32, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldSfixed6415_"), 15, FieldType.SFIXED64, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldSint3216_"), 16, FieldType.SINT32, true)); - builder.withField( - forField(field(Proto3MessageLite.class, "fieldSint6417_"), 17, FieldType.SINT64, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldDoubleList18_"), 18, FieldType.DOUBLE_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldFloatList19_"), 19, FieldType.FLOAT_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldInt64List20_"), 20, FieldType.INT64_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldUint64List21_"), 21, FieldType.UINT64_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldInt32List22_"), 22, FieldType.INT32_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldFixed64List23_"), - 23, - FieldType.FIXED64_LIST, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldFixed32List24_"), - 24, - FieldType.FIXED32_LIST, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldBoolList25_"), 25, FieldType.BOOL_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldStringList26_"), 26, FieldType.STRING_LIST, true)); - builder.withField( - forRepeatedMessageField( - field(Proto3MessageLite.class, "fieldMessageList27_"), - 27, - FieldType.MESSAGE_LIST, - Proto3MessageLite.class)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldBytesList28_"), 28, FieldType.BYTES_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldUint32List29_"), 29, FieldType.UINT32_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldEnumList30_"), 30, FieldType.ENUM_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSfixed32List31_"), - 31, - FieldType.SFIXED32_LIST, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSfixed64List32_"), - 32, - FieldType.SFIXED64_LIST, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSint32List33_"), 33, FieldType.SINT32_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSint64List34_"), 34, FieldType.SINT64_LIST, true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldDoubleListPacked35_"), - 35, - FieldType.DOUBLE_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldFloatListPacked36_"), - 36, - FieldType.FLOAT_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldInt64ListPacked37_"), - 37, - FieldType.INT64_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldUint64ListPacked38_"), - 38, - FieldType.UINT64_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldInt32ListPacked39_"), - 39, - FieldType.INT32_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldFixed64ListPacked40_"), - 40, - FieldType.FIXED64_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldFixed32ListPacked41_"), - 41, - FieldType.FIXED32_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldBoolListPacked42_"), - 42, - FieldType.BOOL_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldUint32ListPacked43_"), - 43, - FieldType.UINT32_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldEnumListPacked44_"), - 44, - FieldType.ENUM_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSfixed32ListPacked45_"), - 45, - FieldType.SFIXED32_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSfixed64ListPacked46_"), - 46, - FieldType.SFIXED64_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSint32ListPacked47_"), - 47, - FieldType.SINT32_LIST_PACKED, - true)); - builder.withField( - forField( - field(Proto3MessageLite.class, "fieldSint64ListPacked48_"), - 48, - FieldType.SINT64_LIST_PACKED, - true)); - - OneofInfo oneof = - new OneofInfo( - 0, - field(Proto3MessageLite.class, "testOneofCase_"), - field(Proto3MessageLite.class, "testOneof_")); - builder.withField(forOneofMemberField(53, FieldType.DOUBLE, oneof, Double.class, true, null)); - builder.withField(forOneofMemberField(54, FieldType.FLOAT, oneof, Float.class, true, null)); - builder.withField(forOneofMemberField(55, FieldType.INT64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(56, FieldType.UINT64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(57, FieldType.INT32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(58, FieldType.FIXED64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(59, FieldType.FIXED32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(60, FieldType.BOOL, oneof, Boolean.class, true, null)); - builder.withField(forOneofMemberField(61, FieldType.STRING, oneof, String.class, true, null)); - builder.withField( - forOneofMemberField(62, FieldType.MESSAGE, oneof, Proto3MessageLite.class, true, null)); - builder.withField( - forOneofMemberField(63, FieldType.BYTES, oneof, ByteString.class, true, null)); - builder.withField(forOneofMemberField(64, FieldType.UINT32, oneof, Integer.class, true, null)); - builder.withField( - forOneofMemberField(65, FieldType.SFIXED32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(66, FieldType.SFIXED64, oneof, Long.class, true, null)); - builder.withField(forOneofMemberField(67, FieldType.SINT32, oneof, Integer.class, true, null)); - builder.withField(forOneofMemberField(68, FieldType.SINT64, oneof, Long.class, true, null)); - } - - private StructuralMessageInfo newMessageInfoForProto3EmptyLite() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO3); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForProto3MessageLiteWithMaps() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(); - builder.withSyntax(ProtoSyntax.PROTO2); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_bool_1", 1)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_bytes_2", 2)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_double_3", 3)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_enum_4", 4)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_fixed32_5", 5)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_fixed64_6", 6)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_float_7", 7)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_int32_8", 8)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_int64_9", 9)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_message_10", 10)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_sfixed32_11", 11)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_sfixed64_12", 12)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_sint32_13", 13)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_sint64_14", 14)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_string_15", 15)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_uint32_16", 16)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_bool_uint64_17", 17)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_bool_18", 18)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_bytes_19", 19)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_double_20", 20)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_enum_21", 21)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_fixed32_22", 22)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_fixed64_23", 23)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_float_24", 24)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_int32_25", 25)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_int64_26", 26)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_message_27", 27)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_sfixed32_28", 28)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_sfixed64_29", 29)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_sint32_30", 30)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_sint64_31", 31)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_string_32", 32)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_uint32_33", 33)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed32_uint64_34", 34)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_bool_35", 35)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_bytes_36", 36)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_double_37", 37)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_enum_38", 38)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_fixed32_39", 39)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_fixed64_40", 40)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_float_41", 41)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_int32_42", 42)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_int64_43", 43)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_message_44", 44)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_sfixed32_45", 45)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_sfixed64_46", 46)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_sint32_47", 47)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_sint64_48", 48)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_string_49", 49)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_uint32_50", 50)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_fixed64_uint64_51", 51)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_bool_52", 52)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_bytes_53", 53)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_double_54", 54)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_enum_55", 55)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_fixed32_56", 56)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_fixed64_57", 57)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_float_58", 58)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_int32_59", 59)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_int64_60", 60)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_message_61", 61)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_sfixed32_62", 62)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_sfixed64_63", 63)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_sint32_64", 64)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_sint64_65", 65)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_string_66", 66)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_uint32_67", 67)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int32_uint64_68", 68)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_bool_69", 69)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_bytes_70", 70)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_double_71", 71)); - builder.withField(mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_enum_72", 72)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_fixed32_73", 73)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_fixed64_74", 74)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_float_75", 75)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_int32_76", 76)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_int64_77", 77)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_message_78", 78)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_sfixed32_79", 79)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_sfixed64_80", 80)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_sint32_81", 81)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_sint64_82", 82)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_string_83", 83)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_uint32_84", 84)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_int64_uint64_85", 85)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_bool_86", 86)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_bytes_87", 87)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_double_88", 88)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_enum_89", 89)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_fixed32_90", 90)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_fixed64_91", 91)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_float_92", 92)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_int32_93", 93)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_int64_94", 94)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_message_95", 95)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_sfixed32_96", 96)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_sfixed64_97", 97)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_sint32_98", 98)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_sint64_99", 99)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_string_100", 100)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_uint32_101", 101)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed32_uint64_102", 102)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_bool_103", 103)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_bytes_104", 104)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_double_105", 105)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_enum_106", 106)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_fixed32_107", 107)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_fixed64_108", 108)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_float_109", 109)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_int32_110", 110)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_int64_111", 111)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_message_112", 112)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_sfixed32_113", 113)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_sfixed64_114", 114)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_sint32_115", 115)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_sint64_116", 116)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_string_117", 117)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_uint32_118", 118)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sfixed64_uint64_119", 119)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_bool_120", 120)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_bytes_121", 121)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_double_122", 122)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_enum_123", 123)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_fixed32_124", 124)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_fixed64_125", 125)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_float_126", 126)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_int32_127", 127)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_int64_128", 128)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_message_129", 129)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_sfixed32_130", 130)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_sfixed64_131", 131)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_sint32_132", 132)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_sint64_133", 133)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_string_134", 134)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_uint32_135", 135)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint32_uint64_136", 136)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_bool_137", 137)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_bytes_138", 138)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_double_139", 139)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_enum_140", 140)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_fixed32_141", 141)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_fixed64_142", 142)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_float_143", 143)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_int32_144", 144)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_int64_145", 145)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_message_146", 146)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_sfixed32_147", 147)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_sfixed64_148", 148)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_sint32_149", 149)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_sint64_150", 150)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_string_151", 151)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_uint32_152", 152)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_sint64_uint64_153", 153)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_bool_154", 154)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_bytes_155", 155)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_double_156", 156)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_enum_157", 157)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_fixed32_158", 158)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_fixed64_159", 159)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_float_160", 160)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_int32_161", 161)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_int64_162", 162)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_message_163", 163)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_sfixed32_164", 164)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_sfixed64_165", 165)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_sint32_166", 166)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_sint64_167", 167)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_string_168", 168)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_uint32_169", 169)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_string_uint64_170", 170)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_bool_171", 171)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_bytes_172", 172)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_double_173", 173)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_enum_174", 174)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_fixed32_175", 175)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_fixed64_176", 176)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_float_177", 177)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_int32_178", 178)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_int64_179", 179)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_message_180", 180)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_sfixed32_181", 181)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_sfixed64_182", 182)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_sint32_183", 183)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_sint64_184", 184)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_string_185", 185)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_uint32_186", 186)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint32_uint64_187", 187)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_bool_188", 188)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_bytes_189", 189)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_double_190", 190)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_enum_191", 191)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_fixed32_192", 192)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_fixed64_193", 193)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_float_194", 194)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_int32_195", 195)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_int64_196", 196)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_message_197", 197)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_sfixed32_198", 198)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_sfixed64_199", 199)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_sint32_200", 200)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_sint64_201", 201)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_string_202", 202)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_uint32_203", 203)); - builder.withField( - mapFieldInfo(Proto3MessageLiteWithMaps.class, "field_map_uint64_uint64_204", 204)); - - return builder.build(); - } - - private static Field field(Class clazz, String name) { - try { - return clazz.getDeclaredField(name); - } catch (NoSuchFieldException | SecurityException e) { - throw new RuntimeException(e); - } - } - - private static FieldInfo mapFieldInfo(Class clazz, String fieldName, int fieldNumber) { - try { - return forMapField( - field(clazz, SchemaUtil.toCamelCase(fieldName, false) + "_"), - fieldNumber, - SchemaUtil.getMapDefaultEntry(clazz, fieldName), - null); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } -} 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 b4092687d919b..377f34c32ea4c 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java @@ -239,7 +239,7 @@ import java.util.List; import java.util.logging.Handler; import java.util.logging.LogRecord; -import junit.framework.Assert; +import org.junit.Assert; /** * Contains methods for setting all fields of {@code TestAllTypes} to some values as well as @@ -901,8 +901,8 @@ public static void assertRepeatedFieldsModified(TestAllTypesOrBuilder message) { Assert.assertEquals(208L, message.getRepeatedFixed64(0)); Assert.assertEquals(209, message.getRepeatedSfixed32(0)); Assert.assertEquals(210L, message.getRepeatedSfixed64(0)); - Assert.assertEquals(211F, message.getRepeatedFloat(0)); - Assert.assertEquals(212D, message.getRepeatedDouble(0)); + Assert.assertEquals(211F, message.getRepeatedFloat(0), 0.0); + Assert.assertEquals(212D, message.getRepeatedDouble(0), 0.0); Assert.assertEquals(true, message.getRepeatedBool(0)); Assert.assertEquals("215", message.getRepeatedString(0)); Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0)); @@ -931,8 +931,8 @@ public static void assertRepeatedFieldsModified(TestAllTypesOrBuilder message) { Assert.assertEquals(508L, message.getRepeatedFixed64(1)); Assert.assertEquals(509, message.getRepeatedSfixed32(1)); Assert.assertEquals(510L, message.getRepeatedSfixed64(1)); - Assert.assertEquals(511F, message.getRepeatedFloat(1)); - Assert.assertEquals(512D, message.getRepeatedDouble(1)); + Assert.assertEquals(511F, message.getRepeatedFloat(1), 0.0); + Assert.assertEquals(512D, message.getRepeatedDouble(1), 0.0); Assert.assertEquals(true, message.getRepeatedBool(1)); Assert.assertEquals("515", message.getRepeatedString(1)); Assert.assertEquals(toBytes("516"), message.getRepeatedBytes(1)); 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 f9b7da46b7cd7..32ca8a8447736 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -69,8 +69,6 @@ /** * Test case for {@link TextFormat}. - * - *

TODO(wenboz): ExtensionTest and rest of text_format_unittest.cc. */ @RunWith(JUnit4.class) public class TextFormatTest { diff --git a/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java index bf4af71da1c36..e66967d739119 100644 --- a/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java +++ b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java @@ -54,6 +54,7 @@ public class UnknownEnumValueTest { @Test + @SuppressWarnings("ProtoNewBuilderMergeFrom") public void testUnknownEnumValues() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.setOptionalNestedEnumValue(4321); diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java new file mode 100644 index 0000000000000..6ce0fc7e348b8 --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java @@ -0,0 +1,78 @@ +// 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. + +package com.google.protobuf; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class UnknownFieldSetPerformanceTest { + + private static byte[] generateBytes(int length) { + assertThat(length % 4).isEqualTo(0); + byte[] input = new byte[length]; + for (int i = 0; i < length; i += 4) { + input[i] = (byte) 0x08; // field 1, wiretype 0 + input[i + 1] = (byte) 0x08; // field 1, payload 8 + input[i + 2] = (byte) 0x20; // field 4, wiretype 0 + input[i + 3] = (byte) 0x20; // field 4, payload 32 + } + return input; + } + + @Test + // This is a performance test. Failure here is a timeout. + public void testAlternatingFieldNumbers() throws IOException { + byte[] input = generateBytes(800000); + InputStream in = new ByteArrayInputStream(input); + UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder(); + CodedInputStream codedInput = CodedInputStream.newInstance(in); + builder.mergeFrom(codedInput); + } + + @Test + // This is a performance test. Failure here is a timeout. + public void testAddField() { + UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder(); + for (int i = 1; i <= 100000; i++) { + UnknownFieldSet.Field field = UnknownFieldSet.Field.newBuilder().addFixed32(i).build(); + builder.addField(i, field); + } + UnknownFieldSet fieldSet = builder.build(); + assertThat(fieldSet.getField(100000).getFixed32List().get(0)).isEqualTo(100000); + } +} diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java index 1e5bc9649a18d..fbc3bb8fcfbcd 100644 --- a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java +++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java @@ -42,7 +42,9 @@ import protobuf_unittest.UnittestProto.TestPackedExtensions; import protobuf_unittest.UnittestProto.TestPackedTypes; import proto3_unittest.UnittestProto3; +import java.util.List; import java.util.Map; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -61,7 +63,7 @@ public void setUp() throws Exception { unknownFields = emptyMessage.getUnknownFields(); } - UnknownFieldSet.Field getField(String name) { + private UnknownFieldSet.Field getField(String name) { Descriptors.FieldDescriptor field = descriptor.findFieldByName(name); assertThat(field).isNotNull(); return unknownFields.getField(field.getNumber()); @@ -100,6 +102,174 @@ ByteString getBizarroData() throws Exception { // ================================================================= + @Test + public void testFieldBuildersAreReusable() { + UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); + fieldBuilder.addFixed32(10); + UnknownFieldSet.Field first = fieldBuilder.build(); + UnknownFieldSet.Field second = fieldBuilder.build(); + fieldBuilder.addFixed32(11); + UnknownFieldSet.Field third = fieldBuilder.build(); + + assertThat(first).isEqualTo(second); + assertThat(first).isNotEqualTo(third); + } + + @Test + public void testClone() { + UnknownFieldSet.Builder unknownSetBuilder = UnknownFieldSet.newBuilder(); + UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); + fieldBuilder.addFixed32(10); + unknownSetBuilder.addField(8, fieldBuilder.build()); + // necessary to call clone twice to expose the bug + UnknownFieldSet.Builder clone1 = unknownSetBuilder.clone(); + UnknownFieldSet.Builder clone2 = unknownSetBuilder.clone(); // failure is a NullPointerException + assertThat(clone1).isNotSameInstanceAs(clone2); + } + + @Test + public void testClone_lengthDelimited() { + UnknownFieldSet.Builder destUnknownFieldSet = + UnknownFieldSet.newBuilder() + .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build()) + .addField( + 999, + UnknownFieldSet.Field.newBuilder() + .addLengthDelimited(ByteString.copyFromUtf8("some data")) + .addLengthDelimited(ByteString.copyFromUtf8("some more data")) + .build()); + UnknownFieldSet clone = destUnknownFieldSet.clone().build(); + assertThat(clone.getField(997)).isNotNull(); + UnknownFieldSet.Field field999 = clone.getField(999); + List lengthDelimited = field999.getLengthDelimitedList(); + assertThat(lengthDelimited.get(0).toStringUtf8()).isEqualTo("some data"); + assertThat(lengthDelimited.get(1).toStringUtf8()).isEqualTo("some more data"); + + UnknownFieldSet clone2 = destUnknownFieldSet.clone().build(); + assertThat(clone2.getField(997)).isNotNull(); + UnknownFieldSet.Field secondField = clone2.getField(999); + List lengthDelimited2 = secondField.getLengthDelimitedList(); + assertThat(lengthDelimited2.get(0).toStringUtf8()).isEqualTo("some data"); + assertThat(lengthDelimited2.get(1).toStringUtf8()).isEqualTo("some more data"); + } + + @Test + public void testReuse() { + UnknownFieldSet.Builder builder = + UnknownFieldSet.newBuilder() + .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build()) + .addField( + 999, + UnknownFieldSet.Field.newBuilder() + .addLengthDelimited(ByteString.copyFromUtf8("some data")) + .addLengthDelimited(ByteString.copyFromUtf8("some more data")) + .build()); + + UnknownFieldSet fieldSet1 = builder.build(); + UnknownFieldSet fieldSet2 = builder.build(); + builder.addField(1000, UnknownFieldSet.Field.newBuilder().addVarint(-90).build()); + UnknownFieldSet fieldSet3 = builder.build(); + + assertThat(fieldSet1).isEqualTo(fieldSet2); + assertThat(fieldSet1).isNotEqualTo(fieldSet3); + } + + @Test + @SuppressWarnings("ModifiedButNotUsed") + public void testAddField_zero() { + UnknownFieldSet.Field field = getField("optional_int32"); + try { + UnknownFieldSet.newBuilder().addField(0, field); + Assert.fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("0 is not a valid field number."); + } + } + + @Test + @SuppressWarnings("ModifiedButNotUsed") + public void testAddField_negative() { + UnknownFieldSet.Field field = getField("optional_int32"); + try { + UnknownFieldSet.newBuilder().addField(-2, field); + Assert.fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); + } + } + + @Test + @SuppressWarnings("ModifiedButNotUsed") + public void testClearField_negative() { + try { + UnknownFieldSet.newBuilder().clearField(-28); + Assert.fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("-28 is not a valid field number."); + } + } + + @Test + @SuppressWarnings("ModifiedButNotUsed") + public void testMergeField_negative() { + UnknownFieldSet.Field field = getField("optional_int32"); + try { + UnknownFieldSet.newBuilder().mergeField(-2, field); + Assert.fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); + } + } + + @Test + @SuppressWarnings("ModifiedButNotUsed") + public void testMergeVarintField_negative() { + try { + UnknownFieldSet.newBuilder().mergeVarintField(-2, 78); + Assert.fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); + } + } + + @Test + @SuppressWarnings("ModifiedButNotUsed") + public void testHasField_negative() { + assertThat(UnknownFieldSet.newBuilder().hasField(-2)).isFalse(); + } + + @Test + @SuppressWarnings("ModifiedButNotUsed") + public void testMergeLengthDelimitedField_negative() { + ByteString byteString = ByteString.copyFromUtf8("some data"); + try { + UnknownFieldSet.newBuilder().mergeLengthDelimitedField(-2, byteString); + Assert.fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); + } + } + + @Test + public void testAddField() { + UnknownFieldSet.Field field = getField("optional_int32"); + UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder().addField(1, field).build(); + assertThat(fieldSet.getField(1)).isEqualTo(field); + } + + @Test + public void testAddField_withReplacement() { + UnknownFieldSet.Field first = UnknownFieldSet.Field.newBuilder().addFixed32(56).build(); + UnknownFieldSet.Field second = UnknownFieldSet.Field.newBuilder().addFixed32(25).build(); + UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder() + .addField(1, first) + .addField(1, second) + .build(); + List list = fieldSet.getField(1).getFixed32List(); + assertThat(list).hasSize(1); + assertThat(list.get(0)).isEqualTo(25); + } + @Test public void testVarint() throws Exception { UnknownFieldSet.Field field = getField("optional_int32"); @@ -185,6 +355,16 @@ public void testMergeFrom() throws Exception { assertThat(destination.toString()).isEqualTo("1: 1\n2: 2\n3: 3\n3: 4\n"); } + @Test + public void testAsMap() throws Exception { + UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder().mergeFrom(unknownFields); + Map mapFromBuilder = builder.asMap(); + assertThat(mapFromBuilder).isNotEmpty(); + UnknownFieldSet fields = builder.build(); + Map mapFromFieldSet = fields.asMap(); + assertThat(mapFromFieldSet).containsExactlyEntriesIn(mapFromBuilder); + } + @Test public void testClear() throws Exception { UnknownFieldSet fields = UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build(); diff --git a/java/core/src/test/java/com/google/protobuf/Utf8Test.java b/java/core/src/test/java/com/google/protobuf/Utf8Test.java index 89f080ef36a2c..44f7cf136d463 100644 --- a/java/core/src/test/java/com/google/protobuf/Utf8Test.java +++ b/java/core/src/test/java/com/google/protobuf/Utf8Test.java @@ -101,7 +101,7 @@ private static String randomString(int maxCodePoint) { int codePoint; do { codePoint = rnd.nextInt(maxCodePoint); - } while (Utf8Utils.isSurrogate(codePoint)); + } while (Character.isSurrogate((char) codePoint)); sb.appendCodePoint(codePoint); } return sb.toString(); diff --git a/java/core/src/test/java/com/google/protobuf/Utf8Utils.java b/java/core/src/test/java/com/google/protobuf/Utf8Utils.java deleted file mode 100644 index 6b031867a390a..0000000000000 --- a/java/core/src/test/java/com/google/protobuf/Utf8Utils.java +++ /dev/null @@ -1,192 +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. - -package com.google.protobuf; - -import static java.lang.Character.MIN_HIGH_SURROGATE; -import static java.lang.Character.MIN_LOW_SURROGATE; -import static java.lang.Character.MIN_SURROGATE; - -import java.util.Random; - -/** Utilities for benchmarking UTF-8. */ -final class Utf8Utils { - private Utf8Utils() {} - - static class MaxCodePoint { - final int value; - - /** - * Convert the input string to a code point. Accepts regular decimal numerals, hex strings, and - * some symbolic names meaningful to humans. - */ - private static int decode(String userFriendly) { - try { - return Integer.decode(userFriendly); - } catch (NumberFormatException ignored) { - if (userFriendly.matches("(?i)(?:American|English|ASCII)")) { - // 1-byte UTF-8 sequences - "American" ASCII text - return 0x80; - } else if (userFriendly.matches("(?i)(?:Danish|Latin|Western.*European)")) { - // Mostly 1-byte UTF-8 sequences, mixed with occasional 2-byte - // sequences - "Western European" text - return 0x90; - } else if (userFriendly.matches("(?i)(?:Greek|Cyrillic|European|ISO.?8859)")) { - // Mostly 2-byte UTF-8 sequences - "European" text - return 0x800; - } else if (userFriendly.matches("(?i)(?:Chinese|Han|Asian|BMP)")) { - // Mostly 3-byte UTF-8 sequences - "Asian" text - return Character.MIN_SUPPLEMENTARY_CODE_POINT; - } else if (userFriendly.matches("(?i)(?:Cuneiform|rare|exotic|supplementary.*)")) { - // Mostly 4-byte UTF-8 sequences - "rare exotic" text - return Character.MAX_CODE_POINT; - } else { - throw new IllegalArgumentException("Can't decode codepoint " + userFriendly); - } - } - } - - public static MaxCodePoint valueOf(String userFriendly) { - return new MaxCodePoint(userFriendly); - } - - public MaxCodePoint(String userFriendly) { - value = decode(userFriendly); - } - } - - /** - * The Utf8 distribution of real data. The distribution is an array with length 4. - * "distribution[i]" means the total number of characters who are encoded with (i + 1) bytes. - * - *

GMM_UTF8_DISTRIBUTION is the distribution of gmm data set. GSR_UTF8_DISTRIBUTION is the - * distribution of gsreq/gsresp data set - */ - public enum Utf8Distribution { - GMM_UTF8_DISTRIBUTION { - @Override - public int[] getDistribution() { - return new int[] {53059, 104, 0, 0}; - } - }, - GSR_UTF8_DISTRIBUTION { - @Override - public int[] getDistribution() { - return new int[] {119458, 74, 2706, 0}; - } - }; - - public abstract int[] getDistribution(); - } - - /** - * Creates an array of random strings. - * - * @param stringCount the number of strings to be created. - * @param charCount the number of characters per string. - * @param maxCodePoint the maximum code point for the characters in the strings. - * @return an array of random strings. - */ - static String[] randomStrings(int stringCount, int charCount, MaxCodePoint maxCodePoint) { - final long seed = 99; - final Random rnd = new Random(seed); - String[] strings = new String[stringCount]; - for (int i = 0; i < stringCount; i++) { - strings[i] = randomString(rnd, charCount, maxCodePoint); - } - return strings; - } - - /** - * Creates a random string - * - * @param rnd the random generator. - * @param charCount the number of characters per string. - * @param maxCodePoint the maximum code point for the characters in the strings. - */ - static String randomString(Random rnd, int charCount, MaxCodePoint maxCodePoint) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < charCount; i++) { - int codePoint; - do { - codePoint = rnd.nextInt(maxCodePoint.value); - } while (Utf8Utils.isSurrogate(codePoint)); - sb.appendCodePoint(codePoint); - } - return sb.toString(); - } - - /** Character.isSurrogate was added in Java SE 7. */ - static boolean isSurrogate(int c) { - return Character.MIN_HIGH_SURROGATE <= c && c <= Character.MAX_LOW_SURROGATE; - } - - /** - * Creates an array of random strings according to UTF8 distribution. - * - * @param stringCount the number of strings to be created. - * @param charCount the number of characters per string. - */ - static String[] randomStringsWithDistribution( - int stringCount, int charCount, Utf8Distribution utf8Distribution) { - final int[] distribution = utf8Distribution.getDistribution(); - for (int i = 0; i < 3; i++) { - distribution[i + 1] += distribution[i]; - } - final long seed = 99; - final Random rnd = new Random(seed); - String[] strings = new String[stringCount]; - for (int i = 0; i < stringCount; i++) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < charCount; j++) { - int codePoint; - do { - codePoint = rnd.nextInt(distribution[3]); - if (codePoint < distribution[0]) { - // 1 bytes - sb.append((char) 0x7F); - } else if (codePoint < distribution[1]) { - // 2 bytes - sb.append((char) 0x7FF); - } else if (codePoint < distribution[2]) { - // 3 bytes - sb.append((char) (MIN_SURROGATE - 1)); - } else { - // 4 bytes - sb.append(MIN_HIGH_SURROGATE); - sb.append(MIN_LOW_SURROGATE); - } - } while (Utf8Utils.isSurrogate(codePoint)); - } - strings[i] = sb.toString(); - } - return strings; - } -} 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/dynamic_message_test.proto similarity index 82% rename from java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto rename to java/core/src/test/proto/com/google/protobuf/dynamic_message_test.proto index 9baf948d2e0a6..a0f28ac03676b 100644 --- a/java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto +++ b/java/core/src/test/proto/com/google/protobuf/dynamic_message_test.proto @@ -28,21 +28,15 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Proto definitions used to test MessageLiteExtensionUtil syntax = "proto2"; -package protobuf_unittest; +package dynamic_message_test; -option java_outer_classname = "MessageLiteExtensionTestProtos"; +option java_package = "dynamicmessagetest"; +option java_outer_classname = "DynamicMessageTestProto"; -message Car { - optional string make = 1; - extensions 1000 to max; -} +message EmptyMessage {} -extend Car { - optional bool turbo = 1001; - optional bool self_driving = 1002; - optional bool flies = 1003; - optional string plate = 9999; +message MessageWithMapFields { + map string_message_map = 1; } diff --git a/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto b/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto index 8bf16914313e5..e513725c044da 100644 --- a/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto +++ b/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto @@ -35,8 +35,6 @@ syntax = "proto2"; -// Some generic_services option(s) added automatically. -// See: http://go/proto2-generic-services-default package io_protocol_tests; option java_generic_services = true; // auto-added diff --git a/java/kotlin-lite/BUILD b/java/kotlin-lite/BUILD new file mode 100644 index 0000000000000..bfd7b8d02be00 --- /dev/null +++ b/java/kotlin-lite/BUILD @@ -0,0 +1,184 @@ +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_lite_proto_library") + +java_lite_proto_library( + name = "example_extensible_message_java_proto_lite", + deps = ["//java/kotlin:example_extensible_message_proto"], +) + +kt_jvm_library( + name = "lite_extensions", + srcs = ["src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt"], + deps = ["//java/lite"], +) + +test_suite( + name = "tests", + tests = [ + "test_lite_extensions", + "proto2_test_lite", + "proto3_test_lite", + ], +) + +kt_jvm_library( + name = "test_lite_extensions_library", + srcs = ["src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt"], + deps = [ + ":example_extensible_message_java_proto_lite", + ":lite_extensions", + "//java/lite", + "//java/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/kotlin:shared_runtime", + "@com_github_jetbrains_kotlin//:kotlin-test", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) + +java_test( + name = "test_lite_extensions", + runtime_deps = [":test_lite_extensions_library"], + test_class = "com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest", +) + +java_lite_proto_library( + name = "evil_names_proto2_java_proto_lite", + deps = ["//java/kotlin:evil_names_proto2"], +) + +java_lite_proto_library( + name = "evil_names_proto3_java_proto_lite", + deps = ["//java/kotlin:evil_names_proto3"], +) + +java_lite_proto_library( + name = "multiple_files_proto3_java_proto_lite", + deps = ["//java/kotlin:multiple_files_proto3"], +) + +genrule( + name = "gen_kotlin_proto3_java_multiple_files_lite", + srcs = ["src/test/proto/com/google/protobuf/multiple_files_proto3.proto"], + outs = [ + "MultipleFilesMessageALiteKt.kt", + "MultipleFilesMessageBLiteKt.kt", + "MultipleFilesProto3LiteKt.kt", + ], + cmd = "$(location //:protoc) " + + "--kotlin_out=lite:$(@D) " + + "$(location src/test/proto/com/google/protobuf/multiple_files_proto3.proto) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/MultipleFilesMessageAKt.kt " + + "$(location MultipleFilesMessageALiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/MultipleFilesMessageBKt.kt " + + "$(location MultipleFilesMessageBLiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/MultipleFilesProto3Kt.kt " + + "$(location MultipleFilesProto3LiteKt.kt)", + tools = ["//:protoc"], +) + +genrule( + name = "gen_evil_names_proto2_lite", + srcs = ["src/test/proto/com/google/protobuf/evil_names_proto2.proto"], + outs = [ + "EvilNamesProto2LiteKt.kt", + "HardKeywordsAllTypesProto2LiteKt.kt", + "InterfaceKt.kt", + ], + cmd = "$(location //:protoc) " + + "--kotlin_out=lite:$(@D) " + + "$(location src/test/proto/com/google/protobuf/evil_names_proto2.proto) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/EvilNamesProto2Kt.kt " + + "$(location EvilNamesProto2LiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/HardKeywordsAllTypesProto2Kt.kt " + + "$(location HardKeywordsAllTypesProto2LiteKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/InterfaceKt.kt " + + "$(location InterfaceKt.kt)", + tools = ["//:protoc"], +) + +genrule( + name = "gen_evil_names_proto3_lite", + srcs = ["src/test/proto/com/google/protobuf/evil_names_proto3.proto"], + outs = [ + "ClassKt.kt", + "EvilNamesProto3Kt.kt", + "HardKeywordsAllTypesProto3Kt.kt", + ], + cmd = "$(location //:protoc) " + + "--kotlin_out=lite:$(@D) " + + "$(location src/test/proto/com/google/protobuf/evil_names_proto3.proto) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/ClassKt.kt " + + "$(location ClassKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/EvilNamesProto3Kt.kt " + + "$(location EvilNamesProto3Kt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/HardKeywordsAllTypesProto3Kt.kt " + + "$(location HardKeywordsAllTypesProto3Kt.kt)", + tools = ["//:protoc"], +) + +kt_jvm_library( + name = "kotlin_unittest_lite", + srcs = [ + ":gen_evil_names_proto2_lite", + "//:gen_kotlin_unittest_lite", + ], + deps = [ + ":evil_names_proto2_java_proto_lite", + "//java/lite:lite", + "//java/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/kotlin:shared_runtime", + "//:java_lite_test_protos", + ], +) + +kt_jvm_library( + name = "kotlin_proto3_unittest_lite", + srcs = [ + ":gen_evil_names_proto3_lite", + ":gen_kotlin_proto3_java_multiple_files_lite", + "//:gen_kotlin_proto3_unittest_lite", + ], + deps = [ + ":evil_names_proto3_java_proto_lite", + ":multiple_files_proto3_java_proto_lite", + "//java/lite:lite", + "//java/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/kotlin:shared_runtime", + "//:java_lite_test_protos", + ], +) + +kt_jvm_library( + name = "proto2_test_lite_library", + srcs = ["src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt"], + deps = [ + ":kotlin_unittest_lite", + "//java/core:test_util_lite", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) + +java_test( + name = "proto2_test_lite", + runtime_deps = [":proto2_test_lite_library"], + test_class = "com.google.protobuf.kotlin.Proto2LiteTest", +) + +kt_jvm_library( + name = "proto3_test_lite_library", + srcs = ["src/test/kotlin/com/google/protobuf/Proto3LiteTest.kt"], + deps = [ + ":kotlin_proto3_unittest_lite", + "//java/core:test_util_lite", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) + +java_test( + name = "proto3_test_lite", + runtime_deps = [":proto3_test_lite_library"], + test_class = "com.google.protobuf.kotlin.Proto3LiteTest", +) diff --git a/java/kotlin-lite/generate-test-sources-build.xml b/java/kotlin-lite/generate-test-sources-build.xml index c5f60b8653692..ed886207cbd70 100644 --- a/java/kotlin-lite/generate-test-sources-build.xml +++ b/java/kotlin-lite/generate-test-sources-build.xml @@ -12,7 +12,7 @@ - + @@ -25,7 +25,7 @@ - + diff --git a/java/kotlin-lite/pom.xml b/java/kotlin-lite/pom.xml index 57416d3ed8045..1f02c4dd8c531 100644 --- a/java/kotlin-lite/pom.xml +++ b/java/kotlin-lite/pom.xml @@ -4,14 +4,14 @@ com.google.protobuf protobuf-parent - 3.18.1 + 3.19.4 protobuf-kotlin-lite - Protocol Buffers [Lite] + Protocol Buffers [Kotlin-Lite] - Lite version of Protocol Buffers library. This version is optimized for code size, but does + Lite version of Kotlin Protocol Buffers library. This version is optimized for code size, but does not guarantee API/ABI stability. @@ -94,7 +94,6 @@ DslList.kt DslMap.kt DslProxy.kt - ExtendableMessageLiteExtensions.kt ExtensionList.kt OnlyForUseByGeneratedProtoCode.kt ProtoDslMarker.kt @@ -119,14 +118,6 @@ TestUtilLite.java - - ${basedir}/../kotlin/src/test/kotlin/com/google/protobuf - - ExtendableMessageExtensionsTest.kt - Proto2Test.kt - ProtoUtil.java - - @@ -223,8 +214,8 @@ compile - ${generated.sources.dir} ${project.basedir}/src/main/kotlin + ${generated.sources.dir} diff --git a/java/kotlin-lite/pom_template.xml b/java/kotlin-lite/pom_template.xml new file mode 100644 index 0000000000000..92be0ea6685c4 --- /dev/null +++ b/java/kotlin-lite/pom_template.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + {groupId} + protobuf-parent + {version} + + + {artifactId} + {type} + + Protocol Buffers [Kotlin-Lite] + + Kotlin lite Protocol Buffers library. Protocol Buffers are a way of encoding structured data in an + efficient yet extensible format. + + + + 1.5.0 + + diff --git a/java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt b/java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt index 76d4847bf5e60..1f45f654a73f0 100644 --- a/java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt +++ b/java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt @@ -71,123 +71,110 @@ class Proto2LiteTest { @Test fun testSetters() { assertThat( - testAllTypesLite { - optionalInt32 = 101 - optionalInt64 = 102 - optionalUint32 = 103 - optionalUint64 = 104 - optionalSint32 = 105 - optionalSint64 = 106 - optionalFixed32 = 107 - optionalFixed64 = 108 - optionalSfixed32 = 109 - optionalSfixed64 = 110 - optionalFloat = 111.0f - optionalDouble = 112.0 - optionalBool = true - optionalString = "115" - optionalBytes = toBytes("116") - optionalGroup = - TestAllTypesLiteKt.optionalGroup { a = 117 } - optionalNestedMessage = nestedMessage { bb = 118 } - optionalForeignMessage = - foreignMessageLite { c = 119 } - optionalImportMessage = - ImportMessageLite.newBuilder().setD(120).build() - optionalPublicImportMessage = - PublicImportMessageLite.newBuilder().setE(126).build() - optionalLazyMessage = nestedMessage { bb = 127 } - optionalNestedEnum = NestedEnum.BAZ - optionalForeignEnum = ForeignEnumLite.FOREIGN_LITE_BAZ - optionalImportEnum = ImportEnumLite.IMPORT_LITE_BAZ - optionalStringPiece = "124" - optionalCord = "125" - repeatedInt32.add(201) - repeatedInt64.add(202) - repeatedUint32.add(203) - repeatedUint64.add(204) - repeatedSint32.add(205) - repeatedSint64.add(206) - repeatedFixed32.add(207) - repeatedFixed64.add(208) - repeatedSfixed32.add(209) - repeatedSfixed64.add(210) - repeatedFloat.add(211f) - repeatedDouble.add(212.0) - repeatedBool.add(true) - repeatedString.add("215") - repeatedBytes.add(toBytes("216")) - repeatedGroup.add(TestAllTypesLiteKt.repeatedGroup { a = 217 }) - repeatedNestedMessage.add(nestedMessage { bb = 218 }) - repeatedForeignMessage.add( - foreignMessageLite { c = 219 } - ) - repeatedImportMessage.add( - ImportMessageLite.newBuilder().setD(220).build() - ) - repeatedLazyMessage.add(nestedMessage { bb = 227 }) - repeatedNestedEnum.add(NestedEnum.BAR) - repeatedForeignEnum.add(ForeignEnumLite.FOREIGN_LITE_BAR) - repeatedImportEnum.add(ImportEnumLite.IMPORT_LITE_BAR) - repeatedStringPiece.add("224") - repeatedCord.add("225") - repeatedInt32 += 301 - repeatedInt64 += 302 - repeatedUint32 += 303 - repeatedUint64 += 304 - repeatedSint32 += 305 - repeatedSint64 += 306 - repeatedFixed32 += 307 - repeatedFixed64 += 308 - repeatedSfixed32 += 309 - repeatedSfixed64 += 310 - repeatedFloat += 311f - repeatedDouble += 312.0 - repeatedBool += false - repeatedString += "315" - repeatedBytes += toBytes("316") - repeatedGroup += TestAllTypesLiteKt.repeatedGroup { a = 317 } - repeatedNestedMessage += nestedMessage { bb = 318 } - repeatedForeignMessage += - foreignMessageLite { c = 319 } - repeatedImportMessage += - ImportMessageLite.newBuilder().setD(320).build() - repeatedLazyMessage += - TestAllTypesLiteKt.nestedMessage { bb = 327 } - repeatedNestedEnum += NestedEnum.BAZ - repeatedForeignEnum += ForeignEnumLite.FOREIGN_LITE_BAZ - repeatedImportEnum += ImportEnumLite.IMPORT_LITE_BAZ - repeatedStringPiece += "324" - repeatedCord += "325" - defaultInt32 = 401 - defaultInt64 = 402 - defaultUint32 = 403 - defaultUint64 = 404 - defaultSint32 = 405 - defaultSint64 = 406 - defaultFixed32 = 407 - defaultFixed64 = 408 - defaultSfixed32 = 409 - defaultSfixed64 = 410 - defaultFloat = 411f - defaultDouble = 412.0 - defaultBool = false - defaultString = "415" - defaultBytes = toBytes("416") - defaultNestedEnum = NestedEnum.FOO - defaultForeignEnum = ForeignEnumLite.FOREIGN_LITE_FOO - defaultImportEnum = ImportEnumLite.IMPORT_LITE_FOO - defaultStringPiece = "424" - defaultCord = "425" - oneofUint32 = 601 - oneofNestedMessage = - TestAllTypesLiteKt.nestedMessage { bb = 602 } - oneofString = "603" - oneofBytes = toBytes("604") - } - ).isEqualTo( - TestUtilLite.getAllLiteSetBuilder().build() - ) + testAllTypesLite { + optionalInt32 = 101 + optionalInt64 = 102 + optionalUint32 = 103 + optionalUint64 = 104 + optionalSint32 = 105 + optionalSint64 = 106 + optionalFixed32 = 107 + optionalFixed64 = 108 + optionalSfixed32 = 109 + optionalSfixed64 = 110 + optionalFloat = 111.0f + optionalDouble = 112.0 + optionalBool = true + optionalString = "115" + optionalBytes = toBytes("116") + optionalGroup = TestAllTypesLiteKt.optionalGroup { a = 117 } + optionalNestedMessage = nestedMessage { bb = 118 } + optionalForeignMessage = foreignMessageLite { c = 119 } + optionalImportMessage = ImportMessageLite.newBuilder().setD(120).build() + optionalPublicImportMessage = PublicImportMessageLite.newBuilder().setE(126).build() + optionalLazyMessage = nestedMessage { bb = 127 } + optionalNestedEnum = NestedEnum.BAZ + optionalForeignEnum = ForeignEnumLite.FOREIGN_LITE_BAZ + optionalImportEnum = ImportEnumLite.IMPORT_LITE_BAZ + optionalStringPiece = "124" + optionalCord = "125" + repeatedInt32.add(201) + repeatedInt64.add(202) + repeatedUint32.add(203) + repeatedUint64.add(204) + repeatedSint32.add(205) + repeatedSint64.add(206) + repeatedFixed32.add(207) + repeatedFixed64.add(208) + repeatedSfixed32.add(209) + repeatedSfixed64.add(210) + repeatedFloat.add(211f) + repeatedDouble.add(212.0) + repeatedBool.add(true) + repeatedString.add("215") + repeatedBytes.add(toBytes("216")) + repeatedGroup.add(TestAllTypesLiteKt.repeatedGroup { a = 217 }) + repeatedNestedMessage.add(nestedMessage { bb = 218 }) + repeatedForeignMessage.add(foreignMessageLite { c = 219 }) + repeatedImportMessage.add(ImportMessageLite.newBuilder().setD(220).build()) + repeatedLazyMessage.add(nestedMessage { bb = 227 }) + repeatedNestedEnum.add(NestedEnum.BAR) + repeatedForeignEnum.add(ForeignEnumLite.FOREIGN_LITE_BAR) + repeatedImportEnum.add(ImportEnumLite.IMPORT_LITE_BAR) + repeatedStringPiece.add("224") + repeatedCord.add("225") + repeatedInt32 += 301 + repeatedInt64 += 302 + repeatedUint32 += 303 + repeatedUint64 += 304 + repeatedSint32 += 305 + repeatedSint64 += 306 + repeatedFixed32 += 307 + repeatedFixed64 += 308 + repeatedSfixed32 += 309 + repeatedSfixed64 += 310 + repeatedFloat += 311f + repeatedDouble += 312.0 + repeatedBool += false + repeatedString += "315" + repeatedBytes += toBytes("316") + repeatedGroup += TestAllTypesLiteKt.repeatedGroup { a = 317 } + repeatedNestedMessage += nestedMessage { bb = 318 } + repeatedForeignMessage += foreignMessageLite { c = 319 } + repeatedImportMessage += ImportMessageLite.newBuilder().setD(320).build() + repeatedLazyMessage += TestAllTypesLiteKt.nestedMessage { bb = 327 } + repeatedNestedEnum += NestedEnum.BAZ + repeatedForeignEnum += ForeignEnumLite.FOREIGN_LITE_BAZ + repeatedImportEnum += ImportEnumLite.IMPORT_LITE_BAZ + repeatedStringPiece += "324" + repeatedCord += "325" + defaultInt32 = 401 + defaultInt64 = 402 + defaultUint32 = 403 + defaultUint64 = 404 + defaultSint32 = 405 + defaultSint64 = 406 + defaultFixed32 = 407 + defaultFixed64 = 408 + defaultSfixed32 = 409 + defaultSfixed64 = 410 + defaultFloat = 411f + defaultDouble = 412.0 + defaultBool = false + defaultString = "415" + defaultBytes = toBytes("416") + defaultNestedEnum = NestedEnum.FOO + defaultForeignEnum = ForeignEnumLite.FOREIGN_LITE_FOO + defaultImportEnum = ImportEnumLite.IMPORT_LITE_FOO + defaultStringPiece = "424" + defaultCord = "425" + oneofUint32 = 601 + oneofNestedMessage = TestAllTypesLiteKt.nestedMessage { bb = 602 } + oneofString = "603" + oneofBytes = toBytes("604") + } + ) + .isEqualTo(TestUtilLite.getAllLiteSetBuilder().build()) } @Test @@ -243,71 +230,70 @@ class Proto2LiteTest { TestAllTypesLiteKt.repeatedGroup { a = 2 } ) ) - assertThat(repeatedGroup).isEqualTo( - listOf( - TestAllTypesLiteKt.repeatedGroup { a = 1 }, - TestAllTypesLiteKt.repeatedGroup { a = 2 } + assertThat(repeatedGroup) + .isEqualTo( + listOf( + TestAllTypesLiteKt.repeatedGroup { a = 1 }, + TestAllTypesLiteKt.repeatedGroup { a = 2 } + ) ) - ) repeatedGroup += listOf( TestAllTypesLiteKt.repeatedGroup { a = 3 }, TestAllTypesLiteKt.repeatedGroup { a = 4 } ) - assertThat(repeatedGroup).isEqualTo( - listOf( - TestAllTypesLiteKt.repeatedGroup { a = 1 }, - TestAllTypesLiteKt.repeatedGroup { a = 2 }, - TestAllTypesLiteKt.repeatedGroup { a = 3 }, - TestAllTypesLiteKt.repeatedGroup { a = 4 } + assertThat(repeatedGroup) + .isEqualTo( + listOf( + TestAllTypesLiteKt.repeatedGroup { a = 1 }, + TestAllTypesLiteKt.repeatedGroup { a = 2 }, + TestAllTypesLiteKt.repeatedGroup { a = 3 }, + TestAllTypesLiteKt.repeatedGroup { a = 4 } + ) ) - ) repeatedGroup[0] = TestAllTypesLiteKt.repeatedGroup { a = 5 } - assertThat(repeatedGroup).isEqualTo( - listOf( - TestAllTypesLiteKt.repeatedGroup { a = 5 }, - TestAllTypesLiteKt.repeatedGroup { a = 2 }, - TestAllTypesLiteKt.repeatedGroup { a = 3 }, - TestAllTypesLiteKt.repeatedGroup { a = 4 } + assertThat(repeatedGroup) + .isEqualTo( + listOf( + TestAllTypesLiteKt.repeatedGroup { a = 5 }, + TestAllTypesLiteKt.repeatedGroup { a = 2 }, + TestAllTypesLiteKt.repeatedGroup { a = 3 }, + TestAllTypesLiteKt.repeatedGroup { a = 4 } + ) ) - ) repeatedNestedMessage.addAll(listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 })) - assertThat(repeatedNestedMessage).isEqualTo( - listOf( - nestedMessage { bb = 1 }, - nestedMessage { bb = 2 } - ) - ) + assertThat(repeatedNestedMessage) + .isEqualTo(listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 })) repeatedNestedMessage += listOf(nestedMessage { bb = 3 }, nestedMessage { bb = 4 }) - assertThat(repeatedNestedMessage).isEqualTo( - listOf( - nestedMessage { bb = 1 }, - nestedMessage { bb = 2 }, - nestedMessage { bb = 3 }, - nestedMessage { bb = 4 } + assertThat(repeatedNestedMessage) + .isEqualTo( + listOf( + nestedMessage { bb = 1 }, + nestedMessage { bb = 2 }, + nestedMessage { bb = 3 }, + nestedMessage { bb = 4 } + ) ) - ) repeatedNestedMessage[0] = nestedMessage { bb = 5 } - assertThat(repeatedNestedMessage).isEqualTo( - listOf( - nestedMessage { bb = 5 }, - nestedMessage { bb = 2 }, - nestedMessage { bb = 3 }, - nestedMessage { bb = 4 } + assertThat(repeatedNestedMessage) + .isEqualTo( + listOf( + nestedMessage { bb = 5 }, + nestedMessage { bb = 2 }, + nestedMessage { bb = 3 }, + nestedMessage { bb = 4 } + ) ) - ) repeatedNestedEnum.addAll(listOf(NestedEnum.FOO, NestedEnum.BAR)) assertThat(repeatedNestedEnum).isEqualTo(listOf(NestedEnum.FOO, NestedEnum.BAR)) repeatedNestedEnum += listOf(NestedEnum.BAZ, NestedEnum.FOO) - assertThat(repeatedNestedEnum).isEqualTo( - listOf(NestedEnum.FOO, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO) - ) + assertThat(repeatedNestedEnum) + .isEqualTo(listOf(NestedEnum.FOO, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)) repeatedNestedEnum[0] = NestedEnum.BAR - assertThat(repeatedNestedEnum).isEqualTo( - listOf(NestedEnum.BAR, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO) - ) + assertThat(repeatedNestedEnum) + .isEqualTo(listOf(NestedEnum.BAR, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)) } } @@ -380,165 +366,155 @@ class Proto2LiteTest { optionalInt32 = 101 optionalString = "115" } - val modifiedMessage = message.copy { - optionalInt32 = 201 - } + val modifiedMessage = message.copy { optionalInt32 = 201 } - assertThat(message).isEqualTo( - TestAllTypesLite.newBuilder() - .setOptionalInt32(101) - .setOptionalString("115") - .build() - ) - assertThat(modifiedMessage).isEqualTo( - TestAllTypesLite.newBuilder() - .setOptionalInt32(201) - .setOptionalString("115") - .build() - ) + assertThat(message) + .isEqualTo( + TestAllTypesLite.newBuilder().setOptionalInt32(101).setOptionalString("115").build() + ) + assertThat(modifiedMessage) + .isEqualTo( + TestAllTypesLite.newBuilder().setOptionalInt32(201).setOptionalString("115").build() + ) } @Test fun testOneof() { val message = testAllTypesLite { oneofString = "foo" - assertThat(oneofFieldCase) - .isEqualTo(TestAllTypesLite.OneofFieldCase.ONEOF_STRING) + assertThat(oneofFieldCase).isEqualTo(TestAllTypesLite.OneofFieldCase.ONEOF_STRING) assertThat(oneofString).isEqualTo("foo") clearOneofField() assertThat(hasOneofUint32()).isFalse() - assertThat(oneofFieldCase) - .isEqualTo(TestAllTypesLite.OneofFieldCase.ONEOFFIELD_NOT_SET) + assertThat(oneofFieldCase).isEqualTo(TestAllTypesLite.OneofFieldCase.ONEOFFIELD_NOT_SET) oneofUint32 = 5 } - assertThat(message.getOneofFieldCase()) - .isEqualTo(TestAllTypesLite.OneofFieldCase.ONEOF_UINT32) + assertThat(message.getOneofFieldCase()).isEqualTo(TestAllTypesLite.OneofFieldCase.ONEOF_UINT32) assertThat(message.getOneofUint32()).isEqualTo(5) } @Test fun testExtensionsSet() { assertThat( - testAllExtensionsLite { - this[UnittestLite.optionalInt32ExtensionLite] = 101 - this[UnittestLite.optionalInt64ExtensionLite] = 102L - this[UnittestLite.optionalUint32ExtensionLite] = 103 - this[UnittestLite.optionalUint64ExtensionLite] = 104L - this[UnittestLite.optionalSint32ExtensionLite] = 105 - this[UnittestLite.optionalSint64ExtensionLite] = 106L - this[UnittestLite.optionalFixed32ExtensionLite] = 107 - this[UnittestLite.optionalFixed64ExtensionLite] = 108L - this[UnittestLite.optionalSfixed32ExtensionLite] = 109 - this[UnittestLite.optionalSfixed64ExtensionLite] = 110L - this[UnittestLite.optionalFloatExtensionLite] = 111F - this[UnittestLite.optionalDoubleExtensionLite] = 112.0 - this[UnittestLite.optionalBoolExtensionLite] = true - this[UnittestLite.optionalStringExtensionLite] = "115" - this[UnittestLite.optionalBytesExtensionLite] = toBytes("116") - this[UnittestLite.optionalGroupExtensionLite] = optionalGroupExtensionLite { a = 117 } - this[UnittestLite.optionalNestedMessageExtensionLite] = - TestAllTypesLiteKt.nestedMessage { bb = 118 } - this[UnittestLite.optionalForeignMessageExtensionLite] = foreignMessageLite { c = 119 } - this[UnittestLite.optionalImportMessageExtensionLite] = - ImportMessageLite.newBuilder().setD(120).build() - this[UnittestLite.optionalPublicImportMessageExtensionLite] = - PublicImportMessageLite.newBuilder().setE(126).build() - this[UnittestLite.optionalLazyMessageExtensionLite] = - TestAllTypesLiteKt.nestedMessage { bb = 127 } - this[UnittestLite.optionalNestedEnumExtensionLite] = NestedEnum.BAZ - this[UnittestLite.optionalForeignEnumExtensionLite] = ForeignEnumLite.FOREIGN_LITE_BAZ - this[UnittestLite.optionalImportEnumExtensionLite] = ImportEnumLite.IMPORT_LITE_BAZ - this[UnittestLite.optionalStringPieceExtensionLite] = "124" - this[UnittestLite.optionalCordExtensionLite] = "125" - this[UnittestLite.repeatedInt32ExtensionLite].add(201) - this[UnittestLite.repeatedInt64ExtensionLite].add(202L) - this[UnittestLite.repeatedUint32ExtensionLite].add(203) - this[UnittestLite.repeatedUint64ExtensionLite].add(204L) - this[UnittestLite.repeatedSint32ExtensionLite].add(205) - this[UnittestLite.repeatedSint64ExtensionLite].add(206L) - this[UnittestLite.repeatedFixed32ExtensionLite].add(207) - this[UnittestLite.repeatedFixed64ExtensionLite].add(208L) - this[UnittestLite.repeatedSfixed32ExtensionLite].add(209) - this[UnittestLite.repeatedSfixed64ExtensionLite].add(210L) - this[UnittestLite.repeatedFloatExtensionLite].add(211F) - this[UnittestLite.repeatedDoubleExtensionLite].add(212.0) - this[UnittestLite.repeatedBoolExtensionLite].add(true) - this[UnittestLite.repeatedStringExtensionLite].add("215") - this[UnittestLite.repeatedBytesExtensionLite].add(toBytes("216")) - this[UnittestLite.repeatedGroupExtensionLite].add(repeatedGroupExtensionLite { a = 217 }) - this[UnittestLite.repeatedNestedMessageExtensionLite].add( - TestAllTypesLiteKt.nestedMessage { bb = 218 } - ) - this[UnittestLite.repeatedForeignMessageExtensionLite].add(foreignMessageLite { c = 219 }) - this[UnittestLite.repeatedImportMessageExtensionLite].add( - ImportMessageLite.newBuilder().setD(220).build() - ) - this[UnittestLite.repeatedLazyMessageExtensionLite].add( - TestAllTypesLiteKt.nestedMessage { bb = 227 } - ) - this[UnittestLite.repeatedNestedEnumExtensionLite].add(NestedEnum.BAR) - this[UnittestLite.repeatedForeignEnumExtensionLite].add(ForeignEnumLite.FOREIGN_LITE_BAR) - this[UnittestLite.repeatedImportEnumExtensionLite].add(ImportEnumLite.IMPORT_LITE_BAR) - this[UnittestLite.repeatedStringPieceExtensionLite].add("224") - this[UnittestLite.repeatedCordExtensionLite].add("225") - this[UnittestLite.repeatedInt32ExtensionLite] += 301 - this[UnittestLite.repeatedInt64ExtensionLite] += 302L - this[UnittestLite.repeatedUint32ExtensionLite] += 303 - this[UnittestLite.repeatedUint64ExtensionLite] += 304L - this[UnittestLite.repeatedSint32ExtensionLite] += 305 - this[UnittestLite.repeatedSint64ExtensionLite] += 306L - this[UnittestLite.repeatedFixed32ExtensionLite] += 307 - this[UnittestLite.repeatedFixed64ExtensionLite] += 308L - this[UnittestLite.repeatedSfixed32ExtensionLite] += 309 - this[UnittestLite.repeatedSfixed64ExtensionLite] += 310L - this[UnittestLite.repeatedFloatExtensionLite] += 311F - this[UnittestLite.repeatedDoubleExtensionLite] += 312.0 - this[UnittestLite.repeatedBoolExtensionLite] += false - this[UnittestLite.repeatedStringExtensionLite] += "315" - this[UnittestLite.repeatedBytesExtensionLite] += toBytes("316") - this[UnittestLite.repeatedGroupExtensionLite] += repeatedGroupExtensionLite { a = 317 } - this[UnittestLite.repeatedNestedMessageExtensionLite] += - TestAllTypesLiteKt.nestedMessage { bb = 318 } - this[UnittestLite.repeatedForeignMessageExtensionLite] += foreignMessageLite { c = 319 } - this[UnittestLite.repeatedImportMessageExtensionLite] += - ImportMessageLite.newBuilder().setD(320).build() - this[UnittestLite.repeatedLazyMessageExtensionLite] += - TestAllTypesLiteKt.nestedMessage { bb = 327 } - this[UnittestLite.repeatedNestedEnumExtensionLite] += NestedEnum.BAZ - this[UnittestLite.repeatedForeignEnumExtensionLite] += ForeignEnumLite.FOREIGN_LITE_BAZ - this[UnittestLite.repeatedImportEnumExtensionLite] += ImportEnumLite.IMPORT_LITE_BAZ - this[UnittestLite.repeatedStringPieceExtensionLite] += "324" - this[UnittestLite.repeatedCordExtensionLite] += "325" - this[UnittestLite.defaultInt32ExtensionLite] = 401 - this[UnittestLite.defaultInt64ExtensionLite] = 402L - this[UnittestLite.defaultUint32ExtensionLite] = 403 - this[UnittestLite.defaultUint64ExtensionLite] = 404L - this[UnittestLite.defaultSint32ExtensionLite] = 405 - this[UnittestLite.defaultSint64ExtensionLite] = 406L - this[UnittestLite.defaultFixed32ExtensionLite] = 407 - this[UnittestLite.defaultFixed64ExtensionLite] = 408L - this[UnittestLite.defaultSfixed32ExtensionLite] = 409 - this[UnittestLite.defaultSfixed64ExtensionLite] = 410L - this[UnittestLite.defaultFloatExtensionLite] = 411F - this[UnittestLite.defaultDoubleExtensionLite] = 412.0 - this[UnittestLite.defaultBoolExtensionLite] = false - this[UnittestLite.defaultStringExtensionLite] = "415" - this[UnittestLite.defaultBytesExtensionLite] = toBytes("416") - this[UnittestLite.defaultNestedEnumExtensionLite] = NestedEnum.FOO - this[UnittestLite.defaultForeignEnumExtensionLite] = ForeignEnumLite.FOREIGN_LITE_FOO - this[UnittestLite.defaultImportEnumExtensionLite] = ImportEnumLite.IMPORT_LITE_FOO - this[UnittestLite.defaultStringPieceExtensionLite] = "424" - this[UnittestLite.defaultCordExtensionLite] = "425" - this[UnittestLite.oneofUint32ExtensionLite] = 601 - this[UnittestLite.oneofNestedMessageExtensionLite] = - TestAllTypesLiteKt.nestedMessage { bb = 602 } - this[UnittestLite.oneofStringExtensionLite] = "603" - this[UnittestLite.oneofBytesExtensionLite] = toBytes("604") - } - ).isEqualTo( - TestUtilLite.getAllLiteExtensionsSet() - ) + testAllExtensionsLite { + this[UnittestLite.optionalInt32ExtensionLite] = 101 + this[UnittestLite.optionalInt64ExtensionLite] = 102L + this[UnittestLite.optionalUint32ExtensionLite] = 103 + this[UnittestLite.optionalUint64ExtensionLite] = 104L + this[UnittestLite.optionalSint32ExtensionLite] = 105 + this[UnittestLite.optionalSint64ExtensionLite] = 106L + this[UnittestLite.optionalFixed32ExtensionLite] = 107 + this[UnittestLite.optionalFixed64ExtensionLite] = 108L + this[UnittestLite.optionalSfixed32ExtensionLite] = 109 + this[UnittestLite.optionalSfixed64ExtensionLite] = 110L + this[UnittestLite.optionalFloatExtensionLite] = 111F + this[UnittestLite.optionalDoubleExtensionLite] = 112.0 + this[UnittestLite.optionalBoolExtensionLite] = true + this[UnittestLite.optionalStringExtensionLite] = "115" + this[UnittestLite.optionalBytesExtensionLite] = toBytes("116") + this[UnittestLite.optionalGroupExtensionLite] = optionalGroupExtensionLite { a = 117 } + this[UnittestLite.optionalNestedMessageExtensionLite] = + TestAllTypesLiteKt.nestedMessage { bb = 118 } + this[UnittestLite.optionalForeignMessageExtensionLite] = foreignMessageLite { c = 119 } + this[UnittestLite.optionalImportMessageExtensionLite] = + ImportMessageLite.newBuilder().setD(120).build() + this[UnittestLite.optionalPublicImportMessageExtensionLite] = + PublicImportMessageLite.newBuilder().setE(126).build() + this[UnittestLite.optionalLazyMessageExtensionLite] = + TestAllTypesLiteKt.nestedMessage { bb = 127 } + this[UnittestLite.optionalNestedEnumExtensionLite] = NestedEnum.BAZ + this[UnittestLite.optionalForeignEnumExtensionLite] = ForeignEnumLite.FOREIGN_LITE_BAZ + this[UnittestLite.optionalImportEnumExtensionLite] = ImportEnumLite.IMPORT_LITE_BAZ + this[UnittestLite.optionalStringPieceExtensionLite] = "124" + this[UnittestLite.optionalCordExtensionLite] = "125" + this[UnittestLite.repeatedInt32ExtensionLite].add(201) + this[UnittestLite.repeatedInt64ExtensionLite].add(202L) + this[UnittestLite.repeatedUint32ExtensionLite].add(203) + this[UnittestLite.repeatedUint64ExtensionLite].add(204L) + this[UnittestLite.repeatedSint32ExtensionLite].add(205) + this[UnittestLite.repeatedSint64ExtensionLite].add(206L) + this[UnittestLite.repeatedFixed32ExtensionLite].add(207) + this[UnittestLite.repeatedFixed64ExtensionLite].add(208L) + this[UnittestLite.repeatedSfixed32ExtensionLite].add(209) + this[UnittestLite.repeatedSfixed64ExtensionLite].add(210L) + this[UnittestLite.repeatedFloatExtensionLite].add(211F) + this[UnittestLite.repeatedDoubleExtensionLite].add(212.0) + this[UnittestLite.repeatedBoolExtensionLite].add(true) + this[UnittestLite.repeatedStringExtensionLite].add("215") + this[UnittestLite.repeatedBytesExtensionLite].add(toBytes("216")) + this[UnittestLite.repeatedGroupExtensionLite].add(repeatedGroupExtensionLite { a = 217 }) + this[UnittestLite.repeatedNestedMessageExtensionLite].add( + TestAllTypesLiteKt.nestedMessage { bb = 218 } + ) + this[UnittestLite.repeatedForeignMessageExtensionLite].add(foreignMessageLite { c = 219 }) + this[UnittestLite.repeatedImportMessageExtensionLite].add( + ImportMessageLite.newBuilder().setD(220).build() + ) + this[UnittestLite.repeatedLazyMessageExtensionLite].add( + TestAllTypesLiteKt.nestedMessage { bb = 227 } + ) + this[UnittestLite.repeatedNestedEnumExtensionLite].add(NestedEnum.BAR) + this[UnittestLite.repeatedForeignEnumExtensionLite].add(ForeignEnumLite.FOREIGN_LITE_BAR) + this[UnittestLite.repeatedImportEnumExtensionLite].add(ImportEnumLite.IMPORT_LITE_BAR) + this[UnittestLite.repeatedStringPieceExtensionLite].add("224") + this[UnittestLite.repeatedCordExtensionLite].add("225") + this[UnittestLite.repeatedInt32ExtensionLite] += 301 + this[UnittestLite.repeatedInt64ExtensionLite] += 302L + this[UnittestLite.repeatedUint32ExtensionLite] += 303 + this[UnittestLite.repeatedUint64ExtensionLite] += 304L + this[UnittestLite.repeatedSint32ExtensionLite] += 305 + this[UnittestLite.repeatedSint64ExtensionLite] += 306L + this[UnittestLite.repeatedFixed32ExtensionLite] += 307 + this[UnittestLite.repeatedFixed64ExtensionLite] += 308L + this[UnittestLite.repeatedSfixed32ExtensionLite] += 309 + this[UnittestLite.repeatedSfixed64ExtensionLite] += 310L + this[UnittestLite.repeatedFloatExtensionLite] += 311F + this[UnittestLite.repeatedDoubleExtensionLite] += 312.0 + this[UnittestLite.repeatedBoolExtensionLite] += false + this[UnittestLite.repeatedStringExtensionLite] += "315" + this[UnittestLite.repeatedBytesExtensionLite] += toBytes("316") + this[UnittestLite.repeatedGroupExtensionLite] += repeatedGroupExtensionLite { a = 317 } + this[UnittestLite.repeatedNestedMessageExtensionLite] += + TestAllTypesLiteKt.nestedMessage { bb = 318 } + this[UnittestLite.repeatedForeignMessageExtensionLite] += foreignMessageLite { c = 319 } + this[UnittestLite.repeatedImportMessageExtensionLite] += + ImportMessageLite.newBuilder().setD(320).build() + this[UnittestLite.repeatedLazyMessageExtensionLite] += + TestAllTypesLiteKt.nestedMessage { bb = 327 } + this[UnittestLite.repeatedNestedEnumExtensionLite] += NestedEnum.BAZ + this[UnittestLite.repeatedForeignEnumExtensionLite] += ForeignEnumLite.FOREIGN_LITE_BAZ + this[UnittestLite.repeatedImportEnumExtensionLite] += ImportEnumLite.IMPORT_LITE_BAZ + this[UnittestLite.repeatedStringPieceExtensionLite] += "324" + this[UnittestLite.repeatedCordExtensionLite] += "325" + this[UnittestLite.defaultInt32ExtensionLite] = 401 + this[UnittestLite.defaultInt64ExtensionLite] = 402L + this[UnittestLite.defaultUint32ExtensionLite] = 403 + this[UnittestLite.defaultUint64ExtensionLite] = 404L + this[UnittestLite.defaultSint32ExtensionLite] = 405 + this[UnittestLite.defaultSint64ExtensionLite] = 406L + this[UnittestLite.defaultFixed32ExtensionLite] = 407 + this[UnittestLite.defaultFixed64ExtensionLite] = 408L + this[UnittestLite.defaultSfixed32ExtensionLite] = 409 + this[UnittestLite.defaultSfixed64ExtensionLite] = 410L + this[UnittestLite.defaultFloatExtensionLite] = 411F + this[UnittestLite.defaultDoubleExtensionLite] = 412.0 + this[UnittestLite.defaultBoolExtensionLite] = false + this[UnittestLite.defaultStringExtensionLite] = "415" + this[UnittestLite.defaultBytesExtensionLite] = toBytes("416") + this[UnittestLite.defaultNestedEnumExtensionLite] = NestedEnum.FOO + this[UnittestLite.defaultForeignEnumExtensionLite] = ForeignEnumLite.FOREIGN_LITE_FOO + this[UnittestLite.defaultImportEnumExtensionLite] = ImportEnumLite.IMPORT_LITE_FOO + this[UnittestLite.defaultStringPieceExtensionLite] = "424" + this[UnittestLite.defaultCordExtensionLite] = "425" + this[UnittestLite.oneofUint32ExtensionLite] = 601 + this[UnittestLite.oneofNestedMessageExtensionLite] = + TestAllTypesLiteKt.nestedMessage { bb = 602 } + this[UnittestLite.oneofStringExtensionLite] = "603" + this[UnittestLite.oneofBytesExtensionLite] = toBytes("604") + } + ) + .isEqualTo(TestUtilLite.getAllLiteExtensionsSet()) } @Test @@ -584,78 +560,72 @@ class Proto2LiteTest { .isEqualTo(listOf("5", "2", "3", "4")) this[UnittestLite.repeatedGroupExtensionLite].addAll( - listOf( - repeatedGroupExtensionLite { a = 1 }, - repeatedGroupExtensionLite { a = 2 } - ) + listOf(repeatedGroupExtensionLite { a = 1 }, repeatedGroupExtensionLite { a = 2 }) ) - assertThat(this[UnittestLite.repeatedGroupExtensionLite]).isEqualTo( - listOf( - repeatedGroupExtensionLite { a = 1 }, - repeatedGroupExtensionLite { a = 2 } + assertThat(this[UnittestLite.repeatedGroupExtensionLite]) + .isEqualTo( + listOf(repeatedGroupExtensionLite { a = 1 }, repeatedGroupExtensionLite { a = 2 }) ) - ) this[UnittestLite.repeatedGroupExtensionLite] += - listOf( - repeatedGroupExtensionLite { a = 3 }, - repeatedGroupExtensionLite { a = 4 } + listOf(repeatedGroupExtensionLite { a = 3 }, repeatedGroupExtensionLite { a = 4 }) + assertThat(this[UnittestLite.repeatedGroupExtensionLite]) + .isEqualTo( + listOf( + repeatedGroupExtensionLite { a = 1 }, + repeatedGroupExtensionLite { a = 2 }, + repeatedGroupExtensionLite { a = 3 }, + repeatedGroupExtensionLite { a = 4 } + ) ) - assertThat(this[UnittestLite.repeatedGroupExtensionLite]).isEqualTo( - listOf( - repeatedGroupExtensionLite { a = 1 }, - repeatedGroupExtensionLite { a = 2 }, - repeatedGroupExtensionLite { a = 3 }, - repeatedGroupExtensionLite { a = 4 } - ) - ) this[UnittestLite.repeatedGroupExtensionLite][0] = repeatedGroupExtensionLite { a = 5 } - assertThat(this[UnittestLite.repeatedGroupExtensionLite]).isEqualTo( - listOf( - repeatedGroupExtensionLite { a = 5 }, - repeatedGroupExtensionLite { a = 2 }, - repeatedGroupExtensionLite { a = 3 }, - repeatedGroupExtensionLite { a = 4 } + assertThat(this[UnittestLite.repeatedGroupExtensionLite]) + .isEqualTo( + listOf( + repeatedGroupExtensionLite { a = 5 }, + repeatedGroupExtensionLite { a = 2 }, + repeatedGroupExtensionLite { a = 3 }, + repeatedGroupExtensionLite { a = 4 } + ) ) - ) this[UnittestLite.repeatedNestedMessageExtensionLite].addAll( listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 }) ) - assertThat(this[UnittestLite.repeatedNestedMessageExtensionLite]).isEqualTo( - listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 }) - ) + assertThat(this[UnittestLite.repeatedNestedMessageExtensionLite]) + .isEqualTo(listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 })) this[UnittestLite.repeatedNestedMessageExtensionLite] += listOf(nestedMessage { bb = 3 }, nestedMessage { bb = 4 }) - assertThat(this[UnittestLite.repeatedNestedMessageExtensionLite]).isEqualTo( - listOf( - nestedMessage { bb = 1 }, - nestedMessage { bb = 2 }, - nestedMessage { bb = 3 }, - nestedMessage { bb = 4 } + assertThat(this[UnittestLite.repeatedNestedMessageExtensionLite]) + .isEqualTo( + listOf( + nestedMessage { bb = 1 }, + nestedMessage { bb = 2 }, + nestedMessage { bb = 3 }, + nestedMessage { bb = 4 } + ) ) - ) this[UnittestLite.repeatedNestedMessageExtensionLite][0] = nestedMessage { bb = 5 } - assertThat(this[UnittestLite.repeatedNestedMessageExtensionLite]).isEqualTo( - listOf( - nestedMessage { bb = 5 }, - nestedMessage { bb = 2 }, - nestedMessage { bb = 3 }, - nestedMessage { bb = 4 } + assertThat(this[UnittestLite.repeatedNestedMessageExtensionLite]) + .isEqualTo( + listOf( + nestedMessage { bb = 5 }, + nestedMessage { bb = 2 }, + nestedMessage { bb = 3 }, + nestedMessage { bb = 4 } + ) ) - ) - this[UnittestLite.repeatedNestedEnumExtensionLite] - .addAll(listOf(NestedEnum.FOO, NestedEnum.BAR)) + this[UnittestLite.repeatedNestedEnumExtensionLite].addAll( + listOf(NestedEnum.FOO, NestedEnum.BAR) + ) assertThat(this[UnittestLite.repeatedNestedEnumExtensionLite]) .isEqualTo(listOf(NestedEnum.FOO, NestedEnum.BAR)) this[UnittestLite.repeatedNestedEnumExtensionLite] += listOf(NestedEnum.BAZ, NestedEnum.FOO) - assertThat(this[UnittestLite.repeatedNestedEnumExtensionLite]).isEqualTo( - listOf(NestedEnum.FOO, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO) - ) + assertThat(this[UnittestLite.repeatedNestedEnumExtensionLite]) + .isEqualTo(listOf(NestedEnum.FOO, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)) this[UnittestLite.repeatedNestedEnumExtensionLite][0] = NestedEnum.BAR - assertThat(this[UnittestLite.repeatedNestedEnumExtensionLite]).isEqualTo( - listOf(NestedEnum.BAR, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO) - ) + assertThat(this[UnittestLite.repeatedNestedEnumExtensionLite]) + .isEqualTo(listOf(NestedEnum.BAR, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)) } } @@ -726,62 +696,56 @@ class Proto2LiteTest { @Test fun testEmptyMessages() { - assertThat( - testEmptyMessageLite {} - ).isEqualTo( - TestEmptyMessageLite.newBuilder().build() - ) + assertThat(testEmptyMessageLite {}).isEqualTo(TestEmptyMessageLite.newBuilder().build()) - assertThat( - testEmptyMessageWithExtensionsLite {} - ).isEqualTo( - TestEmptyMessageWithExtensionsLite.newBuilder().build() - ) + assertThat(testEmptyMessageWithExtensionsLite {}) + .isEqualTo(TestEmptyMessageWithExtensionsLite.newBuilder().build()) } @Test fun testMapSetters() { assertThat( - testMapLite { - mapInt32Int32[1] = 2 - mapInt64Int64[1L] = 2L - mapUint32Uint32[1] = 2 - mapUint64Uint64[1L] = 2L - mapSint32Sint32[1] = 2 - mapSint64Sint64[1L] = 2L - mapFixed32Fixed32[1] = 2 - mapFixed64Fixed64[1L] = 2L - mapSfixed32Sfixed32[1] = 2 - mapSfixed64Sfixed64[1L] = 2L - mapInt32Float[1] = 2F - mapInt32Double[1] = 2.0 - mapBoolBool[true] = true - mapStringString["1"] = "2" - mapInt32Bytes[1] = toBytes("2") - mapInt32Enum[1] = MapEnumLite.MAP_ENUM_FOO_LITE - mapInt32ForeignMessage[1] = foreignMessageLite { c = 1 } - } - ).isEqualTo( - TestMapLite.newBuilder() - .putMapInt32Int32(1, 2) - .putMapInt64Int64(1L, 2L) - .putMapUint32Uint32(1, 2) - .putMapUint64Uint64(1L, 2L) - .putMapSint32Sint32(1, 2) - .putMapSint64Sint64(1L, 2L) - .putMapFixed32Fixed32(1, 2) - .putMapFixed64Fixed64(1L, 2L) - .putMapSfixed32Sfixed32(1, 2) - .putMapSfixed64Sfixed64(1L, 2L) - .putMapInt32Float(1, 2F) - .putMapInt32Double(1, 2.0) - .putMapBoolBool(true, true) - .putMapStringString("1", "2") - .putMapInt32Bytes(1, toBytes("2")) - .putMapInt32Enum(1, MapEnumLite.MAP_ENUM_FOO_LITE) - .putMapInt32ForeignMessage(1, foreignMessageLite { c = 1 }) - .build() - ) + testMapLite { + mapInt32Int32[1] = 2 + mapInt64Int64[1L] = 2L + mapUint32Uint32[1] = 2 + mapUint64Uint64[1L] = 2L + mapSint32Sint32[1] = 2 + mapSint64Sint64[1L] = 2L + mapFixed32Fixed32[1] = 2 + mapFixed64Fixed64[1L] = 2L + mapSfixed32Sfixed32[1] = 2 + mapSfixed64Sfixed64[1L] = 2L + mapInt32Float[1] = 2F + mapInt32Double[1] = 2.0 + mapBoolBool[true] = true + mapStringString["1"] = "2" + mapInt32Bytes[1] = toBytes("2") + mapInt32Enum[1] = MapEnumLite.MAP_ENUM_FOO_LITE + mapInt32ForeignMessage[1] = foreignMessageLite { c = 1 } + } + ) + .isEqualTo( + TestMapLite.newBuilder() + .putMapInt32Int32(1, 2) + .putMapInt64Int64(1L, 2L) + .putMapUint32Uint32(1, 2) + .putMapUint64Uint64(1L, 2L) + .putMapSint32Sint32(1, 2) + .putMapSint64Sint64(1L, 2L) + .putMapFixed32Fixed32(1, 2) + .putMapFixed64Fixed64(1L, 2L) + .putMapSfixed32Sfixed32(1, 2) + .putMapSfixed64Sfixed64(1L, 2L) + .putMapInt32Float(1, 2F) + .putMapInt32Double(1, 2.0) + .putMapBoolBool(true, true) + .putMapStringString("1", "2") + .putMapInt32Bytes(1, toBytes("2")) + .putMapInt32Enum(1, MapEnumLite.MAP_ENUM_FOO_LITE) + .putMapInt32ForeignMessage(1, foreignMessageLite { c = 1 }) + .build() + ) } @Test @@ -804,38 +768,38 @@ class Proto2LiteTest { mapInt32Enum.put(1, MapEnumLite.MAP_ENUM_FOO_LITE) assertThat(mapInt32Enum).isEqualTo(mapOf(1 to MapEnumLite.MAP_ENUM_FOO_LITE)) mapInt32Enum[2] = MapEnumLite.MAP_ENUM_BAR_LITE - assertThat(mapInt32Enum).isEqualTo( - mapOf(1 to MapEnumLite.MAP_ENUM_FOO_LITE, 2 to MapEnumLite.MAP_ENUM_BAR_LITE) - ) + assertThat(mapInt32Enum) + .isEqualTo(mapOf(1 to MapEnumLite.MAP_ENUM_FOO_LITE, 2 to MapEnumLite.MAP_ENUM_BAR_LITE)) mapInt32Enum.putAll( mapOf(3 to MapEnumLite.MAP_ENUM_BAZ_LITE, 4 to MapEnumLite.MAP_ENUM_FOO_LITE) ) - assertThat(mapInt32Enum).isEqualTo( - mapOf( - 1 to MapEnumLite.MAP_ENUM_FOO_LITE, - 2 to MapEnumLite.MAP_ENUM_BAR_LITE, - 3 to MapEnumLite.MAP_ENUM_BAZ_LITE, - 4 to MapEnumLite.MAP_ENUM_FOO_LITE + assertThat(mapInt32Enum) + .isEqualTo( + mapOf( + 1 to MapEnumLite.MAP_ENUM_FOO_LITE, + 2 to MapEnumLite.MAP_ENUM_BAR_LITE, + 3 to MapEnumLite.MAP_ENUM_BAZ_LITE, + 4 to MapEnumLite.MAP_ENUM_FOO_LITE + ) ) - ) mapInt32ForeignMessage.put(1, foreignMessageLite { c = 1 }) assertThat(mapInt32ForeignMessage).isEqualTo(mapOf(1 to foreignMessageLite { c = 1 })) mapInt32ForeignMessage[2] = foreignMessageLite { c = 2 } - assertThat(mapInt32ForeignMessage).isEqualTo( - mapOf(1 to foreignMessageLite { c = 1 }, 2 to foreignMessageLite { c = 2 }) - ) + assertThat(mapInt32ForeignMessage) + .isEqualTo(mapOf(1 to foreignMessageLite { c = 1 }, 2 to foreignMessageLite { c = 2 })) mapInt32ForeignMessage.putAll( mapOf(3 to foreignMessageLite { c = 3 }, 4 to foreignMessageLite { c = 4 }) ) - assertThat(mapInt32ForeignMessage).isEqualTo( - mapOf( - 1 to foreignMessageLite { c = 1 }, - 2 to foreignMessageLite { c = 2 }, - 3 to foreignMessageLite { c = 3 }, - 4 to foreignMessageLite { c = 4 } + assertThat(mapInt32ForeignMessage) + .isEqualTo( + mapOf( + 1 to foreignMessageLite { c = 1 }, + 2 to foreignMessageLite { c = 2 }, + 3 to foreignMessageLite { c = 3 }, + 4 to foreignMessageLite { c = 4 } + ) ) - ) } } @@ -892,56 +856,57 @@ class Proto2LiteTest { @Test fun testEvilNames() { assertThat( - evilNamesProto2 { - initialized = true - hasFoo = true - bar = "foo" - isInitialized = true - fooBar = "foo" - aLLCAPS += "foo" - aLLCAPSMAP[1] = true - hasUnderbarPrecedingNumeric1Foo = true - hasUnderbarPrecedingNumeric42Bar = true - hasUnderbarPrecedingNumeric123Foo42BarBaz = true - extension += "foo" - class_ += 1 - int = 1.0 - long = true - boolean = 1L - sealed = "foo" - interface_ = 1F - in_ = 1 - object_ = "foo" - cachedSize_ = "foo" - serializedSize_ = true - by = "foo" - } - ).isEqualTo( - EvilNamesProto2.newBuilder() - .setInitialized(true) - .setHasFoo(true) - .setBar("foo") - .setIsInitialized(true) - .setFooBar("foo") - .addALLCAPS("foo") - .putALLCAPSMAP(1, true) - .setHasUnderbarPrecedingNumeric1Foo(true) - .setHasUnderbarPrecedingNumeric42Bar(true) - .setHasUnderbarPrecedingNumeric123Foo42BarBaz(true) - .addExtension("foo") - .addClass_(1) - .setInt(1.0) - .setLong(true) - .setBoolean(1L) - .setSealed("foo") - .setInterface(1F) - .setIn(1) - .setObject("foo") - .setCachedSize_("foo") - .setSerializedSize_(true) - .setBy("foo") - .build() - ) + evilNamesProto2 { + initialized = true + hasFoo = true + bar = "foo" + isInitialized = true + fooBar = "foo" + aLLCAPS += "foo" + aLLCAPSMAP[1] = true + hasUnderbarPrecedingNumeric1Foo = true + hasUnderbarPrecedingNumeric42Bar = true + hasUnderbarPrecedingNumeric123Foo42BarBaz = true + extension += "foo" + class_ += 1 + int = 1.0 + long = true + boolean = 1L + sealed = "foo" + interface_ = 1F + in_ = 1 + object_ = "foo" + cachedSize_ = "foo" + serializedSize_ = true + by = "foo" + } + ) + .isEqualTo( + EvilNamesProto2.newBuilder() + .setInitialized(true) + .setHasFoo(true) + .setBar("foo") + .setIsInitialized(true) + .setFooBar("foo") + .addALLCAPS("foo") + .putALLCAPSMAP(1, true) + .setHasUnderbarPrecedingNumeric1Foo(true) + .setHasUnderbarPrecedingNumeric42Bar(true) + .setHasUnderbarPrecedingNumeric123Foo42BarBaz(true) + .addExtension("foo") + .addClass_(1) + .setInt(1.0) + .setLong(true) + .setBoolean(1L) + .setSealed("foo") + .setInterface(1F) + .setIn(1) + .setObject("foo") + .setCachedSize_("foo") + .setSerializedSize_(true) + .setBy("foo") + .build() + ) assertThat(interface_ {}).isEqualTo(Interface.newBuilder().build()) } diff --git a/java/kotlin/BUILD b/java/kotlin/BUILD new file mode 100644 index 0000000000000..5403e6f201df3 --- /dev/null +++ b/java/kotlin/BUILD @@ -0,0 +1,284 @@ +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") +load("//:protobuf_version.bzl", "PROTOBUF_VERSION") + +# Kotlin generated protos depend on this and only this. +kt_jvm_library( + name = "shared_runtime", + srcs = [ + "src/main/kotlin/com/google/protobuf/DslList.kt", + "src/main/kotlin/com/google/protobuf/DslMap.kt", + "src/main/kotlin/com/google/protobuf/DslProxy.kt", + "src/main/kotlin/com/google/protobuf/ExtensionList.kt", + "src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt", + "src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt", + ], + visibility = ["//visibility:public"], + deps = [ + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/lite", + ], +) + +kt_jvm_library( + name = "only_for_use_in_proto_generated_code_its_generator_and_tests", + srcs = ["src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt"], + visibility = ["//java:__subpackages__"], +) + +kt_jvm_library( + name = "bytestring_lib", + srcs = ["src/main/kotlin/com/google/protobuf/ByteStrings.kt"], + deps = ["//java/lite"], +) + +kt_jvm_library( + name = "full_extensions", + srcs = ["src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt"], + deps = ["//java/core"], +) + +test_suite( + name = "tests", + tests = [ + "bytestring_test", + "shared_tests", + "test_extensions", + "proto2_test", + "proto3_test", + ], +) + +kt_jvm_library( + name = "bytestring_test_library", + srcs = ["src/test/kotlin/com/google/protobuf/ByteStringsTest.kt"], + deps = [ + ":bytestring_lib", + "//java/lite", + "@com_github_jetbrains_kotlin//:kotlin-test", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) + +java_test( + name = "bytestring_test", + runtime_deps = [":bytestring_test_library"], + test_class = "com.google.protobuf.kotlin.ByteStringsTest", +) + +proto_library( + name = "example_extensible_message_proto", + srcs = ["src/test/proto/com/google/protobuf/example_extensible_message.proto"], + visibility = ["//java:__subpackages__"], +) + +java_proto_library( + name = "example_extensible_message_java_proto", + deps = [":example_extensible_message_proto"], +) + +kt_jvm_library( + name = "shared_tests_library", + srcs = [ + "src/test/kotlin/com/google/protobuf/DslListTest.kt", + "src/test/kotlin/com/google/protobuf/DslMapTest.kt", + "src/test/kotlin/com/google/protobuf/ExtensionListTest.kt", + ], + deps = [ + ":bytestring_lib", + ":example_extensible_message_java_proto", + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + ":shared_runtime", + "@com_github_jetbrains_kotlin//:kotlin-test", + "@maven//:com_google_truth_truth", + "@maven//:com_google_guava_guava_testlib", + "@maven//:junit_junit", + ], +) + +java_test( + name = "shared_tests", + runtime_deps = [":shared_tests_library"], + test_class = "com.google.protobuf.kotlin.DslListTest", +) + +kt_jvm_library( + name = "test_extensions_library", + srcs = ["src/test/kotlin/com/google/protobuf/ExtendableMessageExtensionsTest.kt"], + deps = [ + ":example_extensible_message_java_proto", + ":full_extensions", + "//java/lite", + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + ":shared_runtime", + "@com_github_jetbrains_kotlin//:kotlin-test", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) + +java_test( + name = "test_extensions", + runtime_deps = [":test_extensions_library"], + test_class = "com.google.protobuf.kotlin.ExtendableMessageExtensionsTest", +) + +proto_library( + name = "evil_names_proto2", + srcs = ["src/test/proto/com/google/protobuf/evil_names_proto2.proto"], + visibility = ["//:__subpackages__"], +) + +proto_library( + name = "evil_names_proto3", + srcs = ["src/test/proto/com/google/protobuf/evil_names_proto3.proto"], + visibility = ["//:__subpackages__"], +) + +java_proto_library( + name = "evil_names_proto2_java_proto", + deps = [":evil_names_proto2"], +) + +java_proto_library( + name = "evil_names_proto3_java_proto", + deps = [":evil_names_proto3"], +) + +proto_library( + name = "multiple_files_proto3", + srcs = ["src/test/proto/com/google/protobuf/multiple_files_proto3.proto"], + visibility = ["//:__subpackages__"], +) + +java_proto_library( name = "multiple_files_proto3_java_proto", + deps = [":multiple_files_proto3"], +) + +genrule( + name = "gen_kotlin_proto3_java_multiple_files", + srcs = ["src/test/proto/com/google/protobuf/multiple_files_proto3.proto"], + outs = [ + "MultipleFilesMessageAKt.kt", + "MultipleFilesMessageBKt.kt", + "MultipleFilesProto3Kt.kt", + ], + cmd = "$(location //:protoc) " + + "--kotlin_out=shared,immutable:$(@D) " + + "$(location src/test/proto/com/google/protobuf/multiple_files_proto3.proto) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/MultipleFilesMessageAKt.kt " + + "$(location MultipleFilesMessageAKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/MultipleFilesMessageBKt.kt " + + "$(location MultipleFilesMessageBKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/MultipleFilesProto3Kt.kt " + + "$(location MultipleFilesProto3Kt.kt)", + tools = ["//:protoc"], +) + +genrule( + name = "gen_evil_names_proto2", + srcs = ["src/test/proto/com/google/protobuf/evil_names_proto2.proto"], + outs = [ + "EvilNamesProto2Kt.kt", + "HardKeywordsAllTypesProto2Kt.kt", + "InterfaceKt.kt", + ], + cmd = "$(location //:protoc) " + + "--kotlin_out=shared,immutable:$(@D) " + + "$(location src/test/proto/com/google/protobuf/evil_names_proto2.proto) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/EvilNamesProto2Kt.kt " + + "$(location EvilNamesProto2Kt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/HardKeywordsAllTypesProto2Kt.kt " + + "$(location HardKeywordsAllTypesProto2Kt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/InterfaceKt.kt " + + "$(location InterfaceKt.kt)", + tools = ["//:protoc"], +) + +genrule( + name = "gen_evil_names_proto3", + srcs = ["src/test/proto/com/google/protobuf/evil_names_proto3.proto"], + outs = [ + "ClassKt.kt", + "EvilNamesProto3Kt.kt", + "HardKeywordsAllTypesProto3Kt.kt", + ], + cmd = "$(location //:protoc) " + + "--kotlin_out=shared,immutable:$(@D) " + + "$(location src/test/proto/com/google/protobuf/evil_names_proto3.proto) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/ClassKt.kt " + + "$(location ClassKt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/EvilNamesProto3Kt.kt " + + "$(location EvilNamesProto3Kt.kt) && " + + "cp $(@D)/com/google/protobuf/kotlin/generator/HardKeywordsAllTypesProto3Kt.kt " + + "$(location HardKeywordsAllTypesProto3Kt.kt)", + tools = ["//:protoc"], +) + +kt_jvm_library( + name = "kotlin_unittest", + srcs = [ + ":gen_evil_names_proto2", + "//:gen_kotlin_unittest", + ], + deps = [ + ":evil_names_proto2_java_proto", + "//java/core:core", + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + ":shared_runtime", + "//:java_test_protos", + ], +) + +kt_jvm_library( + name = "kotlin_proto3_unittest", + srcs = [ + ":gen_evil_names_proto3", + ":gen_kotlin_proto3_java_multiple_files", + "//:gen_kotlin_proto3_unittest", + ], + deps = [ + ":evil_names_proto3_java_proto", + ":multiple_files_proto3_java_proto", + "//java/core:core", + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + ":shared_runtime", + "//:java_test_protos", + ], +) + +kt_jvm_library( + name = "proto2_test_library", + srcs = ["src/test/kotlin/com/google/protobuf/Proto2Test.kt"], + deps = [ + ":kotlin_unittest", + "//java/core:test_util", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) + +java_test( + name = "proto2_test", + runtime_deps = [":proto2_test_library"], + test_class = "com.google.protobuf.kotlin.Proto2Test", +) + +kt_jvm_library( + name = "proto3_test_library", + srcs = ["src/test/kotlin/com/google/protobuf/Proto3Test.kt"], + deps = [ + ":kotlin_proto3_unittest", + "//java/core:test_util", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", + ], +) + +java_test( + name = "proto3_test", + runtime_deps = [":proto3_test_library"], + test_class = "com.google.protobuf.kotlin.Proto3Test", +) diff --git a/java/kotlin/pom.xml b/java/kotlin/pom.xml index 40394eb77d1ac..0f6feb26c5954 100644 --- a/java/kotlin/pom.xml +++ b/java/kotlin/pom.xml @@ -4,14 +4,14 @@ com.google.protobuf protobuf-parent - 3.18.1 + 3.19.4 protobuf-kotlin - Protocol Buffers [Core] + Protocol Buffers [Kotlin-Core] - Core Protocol Buffers library. Protocol Buffers are a way of encoding structured data in an + Kotlin core Protocol Buffers library. Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. diff --git a/java/kotlin/pom_template.xml b/java/kotlin/pom_template.xml new file mode 100644 index 0000000000000..c8ddcad9aab23 --- /dev/null +++ b/java/kotlin/pom_template.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + {groupId} + protobuf-parent + {version} + + + {artifactId} + {type} + + Protocol Buffers [Kotlin-Core] + + Kotlin core Protocol Buffers library. Protocol Buffers are a way of encoding structured data in an + efficient yet extensible format. + + + + 1.5.0 + + + diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt index f3cbf2d04ab9d..4463bc1492bcf 100644 --- a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt @@ -58,6 +58,7 @@ import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions import protobuf_unittest.copy import protobuf_unittest.foreignMessage import protobuf_unittest.optionalGroupExtension +import protobuf_unittest.optionalNestedMessageOrNull import protobuf_unittest.repeatedGroupExtension import protobuf_unittest.testAllExtensions import protobuf_unittest.testAllTypes @@ -953,4 +954,16 @@ class Proto2Test { assertThat(hasDo_()).isFalse() } } + + @Test + fun testGetOrNull() { + val noNestedMessage = testAllTypes {} + assertThat(noNestedMessage.optionalNestedMessageOrNull).isEqualTo(null) + + val someNestedMessage = testAllTypes { + optionalNestedMessage = TestAllTypesKt.nestedMessage { bb = 118 } + } + assertThat(someNestedMessage.optionalNestedMessageOrNull) + .isEqualTo(TestAllTypesKt.nestedMessage { bb = 118 }) + } } diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt index 7b394da941f64..ba69dca8fc884 100644 --- a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt @@ -44,6 +44,7 @@ import proto3_unittest.UnittestProto3.TestAllTypes import proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum import proto3_unittest.UnittestProto3.TestEmptyMessage import proto3_unittest.copy +import proto3_unittest.optionalNestedMessageOrNull import proto3_unittest.testAllTypes import proto3_unittest.testEmptyMessage import org.junit.Test @@ -86,66 +87,61 @@ class Proto3Test { assertThat(repeatedString).isEqualTo(listOf("5", "2", "3", "4")) repeatedNestedMessage.addAll(listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 })) - assertThat(repeatedNestedMessage).isEqualTo( - listOf( - nestedMessage { bb = 1 }, - nestedMessage { bb = 2 } - ) - ) + assertThat(repeatedNestedMessage) + .isEqualTo(listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 })) repeatedNestedMessage += listOf(nestedMessage { bb = 3 }, nestedMessage { bb = 4 }) - assertThat(repeatedNestedMessage).isEqualTo( - listOf( - nestedMessage { bb = 1 }, - nestedMessage { bb = 2 }, - nestedMessage { bb = 3 }, - nestedMessage { bb = 4 } + assertThat(repeatedNestedMessage) + .isEqualTo( + listOf( + nestedMessage { bb = 1 }, + nestedMessage { bb = 2 }, + nestedMessage { bb = 3 }, + nestedMessage { bb = 4 } + ) ) - ) repeatedNestedMessage[0] = nestedMessage { bb = 5 } - assertThat(repeatedNestedMessage).isEqualTo( - listOf( - nestedMessage { bb = 5 }, - nestedMessage { bb = 2 }, - nestedMessage { bb = 3 }, - nestedMessage { bb = 4 } + assertThat(repeatedNestedMessage) + .isEqualTo( + listOf( + nestedMessage { bb = 5 }, + nestedMessage { bb = 2 }, + nestedMessage { bb = 3 }, + nestedMessage { bb = 4 } + ) ) - ) repeatedNestedEnum.addAll(listOf(NestedEnum.FOO, NestedEnum.BAR)) assertThat(repeatedNestedEnum).isEqualTo(listOf(NestedEnum.FOO, NestedEnum.BAR)) repeatedNestedEnum += listOf(NestedEnum.BAZ, NestedEnum.FOO) - assertThat(repeatedNestedEnum).isEqualTo( - listOf(NestedEnum.FOO, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO) - ) + assertThat(repeatedNestedEnum) + .isEqualTo(listOf(NestedEnum.FOO, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)) repeatedNestedEnum[0] = NestedEnum.BAR - assertThat(repeatedNestedEnum).isEqualTo( - listOf(NestedEnum.BAR, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO) - ) + assertThat(repeatedNestedEnum) + .isEqualTo(listOf(NestedEnum.BAR, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)) } } @Test fun testClears() { assertThat( - testAllTypes { - optionalInt32 = 101 - clearOptionalInt32() + testAllTypes { + optionalInt32 = 101 + clearOptionalInt32() - optionalString = "115" - clearOptionalString() + optionalString = "115" + clearOptionalString() - optionalNestedMessage = TestAllTypesKt.nestedMessage { bb = 118 } - clearOptionalNestedMessage() + optionalNestedMessage = TestAllTypesKt.nestedMessage { bb = 118 } + clearOptionalNestedMessage() - optionalNestedEnum = NestedEnum.BAZ - clearOptionalNestedEnum() + optionalNestedEnum = NestedEnum.BAZ + clearOptionalNestedEnum() - oneofUint32 = 601 - clearOneofUint32() - } - ).isEqualTo( - TestAllTypes.newBuilder().build() - ) + oneofUint32 = 601 + clearOneofUint32() + } + ) + .isEqualTo(TestAllTypes.newBuilder().build()) } @Test @@ -154,126 +150,110 @@ class Proto3Test { optionalInt32 = 101 optionalString = "115" } - val modifiedMessage = message.copy { - optionalInt32 = 201 - } + val modifiedMessage = message.copy { optionalInt32 = 201 } - assertThat(message).isEqualTo( - TestAllTypes.newBuilder() - .setOptionalInt32(101) - .setOptionalString("115") - .build() - ) - assertThat(modifiedMessage).isEqualTo( - TestAllTypes.newBuilder() - .setOptionalInt32(201) - .setOptionalString("115") - .build() - ) + assertThat(message) + .isEqualTo(TestAllTypes.newBuilder().setOptionalInt32(101).setOptionalString("115").build()) + assertThat(modifiedMessage) + .isEqualTo(TestAllTypes.newBuilder().setOptionalInt32(201).setOptionalString("115").build()) } @Test fun testOneof() { val message = testAllTypes { oneofString = "foo" - assertThat(oneofFieldCase) - .isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_STRING) + assertThat(oneofFieldCase).isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_STRING) assertThat(oneofString).isEqualTo("foo") clearOneofField() - assertThat(oneofFieldCase) - .isEqualTo(TestAllTypes.OneofFieldCase.ONEOFFIELD_NOT_SET) + assertThat(oneofFieldCase).isEqualTo(TestAllTypes.OneofFieldCase.ONEOFFIELD_NOT_SET) oneofUint32 = 5 } - assertThat(message.getOneofFieldCase()) - .isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_UINT32) + assertThat(message.getOneofFieldCase()).isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_UINT32) assertThat(message.getOneofUint32()).isEqualTo(5) } @Test fun testEmptyMessages() { - assertThat( - testEmptyMessage {} - ).isEqualTo( - TestEmptyMessage.newBuilder().build() - ) + assertThat(testEmptyMessage {}).isEqualTo(TestEmptyMessage.newBuilder().build()) } @Test fun testEvilNames() { assertThat( - evilNamesProto3 { - initialized = true - hasFoo = true - bar = "foo" - isInitialized = true - fooBar = "foo" - aLLCAPS += "foo" - aLLCAPSMAP[1] = true - hasUnderbarPrecedingNumeric1Foo = true - hasUnderbarPrecedingNumeric42Bar = true - hasUnderbarPrecedingNumeric123Foo42BarBaz = true - extension += "foo" - class_ = "foo" - int = 1.0 - long = true - boolean = 1L - sealed = "foo" - interface_ = 1F - in_ = 1 - object_ = "foo" - cachedSize_ = "foo" - serializedSize_ = true - value = "foo" - index = 1L - values += "foo" - newValues += "foo" - builder = true - k[1] = 1 - v["foo"] = "foo" - key["foo"] = 1 - map[1] = "foo" - pairs["foo"] = 1 - LeadingUnderscore = "foo" - option = 1 - } - ).isEqualTo( - EvilNamesProto3.newBuilder() - .setInitialized(true) - .setHasFoo(true) - .setBar("foo") - .setIsInitialized(true) - .setFooBar("foo") - .addALLCAPS("foo") - .putALLCAPSMAP(1, true) - .setHasUnderbarPrecedingNumeric1Foo(true) - .setHasUnderbarPrecedingNumeric42Bar(true) - .setHasUnderbarPrecedingNumeric123Foo42BarBaz(true) - .addExtension("foo") - .setClass_("foo") - .setInt(1.0) - .setLong(true) - .setBoolean(1L) - .setSealed("foo") - .setInterface(1F) - .setIn(1) - .setObject("foo") - .setCachedSize_("foo") - .setSerializedSize_(true) - .setValue("foo") - .setIndex(1L) - .addValues("foo") - .addNewValues("foo") - .setBuilder(true) - .putK(1, 1) - .putV("foo", "foo") - .putKey("foo", 1) - .putMap(1, "foo") - .putPairs("foo", 1) - .setLeadingUnderscore("foo") - .setOption(1) - .build() - ) + evilNamesProto3 { + initialized = true + hasFoo = true + bar = "foo" + isInitialized = true + fooBar = "foo" + aLLCAPS += "foo" + aLLCAPSMAP[1] = true + hasUnderbarPrecedingNumeric1Foo = true + hasUnderbarPrecedingNumeric42Bar = true + hasUnderbarPrecedingNumeric123Foo42BarBaz = true + extension += "foo" + class_ = "foo" + int = 1.0 + long = true + boolean = 1L + sealed = "foo" + interface_ = 1F + in_ = 1 + object_ = "foo" + cachedSize_ = "foo" + serializedSize_ = true + value = "foo" + index = 1L + values += "foo" + newValues += "foo" + builder = true + k[1] = 1 + v["foo"] = "foo" + key["foo"] = 1 + map[1] = "foo" + pairs["foo"] = 1 + LeadingUnderscore = "foo" + option = 1 + } + ) + .isEqualTo( + EvilNamesProto3.newBuilder() + .setInitialized(true) + .setHasFoo(true) + .setBar("foo") + .setIsInitialized(true) + .setFooBar("foo") + .addALLCAPS("foo") + .putALLCAPSMAP(1, true) + .setHasUnderbarPrecedingNumeric1Foo(true) + .setHasUnderbarPrecedingNumeric42Bar(true) + .setHasUnderbarPrecedingNumeric123Foo42BarBaz(true) + .addExtension("foo") + .setClass_("foo") + .setInt(1.0) + .setLong(true) + .setBoolean(1L) + .setSealed("foo") + .setInterface(1F) + .setIn(1) + .setObject("foo") + .setCachedSize_("foo") + .setSerializedSize_(true) + .setValue("foo") + .setIndex(1L) + .addValues("foo") + .addNewValues("foo") + .setBuilder(true) + .putK(1, 1) + .putV("foo", "foo") + .putKey("foo", 1) + .putMap(1, "foo") + .putPairs("foo", 1) + .setLeadingUnderscore("foo") + .setOption(1) + .build() + ) assertThat(class_ {}).isEqualTo(Class.newBuilder().build()) } @@ -350,16 +330,22 @@ class Proto3Test { @Test fun testMultipleFiles() { - assertThat( - com.google.protobuf.kotlin.generator.multipleFilesMessageA {} - ).isEqualTo( - com.google.protobuf.kotlin.generator.MultipleFilesMessageA.newBuilder().build() - ) + assertThat(com.google.protobuf.kotlin.generator.multipleFilesMessageA {}) + .isEqualTo(com.google.protobuf.kotlin.generator.MultipleFilesMessageA.newBuilder().build()) - assertThat( - com.google.protobuf.kotlin.generator.multipleFilesMessageB {} - ).isEqualTo( - com.google.protobuf.kotlin.generator.MultipleFilesMessageB.newBuilder().build() - ) + assertThat(com.google.protobuf.kotlin.generator.multipleFilesMessageB {}) + .isEqualTo(com.google.protobuf.kotlin.generator.MultipleFilesMessageB.newBuilder().build()) + } + + @Test + fun testGetOrNull() { + val noNestedMessage = testAllTypes {} + assertThat(noNestedMessage.optionalNestedMessageOrNull).isEqualTo(null) + + val someNestedMessage = testAllTypes { + optionalNestedMessage = TestAllTypesKt.nestedMessage { bb = 118 } + } + assertThat(someNestedMessage.optionalNestedMessageOrNull) + .isEqualTo(TestAllTypesKt.nestedMessage { bb = 118 }) } } diff --git a/java/lite.md b/java/lite.md index 603609f6763b8..755a1a69f27c5 100644 --- a/java/lite.md +++ b/java/lite.md @@ -30,7 +30,7 @@ protobuf Java runtime. If you are using Maven, use the following: com.google.protobuf protobuf-javalite - 3.18.1 + 3.19.4 ``` diff --git a/java/lite/BUILD b/java/lite/BUILD index 7089f958b0b65..fac19f609ccd5 100644 --- a/java/lite/BUILD +++ b/java/lite/BUILD @@ -3,8 +3,15 @@ load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") load("//:internal.bzl", "conformance_test") load("//java/internal:testing.bzl", "junit_tests") -exports_files(["lite.awk"], visibility = ["//java/core:__pkg__"]) -exports_files(["pom_template.xml"], visibility = ["//java/core:__pkg__"]) +exports_files( + ["lite.awk"], + visibility = ["//java/core:__pkg__"], +) + +exports_files( + ["pom_template.xml"], + visibility = ["//java/core:__pkg__"], +) alias( name = "lite", @@ -17,13 +24,26 @@ proto_lang_toolchain( command_line = "--java_out=lite:$(OUT)", runtime = ":lite", visibility = ["//visibility:public"], + # keep this in sync w/ LITE_WELL_KNOWN_PROTO_MAP in //:BUILD + blacklisted_protos = [ + "//:any_proto", + "//:api_proto", + "//:duration_proto", + "//:empty_proto", + "//:field_mask_proto", + "//:source_context_proto", + "//:struct_proto", + "//:timestamp_proto", + "//:type_proto", + "//:wrappers_proto", + ], ) test_suite( name = "tests", tests = [ - "lite_build_test", "conformance_test", + "lite_build_test", "lite_tests", "//java/core:lite_tests", ], @@ -38,21 +58,21 @@ build_test( conformance_test( name = "conformance_test", - testee = "//:conformance_java_lite", failure_list = "//:conformance/failure_list_java_lite.txt", + testee = "//:conformance_java_lite", text_format_failure_list = "//:conformance/text_format_failure_list_java_lite.txt", ) junit_tests( name = "lite_tests", - srcs = glob(["src/test/**/*.java"]), size = "small", + srcs = glob(["src/test/**/*.java"]), deps = [ ":lite", - "//external:junit", - "//external:truth", "//java/core:generic_test_protos_java_proto_lite", "//java/core:java_test_protos_java_proto_lite", "//java/core:test_util_lite", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", ], ) diff --git a/java/lite/generate-test-sources-build.xml b/java/lite/generate-test-sources-build.xml index 65e62ce4fba7d..365194e1db2ca 100644 --- a/java/lite/generate-test-sources-build.xml +++ b/java/lite/generate-test-sources-build.xml @@ -29,7 +29,6 @@ - diff --git a/java/lite/pom.xml b/java/lite/pom.xml index ac4f25c25d6ee..901ae6767a3c7 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.18.1 + 3.19.4 protobuf-javalite @@ -232,6 +232,7 @@ TypeRegistryTest.java UnknownEnumValueTest.java UnknownFieldSetLiteTest.java + UnknownFieldSetPerformanceTest.java UnknownFieldSetTest.java WellKnownTypesTest.java WireFormatTest.java diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java index b0972111acd80..6686a38864a02 100644 --- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java @@ -1345,6 +1345,7 @@ public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { } @Test + @SuppressWarnings("ProtoNewBuilderMergeFrom") public void testBuilderMergeFromNull() throws Exception { try { TestAllTypesLite.newBuilder().mergeFrom((TestAllTypesLite) null); @@ -1899,6 +1900,7 @@ public void testMergeFrom_sanity() throws Exception { } @Test + @SuppressWarnings("ProtoNewBuilderMergeFrom") public void testMergeFromNoLazyFieldSharing() throws Exception { TestAllTypesLite.Builder sourceBuilder = TestAllTypesLite.newBuilder().setOptionalLazyMessage(NestedMessage.newBuilder().setBb(1)); @@ -2487,9 +2489,9 @@ public void testParseFromByteBufferThrows_extensions() { assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { assertThat( - TestAllExtensionsLite.newBuilder() - .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) - .build()) + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .build()) .isEqualTo(expected.getUnfinishedMessage()); } } @@ -2782,7 +2784,7 @@ public void testNegative0FloatingPointEquality() throws Exception { assertThat(message1).isNotEqualTo(message2); } - private String encodeHex(ByteString bytes) { + private static String encodeHex(ByteString bytes) { String hexDigits = "0123456789abcdef"; StringBuilder stringBuilder = new StringBuilder(bytes.size() * 2); for (byte b : bytes) { @@ -2792,7 +2794,7 @@ private String encodeHex(ByteString bytes) { return stringBuilder.toString(); } - private boolean contains(ByteString a, ByteString b) { + private static boolean contains(ByteString a, ByteString b) { for (int i = 0; i <= a.size() - b.size(); ++i) { if (a.substring(i, i + b.size()).equals(b)) { return true; diff --git a/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java b/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java deleted file mode 100644 index a17dda5c1f173..0000000000000 --- a/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java +++ /dev/null @@ -1,1332 +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. - -package com.google.protobuf; - -import static com.google.protobuf.FieldInfo.forField; -import static com.google.protobuf.FieldInfo.forFieldWithEnumVerifier; -import static com.google.protobuf.FieldInfo.forMapField; -import static com.google.protobuf.FieldInfo.forOneofMemberField; -import static com.google.protobuf.FieldInfo.forProto2OptionalField; -import static com.google.protobuf.FieldInfo.forProto2RequiredField; -import static com.google.protobuf.FieldInfo.forRepeatedMessageField; - -import com.google.protobuf.testing.Proto2TestingLite; -import com.google.protobuf.testing.Proto2TestingLite.Proto2EmptyLite; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.FieldGroup49; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.FieldGroup69; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.FieldGroupList51; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.FieldRequiredGroup88; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.RequiredNestedMessage; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.TestEnum; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLiteWithExtensions; -import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLiteWithMaps; -import java.lang.reflect.Field; - -/** A factory that generates a hard-coded info for {@link Proto2MessageLite}. */ -public final class Proto2MessageLiteInfoFactory implements MessageInfoFactory { - private static final Proto2MessageLiteInfoFactory instanceForRawMessageInfo = - new Proto2MessageLiteInfoFactory(true); - private static final Proto2MessageLiteInfoFactory instanceForStructuralMessageInfo = - new Proto2MessageLiteInfoFactory(false); - - public static Proto2MessageLiteInfoFactory getInstanceForRawMessageInfo() { - return instanceForRawMessageInfo; - } - - public static Proto2MessageLiteInfoFactory getInstanceForStructuralMessageInfo() { - return instanceForStructuralMessageInfo; - } - - private final boolean produceRawMessageInfo; - - private Proto2MessageLiteInfoFactory(boolean produceRawMessageInfo) { - this.produceRawMessageInfo = produceRawMessageInfo; - } - - @Override - public boolean isSupported(Class clazz) { - return true; - } - - @Override - public MessageInfo messageInfoFor(Class clazz) { - return produceRawMessageInfo ? rawMessageInfoFor(clazz) : structuralMessageInfoFor(clazz); - } - - private MessageInfo rawMessageInfoFor(Class clazz) { - if (Proto2MessageLite.class.isAssignableFrom(clazz)) { - return newRawMessageInfoForProto2MessageLite(); - } else { - throw new IllegalArgumentException("Unsupported class: " + clazz.getName()); - } - } - - private MessageInfo newRawMessageInfoForProto2MessageLite() { - java.lang.Object[] objects = - new java.lang.Object[] { - "testOneof_", - "testOneofCase_", - "bitField0_", - "bitField1_", - "fieldDouble1_", - "fieldFloat2_", - "fieldInt643_", - "fieldUint644_", - "fieldInt325_", - "fieldFixed646_", - "fieldFixed327_", - "fieldBool8_", - "fieldString9_", - "fieldMessage10_", - "fieldBytes11_", - "fieldUint3212_", - "fieldEnum13_", - Proto2MessageLite.TestEnum.internalGetVerifier(), - "fieldSfixed3214_", - "fieldSfixed6415_", - "fieldSint3216_", - "fieldSint6417_", - "fieldDoubleList18_", - "fieldFloatList19_", - "fieldInt64List20_", - "fieldUint64List21_", - "fieldInt32List22_", - "fieldFixed64List23_", - "fieldFixed32List24_", - "fieldBoolList25_", - "fieldStringList26_", - "fieldMessageList27_", - Proto2MessageLite.class, - "fieldBytesList28_", - "fieldUint32List29_", - "fieldEnumList30_", - Proto2MessageLite.TestEnum.internalGetVerifier(), - "fieldSfixed32List31_", - "fieldSfixed64List32_", - "fieldSint32List33_", - "fieldSint64List34_", - "fieldDoubleListPacked35_", - "fieldFloatListPacked36_", - "fieldInt64ListPacked37_", - "fieldUint64ListPacked38_", - "fieldInt32ListPacked39_", - "fieldFixed64ListPacked40_", - "fieldFixed32ListPacked41_", - "fieldBoolListPacked42_", - "fieldUint32ListPacked43_", - "fieldEnumListPacked44_", - Proto2MessageLite.TestEnum.internalGetVerifier(), - "fieldSfixed32ListPacked45_", - "fieldSfixed64ListPacked46_", - "fieldSint32ListPacked47_", - "fieldSint64ListPacked48_", - "fieldGroup49_", - "fieldGroupList51_", - Proto2MessageLite.FieldGroupList51.class, - Proto2MessageLite.class, - Proto2MessageLite.FieldGroup69.class, - "fieldRequiredDouble71_", - "fieldRequiredFloat72_", - "fieldRequiredInt6473_", - "fieldRequiredUint6474_", - "fieldRequiredInt3275_", - "fieldRequiredFixed6476_", - "fieldRequiredFixed3277_", - "fieldRequiredBool78_", - "fieldRequiredString79_", - "fieldRequiredMessage80_", - "fieldRequiredBytes81_", - "fieldRequiredUint3282_", - "fieldRequiredEnum83_", - Proto2MessageLite.TestEnum.internalGetVerifier(), - "fieldRequiredSfixed3284_", - "fieldRequiredSfixed6485_", - "fieldRequiredSint3286_", - "fieldRequiredSint6487_", - "fieldRequiredGroup88_", - }; - // 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\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); - } - - private MessageInfo structuralMessageInfoFor(Class clazz) { - if (Proto2MessageLite.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2MessageLite(); - } else if (FieldGroup49.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldGroup49(); - } else if (FieldGroupList51.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldGroupList51(); - } else if (FieldGroup69.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldGroup69(); - } else if (FieldRequiredGroup88.class.isAssignableFrom(clazz)) { - return newMessageInfoForFieldRequiredGroup88(); - } else if (RequiredNestedMessage.class.isAssignableFrom(clazz)) { - return newMessageInfoForRequiredNestedMessage(); - } else if (Proto2EmptyLite.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2EmptyLite(); - } else if (Proto2MessageLiteWithExtensions.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2MessageLiteWithExtensions(); - } else if (Proto2TestingLite.FieldGroup49.class.isAssignableFrom(clazz)) { - return newMessageInfoForExtensionFieldGroup49(); - } else if (Proto2TestingLite.FieldGroupList51.class.isAssignableFrom(clazz)) { - return newMessageInfoForExtensionFieldGroupList51(); - } else if (Proto2TestingLite.Proto2MessageLiteWithMaps.class.isAssignableFrom(clazz)) { - return newMessageInfoForProto2MessageLiteWithMaps(); - } else { - throw new IllegalArgumentException("Unsupported class: " + clazz.getName()); - } - } - - /** - * Creates a new hard-coded info for {@link Proto2MessageLite}. Each time this is called, we - * manually go through the entire process of what a message would do if it self-registered its own - * info, including looking up each field by name. This is done for benchmarking purposes, so that - * we get a more accurate representation of the time it takes to perform this process. - */ - private static StructuralMessageInfo newMessageInfoForProto2MessageLite() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(48); - builder.withCheckInitialized( - new int[] { - 10, 27, 62, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - }); - lookupFieldsByName(builder); - return builder.build(); - } - - private static void lookupFieldsByName(StructuralMessageInfo.Builder builder) { - Field bitField0 = field(Proto2MessageLite.class, "bitField0_"); - - builder.withDefaultInstance(Proto2MessageLite.getDefaultInstance()); - builder.withSyntax(ProtoSyntax.PROTO2); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldDouble1_"), - 1, - FieldType.DOUBLE, - bitField0, - 0x00000001, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldFloat2_"), - 2, - FieldType.FLOAT, - bitField0, - 0x00000002, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldInt643_"), - 3, - FieldType.INT64, - bitField0, - 0x00000004, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldUint644_"), - 4, - FieldType.UINT64, - bitField0, - 0x00000008, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldInt325_"), - 5, - FieldType.INT32, - bitField0, - 0x00000010, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldFixed646_"), - 6, - FieldType.FIXED64, - bitField0, - 0x00000020, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldFixed327_"), - 7, - FieldType.FIXED32, - bitField0, - 0x00000040, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldBool8_"), - 8, - FieldType.BOOL, - bitField0, - 0x00000080, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldString9_"), - 9, - FieldType.STRING, - bitField0, - 0x00000100, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldMessage10_"), - 10, - FieldType.MESSAGE, - bitField0, - 0x00000200, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldBytes11_"), - 11, - FieldType.BYTES, - bitField0, - 0x00000400, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldUint3212_"), - 12, - FieldType.UINT32, - bitField0, - 0x00000800, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldEnum13_"), - 13, - FieldType.ENUM, - bitField0, - 0x00001000, - false, - TestEnum.internalGetVerifier())); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldSfixed3214_"), - 14, - FieldType.SFIXED32, - bitField0, - 0x00002000, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldSfixed6415_"), - 15, - FieldType.SFIXED64, - bitField0, - 0x00004000, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldSint3216_"), - 16, - FieldType.SINT32, - bitField0, - 0x00008000, - false, - null)); - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldSint6417_"), - 17, - FieldType.SINT64, - bitField0, - 0x00010000, - false, - null)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldDoubleList18_"), - 18, - FieldType.DOUBLE_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldFloatList19_"), 19, FieldType.FLOAT_LIST, false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldInt64List20_"), 20, FieldType.INT64_LIST, false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldUint64List21_"), - 21, - FieldType.UINT64_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldInt32List22_"), 22, FieldType.INT32_LIST, false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldFixed64List23_"), - 23, - FieldType.FIXED64_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldFixed32List24_"), - 24, - FieldType.FIXED32_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldBoolList25_"), 25, FieldType.BOOL_LIST, false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldStringList26_"), - 26, - FieldType.STRING_LIST, - false)); - builder.withField( - forRepeatedMessageField( - field(Proto2MessageLite.class, "fieldMessageList27_"), - 27, - FieldType.MESSAGE_LIST, - Proto2MessageLite.class)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldBytesList28_"), 28, FieldType.BYTES_LIST, false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldUint32List29_"), - 29, - FieldType.UINT32_LIST, - false)); - builder.withField( - forFieldWithEnumVerifier( - field(Proto2MessageLite.class, "fieldEnumList30_"), - 30, - FieldType.ENUM_LIST, - TestEnum.internalGetVerifier())); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSfixed32List31_"), - 31, - FieldType.SFIXED32_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSfixed64List32_"), - 32, - FieldType.SFIXED64_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSint32List33_"), - 33, - FieldType.SINT32_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSint64List34_"), - 34, - FieldType.SINT64_LIST, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldDoubleListPacked35_"), - 35, - FieldType.DOUBLE_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldFloatListPacked36_"), - 36, - FieldType.FLOAT_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldInt64ListPacked37_"), - 37, - FieldType.INT64_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldUint64ListPacked38_"), - 38, - FieldType.UINT64_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldInt32ListPacked39_"), - 39, - FieldType.INT32_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldFixed64ListPacked40_"), - 40, - FieldType.FIXED64_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldFixed32ListPacked41_"), - 41, - FieldType.FIXED32_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldBoolListPacked42_"), - 42, - FieldType.BOOL_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldUint32ListPacked43_"), - 43, - FieldType.UINT32_LIST_PACKED, - false)); - builder.withField( - forFieldWithEnumVerifier( - field(Proto2MessageLite.class, "fieldEnumListPacked44_"), - 44, - FieldType.ENUM_LIST_PACKED, - TestEnum.internalGetVerifier())); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSfixed32ListPacked45_"), - 45, - FieldType.SFIXED32_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSfixed64ListPacked46_"), - 46, - FieldType.SFIXED64_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSint32ListPacked47_"), - 47, - FieldType.SINT32_LIST_PACKED, - false)); - builder.withField( - forField( - field(Proto2MessageLite.class, "fieldSint64ListPacked48_"), - 48, - FieldType.SINT64_LIST_PACKED, - false)); - - builder.withField( - forProto2OptionalField( - field(Proto2MessageLite.class, "fieldGroup49_"), - 49, - FieldType.GROUP, - bitField0, - 0x00020000, - false, - null)); - builder.withField( - forRepeatedMessageField( - field(Proto2MessageLite.class, "fieldGroupList51_"), - 51, - FieldType.GROUP_LIST, - Proto2MessageLite.FieldGroupList51.class)); - - OneofInfo oneof = - new OneofInfo( - 0, - field(Proto2MessageLite.class, "testOneofCase_"), - field(Proto2MessageLite.class, "testOneof_")); - builder.withField(forOneofMemberField(53, FieldType.DOUBLE, oneof, Double.class, false, null)); - builder.withField(forOneofMemberField(54, FieldType.FLOAT, oneof, Float.class, false, null)); - builder.withField(forOneofMemberField(55, FieldType.INT64, oneof, Long.class, false, null)); - builder.withField(forOneofMemberField(56, FieldType.UINT64, oneof, Long.class, false, null)); - builder.withField(forOneofMemberField(57, FieldType.INT32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(58, FieldType.FIXED64, oneof, Long.class, false, null)); - builder.withField( - forOneofMemberField(59, FieldType.FIXED32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(60, FieldType.BOOL, oneof, Boolean.class, false, null)); - builder.withField(forOneofMemberField(61, FieldType.STRING, oneof, String.class, false, null)); - builder.withField( - forOneofMemberField(62, FieldType.MESSAGE, oneof, Proto2MessageLite.class, false, null)); - builder.withField( - forOneofMemberField(63, FieldType.BYTES, oneof, ByteString.class, false, null)); - builder.withField(forOneofMemberField(64, FieldType.UINT32, oneof, Integer.class, false, null)); - builder.withField( - forOneofMemberField(65, FieldType.SFIXED32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(66, FieldType.SFIXED64, oneof, Long.class, false, null)); - builder.withField(forOneofMemberField(67, FieldType.SINT32, oneof, Integer.class, false, null)); - builder.withField(forOneofMemberField(68, FieldType.SINT64, oneof, Long.class, false, null)); - builder.withField( - forOneofMemberField( - 69, FieldType.GROUP, oneof, Proto2MessageLite.FieldGroup69.class, false, null)); - - Field bitField1 = field(Proto2MessageLite.class, "bitField1_"); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredDouble71_"), - 71, - FieldType.DOUBLE, - bitField1, - 0x00000008, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredFloat72_"), - 72, - FieldType.FLOAT, - bitField1, - 0x00000010, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredInt6473_"), - 73, - FieldType.INT64, - bitField1, - 0x00000020, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredUint6474_"), - 74, - FieldType.UINT64, - bitField1, - 0x00000040, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredInt3275_"), - 75, - FieldType.INT32, - bitField1, - 0x00000080, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredFixed6476_"), - 76, - FieldType.FIXED64, - bitField1, - 0x00000100, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredFixed3277_"), - 77, - FieldType.FIXED32, - bitField1, - 0x00000200, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredBool78_"), - 78, - FieldType.BOOL, - bitField1, - 0x00000400, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredString79_"), - 79, - FieldType.STRING, - bitField1, - 0x00000800, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredMessage80_"), - 80, - FieldType.MESSAGE, - bitField1, - 0x00001000, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredBytes81_"), - 81, - FieldType.BYTES, - bitField1, - 0x00002000, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredUint3282_"), - 82, - FieldType.UINT32, - bitField1, - 0x00004000, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredEnum83_"), - 83, - FieldType.ENUM, - bitField1, - 0x00008000, - false, - TestEnum.internalGetVerifier())); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredSfixed3284_"), - 84, - FieldType.SFIXED32, - bitField1, - 0x00010000, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredSfixed6485_"), - 85, - FieldType.SFIXED64, - bitField1, - 0x00020000, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredSint3286_"), - 86, - FieldType.SINT32, - bitField1, - 0x00040000, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredSint6487_"), - 87, - FieldType.SINT64, - bitField1, - 0x00080000, - false, - null)); - builder.withField( - forProto2RequiredField( - field(Proto2MessageLite.class, "fieldRequiredGroup88_"), - 88, - FieldType.GROUP, - bitField1, - 0x00100000, - false, - null)); - } - - private static StructuralMessageInfo newMessageInfoForFieldGroup49() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldGroup49.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldGroup49.class, "fieldInt3250_"), - 50, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForFieldGroupList51() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldGroup49.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldGroupList51.class, "fieldInt3252_"), - 52, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForFieldGroup69() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldGroup69.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldGroup69.class, "fieldInt3270_"), - 70, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForRequiredNestedMessage() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(RequiredNestedMessage.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(RequiredNestedMessage.class, "value_"), - 1, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForFieldRequiredGroup88() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(FieldRequiredGroup88.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(FieldRequiredGroup88.class, "fieldInt3289_"), - 89, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForProto2EmptyLite() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForProto2MessageLiteWithExtensions() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(0); - builder.withSyntax(ProtoSyntax.PROTO2); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForExtensionFieldGroup49() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(Proto2TestingLite.FieldGroup49.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(Proto2TestingLite.FieldGroup49.class, "fieldInt3250_"), - 50, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - private static StructuralMessageInfo newMessageInfoForExtensionFieldGroupList51() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1); - builder.withSyntax(ProtoSyntax.PROTO2); - Field bitField0 = field(Proto2TestingLite.FieldGroup49.class, "bitField0_"); - builder.withField( - forProto2OptionalField( - field(Proto2TestingLite.FieldGroupList51.class, "fieldInt3252_"), - 52, - FieldType.INT32, - bitField0, - 0x00000001, - false, - null)); - return builder.build(); - } - - - private static StructuralMessageInfo newMessageInfoForProto2MessageLiteWithMaps() { - StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(); - builder.withCheckInitialized( - new int[] { - 10, 27, 44, 61, 78, 95, 112, 129, 146, 163, 180, 197, - }); - builder.withSyntax(ProtoSyntax.PROTO2); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_bool_1", 1)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_bytes_2", 2)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_double_3", 3)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_enum_4", 4)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_fixed32_5", 5)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_fixed64_6", 6)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_float_7", 7)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_int32_8", 8)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_int64_9", 9)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_message_10", 10)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_sfixed32_11", 11)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_sfixed64_12", 12)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_sint32_13", 13)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_sint64_14", 14)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_string_15", 15)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_uint32_16", 16)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_bool_uint64_17", 17)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_bool_18", 18)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_bytes_19", 19)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_double_20", 20)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_enum_21", 21)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_fixed32_22", 22)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_fixed64_23", 23)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_float_24", 24)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_int32_25", 25)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_int64_26", 26)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_message_27", 27)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_sfixed32_28", 28)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_sfixed64_29", 29)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_sint32_30", 30)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_sint64_31", 31)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_string_32", 32)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_uint32_33", 33)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed32_uint64_34", 34)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_bool_35", 35)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_bytes_36", 36)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_double_37", 37)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_enum_38", 38)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_fixed32_39", 39)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_fixed64_40", 40)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_float_41", 41)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_int32_42", 42)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_int64_43", 43)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_message_44", 44)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_sfixed32_45", 45)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_sfixed64_46", 46)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_sint32_47", 47)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_sint64_48", 48)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_string_49", 49)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_uint32_50", 50)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_fixed64_uint64_51", 51)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_bool_52", 52)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_bytes_53", 53)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_double_54", 54)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_enum_55", 55)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_fixed32_56", 56)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_fixed64_57", 57)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_float_58", 58)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_int32_59", 59)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_int64_60", 60)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_message_61", 61)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_sfixed32_62", 62)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_sfixed64_63", 63)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_sint32_64", 64)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_sint64_65", 65)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_string_66", 66)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_uint32_67", 67)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int32_uint64_68", 68)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_bool_69", 69)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_bytes_70", 70)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_double_71", 71)); - builder.withField(mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_enum_72", 72)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_fixed32_73", 73)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_fixed64_74", 74)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_float_75", 75)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_int32_76", 76)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_int64_77", 77)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_message_78", 78)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_sfixed32_79", 79)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_sfixed64_80", 80)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_sint32_81", 81)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_sint64_82", 82)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_string_83", 83)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_uint32_84", 84)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_int64_uint64_85", 85)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_bool_86", 86)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_bytes_87", 87)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_double_88", 88)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_enum_89", 89)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_fixed32_90", 90)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_fixed64_91", 91)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_float_92", 92)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_int32_93", 93)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_int64_94", 94)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_message_95", 95)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_sfixed32_96", 96)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_sfixed64_97", 97)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_sint32_98", 98)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_sint64_99", 99)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_string_100", 100)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_uint32_101", 101)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed32_uint64_102", 102)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_bool_103", 103)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_bytes_104", 104)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_double_105", 105)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_enum_106", 106)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_fixed32_107", 107)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_fixed64_108", 108)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_float_109", 109)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_int32_110", 110)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_int64_111", 111)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_message_112", 112)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_sfixed32_113", 113)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_sfixed64_114", 114)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_sint32_115", 115)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_sint64_116", 116)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_string_117", 117)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_uint32_118", 118)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sfixed64_uint64_119", 119)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_bool_120", 120)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_bytes_121", 121)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_double_122", 122)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_enum_123", 123)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_fixed32_124", 124)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_fixed64_125", 125)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_float_126", 126)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_int32_127", 127)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_int64_128", 128)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_message_129", 129)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_sfixed32_130", 130)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_sfixed64_131", 131)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_sint32_132", 132)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_sint64_133", 133)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_string_134", 134)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_uint32_135", 135)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint32_uint64_136", 136)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_bool_137", 137)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_bytes_138", 138)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_double_139", 139)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_enum_140", 140)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_fixed32_141", 141)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_fixed64_142", 142)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_float_143", 143)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_int32_144", 144)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_int64_145", 145)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_message_146", 146)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_sfixed32_147", 147)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_sfixed64_148", 148)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_sint32_149", 149)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_sint64_150", 150)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_string_151", 151)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_uint32_152", 152)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_sint64_uint64_153", 153)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_bool_154", 154)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_bytes_155", 155)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_double_156", 156)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_enum_157", 157)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_fixed32_158", 158)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_fixed64_159", 159)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_float_160", 160)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_int32_161", 161)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_int64_162", 162)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_message_163", 163)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_sfixed32_164", 164)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_sfixed64_165", 165)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_sint32_166", 166)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_sint64_167", 167)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_string_168", 168)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_uint32_169", 169)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_string_uint64_170", 170)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_bool_171", 171)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_bytes_172", 172)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_double_173", 173)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_enum_174", 174)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_fixed32_175", 175)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_fixed64_176", 176)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_float_177", 177)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_int32_178", 178)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_int64_179", 179)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_message_180", 180)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_sfixed32_181", 181)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_sfixed64_182", 182)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_sint32_183", 183)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_sint64_184", 184)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_string_185", 185)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_uint32_186", 186)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint32_uint64_187", 187)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_bool_188", 188)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_bytes_189", 189)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_double_190", 190)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_enum_191", 191)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_fixed32_192", 192)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_fixed64_193", 193)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_float_194", 194)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_int32_195", 195)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_int64_196", 196)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_message_197", 197)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_sfixed32_198", 198)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_sfixed64_199", 199)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_sint32_200", 200)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_sint64_201", 201)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_string_202", 202)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_uint32_203", 203)); - builder.withField( - mapFieldInfo(Proto2MessageLiteWithMaps.class, "field_map_uint64_uint64_204", 204)); - - return builder.build(); - } - - private static Field field(Class clazz, String name) { - try { - return clazz.getDeclaredField(name); - } catch (NoSuchFieldException | SecurityException e) { - throw new RuntimeException(e); - } - } - - private static FieldInfo mapFieldInfo(Class clazz, String fieldName, int fieldNumber) { - try { - return forMapField( - field(clazz, SchemaUtil.toCamelCase(fieldName, false) + "_"), - fieldNumber, - SchemaUtil.getMapDefaultEntry(clazz, fieldName), - fieldName.contains("_enum_") ? TestEnum.internalGetVerifier() : null); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } -} diff --git a/java/pom.xml b/java/pom.xml index 9864f73cc3433..e1025976c1b16 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.18.1 + 3.19.4 pom Protocol Buffers [Parent] @@ -41,7 +41,7 @@ - 3-Clause BSD License + BSD-3-Clause https://opensource.org/licenses/BSD-3-Clause repo @@ -158,31 +158,45 @@ maven-antrun-plugin - 1.8 + 3.0.0 + + + maven-surefire-plugin + 3.0.0-M5 org.codehaus.mojo animal-sniffer-maven-plugin 1.20 - - - net.sf.androidscents.signature - android-api-level-14 - 4.0_r4 - - - - - android - test - - check - - - + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + net.sf.androidscents.signature + android-api-level-14 + 4.0_r4 + + + sun.misc.Unsafe + + + + + android + test + + check + + + + + diff --git a/java/util/BUILD b/java/util/BUILD index 02e55496897f0..2714917e41553 100644 --- a/java/util/BUILD +++ b/java/util/BUILD @@ -11,32 +11,33 @@ java_library( ]), visibility = ["//visibility:public"], deps = [ - "//external:error_prone_annotations", - "//external:j2objc_annotations", - "//external:gson", - "//external:guava", "//java/core", - "//java/lite", + "@maven//:com_google_code_findbugs_jsr305", + "@maven//:com_google_code_gson_gson", + "@maven//:com_google_errorprone_error_prone_annotations", + "@maven//:com_google_guava_guava", + "@maven//:com_google_j2objc_j2objc_annotations", ], ) + # Bazel users, don't depend on this target, use :util. java_export( name = "util_mvn", maven_coordinates = "com.google.protobuf:protobuf-java-util:%s" % PROTOBUF_VERSION, pom_template = "pom_template.xml", - runtime_deps = [":util"], visibility = ["//java:__pkg__"], + runtime_deps = [":util"], ) filegroup( name = "release", - visibility = ["//java:__pkg__"], srcs = [ - ":util_mvn-pom", - ":util_mvn-maven-source", ":util_mvn-docs", + ":util_mvn-maven-source", + ":util_mvn-pom", ":util_mvn-project", - ] + ], + visibility = ["//java:__pkg__"], ) proto_library( @@ -59,15 +60,15 @@ java_proto_library( junit_tests( name = "tests", - srcs = glob(["src/test/java/**/*.java"]), package_name = "com.google.protobuf.util", + srcs = glob(["src/test/java/**/*.java"]), deps = [ ":test_protos_java_proto", ":util", - "//external:guava", - "//external:junit", - "//external:truth", "//java/core", "//java/core:generic_test_protos_java_proto", + "@maven//:com_google_guava_guava", + "@maven//:com_google_truth_truth", + "@maven//:junit_junit", ], ) diff --git a/java/util/pom.xml b/java/util/pom.xml index 31ccf5d567a1c..27c82be64bf76 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.18.1 + 3.19.4 protobuf-java-util @@ -32,6 +32,11 @@ j2objc-annotations 1.3 + + com.google.code.findbugs + jsr305 + 3.0.2 + com.google.guava guava-testlib @@ -40,7 +45,7 @@ com.google.code.gson gson - 2.8.6 + 2.8.9 junit @@ -112,7 +117,27 @@ - + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + net.sf.androidscents.signature + android-api-level-19 + 4.4.2_r4 + + + + + android + test + + check + + + + org.apache.felix 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 f81da1faede67..1495f09702c10 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 @@ -238,13 +238,13 @@ public static String toString(Duration duration) { } /** - * Parse from a string to produce a duration. + * Parse a string to produce a duration. * - * @return A Duration parsed from the string. - * @throws ParseException if parsing fails. + * @return a Duration parsed from the string + * @throws ParseException if the string is not in the duration format */ public static Duration parse(String value) throws ParseException { - // Must ended with "s". + // Must end with "s". if (value.isEmpty() || value.charAt(value.length() - 1) != 's') { throw new ParseException("Invalid duration string: " + value, 0); } @@ -272,7 +272,9 @@ public static Duration parse(String value) throws ParseException { try { return normalizedDuration(seconds, nanos); } catch (IllegalArgumentException e) { - throw new ParseException("Duration value is out of range.", 0); + ParseException ex = new ParseException("Duration value is out of range.", 0); + ex.initCause(e); + throw ex; } } 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 352376e015093..854c8264860df 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 @@ -44,10 +44,11 @@ import java.util.logging.Logger; /** - * A tree representation of a FieldMask. Each leaf node in this tree represent - * a field path in the FieldMask. + * A tree representation of a FieldMask. Each leaf node in this tree represent a field path in the + * FieldMask. * *

For example, FieldMask "foo.bar,foo.baz,bar.baz" as a tree will be: + * *

  *   [root] -+- foo -+- bar
  *           |       |
@@ -56,10 +57,9 @@
  *           +- bar --- baz
  * 
* - *

By representing FieldMasks with this tree structure we can easily convert - * a FieldMask to a canonical form, merge two FieldMasks, calculate the - * intersection to two FieldMasks and traverse all fields specified by the - * FieldMask in a message tree. + *

By representing FieldMasks with this tree structure we can easily convert a FieldMask to a + * canonical form, merge two FieldMasks, calculate the intersection to two FieldMasks and traverse + * all fields specified by the FieldMask in a message tree. */ final class FieldMaskTree { private static final Logger logger = Logger.getLogger(FieldMaskTree.class.getName()); @@ -72,14 +72,10 @@ private static final class Node { private final Node root = new Node(); - /** - * Creates an empty FieldMaskTree. - */ + /** Creates an empty FieldMaskTree. */ FieldMaskTree() {} - /** - * Creates a FieldMaskTree for a given FieldMask. - */ + /** Creates a FieldMaskTree for a given FieldMask. */ FieldMaskTree(FieldMask mask) { mergeFromFieldMask(mask); } @@ -143,11 +139,10 @@ FieldMaskTree mergeFromFieldMask(FieldMask mask) { * 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. + *
  • If all children of a node have 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. + * 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. * */ @@ -195,9 +190,7 @@ FieldMaskTree removeFromFieldMask(FieldMask mask) { return this; } - /** - * Converts this tree to a FieldMask. - */ + /** Converts this tree to a FieldMask. */ FieldMask toFieldMask() { if (root.children.isEmpty()) { return FieldMask.getDefaultInstance(); @@ -219,9 +212,7 @@ private static void getFieldPaths(Node node, String path, List paths) { } } - /** - * Adds the intersection of this tree with the given {@code path} to {@code output}. - */ + /** Adds the intersection of this tree with the given {@code path} to {@code output}. */ void intersectFieldPath(String path, FieldMaskTree output) { if (root.children.isEmpty()) { return; @@ -262,21 +253,18 @@ void merge(Message source, Message.Builder destination, FieldMaskUtil.MergeOptio if (root.children.isEmpty()) { return; } - merge(root, "", source, destination, options); + merge(root, source, destination, options); } /** Merges all fields specified by a sub-tree from {@code source} to {@code destination}. */ private static void merge( - Node node, - String path, - Message source, - Message.Builder destination, - FieldMaskUtil.MergeOptions options) { + Node node, Message source, Message.Builder destination, FieldMaskUtil.MergeOptions options) { if (source.getDescriptorForType() != destination.getDescriptorForType()) { throw new IllegalArgumentException( String.format( "source (%s) and destination (%s) descriptor must be equal", - source.getDescriptorForType(), destination.getDescriptorForType())); + source.getDescriptorForType().getFullName(), + destination.getDescriptorForType().getFullName())); } Descriptor descriptor = source.getDescriptorForType(); @@ -304,9 +292,8 @@ private static void merge( // so we don't create unnecessary empty messages. continue; } - String childPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey(); Message.Builder childBuilder = ((Message) destination.getField(field)).toBuilder(); - merge(entry.getValue(), childPath, (Message) source.getField(field), childBuilder, options); + merge(entry.getValue(), (Message) source.getField(field), childBuilder, options); destination.setField(field, childBuilder.buildPartial()); continue; } @@ -331,9 +318,7 @@ private static void merge( destination.setField( field, ((Message) destination.getField(field)) - .toBuilder() - .mergeFrom((Message) source.getField(field)) - .build()); + .toBuilder().mergeFrom((Message) source.getField(field)).build()); } } } else { 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 ddfbc9ed900e1..31a4a0a0ce1a3 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 @@ -91,13 +91,12 @@ import javax.annotation.Nullable; /** - * Utility classes to convert protobuf messages to/from JSON format. The JSON - * format follows Proto3 JSON specification and only proto3 features are - * supported. Proto2 only features (e.g., extensions and unknown fields) will - * be discarded in the conversion. That is, when converting proto2 messages - * to JSON format, extensions and unknown fields will be treated as if they - * do not exist. This applies to proto2 messages embedded in proto3 messages - * as well. + * Utility class to convert protobuf messages to/from the Proto3 JSON format. + * Only proto3 features are supported. Proto2 only features such as extensions and unknown fields + * are discarded in the conversion. That is, when converting proto2 messages to JSON format, + * extensions and unknown fields are treated as if they do not exist. This applies to proto2 + * messages embedded in proto3 messages as well. */ public class JsonFormat { private static final Logger logger = Logger.getLogger(JsonFormat.class.getName()); @@ -120,7 +119,7 @@ public static Printer printer() { } /** - * A Printer converts protobuf message to JSON format. + * A Printer converts a protobuf message to the proto3 JSON format. */ public static class Printer { private final com.google.protobuf.TypeRegistry registry; @@ -163,7 +162,7 @@ private Printer( * Creates a new {@link Printer} using the given registry. The new Printer clones all other * configurations from the current {@link Printer}. * - * @throws IllegalArgumentException if a registry is already set. + * @throws IllegalArgumentException if a registry is already set */ public Printer usingTypeRegistry(TypeRegistry oldRegistry) { if (this.oldRegistry != TypeRegistry.getEmptyTypeRegistry() @@ -185,7 +184,7 @@ public Printer usingTypeRegistry(TypeRegistry oldRegistry) { * Creates a new {@link Printer} using the given registry. The new Printer clones all other * configurations from the current {@link Printer}. * - * @throws IllegalArgumentException if a registry is already set. + * @throws IllegalArgumentException if a registry is already set */ public Printer usingTypeRegistry(com.google.protobuf.TypeRegistry registry) { if (this.oldRegistry != TypeRegistry.getEmptyTypeRegistry() @@ -223,10 +222,8 @@ public Printer includingDefaultValueFields() { } /** - * Creates a new {@link Printer} that will print enum field values as integers instead of as - * string. - * The new Printer clones all other configurations from the current - * {@link Printer}. + * Creates a new {@link Printer} that prints enum field values as integers instead of as + * string. The new Printer clones all other configurations from the current {@link Printer}. */ public Printer printingEnumsAsInts() { checkUnsetPrintingEnumsAsInts(); @@ -329,7 +326,7 @@ 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 + *

    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. * @@ -350,11 +347,11 @@ public Printer sortingMapKeys() { } /** - * Converts a protobuf message to JSON format. + * Converts a protobuf message to the proto3 JSON format. * * @throws InvalidProtocolBufferException if the message contains Any types that can't be - * resolved. - * @throws IOException if writing to the output fails. + * resolved + * @throws IOException if writing to the output fails */ public void appendTo(MessageOrBuilder message, Appendable output) throws IOException { // TODO(xiaofeng): Investigate the allocation overhead and optimize for @@ -373,7 +370,7 @@ public void appendTo(MessageOrBuilder message, Appendable output) throws IOExcep } /** - * Converts a protobuf message to JSON format. Throws exceptions if there + * Converts a protobuf message to the proto3 JSON format. Throws exceptions if there * are unknown Any types in the message. */ public String print(MessageOrBuilder message) throws InvalidProtocolBufferException { @@ -402,7 +399,7 @@ public static Parser parser() { } /** - * A Parser parses JSON to protobuf message. + * A Parser parses the proto3 JSON format into a protobuf message. */ public static class Parser { private final com.google.protobuf.TypeRegistry registry; @@ -428,7 +425,7 @@ private Parser( * Creates a new {@link Parser} using the given registry. The new Parser clones all other * configurations from this Parser. * - * @throws IllegalArgumentException if a registry is already set. + * @throws IllegalArgumentException if a registry is already set */ public Parser usingTypeRegistry(TypeRegistry oldRegistry) { if (this.oldRegistry != TypeRegistry.getEmptyTypeRegistry() @@ -446,7 +443,7 @@ public Parser usingTypeRegistry(TypeRegistry oldRegistry) { * Creates a new {@link Parser} using the given registry. The new Parser clones all other * configurations from this Parser. * - * @throws IllegalArgumentException if a registry is already set. + * @throws IllegalArgumentException if a registry is already set */ public Parser usingTypeRegistry(com.google.protobuf.TypeRegistry registry) { if (this.oldRegistry != TypeRegistry.getEmptyTypeRegistry() @@ -465,10 +462,10 @@ public Parser ignoringUnknownFields() { } /** - * Parses from JSON into a protobuf message. + * Parses from the proto3 JSON format into a protobuf message. * * @throws InvalidProtocolBufferException if the input is not valid JSON - * format or there are unknown fields in the input. + * proto3 format or there are unknown fields in the input. */ public void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException { // TODO(xiaofeng): Investigate the allocation overhead and optimize for @@ -478,11 +475,11 @@ public void merge(String json, Message.Builder builder) throws InvalidProtocolBu } /** - * Parses from JSON into a protobuf message. + * Parses from the proto3 JSON encoding into a protobuf message. * - * @throws InvalidProtocolBufferException if the input is not valid JSON - * format or there are unknown fields in the input. - * @throws IOException if reading from the input throws. + * @throws InvalidProtocolBufferException if the input is not valid proto3 JSON + * format or there are unknown fields in the input + * @throws IOException if reading from the input throws */ public void merge(Reader json, Message.Builder builder) throws IOException { // TODO(xiaofeng): Investigate the allocation overhead and optimize for @@ -606,15 +603,15 @@ private void addMessage(Descriptor message) { types.put(message.getFullName(), message); } - private final Set files = new HashSet(); - private Map types = new HashMap(); + private final Set files = new HashSet<>(); + private final Map types = new HashMap<>(); private boolean built = false; } } /** - * An interface for json formatting that can be used in - * combination with the omittingInsignificantWhitespace() method + * An interface for JSON formatting that can be used in + * combination with the omittingInsignificantWhitespace() method. */ interface TextGenerator { void indent(); @@ -625,7 +622,7 @@ interface TextGenerator { } /** - * Format the json without indentation + * Format the JSON without indentation */ private static final class CompactTextGenerator implements TextGenerator { private final Appendable output; @@ -709,7 +706,7 @@ private void write(final CharSequence data) throws IOException { } /** - * A Printer converts protobuf messages to JSON format. + * A Printer converts protobuf messages to the proto3 JSON format. */ private static final class PrinterImpl { private final com.google.protobuf.TypeRegistry registry; @@ -1068,7 +1065,6 @@ private void printRepeatedFieldValue(FieldDescriptor field, Object value) throws generator.print("]"); } - @SuppressWarnings("rawtypes") private void printMapFieldValue(FieldDescriptor field, Object value) throws IOException { Descriptor type = field.getMessageType(); FieldDescriptor keyField = type.findFieldByName("key"); @@ -1093,7 +1089,7 @@ public int compare(final Object o1, final Object o2) { } }; } - TreeMap tm = new TreeMap(cmp); + TreeMap tm = new TreeMap<>(cmp); for (Object element : elements) { Message entry = (Message) element; Object entryKey = entry.getField(keyField); @@ -1129,10 +1125,10 @@ private void printSingleFieldValue(FieldDescriptor field, Object value) throws I } /** - * Prints a field's value in JSON format. + * Prints a field's value in the proto3 JSON format. * * @param alwaysWithQuotes whether to always add double-quotes to primitive - * types. + * types */ private void printSingleFieldValue( final FieldDescriptor field, final Object value, boolean alwaysWithQuotes) @@ -1318,8 +1314,6 @@ void merge(Reader json, Message.Builder builder) throws IOException { JsonReader reader = new JsonReader(json); reader.setLenient(false); merge(JsonParser.parseReader(reader), builder); - } catch (InvalidProtocolBufferException e) { - throw e; } catch (JsonIOException e) { // Unwrap IOException. if (e.getCause() instanceof IOException) { @@ -1327,7 +1321,7 @@ void merge(Reader json, Message.Builder builder) throws IOException { } else { throw new InvalidProtocolBufferException(e.getMessage()); } - } catch (Exception e) { + } catch (RuntimeException e) { // We convert all exceptions from JSON parsing to our own exceptions. throw new InvalidProtocolBufferException(e.getMessage()); } @@ -1338,9 +1332,7 @@ void merge(String json, Message.Builder builder) throws InvalidProtocolBufferExc JsonReader reader = new JsonReader(new StringReader(json)); reader.setLenient(false); merge(JsonParser.parseReader(reader), builder); - } catch (InvalidProtocolBufferException e) { - throw e; - } catch (Exception e) { + } catch (RuntimeException e) { // We convert all exceptions from JSON parsing to our own exceptions. InvalidProtocolBufferException toThrow = new InvalidProtocolBufferException(e.getMessage()); toThrow.initCause(e); @@ -1563,7 +1555,10 @@ private void mergeTimestamp(JsonElement json, Message.Builder builder) Timestamp value = Timestamps.parse(json.getAsString()); builder.mergeFrom(value.toByteString()); } catch (ParseException | UnsupportedOperationException e) { - throw new InvalidProtocolBufferException("Failed to parse timestamp: " + json); + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Failed to parse timestamp: " + json); + ex.initCause(e); + throw ex; } } @@ -1573,7 +1568,10 @@ private void mergeDuration(JsonElement json, Message.Builder builder) Duration value = Durations.parse(json.getAsString()); builder.mergeFrom(value.toByteString()); } catch (ParseException | UnsupportedOperationException e) { - throw new InvalidProtocolBufferException("Failed to parse duration: " + json); + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Failed to parse duration: " + json); + ex.initCause(e); + throw ex; } } @@ -1741,7 +1739,7 @@ private void mergeRepeatedField( private int parseInt32(JsonElement json) throws InvalidProtocolBufferException { try { return Integer.parseInt(json.getAsString()); - } catch (Exception e) { + } catch (RuntimeException e) { // Fall through. } // JSON doesn't distinguish between integer values and floating point values so "1" and @@ -1750,15 +1748,18 @@ private int parseInt32(JsonElement json) throws InvalidProtocolBufferException { try { BigDecimal value = new BigDecimal(json.getAsString()); return value.intValueExact(); - } catch (Exception e) { - throw new InvalidProtocolBufferException("Not an int32 value: " + json); + } catch (RuntimeException e) { + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Not an int32 value: " + json); + ex.initCause(e); + throw ex; } } private long parseInt64(JsonElement json) throws InvalidProtocolBufferException { try { return Long.parseLong(json.getAsString()); - } catch (Exception e) { + } catch (RuntimeException e) { // Fall through. } // JSON doesn't distinguish between integer values and floating point values so "1" and @@ -1767,8 +1768,11 @@ private long parseInt64(JsonElement json) throws InvalidProtocolBufferException try { BigDecimal value = new BigDecimal(json.getAsString()); return value.longValueExact(); - } catch (Exception e) { - throw new InvalidProtocolBufferException("Not an int64 value: " + json); + } catch (RuntimeException e) { + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Not an int64 value: " + json); + ex.initCause(e); + throw ex; } } @@ -1779,9 +1783,7 @@ private int parseUint32(JsonElement json) throws InvalidProtocolBufferException throw new InvalidProtocolBufferException("Out of range uint32 value: " + json); } return (int) result; - } catch (InvalidProtocolBufferException e) { - throw e; - } catch (Exception e) { + } catch (RuntimeException e) { // Fall through. } // JSON doesn't distinguish between integer values and floating point values so "1" and @@ -1794,10 +1796,11 @@ private int parseUint32(JsonElement json) throws InvalidProtocolBufferException throw new InvalidProtocolBufferException("Out of range uint32 value: " + json); } return value.intValue(); - } catch (InvalidProtocolBufferException e) { - throw e; - } catch (Exception e) { - throw new InvalidProtocolBufferException("Not an uint32 value: " + json); + } catch (RuntimeException e) { + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Not an uint32 value: " + json); + ex.initCause(e); + throw ex; } } @@ -1811,10 +1814,11 @@ private long parseUint64(JsonElement json) throws InvalidProtocolBufferException throw new InvalidProtocolBufferException("Out of range uint64 value: " + json); } return value.longValue(); - } catch (InvalidProtocolBufferException e) { - throw e; - } catch (Exception e) { - throw new InvalidProtocolBufferException("Not an uint64 value: " + json); + } catch (RuntimeException e) { + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Not an uint64 value: " + json); + ex.initCause(e); + throw ex; } } @@ -1851,10 +1855,11 @@ private float parseFloat(JsonElement json) throws InvalidProtocolBufferException throw new InvalidProtocolBufferException("Out of range float value: " + json); } return (float) value; - } catch (InvalidProtocolBufferException e) { + } catch (RuntimeException e) { + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Not a float value: " + json); + ex.initCause(e); throw e; - } catch (Exception e) { - throw new InvalidProtocolBufferException("Not a float value: " + json); } } @@ -1884,10 +1889,11 @@ private double parseDouble(JsonElement json) throws InvalidProtocolBufferExcepti throw new InvalidProtocolBufferException("Out of range double value: " + json); } return value.doubleValue(); - } catch (InvalidProtocolBufferException e) { - throw e; - } catch (Exception e) { - throw new InvalidProtocolBufferException("Not an double value: " + json); + } catch (RuntimeException e) { + InvalidProtocolBufferException ex = new InvalidProtocolBufferException( + "Not a double value: " + json); + ex.initCause(e); + throw ex; } } @@ -1923,6 +1929,8 @@ private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement // an exception later. } + // todo(elharo): if we are ignoring unknown fields, shouldn't we still + // throw InvalidProtocolBufferException for a non-numeric value here? if (result == null && !ignoringUnknownFields) { throw new InvalidProtocolBufferException( "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName()); 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 c9276a0c7075a..95f3665fab193 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 @@ -62,11 +62,11 @@ public final class Timestamps { // Timestamp for "9999-12-31T23:59:59Z" static final long TIMESTAMP_SECONDS_MAX = 253402300799L; - static final long NANOS_PER_SECOND = 1000000000; - static final long NANOS_PER_MILLISECOND = 1000000; - static final long NANOS_PER_MICROSECOND = 1000; - static final long MILLIS_PER_SECOND = 1000; - static final long MICROS_PER_SECOND = 1000000; + static final int NANOS_PER_SECOND = 1000000000; + static final int NANOS_PER_MILLISECOND = 1000000; + static final int NANOS_PER_MICROSECOND = 1000; + static final int MILLIS_PER_SECOND = 1000; + static final int MICROS_PER_SECOND = 1000000; /** A constant holding the minimum valid {@link Timestamp}, {@code 0001-01-01T00:00:00Z}. */ public static final Timestamp MIN_VALUE = @@ -230,8 +230,8 @@ public static String toString(Timestamp timestamp) { * *

    Example of accepted format: "1972-01-01T10:00:20.021-05:00" * - * @return A Timestamp parsed from the string. - * @throws ParseException if parsing fails. + * @return a Timestamp parsed from the string + * @throws ParseException if parsing fails */ public static Timestamp parse(String value) throws ParseException { int dayOffset = value.indexOf('T'); @@ -281,7 +281,10 @@ public static Timestamp parse(String value) throws ParseException { try { return normalizedTimestamp(seconds, nanos); } catch (IllegalArgumentException e) { - throw new ParseException("Failed to parse timestamp: timestamp is out of range.", 0); + ParseException ex = new ParseException( + "Failed to parse timestamp " + value + " Timestamp is out of range.", 0); + ex.initCause(e); + throw ex; } } @@ -353,7 +356,7 @@ public static Timestamp fromDate(Date date) { /** * Convert a Timestamp to the number of milliseconds elapsed from the epoch. * - *

    The result will be rounded down to the nearest millisecond. E.g., if the timestamp + *

    The result will be rounded down to the nearest millisecond. For instance, if the timestamp * represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 millisecond. */ @SuppressWarnings("GoodTime") // this is a legacy conversion API diff --git a/java/util/src/test/java/com/google/protobuf/util/DurationsTest.java b/java/util/src/test/java/com/google/protobuf/util/DurationsTest.java new file mode 100644 index 0000000000000..ffcd4dcc63efa --- /dev/null +++ b/java/util/src/test/java/com/google/protobuf/util/DurationsTest.java @@ -0,0 +1,631 @@ +// 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. + +package com.google.protobuf.util; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static com.google.protobuf.util.Durations.toSecondsAsDouble; +import static org.junit.Assert.fail; + +import com.google.common.collect.Lists; +import com.google.protobuf.Duration; +import com.google.protobuf.Timestamp; +import java.text.ParseException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Durations}. */ +@RunWith(JUnit4.class) +public class DurationsTest { + + private static final Duration INVALID_MAX = + Duration.newBuilder().setSeconds(Long.MAX_VALUE).setNanos(Integer.MAX_VALUE).build(); + private static final Duration INVALID_MIN = + Duration.newBuilder().setSeconds(Long.MIN_VALUE).setNanos(Integer.MIN_VALUE).build(); + + @Test + public void testIsPositive() { + assertThat(Durations.isPositive(Durations.ZERO)).isFalse(); + assertThat(Durations.isPositive(Durations.fromNanos(-1))).isFalse(); + assertThat(Durations.isPositive(Durations.fromNanos(1))).isTrue(); + } + + @Test + public void testIsNegative() { + assertThat(Durations.isNegative(Durations.ZERO)).isFalse(); + assertThat(Durations.isNegative(Durations.fromNanos(1))).isFalse(); + assertThat(Durations.isNegative(Durations.fromNanos(-1))).isTrue(); + } + + @Test + public void testCheckNotNegative() { + Durations.checkNotNegative(Durations.ZERO); + Durations.checkNotNegative(Durations.fromNanos(1)); + Durations.checkNotNegative(Durations.fromSeconds(1)); + + try { + Durations.checkNotNegative(Durations.fromNanos(-1)); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo( + "duration (-0.000000001s) must not be negative"); + } + try { + Durations.checkNotNegative(Durations.fromSeconds(-1)); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("duration (-1s) must not be negative"); + } + } + + @Test + public void testCheckPositive() { + Durations.checkPositive(Durations.fromNanos(1)); + Durations.checkPositive(Durations.fromSeconds(1)); + + try { + Durations.checkPositive(Durations.ZERO); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("duration (0s) must be positive"); + } + + try { + Durations.checkPositive(Durations.fromNanos(-1)); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("duration (-0.000000001s) must be positive"); + } + + try { + Durations.checkPositive(Durations.fromSeconds(-1)); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("duration (-1s) must be positive"); + } + } + + @Test + public void testToSecondsAsDouble() { + assertThat(toSecondsAsDouble(duration(0, 1))).isEqualTo(1.0e-9); + assertThat(toSecondsAsDouble(Durations.fromMillis(999))).isEqualTo(0.999); + assertThat(toSecondsAsDouble(duration(1, 0))).isEqualTo(1.0); + assertWithMessage("Precision loss detected") + .that(toSecondsAsDouble(Durations.fromNanos(1234567890987654321L))) + .isWithin(1.0e-6) + .of(1234567890.9876544); + } + + @Test + public void testRoundtripConversions() { + for (long value : Arrays.asList(-123456, -42, -1, 0, 1, 42, 123456)) { + assertThat(Durations.toDays(Durations.fromDays(value))).isEqualTo(value); + assertThat(Durations.toHours(Durations.fromHours(value))).isEqualTo(value); + assertThat(Durations.toMinutes(Durations.fromMinutes(value))).isEqualTo(value); + assertThat(Durations.toSeconds(Durations.fromSeconds(value))).isEqualTo(value); + assertThat(Durations.toMillis(Durations.fromMillis(value))).isEqualTo(value); + assertThat(Durations.toMicros(Durations.fromMicros(value))).isEqualTo(value); + assertThat(Durations.toNanos(Durations.fromNanos(value))).isEqualTo(value); + } + } + + @Test + public void testStaticFactories() { + Duration[] durations = { + Durations.fromDays(1), + Durations.fromHours(24), + Durations.fromMinutes(1440), + Durations.fromSeconds(86_400L), + Durations.fromMillis(86_400_000L), + Durations.fromMicros(86_400_000_000L), + Durations.fromNanos(86_400_000_000_000L) + }; + + for (Duration d1 : durations) { + assertThat(d1).isNotEqualTo(null); + for (Duration d2 : durations) { + assertThat(d1).isEqualTo(d2); + } + } + } + + @Test + public void testMinMaxAreValid() { + assertThat(Durations.isValid(Durations.MAX_VALUE)).isTrue(); + assertThat(Durations.isValid(Durations.MIN_VALUE)).isTrue(); + } + + @Test + public void testIsValid_false() { + assertThat(Durations.isValid(-315576000001L, 0)).isFalse(); + assertThat(Durations.isValid(315576000001L, 0)).isFalse(); + assertThat(Durations.isValid(42L, -42)).isFalse(); + assertThat(Durations.isValid(-42L, 42)).isFalse(); + } + + @Test + public void testIsValid_true() { + assertThat(Durations.isValid(0L, 42)).isTrue(); + assertThat(Durations.isValid(0L, -42)).isTrue(); + assertThat(Durations.isValid(42L, 0)).isTrue(); + assertThat(Durations.isValid(42L, 42)).isTrue(); + assertThat(Durations.isValid(-315576000000L, 0)).isTrue(); + assertThat(Durations.isValid(315576000000L, 0)).isTrue(); + } + + @Test + public void testParse_outOfRange() throws ParseException { + try { + Duration x = Durations.parse("316576000000.123456789123456789s"); + fail("expected ParseException"); + } catch (ParseException expected) { + assertThat(expected).hasMessageThat().isEqualTo("Duration value is out of range."); + assertThat(expected).hasCauseThat().isNotNull(); + } + } + + @Test + public void testDurationStringFormat() throws Exception { + Timestamp start = Timestamps.parse("0001-01-01T00:00:00Z"); + Timestamp end = Timestamps.parse("9999-12-31T23:59:59.999999999Z"); + Duration duration = Timestamps.between(start, end); + assertThat(Durations.toString(duration)).isEqualTo("315537897599.999999999s"); + duration = Timestamps.between(end, start); + assertThat(Durations.toString(duration)).isEqualTo("-315537897599.999999999s"); + + // Generated output should contain 3, 6, or 9 fractional digits. + duration = Duration.newBuilder().setSeconds(1).build(); + assertThat(Durations.toString(duration)).isEqualTo("1s"); + duration = Duration.newBuilder().setNanos(10000000).build(); + assertThat(Durations.toString(duration)).isEqualTo("0.010s"); + duration = Duration.newBuilder().setNanos(10000).build(); + assertThat(Durations.toString(duration)).isEqualTo("0.000010s"); + duration = Duration.newBuilder().setNanos(10).build(); + assertThat(Durations.toString(duration)).isEqualTo("0.000000010s"); + + // Parsing accepts an fractional digits as long as they fit into nano + // precision. + duration = Durations.parse("0.1s"); + assertThat(duration.getNanos()).isEqualTo(100000000); + duration = Durations.parse("0.0001s"); + assertThat(duration.getNanos()).isEqualTo(100000); + duration = Durations.parse("0.0000001s"); + assertThat(duration.getNanos()).isEqualTo(100); + // Repeat using parseUnchecked(). + duration = Durations.parseUnchecked("0.1s"); + assertThat(duration.getNanos()).isEqualTo(100000000); + duration = Durations.parseUnchecked("0.0001s"); + assertThat(duration.getNanos()).isEqualTo(100000); + duration = Durations.parseUnchecked("0.0000001s"); + assertThat(duration.getNanos()).isEqualTo(100); + + // Duration must support range from -315,576,000,000s to +315576000000s + // which includes negative values. + duration = Durations.parse("315576000000.999999999s"); + assertThat(duration.getSeconds()).isEqualTo(315576000000L); + assertThat(duration.getNanos()).isEqualTo(999999999); + duration = Durations.parse("-315576000000.999999999s"); + assertThat(duration.getSeconds()).isEqualTo(-315576000000L); + assertThat(duration.getNanos()).isEqualTo(-999999999); + // Repeat using parseUnchecked(). + duration = Durations.parseUnchecked("315576000000.999999999s"); + assertThat(duration.getSeconds()).isEqualTo(315576000000L); + assertThat(duration.getNanos()).isEqualTo(999999999); + duration = Durations.parseUnchecked("-315576000000.999999999s"); + assertThat(duration.getSeconds()).isEqualTo(-315576000000L); + assertThat(duration.getNanos()).isEqualTo(-999999999); + } + + @Test + public void testDurationInvalidFormat() { + // Value too small. + try { + Durations.toString( + Duration.newBuilder().setSeconds(Durations.DURATION_SECONDS_MIN - 1).build()); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + try { + Durations.toString( + Duration.newBuilder().setSeconds(Durations.DURATION_SECONDS_MAX + 1).build()); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Invalid nanos value. + try { + Durations.toString(Duration.newBuilder().setSeconds(1).setNanos(-1).build()); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Invalid seconds value. + try { + Durations.toString(Duration.newBuilder().setSeconds(-1).setNanos(1).build()); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Value too small. + try { + Durations.parse("-315576000001s"); + fail(); + } catch (ParseException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + try { + Durations.parseUnchecked("-315576000001s"); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Value too large. + try { + Durations.parse("315576000001s"); + fail(); + } catch (ParseException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + try { + Durations.parseUnchecked("315576000001s"); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Empty. + try { + Durations.parse(""); + fail(); + } catch (ParseException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + try { + Durations.parseUnchecked(""); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Missing "s". + try { + Durations.parse("0"); + fail(); + } catch (ParseException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + try { + Durations.parseUnchecked("0"); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Invalid trailing data. + try { + Durations.parse("0s0"); + fail(); + } catch (ParseException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + try { + Durations.parseUnchecked("0s0"); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + + // Invalid prefix. + try { + Durations.parse("--1s"); + fail(); + } catch (ParseException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + try { + Durations.parseUnchecked("--1s"); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isNotNull(); + } + } + + @Test + public void testDurationConversion() throws Exception { + Duration duration = Durations.parse("1.111111111s"); + assertThat(Durations.toNanos(duration)).isEqualTo(1111111111); + assertThat(Durations.toMicros(duration)).isEqualTo(1111111); + assertThat(Durations.toMillis(duration)).isEqualTo(1111); + assertThat(Durations.toSeconds(duration)).isEqualTo(1); + duration = Durations.fromNanos(1111111111); + assertThat(Durations.toString(duration)).isEqualTo("1.111111111s"); + duration = Durations.fromMicros(1111111); + assertThat(Durations.toString(duration)).isEqualTo("1.111111s"); + duration = Durations.fromMillis(1111); + assertThat(Durations.toString(duration)).isEqualTo("1.111s"); + duration = Durations.fromSeconds(1); + assertThat(Durations.toString(duration)).isEqualTo("1s"); + + duration = Durations.parse("-1.111111111s"); + assertThat(Durations.toNanos(duration)).isEqualTo(-1111111111); + assertThat(Durations.toMicros(duration)).isEqualTo(-1111111); + assertThat(Durations.toMillis(duration)).isEqualTo(-1111); + assertThat(Durations.toSeconds(duration)).isEqualTo(-1); + duration = Durations.fromNanos(-1111111111); + assertThat(Durations.toString(duration)).isEqualTo("-1.111111111s"); + duration = Durations.fromMicros(-1111111); + assertThat(Durations.toString(duration)).isEqualTo("-1.111111s"); + duration = Durations.fromMillis(-1111); + assertThat(Durations.toString(duration)).isEqualTo("-1.111s"); + duration = Durations.fromSeconds(-1); + assertThat(Durations.toString(duration)).isEqualTo("-1s"); + } + + @Test + public void testTimeOperations() throws Exception { + Timestamp start = Timestamps.parse("0001-01-01T00:00:00Z"); + Timestamp end = Timestamps.parse("9999-12-31T23:59:59.999999999Z"); + + Duration duration = Timestamps.between(start, end); + assertThat(Durations.toString(duration)).isEqualTo("315537897599.999999999s"); + Timestamp value = Timestamps.add(start, duration); + assertThat(value).isEqualTo(end); + value = Timestamps.subtract(end, duration); + assertThat(value).isEqualTo(start); + + duration = Timestamps.between(end, start); + assertThat(Durations.toString(duration)).isEqualTo("-315537897599.999999999s"); + value = Timestamps.add(end, duration); + assertThat(value).isEqualTo(start); + value = Timestamps.subtract(start, duration); + assertThat(value).isEqualTo(end); + + duration = Durations.parse("-1.125s"); + assertThat(Durations.toString(duration)).isEqualTo("-1.125s"); + + duration = Durations.add(duration, duration); + assertThat(Durations.toString(duration)).isEqualTo("-2.250s"); + + duration = Durations.subtract(duration, Durations.parse("-1s")); + assertThat(Durations.toString(duration)).isEqualTo("-1.250s"); + } + + @Test + public void testToString() { + assertThat(Durations.toString(duration(1, 1))).isEqualTo("1.000000001s"); + assertThat(Durations.toString(duration(-1, -1))).isEqualTo("-1.000000001s"); + assertThat(Durations.toString(duration(1, 0))).isEqualTo("1s"); + assertThat(Durations.toString(duration(-1, 0))).isEqualTo("-1s"); + assertThat(Durations.toString(duration(0, 1))).isEqualTo("0.000000001s"); + assertThat(Durations.toString(duration(0, -1))).isEqualTo("-0.000000001s"); + } + + @Test + public void testAdd() { + assertThat(Durations.add(duration(1, 10), duration(1, 20))).isEqualTo(duration(2, 30)); + assertThat(Durations.add(duration(1, 999999999), duration(1, 2))).isEqualTo(duration(3, 1)); + assertThat(Durations.add(duration(1, 999999999), duration(1, 1))).isEqualTo(duration(3, 0)); + assertThat(Durations.add(duration(1, 999999999), duration(-2, -1))).isEqualTo(duration(0, -2)); + assertThat(Durations.add(duration(1, 999999999), duration(-2, 0))).isEqualTo(duration(0, -1)); + assertThat(Durations.add(duration(-1, -10), duration(-1, -20))).isEqualTo(duration(-2, -30)); + assertThat(Durations.add(duration(-1, -999999999), duration(-1, -2))) + .isEqualTo(duration(-3, -1)); + assertThat(Durations.add(duration(-1, -999999999), duration(-1, -1))) + .isEqualTo(duration(-3, 0)); + assertThat(Durations.add(duration(-1, -999999999), duration(2, 1))).isEqualTo(duration(0, 2)); + assertThat(Durations.add(duration(-1, -999999999), duration(2, 0))).isEqualTo(duration(0, 1)); + } + + @Test + public void testSubtract() { + assertThat(Durations.subtract(duration(3, 2), duration(1, 1))).isEqualTo(duration(2, 1)); + assertThat(Durations.subtract(duration(3, 10), duration(1, 10))).isEqualTo(duration(2, 0)); + assertThat(Durations.subtract(duration(3, 1), duration(1, 2))) + .isEqualTo(duration(1, 999999999)); + assertThat(Durations.subtract(duration(3, 2), duration(4, 1))) + .isEqualTo(duration(0, -999999999)); + assertThat(Durations.subtract(duration(1, 1), duration(3, 2))).isEqualTo(duration(-2, -1)); + assertThat(Durations.subtract(duration(1, 10), duration(3, 10))).isEqualTo(duration(-2, 0)); + assertThat(Durations.subtract(duration(1, 2), duration(3, 1))) + .isEqualTo(duration(-1, -999999999)); + assertThat(Durations.subtract(duration(4, 1), duration(3, 2))) + .isEqualTo(duration(0, 999999999)); + } + + @Test + public void testComparator() { + assertThat(Durations.comparator().compare(duration(3, 2), duration(3, 2))).isEqualTo(0); + assertThat(Durations.comparator().compare(duration(0, 0), duration(0, 0))).isEqualTo(0); + assertThat(Durations.comparator().compare(duration(3, 1), duration(1, 1))).isGreaterThan(0); + assertThat(Durations.comparator().compare(duration(3, 2), duration(3, 1))).isGreaterThan(0); + assertThat(Durations.comparator().compare(duration(1, 1), duration(3, 1))).isLessThan(0); + assertThat(Durations.comparator().compare(duration(3, 1), duration(3, 2))).isLessThan(0); + assertThat(Durations.comparator().compare(duration(-3, -1), duration(-1, -1))).isLessThan(0); + assertThat(Durations.comparator().compare(duration(-3, -2), duration(-3, -1))).isLessThan(0); + assertThat(Durations.comparator().compare(duration(-1, -1), duration(-3, -1))).isGreaterThan(0); + assertThat(Durations.comparator().compare(duration(-3, -1), duration(-3, -2))).isGreaterThan(0); + assertThat(Durations.comparator().compare(duration(-10, -1), duration(1, 1))).isLessThan(0); + assertThat(Durations.comparator().compare(duration(0, -1), duration(0, 1))).isLessThan(0); + assertThat(Durations.comparator().compare(duration(0x80000000L, 0), duration(0, 0))) + .isGreaterThan(0); + assertThat(Durations.comparator().compare(duration(0xFFFFFFFF00000000L, 0), duration(0, 0))) + .isLessThan(0); + + Duration duration0 = duration(-50, -500); + Duration duration1 = duration(-50, -400); + Duration duration2 = duration(50, 500); + Duration duration3 = duration(100, 20); + Duration duration4 = duration(100, 50); + Duration duration5 = duration(100, 150); + Duration duration6 = duration(150, 40); + + List durations = + Lists.newArrayList( + duration5, duration3, duration1, duration4, duration6, duration2, duration0, duration3); + + Collections.sort(durations, Durations.comparator()); + assertThat(durations) + .containsExactly( + duration0, duration1, duration2, duration3, duration3, duration4, duration5, duration6) + .inOrder(); + } + + @Test + public void testCompare() { + assertThat(Durations.compare(duration(3, 2), duration(3, 2))).isEqualTo(0); + assertThat(Durations.compare(duration(0, 0), duration(0, 0))).isEqualTo(0); + assertThat(Durations.compare(duration(3, 1), duration(1, 1))).isGreaterThan(0); + assertThat(Durations.compare(duration(3, 2), duration(3, 1))).isGreaterThan(0); + assertThat(Durations.compare(duration(1, 1), duration(3, 1))).isLessThan(0); + assertThat(Durations.compare(duration(3, 1), duration(3, 2))).isLessThan(0); + assertThat(Durations.compare(duration(-3, -1), duration(-1, -1))).isLessThan(0); + assertThat(Durations.compare(duration(-3, -2), duration(-3, -1))).isLessThan(0); + assertThat(Durations.compare(duration(-1, -1), duration(-3, -1))).isGreaterThan(0); + assertThat(Durations.compare(duration(-3, -1), duration(-3, -2))).isGreaterThan(0); + assertThat(Durations.compare(duration(-10, -1), duration(1, 1))).isLessThan(0); + assertThat(Durations.compare(duration(0, -1), duration(0, 1))).isLessThan(0); + assertThat(Durations.compare(duration(0x80000000L, 0), duration(0, 0))).isGreaterThan(0); + assertThat(Durations.compare(duration(0xFFFFFFFF00000000L, 0), duration(0, 0))).isLessThan(0); + } + + @Test + public void testOverflows() throws Exception { + try { + Durations.toNanos(duration(315576000000L, 999999999)); + assertWithMessage("Expected an ArithmeticException to be thrown").fail(); + } catch (ArithmeticException expected) { + } + + try { + Durations.add(Durations.MAX_VALUE, Durations.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.subtract(Durations.MIN_VALUE, Durations.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + + try { + Durations.toNanos(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.toMicros(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.toMillis(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.toSeconds(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + + try { + Durations.toNanos(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.toMicros(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.toMillis(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.toSeconds(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + + assertThat(Durations.toString(Durations.fromNanos(Long.MAX_VALUE))) + .isEqualTo("9223372036.854775807s"); + try { + Durations.fromMicros(Long.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.fromMillis(Long.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.fromSeconds(Long.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + + assertThat(Durations.toString(Durations.fromNanos(Long.MIN_VALUE))) + .isEqualTo("-9223372036.854775808s"); + try { + Durations.fromMicros(Long.MIN_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.fromMillis(Long.MIN_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + try { + Durations.fromSeconds(Long.MIN_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + static Duration duration(long seconds, int nanos) { + return Durations.checkValid( + Durations.checkValid(Duration.newBuilder().setSeconds(seconds).setNanos(nanos))); + } +} 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 f00bbb1b4c9e2..a38ebeb623f0e 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 @@ -79,17 +79,29 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class JsonFormatTest { - public JsonFormatTest() { + + private static Locale originalLocale; + + @BeforeClass + public static void setLocale() { + originalLocale = Locale.getDefault(); // Test that locale does not affect JsonFormat. Locale.setDefault(Locale.forLanguageTag("hi-IN")); } + @AfterClass + public static void resetLocale() { + Locale.setDefault(originalLocale); + } + private void setAllFields(TestAllTypes.Builder builder) { builder.setOptionalInt32(1234); builder.setOptionalInt64(1234567890123456789L); @@ -343,29 +355,94 @@ public void testParserAcceptFloatingPointValueForIntegerField() throws Exception assertThat(builder.getRepeatedInt64(i)).isEqualTo(expectedValues[i]); assertThat(builder.getRepeatedUint64(i)).isEqualTo(expectedValues[i]); } + } - // Non-integers will still be rejected. - assertRejects("optionalInt32", "1.5"); - assertRejects("optionalUint32", "1.5"); - assertRejects("optionalInt64", "1.5"); - assertRejects("optionalUint64", "1.5"); + @Test + public void testRejectTooLargeFloat() throws IOException { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + double tooLarge = 2.0 * Float.MAX_VALUE; + try { + mergeFromJson("{\"" + "optionalFloat" + "\":" + tooLarge + "}", builder); + assertWithMessage("InvalidProtocolBufferException expected.").fail(); + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().isEqualTo("Out of range float value: " + tooLarge); + } } - private void assertRejects(String name, String value) { + @Test + public void testRejectMalformedFloat() throws IOException { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + mergeFromJson("{\"optionalFloat\":3.5aa}", builder); + assertWithMessage("InvalidProtocolBufferException expected.").fail(); + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasCauseThat().isNotNull(); + } + } + + @Test + public void testRejectFractionalInt64() throws IOException { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + mergeFromJson("{\"" + "optionalInt64" + "\":" + "1.5" + "}", builder); + assertWithMessage("Exception is expected.").fail(); + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().isEqualTo("Not an int64 value: 1.5"); + assertThat(expected).hasCauseThat().isNotNull(); + } + } + + @Test + public void testRejectFractionalInt32() throws IOException { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + mergeFromJson("{\"" + "optionalInt32" + "\":" + "1.5" + "}", builder); + assertWithMessage("Exception is expected.").fail(); + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().isEqualTo("Not an int32 value: 1.5"); + assertThat(expected).hasCauseThat().isNotNull(); + } + } + + @Test + public void testRejectFractionalUnsignedInt32() throws IOException { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + mergeFromJson("{\"" + "optionalUint32" + "\":" + "1.5" + "}", builder); + assertWithMessage("Exception is expected.").fail(); + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().isEqualTo("Not an uint32 value: 1.5"); + assertThat(expected).hasCauseThat().isNotNull(); + } + } + + @Test + public void testRejectFractionalUnsignedInt64() throws IOException { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + mergeFromJson("{\"" + "optionalUint64" + "\":" + "1.5" + "}", builder); + assertWithMessage("Exception is expected.").fail(); + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().isEqualTo("Not an uint64 value: 1.5"); + assertThat(expected).hasCauseThat().isNotNull(); + } + } + + private void assertRejects(String name, String value) throws IOException { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { // Numeric form is rejected. mergeFromJson("{\"" + name + "\":" + value + "}", builder); assertWithMessage("Exception is expected.").fail(); - } catch (IOException e) { - // Expected. + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().contains(value); } try { // String form is also rejected. mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder); assertWithMessage("Exception is expected.").fail(); - } catch (IOException e) { - // Expected. + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().contains(value); } } @@ -833,6 +910,7 @@ public void testTimestampMergeError() throws Exception { assertThat(e) .hasMessageThat() .isEqualTo("Failed to parse timestamp: " + incorrectTimestampString); + assertThat(e).hasCauseThat().isNotNull(); } } @@ -857,6 +935,7 @@ public void testDurationMergeError() throws Exception { assertThat(e) .hasMessageThat() .isEqualTo("Failed to parse duration: " + incorrectDurationString); + assertThat(e).hasCauseThat().isNotNull(); } } @@ -973,8 +1052,9 @@ public void testAnyFields() throws Exception { try { toJsonString(message); assertWithMessage("Exception is expected.").fail(); - } catch (IOException e) { - // Expected. + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasMessageThat().isEqualTo( + "Cannot find type for url: type.googleapis.com/json_test.TestAllTypes"); } JsonFormat.TypeRegistry registry = @@ -1288,7 +1368,13 @@ public void testParserRejectTrailingComma() throws Exception { @Test public void testParserRejectInvalidBase64() throws Exception { - assertRejects("optionalBytes", "!@#$"); + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + mergeFromJson("{\"" + "optionalBytes" + "\":" + "!@#$" + "}", builder); + assertWithMessage("Exception is expected.").fail(); + } catch (InvalidProtocolBufferException expected) { + assertThat(expected).hasCauseThat().isNotNull(); + } } @Test diff --git a/java/util/src/test/java/com/google/protobuf/util/TimestampsTest.java b/java/util/src/test/java/com/google/protobuf/util/TimestampsTest.java new file mode 100644 index 0000000000000..ea90a6b2081f2 --- /dev/null +++ b/java/util/src/test/java/com/google/protobuf/util/TimestampsTest.java @@ -0,0 +1,829 @@ +// 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. + +package com.google.protobuf.util; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static com.google.protobuf.util.DurationsTest.duration; + +import com.google.common.collect.Lists; +import com.google.protobuf.Duration; +import com.google.protobuf.Timestamp; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Timestamps}. */ +@RunWith(JUnit4.class) +public class TimestampsTest { + private static final int MILLIS_PER_SECOND = 1000; + private static final long MILLIS = 1409130915111L; + private static final long SECONDS = MILLIS / MILLIS_PER_SECOND; + private static final long MICROS = MILLIS * 1000; + private static final long NANOS = MICROS * 1000; + + @SuppressWarnings("ConstantOverflow") + private static final long MAX_VALUE = Long.MAX_VALUE * MILLIS_PER_SECOND + MILLIS_PER_SECOND; + + @SuppressWarnings("ConstantOverflow") + private static final long MIN_VALUE = Long.MIN_VALUE * MILLIS_PER_SECOND; + + private static final Timestamp TIMESTAMP = timestamp(1409130915, 111000000); + private static final Timestamp ZERO_TIMESTAMP = timestamp(0, 0); + private static final Timestamp ONE_OF_TIMESTAMP = timestamp(-1, 999000000); + + private static final Timestamp INVALID_MAX = + Timestamp.newBuilder().setSeconds(Long.MAX_VALUE).setNanos(Integer.MAX_VALUE).build(); + private static final Timestamp INVALID_MIN = + Timestamp.newBuilder().setSeconds(Long.MIN_VALUE).setNanos(Integer.MIN_VALUE).build(); + + @Test + public void testMinMaxAreValid() { + assertThat(Timestamps.isValid(Timestamps.MAX_VALUE)).isTrue(); + assertThat(Timestamps.isValid(Timestamps.MIN_VALUE)).isTrue(); + } + + + @Test + public void testIsValid_false() { + assertThat(Timestamps.isValid(0L, -1)).isFalse(); + assertThat(Timestamps.isValid(1L, -1)).isFalse(); + assertThat(Timestamps.isValid(1L, (int) Timestamps.NANOS_PER_SECOND)).isFalse(); + assertThat(Timestamps.isValid(-62135596801L, 0)).isFalse(); + assertThat(Timestamps.isValid(253402300800L, 0)).isFalse(); + } + + @Test + public void testIsValid_true() { + assertThat(Timestamps.isValid(0L, 0)).isTrue(); + assertThat(Timestamps.isValid(1L, 0)).isTrue(); + assertThat(Timestamps.isValid(1L, 1)).isTrue(); + assertThat(Timestamps.isValid(42L, 0)).isTrue(); + assertThat(Timestamps.isValid(42L, 42)).isTrue(); + assertThat(Timestamps.isValid(-62135596800L, 0)).isTrue(); + assertThat(Timestamps.isValid(-62135596800L, 1)).isTrue(); + assertThat(Timestamps.isValid(62135596799L, 1)).isTrue(); + assertThat(Timestamps.isValid(253402300799L, 0)).isTrue(); + assertThat(Timestamps.isValid(253402300798L, 1)).isTrue(); + assertThat(Timestamps.isValid(253402300798L, (int) (Timestamps.NANOS_PER_SECOND - 1))).isTrue(); + } + + @Test + public void testTimestampStringFormat() throws Exception { + Timestamp start = Timestamps.parse("0001-01-01T00:00:00Z"); + Timestamp end = Timestamps.parse("9999-12-31T23:59:59.999999999Z"); + assertThat(start.getSeconds()).isEqualTo(Timestamps.TIMESTAMP_SECONDS_MIN); + assertThat(start.getNanos()).isEqualTo(0); + assertThat(end.getSeconds()).isEqualTo(Timestamps.TIMESTAMP_SECONDS_MAX); + assertThat(end.getNanos()).isEqualTo(999999999); + assertThat(Timestamps.toString(start)).isEqualTo("0001-01-01T00:00:00Z"); + assertThat(Timestamps.toString(end)).isEqualTo("9999-12-31T23:59:59.999999999Z"); + + Timestamp value = Timestamps.parse("1970-01-01T00:00:00Z"); + assertThat(value.getSeconds()).isEqualTo(0); + assertThat(value.getNanos()).isEqualTo(0); + value = Timestamps.parseUnchecked("1970-01-01T00:00:00Z"); + assertThat(value.getSeconds()).isEqualTo(0); + assertThat(value.getNanos()).isEqualTo(0); + + // Test negative timestamps. + value = Timestamps.parse("1969-12-31T23:59:59.999Z"); + assertThat(value.getSeconds()).isEqualTo(-1); + // Nano part is in the range of [0, 999999999] for Timestamp. + assertThat(value.getNanos()).isEqualTo(999000000); + value = Timestamps.parseUnchecked("1969-12-31T23:59:59.999Z"); + assertThat(value.getSeconds()).isEqualTo(-1); + // Nano part is in the range of [0, 999999999] for Timestamp. + assertThat(value.getNanos()).isEqualTo(999000000); + + // Test that 3, 6, or 9 digits are used for the fractional part. + value = Timestamp.newBuilder().setNanos(10).build(); + assertThat(Timestamps.toString(value)).isEqualTo("1970-01-01T00:00:00.000000010Z"); + value = Timestamp.newBuilder().setNanos(10000).build(); + assertThat(Timestamps.toString(value)).isEqualTo("1970-01-01T00:00:00.000010Z"); + value = Timestamp.newBuilder().setNanos(10000000).build(); + assertThat(Timestamps.toString(value)).isEqualTo("1970-01-01T00:00:00.010Z"); + + // Test that parsing accepts timezone offsets. + value = Timestamps.parse("1970-01-01T00:00:00.010+08:00"); + assertThat(Timestamps.toString(value)).isEqualTo("1969-12-31T16:00:00.010Z"); + value = Timestamps.parse("1970-01-01T00:00:00.010-08:00"); + assertThat(Timestamps.toString(value)).isEqualTo("1970-01-01T08:00:00.010Z"); + value = Timestamps.parseUnchecked("1970-01-01T00:00:00.010+08:00"); + assertThat(Timestamps.toString(value)).isEqualTo("1969-12-31T16:00:00.010Z"); + value = Timestamps.parseUnchecked("1970-01-01T00:00:00.010-08:00"); + assertThat(Timestamps.toString(value)).isEqualTo("1970-01-01T08:00:00.010Z"); + } + + private volatile boolean stopParsingThreads = false; + private volatile String errorMessage = ""; + + private class ParseTimestampThread extends Thread { + private final String[] strings; + private final Timestamp[] values; + + public ParseTimestampThread(String[] strings, Timestamp[] values) { + this.strings = strings; + this.values = values; + } + + @Override + public void run() { + int index = 0; + while (!stopParsingThreads) { + Timestamp result; + try { + result = Timestamps.parse(strings[index]); + } catch (ParseException e) { + errorMessage = "Failed to parse timestamp: " + strings[index]; + break; + } + if (result.getSeconds() != values[index].getSeconds() + || result.getNanos() != values[index].getNanos()) { + errorMessage = + "Actual result: " + result.toString() + ", expected: " + values[index].toString(); + break; + } + index = (index + 1) % strings.length; + } + } + } + + @Test + public void testTimestampConcurrentParsing() throws Exception { + String[] timestampStrings = + new String[] { + "0001-01-01T00:00:00Z", + "9999-12-31T23:59:59.999999999Z", + "1970-01-01T00:00:00Z", + "1969-12-31T23:59:59.999Z", + }; + Timestamp[] timestampValues = new Timestamp[timestampStrings.length]; + for (int i = 0; i < timestampStrings.length; i++) { + timestampValues[i] = Timestamps.parse(timestampStrings[i]); + } + + final int threadCount = 16; + final int runningTime = 5000; // in milliseconds. + final List threads = new ArrayList<>(); + + stopParsingThreads = false; + errorMessage = ""; + for (int i = 0; i < threadCount; i++) { + Thread thread = new ParseTimestampThread(timestampStrings, timestampValues); + thread.start(); + threads.add(thread); + } + Thread.sleep(runningTime); + stopParsingThreads = true; + for (Thread thread : threads) { + thread.join(); + } + assertThat(errorMessage).isEmpty(); + } + + @Test + public void testTimestampInvalidFormatValueTooSmall() throws Exception { + try { + // Value too small. + Timestamp value = + Timestamp.newBuilder().setSeconds(Timestamps.TIMESTAMP_SECONDS_MIN - 1).build(); + Timestamps.toString(value); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testTimestampInvalidFormatValueTooLarge() throws Exception { + try { + // Value too large. + Timestamp value = + Timestamp.newBuilder().setSeconds(Timestamps.TIMESTAMP_SECONDS_MAX + 1).build(); + Timestamps.toString(value); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testTimestampInvalidFormatNanosTooSmall() throws Exception { + try { + // Invalid nanos value. + Timestamp value = Timestamp.newBuilder().setNanos(-1).build(); + Timestamps.toString(value); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testTimestampInvalidFormatNanosTooLarge() throws Exception { + try { + // Invalid nanos value. + Timestamp value = Timestamp.newBuilder().setNanos(1000000000).build(); + Timestamps.toString(value); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testTimestampInvalidFormatDateTooSmall() { + try { + Timestamps.parse("0000-01-01T00:00:00Z"); + Assert.fail(); + } catch (ParseException expected) { + Assert.assertNotNull(expected.getMessage()); + assertThat(expected).hasCauseThat().isNotNull(); + } + try { + Timestamps.parseUnchecked("0000-01-01T00:00:00Z"); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + Assert.assertNotNull(expected.getMessage()); + } + } + + @Test + public void testTimestampInvalidFormatDateTooLarge() { + try { + Timestamps.parse("10000-01-01T00:00:00Z"); + Assert.fail(); + } catch (ParseException expected) { + Assert.assertNotNull(expected.getMessage()); + } + try { + Timestamps.parseUnchecked("10000-01-01T00:00:00Z"); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + Assert.assertNotNull(expected.getMessage()); + } + } + + @Test + public void testTimestampInvalidFormatMissingT() { + try { + Timestamps.parse("1970-01-01 00:00:00Z"); + Assert.fail(); + } catch (ParseException expected) { + Assert.assertNotNull(expected.getMessage()); + } + try { + Timestamps.parseUnchecked("1970-01-01 00:00:00Z"); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + Assert.assertNotNull(expected.getMessage()); + } + } + + @Test + public void testTimestampInvalidFormatMissingZ() { + try { + Timestamps.parse("1970-01-01T00:00:00"); + assertWithMessage("ParseException is expected.").fail(); + } catch (ParseException expected) { + Assert.assertNotNull(expected.getMessage()); + } + try { + Timestamps.parseUnchecked("1970-01-01T00:00:00"); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + Assert.assertNotNull(expected.getMessage()); + } + } + + @Test + public void testTimestampInvalidOffset() { + try { + Timestamps.parse("1970-01-01T00:00:00+0000"); + assertWithMessage("ParseException is expected.").fail(); + } catch (ParseException expected) { + Assert.assertNotNull(expected.getMessage()); + } + try { + Timestamps.parseUnchecked("1970-01-01T00:00:00+0000"); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + Assert.assertNotNull(expected.getMessage()); + } + } + + @Test + public void testTimestampInvalidTrailingText() { + try { + Timestamps.parse("1970-01-01T00:00:00Z0"); + assertWithMessage("ParseException is expected.").fail(); + } catch (ParseException expected) { + Assert.assertNotNull(expected.getMessage()); + } + try { + Timestamps.parseUnchecked("1970-01-01T00:00:00Z0"); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + Assert.assertNotNull(expected.getMessage()); + } + } + + @Test + public void testTimestampInvalidNanoSecond() { + try { + Timestamps.parse("1970-01-01T00:00:00.ABCZ"); + assertWithMessage("ParseException is expected.").fail(); + } catch (ParseException expected) { + Assert.assertNotNull(expected.getMessage()); + } + try { + Timestamps.parseUnchecked("1970-01-01T00:00:00.ABCZ"); + assertWithMessage("IllegalArgumentException is expected.").fail(); + } catch (IllegalArgumentException expected) { + Assert.assertNotNull(expected.getMessage()); + } + } + + @Test + public void testTimestampConversion() throws Exception { + Timestamp timestamp = Timestamps.parse("1970-01-01T00:00:01.111111111Z"); + assertThat(Timestamps.toNanos(timestamp)).isEqualTo(1111111111); + assertThat(Timestamps.toMicros(timestamp)).isEqualTo(1111111); + assertThat(Timestamps.toMillis(timestamp)).isEqualTo(1111); + assertThat(Timestamps.toSeconds(timestamp)).isEqualTo(1); + timestamp = Timestamps.fromNanos(1111111111); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01.111111111Z"); + timestamp = Timestamps.fromMicros(1111111); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01.111111Z"); + timestamp = Timestamps.fromMillis(1111); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01.111Z"); + timestamp = Timestamps.fromSeconds(1); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01Z"); + + timestamp = Timestamps.parse("1969-12-31T23:59:59.111111111Z"); + assertThat(Timestamps.toNanos(timestamp)).isEqualTo(-888888889); + assertThat(Timestamps.toMicros(timestamp)).isEqualTo(-888889); + assertThat(Timestamps.toMillis(timestamp)).isEqualTo(-889); + assertThat(Timestamps.toSeconds(timestamp)).isEqualTo(-1); + timestamp = Timestamps.fromNanos(-888888889); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1969-12-31T23:59:59.111111111Z"); + timestamp = Timestamps.fromMicros(-888889); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1969-12-31T23:59:59.111111Z"); + timestamp = Timestamps.fromMillis(-889); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1969-12-31T23:59:59.111Z"); + timestamp = Timestamps.fromSeconds(-1); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1969-12-31T23:59:59Z"); + } + + @Test + public void testFromDate() { + Date date = new Date(1111); + Timestamp timestamp = Timestamps.fromDate(date); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01.111Z"); + } + + @Test + public void testFromDate_after9999CE() { + // protobuf still requires Java 7 so no java.time :-( + Calendar calendar = Calendar.getInstance(); + calendar.clear(); // avoid random number of milliseconds + calendar.setTimeZone(TimeZone.getTimeZone("GMT-0")); + calendar.set(20000, Calendar.OCTOBER, 20, 5, 4, 3); + Date date = calendar.getTime(); + try { + Timestamps.fromDate(date); + Assert.fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().startsWith("Timestamp is not valid."); + } + } + + @Test + public void testFromDate_beforeYear1() { + // protobuf still requires Java 7 so no java.time :-( + Calendar calendar = Calendar.getInstance(); + calendar.clear(); // avoid random number of milliseconds + calendar.setTimeZone(TimeZone.getTimeZone("GMT-0")); + calendar.set(-32, Calendar.OCTOBER, 20, 5, 4, 3); + Date date = calendar.getTime(); + try { + Timestamps.fromDate(date); + Assert.fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().startsWith("Timestamp is not valid."); + } + } + + @Test + public void testFromDate_after2262CE() { + // protobuf still requires Java 7 so no java.time :-( + Calendar calendar = Calendar.getInstance(); + calendar.clear(); // avoid random number of milliseconds + calendar.setTimeZone(TimeZone.getTimeZone("GMT-0")); + calendar.set(2299, Calendar.OCTOBER, 20, 5, 4, 3); + Date date = calendar.getTime(); + Timestamp timestamp = Timestamps.fromDate(date); + assertThat(Timestamps.toString(timestamp)).isEqualTo("2299-10-20T05:04:03Z"); + } + + /* Timestamp only stores integral seconds in the Date parent class and stores the nanosecond + * adjustment in the Timestamp class. */ + @Test + public void testFromSqlTimestampSubMillisecondPrecision() { + java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(1111); + sqlTimestamp.setNanos(sqlTimestamp.getNanos() + 234567); + Timestamp timestamp = Timestamps.fromDate(sqlTimestamp); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01.111234567Z"); + } + + @Test + public void testFromSqlTimestamp() { + Date date = new java.sql.Timestamp(1111); + Timestamp timestamp = Timestamps.fromDate(date); + assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01.111Z"); + } + + @Test + public void testTimeOperations() throws Exception { + Timestamp start = Timestamps.parse("0001-01-01T00:00:00Z"); + Timestamp end = Timestamps.parse("9999-12-31T23:59:59.999999999Z"); + + Duration duration = Timestamps.between(start, end); + assertThat(Durations.toString(duration)).isEqualTo("315537897599.999999999s"); + Timestamp value = Timestamps.add(start, duration); + assertThat(value).isEqualTo(end); + value = Timestamps.subtract(end, duration); + assertThat(value).isEqualTo(start); + + duration = Timestamps.between(end, start); + assertThat(Durations.toString(duration)).isEqualTo("-315537897599.999999999s"); + value = Timestamps.add(end, duration); + assertThat(value).isEqualTo(start); + value = Timestamps.subtract(start, duration); + assertThat(value).isEqualTo(end); + } + + @Test + public void testComparator() { + assertThat(Timestamps.compare(timestamp(3, 2), timestamp(3, 2))).isEqualTo(0); + assertThat(Timestamps.compare(timestamp(0, 0), timestamp(0, 0))).isEqualTo(0); + assertThat(Timestamps.compare(timestamp(3, 1), timestamp(1, 1))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(3, 2), timestamp(3, 1))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(1, 1), timestamp(3, 1))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(3, 1), timestamp(3, 2))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-3, 1), timestamp(-1, 1))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-3, 2), timestamp(-3, 3))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-1, 1), timestamp(-3, 1))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(-3, 1), timestamp(-3, 2))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-10, 1), timestamp(1, 1))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(0, 1), timestamp(0, 1))).isEqualTo(0); + assertThat(Timestamps.compare(timestamp(0x80000000L, 0), timestamp(0, 0))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(0xFFFFFFFF00000000L, 0), timestamp(0, 0))) + .isLessThan(0); + + Timestamp timestamp0 = timestamp(-50, 400); + Timestamp timestamp1 = timestamp(-50, 500); + Timestamp timestamp2 = timestamp(50, 500); + Timestamp timestamp3 = timestamp(100, 20); + Timestamp timestamp4 = timestamp(100, 50); + Timestamp timestamp5 = timestamp(100, 150); + Timestamp timestamp6 = timestamp(150, 40); + + List timestamps = + Lists.newArrayList( + timestamp5, + timestamp3, + timestamp1, + timestamp4, + timestamp6, + timestamp2, + timestamp0, + timestamp3); + + Collections.sort(timestamps, Timestamps.comparator()); + assertThat(timestamps) + .containsExactly( + timestamp0, + timestamp1, + timestamp2, + timestamp3, + timestamp3, + timestamp4, + timestamp5, + timestamp6) + .inOrder(); + } + + @Test + public void testCompare() { + assertThat(Timestamps.compare(timestamp(3, 2), timestamp(3, 2))).isEqualTo(0); + assertThat(Timestamps.compare(timestamp(0, 0), timestamp(0, 0))).isEqualTo(0); + assertThat(Timestamps.compare(timestamp(3, 1), timestamp(1, 1))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(3, 2), timestamp(3, 1))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(1, 1), timestamp(3, 1))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(3, 1), timestamp(3, 2))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-3, 1), timestamp(-1, 1))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-3, 2), timestamp(-3, 3))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-1, 1), timestamp(-3, 1))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(-3, 1), timestamp(-3, 2))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(-10, 1), timestamp(1, 1))).isLessThan(0); + assertThat(Timestamps.compare(timestamp(0, 1), timestamp(0, 1))).isEqualTo(0); + assertThat(Timestamps.compare(timestamp(0x80000000L, 0), timestamp(0, 0))).isGreaterThan(0); + assertThat(Timestamps.compare(timestamp(0xFFFFFFFF00000000L, 0), timestamp(0, 0))) + .isLessThan(0); + } + + @Test + public void testOverflowsArithmeticException() throws Exception { + try { + Timestamps.toNanos(Timestamps.parse("9999-12-31T23:59:59.999999999Z")); + assertWithMessage("Expected an ArithmeticException to be thrown").fail(); + } catch (ArithmeticException expected) { + } + } + + @Test + public void testPositiveOverflow() { + try { + Timestamps.add(Timestamps.MAX_VALUE, Durations.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testNegativeOverflow() { + try { + Timestamps.subtract(Timestamps.MIN_VALUE, Durations.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testInvalidMaxNanosecondsOverflow() { + try { + Timestamps.toNanos(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + @Test + public void testInvalidMaxMicrosecondsOverflow() { + try { + Timestamps.toMicros(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testInvalidMaxMillisecondsOverflow() { + try { + Timestamps.toMillis(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testInvalidMaxSecondsOverflow() { + try { + Timestamps.toSeconds(INVALID_MAX); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testInvalidMinNanosecondsOverflow() { + try { + Timestamps.toNanos(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testInvalidMicrosecondsMinOverflow() { + try { + Timestamps.toMicros(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testInvalidMinMillisecondsOverflow() { + try { + Timestamps.toMillis(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testOverInvalidMinSecondsflow() { + try { + Timestamps.toSeconds(INVALID_MIN); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testMaxNanosecondsConversion() { + assertThat(Timestamps.toString(Timestamps.fromNanos(Long.MAX_VALUE))) + .isEqualTo("2262-04-11T23:47:16.854775807Z"); + } + + @Test + public void testIllegalArgumentExceptionForMaxMicroseconds() { + try { + Timestamps.fromMicros(Long.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + + @Test + public void testIllegalArgumentExceptionForMaxMilliseconds() { + try { + Durations.fromMillis(Long.MAX_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testMinNanosecondsConversion() { + assertThat(Timestamps.toString(Timestamps.fromNanos(Long.MIN_VALUE))) + .isEqualTo("1677-09-21T00:12:43.145224192Z"); + } + + @Test + public void testIllegalArgumentExceptionForMinMicroseconds() { + try { + Timestamps.fromMicros(Long.MIN_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + + @Test + public void testIllegalArgumentExceptionForMinMilliseconds() { + try { + Timestamps.fromMillis(Long.MIN_VALUE); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testConvertFromSeconds() { + assertThat(Timestamps.fromSeconds(SECONDS).getSeconds()).isEqualTo(TIMESTAMP.getSeconds()); + assertThat(Timestamps.EPOCH).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromSeconds(MAX_VALUE)).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromSeconds(MIN_VALUE)).isEqualTo(ZERO_TIMESTAMP); + } + + @Test + public void testConvertFromMillis() { + assertThat(Timestamps.fromMillis(MILLIS)).isEqualTo(TIMESTAMP); + assertThat(Timestamps.EPOCH).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromMillis(-1)).isEqualTo(ONE_OF_TIMESTAMP); + assertThat(Timestamps.fromMillis(MAX_VALUE)).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromMillis(MIN_VALUE)).isEqualTo(ZERO_TIMESTAMP); + } + + @Test + public void testConvertFromMicros() { + assertThat(Timestamps.fromMicros(MICROS)).isEqualTo(TIMESTAMP); + assertThat(Timestamps.EPOCH).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromMicros(-1000)).isEqualTo(ONE_OF_TIMESTAMP); + assertThat(Timestamps.fromMicros(MAX_VALUE)).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromMicros(MIN_VALUE)).isEqualTo(ZERO_TIMESTAMP); + } + + @Test + public void testConvertToSeconds() { + assertThat(Timestamps.toSeconds(TIMESTAMP)).isEqualTo(SECONDS); + assertThat(Timestamps.toSeconds(ZERO_TIMESTAMP)).isEqualTo(0); + assertThat(Timestamps.toSeconds(ONE_OF_TIMESTAMP)).isEqualTo(-1); + } + + @Test + public void testConvertToMillis() { + assertThat(Timestamps.toMillis(TIMESTAMP)).isEqualTo(MILLIS); + assertThat(Timestamps.toMillis(ZERO_TIMESTAMP)).isEqualTo(0); + assertThat(Timestamps.toMillis(ONE_OF_TIMESTAMP)).isEqualTo(-1); + } + + @Test + public void testConvertToMicros() { + assertThat(Timestamps.toMicros(TIMESTAMP)).isEqualTo(MICROS); + assertThat(Timestamps.toMicros(ZERO_TIMESTAMP)).isEqualTo(0); + assertThat(Timestamps.toMicros(ONE_OF_TIMESTAMP)).isEqualTo(-1000); + } + + @Test + public void testConvertFromMillisAboveTimestampMaxLimit() { + long timestampMaxSeconds = 253402300799L; + try { + Timestamps.fromMillis((timestampMaxSeconds + 1) * MILLIS_PER_SECOND); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testConvertFromMillisBelowTimestampMaxLimit() { + long timestampMinSeconds = -62135596800L; + try { + Timestamps.fromMillis((timestampMinSeconds - 1) * MILLIS_PER_SECOND); + assertWithMessage("Expected an IllegalArgumentException to be thrown").fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testConvertFromNanos() { + assertThat(Timestamps.fromNanos(NANOS)).isEqualTo(TIMESTAMP); + assertThat(Timestamps.fromNanos(0)).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromNanos(-1000000)).isEqualTo(ONE_OF_TIMESTAMP); + assertThat(Timestamps.fromNanos(MAX_VALUE)).isEqualTo(ZERO_TIMESTAMP); + assertThat(Timestamps.fromNanos(MIN_VALUE)).isEqualTo(ZERO_TIMESTAMP); + } + + @Test + public void testConvertToNanos() { + assertThat(Timestamps.toNanos(TIMESTAMP)).isEqualTo(NANOS); + assertThat(Timestamps.toNanos(ZERO_TIMESTAMP)).isEqualTo(0); + assertThat(Timestamps.toNanos(ONE_OF_TIMESTAMP)).isEqualTo(-1000000); + } + + @Test + public void testAdd() { + assertThat(Timestamps.add(timestamp(1, 10), duration(1, 20))).isEqualTo(timestamp(2, 30)); + assertThat(Timestamps.add(timestamp(1, 10), duration(-1, -11))) + .isEqualTo(timestamp(-1, 999999999)); + assertThat(Timestamps.add(timestamp(10, 10), duration(-1, -11))) + .isEqualTo(timestamp(8, 999999999)); + assertThat(Timestamps.add(timestamp(1, 1), duration(1, 999999999))).isEqualTo(timestamp(3, 0)); + assertThat(Timestamps.add(timestamp(1, 2), duration(1, 999999999))).isEqualTo(timestamp(3, 1)); + } + + @Test + public void testSubtractDuration() { + assertThat(Timestamps.subtract(timestamp(1, 10), duration(-1, -20))) + .isEqualTo(timestamp(2, 30)); + assertThat(Timestamps.subtract(timestamp(1, 10), duration(1, 11))) + .isEqualTo(timestamp(-1, 999999999)); + assertThat(Timestamps.subtract(timestamp(10, 10), duration(1, 11))) + .isEqualTo(timestamp(8, 999999999)); + assertThat(Timestamps.subtract(timestamp(1, 1), duration(-1, -999999999))) + .isEqualTo(timestamp(3, 0)); + assertThat(Timestamps.subtract(timestamp(1, 2), duration(-1, -999999999))) + .isEqualTo(timestamp(3, 1)); + } + + static Timestamp timestamp(long seconds, int nanos) { + return Timestamps.checkValid( + Timestamps.checkValid(Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos))); + } +} diff --git a/js/commonjs/export.js b/js/commonjs/export.js index a9932e95ae53e..29a871359177f 100644 --- a/js/commonjs/export.js +++ b/js/commonjs/export.js @@ -15,15 +15,18 @@ goog.require('jspb.ExtensionFieldInfo'); goog.require('jspb.Message'); goog.require('jspb.Map'); -exports.Map = jspb.Map; -exports.Message = jspb.Message; -exports.BinaryReader = jspb.BinaryReader; -exports.BinaryWriter = jspb.BinaryWriter; -exports.ExtensionFieldInfo = jspb.ExtensionFieldInfo; -exports.ExtensionFieldBinaryInfo = jspb.ExtensionFieldBinaryInfo; +if (typeof exports === 'object') { + exports.Map = jspb.Map; + exports.Message = jspb.Message; + exports.BinaryReader = jspb.BinaryReader; + exports.BinaryWriter = jspb.BinaryWriter; + exports.ExtensionFieldInfo = jspb.ExtensionFieldInfo; + exports.ExtensionFieldBinaryInfo = jspb.ExtensionFieldBinaryInfo; -// These are used by generated code but should not be used directly by clients. -exports.exportSymbol = goog.exportSymbol; -exports.inherits = goog.inherits; -exports.object = {extend: goog.object.extend}; -exports.typeOf = goog.typeOf; + // These are used by generated code but should not be used directly by + // clients. + exports.exportSymbol = goog.exportSymbol; + exports.inherits = goog.inherits; + exports.object = {extend: goog.object.extend}; + exports.typeOf = goog.typeOf; +} \ No newline at end of file diff --git a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js b/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js index 252520f71c47d..94c2598a8c6dd 100644 --- a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js +++ b/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js @@ -119,7 +119,7 @@ function accessAllTypes() { arrayVal[0] = true; msgAllTypes.setRepeatedBoolList(arrayVal); msgAllTypes.setRepeatedBytesList(['']); - arrayVal = msgAllTypes.getRepeatedBytesList(); + arrayVal = msgAllTypes.getRepeatedBytesList_asB64(); arrayVal[0] = ''; msgAllTypes.setRepeatedBytesList(arrayVal); msgPackedTypes.setPackedDoubleList([1.0]); @@ -233,8 +233,7 @@ function accessAllTypes() { let s = ''; s += msgAllTypes.getOptionalBool() || false; - s += msgAllTypes.getOptionalBytes() || ''; - // s += msgAllTypes.getOptionalBytes_asB64() || ""; + s += msgAllTypes.getOptionalBytes_asB64() || ''; // s += msgAllTypes.getOptionalBytes_asU8() || new Uint8Array([]); s += msgAllTypes.getOptionalDouble() || 0.0; s += msgAllTypes.getOptionalFixed32() || 0; @@ -254,10 +253,9 @@ function accessAllTypes() { s += msgAllTypes.getRepeatedBoolList(); s += msgAllTypes.getRepeatedBoolList()[0]; s += msgAllTypes.getRepeatedBoolList().length; - s += msgAllTypes.getRepeatedBytesList(); - s += msgAllTypes.getRepeatedBytesList()[0]; - s += msgAllTypes.getRepeatedBytesList().length; s += msgAllTypes.getRepeatedBytesList_asB64(); + s += msgAllTypes.getRepeatedBytesList_asB64()[0]; + s += msgAllTypes.getRepeatedBytesList_asB64().length; s += msgAllTypes.getRepeatedBytesList_asU8(); s += msgAllTypes.getRepeatedDoubleList(); s += msgAllTypes.getRepeatedDoubleList()[0]; diff --git a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js b/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js index 3637df612f8d1..9eb8126a88980 100644 --- a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js +++ b/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js @@ -119,7 +119,7 @@ function accessAllTypes() { arrayVal[0] = true; msgAllTypes.setRepeatedBoolList(arrayVal); msgAllTypes.setRepeatedBytesList(['']); - arrayVal = msgAllTypes.getRepeatedBytesList(); + arrayVal = msgAllTypes.getRepeatedBytesList_asB64(); arrayVal[0] = ''; msgAllTypes.setRepeatedBytesList(arrayVal); msgPackedTypes.setPackedDoubleList([1.0]); @@ -233,8 +233,7 @@ function accessAllTypes() { let s = ''; s += msgAllTypes.getOptionalBool() || false; - s += msgAllTypes.getOptionalBytes() || ''; - // s += msgAllTypes.getOptionalBytes_asB64() || ""; + s += msgAllTypes.getOptionalBytes_asB64() || ''; // s += msgAllTypes.getOptionalBytes_asU8() || new Uint8Array([]); s += msgAllTypes.getOptionalDouble() || 0.0; s += msgAllTypes.getOptionalFixed32() || 0; @@ -254,10 +253,9 @@ function accessAllTypes() { s += msgAllTypes.getRepeatedBoolList(); s += msgAllTypes.getRepeatedBoolList()[0]; s += msgAllTypes.getRepeatedBoolList().length; - s += msgAllTypes.getRepeatedBytesList(); - s += msgAllTypes.getRepeatedBytesList()[0]; - s += msgAllTypes.getRepeatedBytesList().length; s += msgAllTypes.getRepeatedBytesList_asB64(); + s += msgAllTypes.getRepeatedBytesList_asB64()[0]; + s += msgAllTypes.getRepeatedBytesList_asB64().length; s += msgAllTypes.getRepeatedBytesList_asU8(); s += msgAllTypes.getRepeatedDoubleList(); s += msgAllTypes.getRepeatedDoubleList()[0]; diff --git a/js/experimental/runtime/kernel/reader.js b/js/experimental/runtime/kernel/reader.js index 2b80e15bffa63..44708b5aec56b 100644 --- a/js/experimental/runtime/kernel/reader.js +++ b/js/experimental/runtime/kernel/reader.js @@ -97,19 +97,6 @@ function readSfixed64(bufferDecoder, start) { return Int64.fromBits(lowBits, highBits); } -/** - * Reads a sint32 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readSint32(bufferDecoder, start) { - const bits = bufferDecoder.getUnsignedVarint32At(start); - // Truncate upper bits and convert from zig zag to signd int - return (bits >>> 1) ^ -(bits & 0x01); -} - /** * Reads a sint64 value from the binary bytes encoded as varint. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. @@ -125,6 +112,17 @@ function readSint64(bufferDecoder, start) { return Int64.fromBits(decodedLowerBits, decodedUpperBits); } +/** + * Reads a sint32 value from the binary bytes encoded as varint. + * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. + * @param {number} start Start of the data. + * @return {number} + * @package + */ +function readSint32(bufferDecoder, start) { + return readSint64(bufferDecoder, start).getLowBits(); +} + /** * Read a subarray of bytes representing a length delimited field. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. diff --git a/kokoro/linux/64-bit/Dockerfile b/kokoro/linux/64-bit/Dockerfile index 3a279e6602492..189d0cf9412aa 100644 --- a/kokoro/linux/64-bit/Dockerfile +++ b/kokoro/linux/64-bit/Dockerfile @@ -60,8 +60,6 @@ RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ nunit \ # -- For all Java builds -- \ maven \ - # -- For java_jdk6 -- \ - # oops! not in jessie. too old? openjdk-6-jdk \ # -- For java_jdk7 -- \ openjdk-7-jdk \ # -- For java_oracle7 -- \ diff --git a/kokoro/linux/aarch64/python_run_tests_with_qemu_aarch64.sh b/kokoro/linux/aarch64/python_run_tests_with_qemu_aarch64.sh index 527fc4849d3e7..5026d0448f712 100755 --- a/kokoro/linux/aarch64/python_run_tests_with_qemu_aarch64.sh +++ b/kokoro/linux/aarch64/python_run_tests_with_qemu_aarch64.sh @@ -7,7 +7,7 @@ cd $(dirname $0)/../../.. cd python PYTHON="/opt/python/cp38-cp38/bin/python" -${PYTHON} -m pip install --user six pytest auditwheel +${PYTHON} -m pip install --user pytest auditwheel # check that we are really using aarch64 python (${PYTHON} -c 'import sysconfig; print(sysconfig.get_platform())' | grep -q "linux-aarch64") || (echo "Wrong python platform, needs to be aarch64 python."; exit 1) diff --git a/kokoro/linux/aarch64/test_csharp_aarch64.sh b/kokoro/linux/aarch64/test_csharp_aarch64.sh index 450bb1e04d697..cc3bffe04d4b7 100755 --- a/kokoro/linux/aarch64/test_csharp_aarch64.sh +++ b/kokoro/linux/aarch64/test_csharp_aarch64.sh @@ -15,8 +15,8 @@ fi # First, build protobuf C# tests under x86_64 docker image # Tests are built "dotnet publish" because we want all the dependencies to the copied to the destination directory # (we want to avoid references to ~/.nuget that won't be available in the subsequent docker run) -CSHARP_BUILD_COMMAND="dotnet publish -c Release -f net50 csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj" -docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -e "DOTNET_CLI_TELEMETRY_OPTOUT=true" -e "DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work mcr.microsoft.com/dotnet/sdk:5.0.202-buster-slim bash -c "$CSHARP_BUILD_COMMAND" +CSHARP_BUILD_COMMAND="dotnet publish -c Release -f net60 csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj" +docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -e "DOTNET_CLI_TELEMETRY_OPTOUT=true" -e "DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work mcr.microsoft.com/dotnet/sdk:6.0.100-bullseye-slim bash -c "$CSHARP_BUILD_COMMAND" # Use an actual aarch64 docker image to run protobuf C# tests with an emulator. "dotnet vstest" allows # running tests from a pre-built project. @@ -25,5 +25,5 @@ docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake- # running under current user's UID and GID. To be able to do that, we need to provide a home directory for the user # otherwise the UID would be homeless under the docker container and pip install wouldn't work. For simplicity, # we just run map the user's home to a throwaway temporary directory -CSHARP_TEST_COMMAND="dotnet vstest csharp/src/Google.Protobuf.Test/bin/Release/net50/publish/Google.Protobuf.Test.dll" -docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -e "DOTNET_CLI_TELEMETRY_OPTOUT=true" -e "DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work mcr.microsoft.com/dotnet/sdk:5.0.202-buster-slim-arm64v8 bash -c "$CSHARP_TEST_COMMAND" +CSHARP_TEST_COMMAND="dotnet vstest csharp/src/Google.Protobuf.Test/bin/Release/net60/publish/Google.Protobuf.Test.dll" +docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -e "DOTNET_CLI_TELEMETRY_OPTOUT=true" -e "DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work mcr.microsoft.com/dotnet/sdk:6.0.100-bullseye-slim-arm64v8 bash -c "$CSHARP_TEST_COMMAND" diff --git a/kokoro/linux/bazel/build.sh b/kokoro/linux/bazel/build.sh index 5ec92ce7e5b48..d0d4b3ef4d942 100755 --- a/kokoro/linux/bazel/build.sh +++ b/kokoro/linux/bazel/build.sh @@ -35,5 +35,13 @@ bazel test -k --copt=-Werror --host_copt=-Werror \ @com_google_protobuf//:cc_proto_blacklist_test trap - EXIT -cd examples +pushd examples bazel build //... +popd + +# Verify that we can build successfully from generated tar files. +./autogen.sh && ./configure && make -j$(nproc) dist +DIST=`ls *.tar.gz` +tar -xf $DIST +cd ${DIST//.tar.gz} +bazel build //:protobuf //:protobuf_java diff --git a/kokoro/linux/benchmark/run.sh b/kokoro/linux/benchmark/run.sh index 502f4365366a6..acd8737077343 100755 --- a/kokoro/linux/benchmark/run.sh +++ b/kokoro/linux/benchmark/run.sh @@ -23,8 +23,10 @@ popd ./configure CXXFLAGS="-fPIC -O2" make -j8 pushd python -python setup.py build --cpp_implementation -pip install . --user +virtualenv -p python3 env +source env/bin/activate +python3 setup.py build --cpp_implementation +pip3 install --install-option="--cpp_implementation" . popd # build and run Python benchmark @@ -91,7 +93,7 @@ cat tmp/python_result.json # print the postprocessed results to the build job log # TODO(jtattermusch): re-enable uploading results to bigquery (it is currently broken) make python_add_init -env LD_LIBRARY_PATH="${repo_root}/src/.libs" python -m util.result_parser \ +env LD_LIBRARY_PATH="${repo_root}/src/.libs" python3 -m util.result_parser \ -cpp="../tmp/cpp_result.json" -java="../tmp/java_result.json" -python="../tmp/python_result.json" popd diff --git a/kokoro/linux/dockerfile/test/csharp/Dockerfile b/kokoro/linux/dockerfile/test/csharp/Dockerfile index 37edbfda999e0..c07fcbcef102d 100644 --- a/kokoro/linux/dockerfile/test/csharp/Dockerfile +++ b/kokoro/linux/dockerfile/test/csharp/Dockerfile @@ -32,8 +32,8 @@ RUN apt-get update && apt-get install -y libunwind8 libicu63 && apt-get clean # Install dotnet SDK via install script 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 5.0.102 && \ + ./dotnet-install.sh --version 3.1.415 && \ + ./dotnet-install.sh --version 6.0.100 && \ 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/python310/Dockerfile b/kokoro/linux/dockerfile/test/python310/Dockerfile new file mode 100644 index 0000000000000..e16e93b3b2465 --- /dev/null +++ b/kokoro/linux/dockerfile/test/python310/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.10-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/ruby/Dockerfile b/kokoro/linux/dockerfile/test/ruby/Dockerfile index 2affd1419627b..836287090ac71 100644 --- a/kokoro/linux/dockerfile/test/ruby/Dockerfile +++ b/kokoro/linux/dockerfile/test/ruby/Dockerfile @@ -29,10 +29,8 @@ RUN apt-get update && apt-get install -y \ RUN gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys \ 409B6B1796C275462A1703113804BB82D39DC0E3 \ 7D2BAF1CF37B13E2069D6956105BD0E739499BDB -RUN \curl -sSL https://get.rvm.io | bash -s master +RUN \curl -sSL https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer | bash -s master -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" diff --git a/kokoro/linux/ruby23/build.sh b/kokoro/linux/python310/build.sh similarity index 85% rename from kokoro/linux/ruby23/build.sh rename to kokoro/linux/python310/build.sh index 503a320de22e7..0d8a2c9c6d497 100755 --- a/kokoro/linux/ruby23/build.sh +++ b/kokoro/linux/python310/build.sh @@ -11,8 +11,8 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/ruby +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python310 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput -export TEST_SET="ruby23" +export TEST_SET="python310" ./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/ruby23/continuous.cfg b/kokoro/linux/python310/continuous.cfg similarity index 75% rename from kokoro/linux/ruby23/continuous.cfg rename to kokoro/linux/python310/continuous.cfg index f5c64988bfc7c..6ec74d8597e81 100644 --- a/kokoro/linux/ruby23/continuous.cfg +++ b/kokoro/linux/python310/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/ruby23/build.sh" +build_file: "protobuf/kokoro/linux/python310/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/ruby23/presubmit.cfg b/kokoro/linux/python310/presubmit.cfg similarity index 75% rename from kokoro/linux/ruby23/presubmit.cfg rename to kokoro/linux/python310/presubmit.cfg index f5c64988bfc7c..6ec74d8597e81 100644 --- a/kokoro/linux/ruby23/presubmit.cfg +++ b/kokoro/linux/python310/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/ruby23/build.sh" +build_file: "protobuf/kokoro/linux/python310/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/ruby24/build.sh b/kokoro/linux/python310_cpp/build.sh similarity index 85% rename from kokoro/linux/ruby24/build.sh rename to kokoro/linux/python310_cpp/build.sh index 68585aabc0a59..2903a2d9c2dd4 100755 --- a/kokoro/linux/ruby24/build.sh +++ b/kokoro/linux/python310_cpp/build.sh @@ -11,8 +11,8 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/ruby +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python310 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput -export TEST_SET="ruby24" +export TEST_SET="python310_cpp" ./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/ruby24/continuous.cfg b/kokoro/linux/python310_cpp/continuous.cfg similarity index 74% rename from kokoro/linux/ruby24/continuous.cfg rename to kokoro/linux/python310_cpp/continuous.cfg index a1ccfc0b8ba85..7ec844196e240 100644 --- a/kokoro/linux/ruby24/continuous.cfg +++ b/kokoro/linux/python310_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/ruby24/build.sh" +build_file: "protobuf/kokoro/linux/python310_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/ruby24/presubmit.cfg b/kokoro/linux/python310_cpp/presubmit.cfg similarity index 74% rename from kokoro/linux/ruby24/presubmit.cfg rename to kokoro/linux/python310_cpp/presubmit.cfg index a1ccfc0b8ba85..7ec844196e240 100644 --- a/kokoro/linux/ruby24/presubmit.cfg +++ b/kokoro/linux/python310_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/ruby24/build.sh" +build_file: "protobuf/kokoro/linux/python310_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/macos/prepare_build_macos_rc b/kokoro/macos/prepare_build_macos_rc index ef428fcda30cd..c0017b64ac822 100755 --- a/kokoro/macos/prepare_build_macos_rc +++ b/kokoro/macos/prepare_build_macos_rc @@ -33,5 +33,8 @@ 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 + # Old OpenSSL versions cannot handle the SSL certificate used by + # https://get.rvm.io, so as a workaround we download RVM directly from + # GitHub. See this issue for details: https://github.com/rvm/rvm/issues/5133 + curl -sSL https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer | bash -s stable --ruby fi diff --git a/kokoro/macos/ruby23/build.sh b/kokoro/macos/ruby23/build.sh deleted file mode 100755 index 5a29a997fc2fb..0000000000000 --- a/kokoro/macos/ruby23/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/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_RVM=yes -source kokoro/macos/prepare_build_macos_rc - -./tests.sh ruby23 diff --git a/kokoro/macos/ruby23/continuous.cfg b/kokoro/macos/ruby23/continuous.cfg deleted file mode 100644 index c9b1f61284af3..0000000000000 --- a/kokoro/macos/ruby23/continuous.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/ruby23/build.sh" -timeout_mins: 1440 diff --git a/kokoro/macos/ruby23/presubmit.cfg b/kokoro/macos/ruby23/presubmit.cfg deleted file mode 100644 index c9b1f61284af3..0000000000000 --- a/kokoro/macos/ruby23/presubmit.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/ruby23/build.sh" -timeout_mins: 1440 diff --git a/kokoro/macos/ruby24/build.sh b/kokoro/macos/ruby24/build.sh deleted file mode 100755 index 10ac85f7a4fcf..0000000000000 --- a/kokoro/macos/ruby24/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/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_RVM=yes -source kokoro/macos/prepare_build_macos_rc - -./tests.sh ruby24 diff --git a/kokoro/macos/ruby24/continuous.cfg b/kokoro/macos/ruby24/continuous.cfg deleted file mode 100644 index fada028fc502e..0000000000000 --- a/kokoro/macos/ruby24/continuous.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/ruby24/build.sh" -timeout_mins: 1440 diff --git a/kokoro/macos/ruby24/presubmit.cfg b/kokoro/macos/ruby24/presubmit.cfg deleted file mode 100644 index fada028fc502e..0000000000000 --- a/kokoro/macos/ruby24/presubmit.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/ruby24/build.sh" -timeout_mins: 1440 diff --git a/kokoro/release/python/linux/build_artifacts.sh b/kokoro/release/python/linux/build_artifacts.sh index 2407a302c7879..9a3fc5841f4e2 100755 --- a/kokoro/release/python/linux/build_artifacts.sh +++ b/kokoro/release/python/linux/build_artifacts.sh @@ -26,6 +26,13 @@ mkdir artifacts export ARTIFACT_DIR=$(pwd)/artifacts git clone https://github.com/matthew-brett/multibuild.git +# Pin multibuild scripts at a known commit to avoid potentially unwanted future changes from +# silently creeping in (see https://github.com/protocolbuffers/protobuf/issues/9180). +# IMPORTANT: always pin multibuild at the same commit for: +# - linux/build_artifacts.sh +# - linux/build_artifacts.sh +# - windows/build_artifacts.bat +(cd multibuild; git checkout b89bb903e94308be79abefa4f436bf123ebb1313) cp kokoro/release/python/linux/config.sh config.sh build_artifact_version() { @@ -47,9 +54,23 @@ build_artifact_version() { sudo rm -rf $REPO_DIR } -build_crosscompiled_aarch64_artifact_version() { +build_x86_64_manylinux1_artifact_version() { + # Explicitly request building manylinux1 wheels, which is no longer the default. + # https://github.com/protocolbuffers/protobuf/issues/9180 + MB_ML_VER=1 + build_artifact_version $@ +} + +build_x86_64_manylinux2010_artifact_version() { + # Explicitly request building manylinux2010 wheels + MB_ML_VER=2010 + build_artifact_version $@ +} + +build_crosscompiled_aarch64_manylinux2014_artifact_version() { # crosscompilation is only supported with the dockcross manylinux2014 image DOCKER_IMAGE=dockcross/manylinux2014-aarch64:20210706-65bf2dd + MB_ML_VER=2014 PLAT=aarch64 # TODO(jtatermusch): currently when crosscompiling, "auditwheel repair" will be disabled @@ -57,11 +78,13 @@ build_crosscompiled_aarch64_artifact_version() { build_artifact_version $@ } -build_artifact_version 3.6 -build_artifact_version 3.7 -build_artifact_version 3.8 -build_artifact_version 3.9 +build_x86_64_manylinux1_artifact_version 3.6 +build_x86_64_manylinux1_artifact_version 3.7 +build_x86_64_manylinux1_artifact_version 3.8 +build_x86_64_manylinux1_artifact_version 3.9 +build_x86_64_manylinux2010_artifact_version 3.10 -build_crosscompiled_aarch64_artifact_version 3.7 -build_crosscompiled_aarch64_artifact_version 3.8 -build_crosscompiled_aarch64_artifact_version 3.9 +build_crosscompiled_aarch64_manylinux2014_artifact_version 3.7 +build_crosscompiled_aarch64_manylinux2014_artifact_version 3.8 +build_crosscompiled_aarch64_manylinux2014_artifact_version 3.9 +build_crosscompiled_aarch64_manylinux2014_artifact_version 3.10 diff --git a/kokoro/release/python/macos/build_artifacts.sh b/kokoro/release/python/macos/build_artifacts.sh index fbbd650b71c7f..aeb4242a6b9b1 100755 --- a/kokoro/release/python/macos/build_artifacts.sh +++ b/kokoro/release/python/macos/build_artifacts.sh @@ -26,6 +26,13 @@ mkdir artifacts export ARTIFACT_DIR=$(pwd)/artifacts git clone https://github.com/matthew-brett/multibuild.git +# Pin multibuild scripts at a known commit to avoid potentially unwanted future changes from +# silently creeping in (see https://github.com/protocolbuffers/protobuf/issues/9180). +# IMPORTANT: always pin multibuild at the same commit for: +# - linux/build_artifacts.sh +# - linux/build_artifacts.sh +# - windows/build_artifacts.bat +(cd multibuild; git checkout b89bb903e94308be79abefa4f436bf123ebb1313) cp kokoro/release/python/macos/config.sh config.sh OLD_PATH=$PATH @@ -55,3 +62,4 @@ build_artifact_version 3.6 build_artifact_version 3.7 build_artifact_version 3.8 build_artifact_version 3.9 +build_artifact_version 3.10 diff --git a/kokoro/release/python/windows/build_artifacts.bat b/kokoro/release/python/windows/build_artifacts.bat index 5c5df7c21cbd2..a8f8f78314202 100644 --- a/kokoro/release/python/windows/build_artifacts.bat +++ b/kokoro/release/python/windows/build_artifacts.bat @@ -9,12 +9,20 @@ set PACKAGE_NAME=protobuf set REPO_DIR=protobuf set BUILD_DLL=OFF set UNICODE=ON -set PB_TEST_DEP="six==1.9" set OTHER_TEST_DEP="setuptools==38.5.1" set OLD_PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH% REM Fetch multibuild git clone https://github.com/matthew-brett/multibuild.git +REM Pin multibuild scripts at a known commit to avoid potentially unwanted future changes from +REM silently creeping in (see https://github.com/protocolbuffers/protobuf/issues/9180). +REM IMPORTANT: always pin multibuild at the same commit for: +REM - linux/build_artifacts.sh +REM - linux/build_artifacts.sh +REM - windows/build_artifacts.bat +cd multibuild +git checkout b89bb903e94308be79abefa4f436bf123ebb1313 +cd .. REM Install zlib mkdir zlib @@ -74,6 +82,16 @@ SET PYTHON_VERSION=3.9 SET PYTHON_ARCH=64 CALL build_single_artifact.bat || goto :error +SET PYTHON=C:\python310_32bit +SET PYTHON_VERSION=3.10 +SET PYTHON_ARCH=32 +CALL build_single_artifact.bat || goto :error + +SET PYTHON=C:\python310 +SET PYTHON_VERSION=3.10 +SET PYTHON_ARCH=64 +CALL build_single_artifact.bat || goto :error + goto :EOF :error diff --git a/kokoro/release/python/windows/build_single_artifact.bat b/kokoro/release/python/windows/build_single_artifact.bat index 920f9c83a8bf1..8d3cd0c9d8ee9 100644 --- a/kokoro/release/python/windows/build_single_artifact.bat +++ b/kokoro/release/python/windows/build_single_artifact.bat @@ -24,6 +24,12 @@ if %PYTHON%==C:\python39_32bit set vcplatform=Win32 if %PYTHON%==C:\python39 set generator=Visual Studio 14 Win64 if %PYTHON%==C:\python39 set vcplatform=x64 +if %PYTHON%==C:\python310_32bit set generator=Visual Studio 14 +if %PYTHON%==C:\python310_32bit set vcplatform=Win32 + +if %PYTHON%==C:\python310 set generator=Visual Studio 14 Win64 +if %PYTHON%==C:\python310 set vcplatform=x64 + REM Prepend newly installed Python to the PATH of this build (this cannot be REM done from inside the powershell script as it would require to restart REM the parent CMD process). diff --git a/kokoro/release/python/windows/install_python_interpreters.ps1 b/kokoro/release/python/windows/install_python_interpreters.ps1 index b63259a829848..3f8db95b7a22b 100644 --- a/kokoro/release/python/windows/install_python_interpreters.ps1 +++ b/kokoro/release/python/windows/install_python_interpreters.ps1 @@ -95,3 +95,20 @@ $Python39x64Config = @{ PythonInstallerHash = "b61a33dc28f13b561452f3089c87eb63" } Install-Python @Python39x64Config + +# Python 3.10 +$Python310x86Config = @{ + PythonVersion = "3.10.0" + PythonInstaller = "python-3.10.0" + PythonInstallPath = "C:\python310_32bit" + PythonInstallerHash = "133aa48145032e341ad2a000cd3bff50" +} +Install-Python @Python310x86Config + +$Python310x64Config = @{ + PythonVersion = "3.10.0" + PythonInstaller = "python-3.10.0-amd64" + PythonInstallPath = "C:\python310" + PythonInstallerHash = "c3917c08a7fe85db7203da6dcaa99a70" +} +Install-Python @Python310x64Config diff --git a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh index 046b604b40e10..98270d138338b 100755 --- a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh +++ b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh @@ -60,19 +60,18 @@ set -x ruby --version | grep 'ruby 2.7.0' for v in 3.0.0 2.7.0 ; do ccache -c - rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" + rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin MAKE="$MAKE" + rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=aarch64-darwin 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 +for v in 2.6.0 2.5.1; do ccache -c - rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" + rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin MAKE="$MAKE" + rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=aarch64-darwin 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/maven_install.json b/maven_install.json index f9342185c4e4e..bce3e2b463b77 100644 --- a/maven_install.json +++ b/maven_install.json @@ -1,9 +1,11 @@ { "dependency_tree": { - "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": 1033791982, + "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", + "__INPUT_ARTIFACTS_HASH": 1634601905, + "__RESOLVED_ARTIFACTS_HASH": -143733866, "conflict_resolution": { "com.google.errorprone:error_prone_annotations:2.3.2": "com.google.errorprone:error_prone_annotations:2.5.1", - "junit:junit:4.12": "junit:junit:4.13.1" + "junit:junit:4.12": "junit:junit:4.13.2" }, "dependencies": [ { @@ -43,16 +45,16 @@ "url": "https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar" }, { - "coord": "com.google.code.gson:gson:2.8.6", + "coord": "com.google.code.gson:gson:2.8.9", "dependencies": [], "directDependencies": [], - "file": "v1/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar", + "file": "v1/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar", "mirror_urls": [ - "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar", - "https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar" + "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar", + "https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar" ], - "sha256": "c8fb4839054d280b3033f800d1f5a97de2f028eb8ba2eb458ad287e536f3f25f", - "url": "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar" + "sha256": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", + "url": "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar" }, { "coord": "com.google.errorprone:error_prone_annotations:2.5.1", @@ -78,6 +80,35 @@ "sha256": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", "url": "https://repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" }, + { + "coord": "com.google.guava:guava-testlib:30.1.1-jre", + "dependencies": [ + "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", + "com.google.j2objc:j2objc-annotations:1.3", + "com.google.code.findbugs:jsr305:3.0.2", + "org.hamcrest:hamcrest-core:1.3", + "com.google.guava:guava:30.1.1-jre", + "com.google.guava:failureaccess:1.0.1", + "com.google.errorprone:error_prone_annotations:2.5.1", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.9.1" + ], + "directDependencies": [ + "com.google.j2objc:j2objc-annotations:1.3", + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.guava:guava:30.1.1-jre", + "com.google.errorprone:error_prone_annotations:2.5.1", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.9.1" + ], + "file": "v1/https/repo1.maven.org/maven2/com/google/guava/guava-testlib/30.1.1-jre/guava-testlib-30.1.1-jre.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/guava/guava-testlib/30.1.1-jre/guava-testlib-30.1.1-jre.jar", + "https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/30.1.1-jre/guava-testlib-30.1.1-jre.jar" + ], + "sha256": "8a7fc9adfa1e7441d1d30ca288c593ebc7c4a24c601d01169b781c398f24099b", + "url": "https://repo1.maven.org/maven2/com/google/guava/guava-testlib/30.1.1-jre/guava-testlib-30.1.1-jre.jar" + }, { "coord": "com.google.guava:guava:30.1.1-jre", "dependencies": [ @@ -132,19 +163,18 @@ "coord": "com.google.truth:truth:1.1.2", "dependencies": [ "org.ow2.asm:asm:9.0", - "org.hamcrest:hamcrest-core:1.3", "com.google.auto.value:auto-value-annotations:1.7.4", - "junit:junit:4.13.1", "com.google.guava:guava:30.1.1-jre", "com.google.errorprone:error_prone_annotations:2.5.1", + "junit:junit:4.13.2", "org.checkerframework:checker-qual:3.9.1" ], "directDependencies": [ "org.ow2.asm:asm:9.0", "com.google.auto.value:auto-value-annotations:1.7.4", - "junit:junit:4.13.1", "com.google.guava:guava:30.1.1-jre", "com.google.errorprone:error_prone_annotations:2.5.1", + "junit:junit:4.13.2", "org.checkerframework:checker-qual:3.9.1" ], "file": "v1/https/repo1.maven.org/maven2/com/google/truth/truth/1.1.2/truth-1.1.2.jar", @@ -156,20 +186,20 @@ "url": "https://repo1.maven.org/maven2/com/google/truth/truth/1.1.2/truth-1.1.2.jar" }, { - "coord": "junit:junit:4.13.1", + "coord": "junit:junit:4.13.2", "dependencies": [ "org.hamcrest:hamcrest-core:1.3" ], "directDependencies": [ "org.hamcrest:hamcrest-core:1.3" ], - "file": "v1/https/repo1.maven.org/maven2/junit/junit/4.13.1/junit-4.13.1.jar", + "file": "v1/https/repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar", "mirror_urls": [ - "https://repo1.maven.org/maven2/junit/junit/4.13.1/junit-4.13.1.jar", - "https://repo.maven.apache.org/maven2/junit/junit/4.13.1/junit-4.13.1.jar" + "https://repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar", + "https://repo.maven.apache.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar" ], - "sha256": "c30719db974d6452793fe191b3638a5777005485bae145924044530ffa5f6122", - "url": "https://repo1.maven.org/maven2/junit/junit/4.13.1/junit-4.13.1.jar" + "sha256": "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", + "url": "https://repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar" }, { "coord": "org.checkerframework:checker-qual:3.9.1", @@ -201,24 +231,6 @@ "sha256": "b3dd1cf5019f942d8cc2afad0aa6aef4b21532446fe90a6b68d567e3389763dd", "url": "https://repo1.maven.org/maven2/org/easymock/easymock/3.2/easymock-3.2.jar" }, - { - "coord": "org.easymock:easymockclassextension:3.2", - "dependencies": [ - "org.easymock:easymock:3.2", - "cglib:cglib-nodep:2.2.2", - "org.objenesis:objenesis:1.3" - ], - "directDependencies": [ - "org.easymock:easymock:3.2" - ], - "file": "v1/https/repo1.maven.org/maven2/org/easymock/easymockclassextension/3.2/easymockclassextension-3.2.jar", - "mirror_urls": [ - "https://repo1.maven.org/maven2/org/easymock/easymockclassextension/3.2/easymockclassextension-3.2.jar", - "https://repo.maven.apache.org/maven2/org/easymock/easymockclassextension/3.2/easymockclassextension-3.2.jar" - ], - "sha256": "e2aeb3ecec87d859b2f3072985d4b15873558bcf6410f422db0c0c5194c76c87", - "url": "https://repo1.maven.org/maven2/org/easymock/easymockclassextension/3.2/easymockclassextension-3.2.jar" - }, { "coord": "org.hamcrest:hamcrest-core:1.3", "dependencies": [], diff --git a/php/ext/google/protobuf/names.c b/php/ext/google/protobuf/names.c index 6108ff4a0d9b6..a99188800df07 100644 --- a/php/ext/google/protobuf/names.c +++ b/php/ext/google/protobuf/names.c @@ -71,22 +71,22 @@ 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", - "finally", "fn", "for", "foreach", "function", - "if", "implements", "include", "include_once", "instanceof", - "global", "goto", "insteadof", "interface", "isset", - "list", "match", "namespace", "new", "or", - "print", "private", "protected", "public", "require", - "require_once", "return", "static", "switch", "throw", - "trait", "try", "unset", "use", "var", - "while", "xor", "yield", "int", "float", - "bool", "string", "true", "false", "null", - "void", "iterable", NULL}; + "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", + "finally", "fn", "for", "foreach", "function", + "if", "implements", "include", "include_once", "instanceof", + "global", "goto", "insteadof", "interface", "isset", + "list", "match", "namespace", "new", "object", + "or", "print", "private", "protected", "public", + "require", "require_once", "return", "static", "switch", + "throw", "trait", "try", "unset", "use", + "var", "while", "xor", "yield", "int", + "float", "bool", "string", "true", "false", + "null", "void", "iterable", NULL}; bool is_reserved_name(const char* name) { int i; diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index f083785bb1e94..5bdb92833e1a3 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -10,19 +10,19 @@ protobuf-opensource@google.com yes - 2021-10-04 - + 2022-01-28 + - 3.18.1 - 3.18.1 + 3.19.4 + 3.19.4 stable stable - 3-Clause BSD License + BSD-3-Clause - * No new changes in 3.18.1 + * See github.com/protocolbuffers/protobuf/releases for release notes.

    @@ -73,7 +73,7 @@ 2016-09-23 - 3-Clause BSD License + BSD-3-Clause First alpha release @@ -89,7 +89,7 @@ First alpha release 2017-01-13 - 3-Clause BSD License + BSD-3-Clause Second alpha release. @@ -105,7 +105,7 @@ Second alpha release. 2017-04-28 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -121,7 +121,7 @@ GA release. 2017-05-08 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -137,7 +137,7 @@ GA release. 2017-06-21 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -153,7 +153,7 @@ GA release. 2017-08-16 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -169,7 +169,7 @@ GA release. 2017-09-14 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -185,7 +185,7 @@ GA release. 2017-11-15 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -201,7 +201,7 @@ GA release. 2017-12-06 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -217,7 +217,7 @@ GA release. 2017-12-11 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -233,7 +233,7 @@ GA release. 2018-03-06 - 3-Clause BSD License + BSD-3-Clause G A release. @@ -249,7 +249,7 @@ G A release. 2018-06-06 - 3-Clause BSD License + BSD-3-Clause G A release. @@ -265,7 +265,7 @@ G A release. 2018-08-03 - 3-Clause BSD License + BSD-3-Clause G A release. @@ -281,7 +281,7 @@ G A release. 2019-02-1 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -295,7 +295,7 @@ G A release. 2019-02-22 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -309,7 +309,7 @@ G A release. 2019-02-28 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -323,7 +323,7 @@ G A release. 2019-03-25 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -337,7 +337,7 @@ G A release. 2019-04-23 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -351,7 +351,7 @@ G A release. 2019-05-21 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -365,7 +365,7 @@ G A release. 2019-06-17 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -379,7 +379,7 @@ G A release. 2019-07-10 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -393,7 +393,7 @@ G A release. 2019-08-02 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -407,7 +407,7 @@ G A release. 2019-09-04 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -421,7 +421,7 @@ G A release. 2019-09-05 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -435,7 +435,7 @@ G A release. 2019-09-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -449,7 +449,7 @@ G A release. 2019-11-15 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -463,7 +463,7 @@ G A release. 2019-11-21 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -477,7 +477,7 @@ G A release. 2019-11-25 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -491,7 +491,7 @@ G A release. 2019-12-02 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -505,7 +505,7 @@ G A release. 2019-12-10 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -519,7 +519,7 @@ G A release. 2020-01-28 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -533,7 +533,7 @@ G A release. 2020-02-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -547,7 +547,7 @@ G A release. 2020-04-30 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -561,7 +561,7 @@ G A release. 2020-05-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -575,7 +575,7 @@ G A release. 2020-05-15 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -589,7 +589,7 @@ G A release. 2020-05-20 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -603,7 +603,7 @@ G A release. 2020-05-26 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -617,7 +617,7 @@ G A release. 2020-06-01 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -631,7 +631,7 @@ G A release. 2020-08-05 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -645,7 +645,7 @@ G A release. 2020-08-05 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -659,7 +659,7 @@ G A release. 2020-08-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -673,7 +673,7 @@ G A release. 2020-08-14 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -687,7 +687,7 @@ G A release. 2020-10-08 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -701,7 +701,7 @@ G A release. 2020-11-05 - 3-Clause BSD License + BSD-3-Clause @@ -716,7 +716,7 @@ G A release. 2020-11-10 - 3-Clause BSD License + BSD-3-Clause @@ -731,7 +731,7 @@ G A release. 2020-11-11 - 3-Clause BSD License + BSD-3-Clause @@ -746,7 +746,7 @@ G A release. 2020-11-12 - 3-Clause BSD License + BSD-3-Clause @@ -761,7 +761,7 @@ G A release. 2021-02-05 - 3-Clause BSD License + BSD-3-Clause @@ -776,7 +776,7 @@ G A release. 2021-02-17 - 3-Clause BSD License + BSD-3-Clause @@ -791,7 +791,7 @@ G A release. 2021-02-18 - 3-Clause BSD License + BSD-3-Clause @@ -806,7 +806,7 @@ G A release. 2021-02-19 - 3-Clause BSD License + BSD-3-Clause @@ -821,7 +821,7 @@ G A release. 2021-02-23 - 3-Clause BSD License + BSD-3-Clause @@ -836,7 +836,7 @@ G A release. 2021-02-24 - 3-Clause BSD License + BSD-3-Clause @@ -851,7 +851,7 @@ G A release. 2021-03-02 - 3-Clause BSD License + BSD-3-Clause @@ -866,7 +866,7 @@ G A release. 2021-03-04 - 3-Clause BSD License + BSD-3-Clause @@ -881,7 +881,7 @@ G A release. 2021-03-10 - 3-Clause BSD License + BSD-3-Clause @@ -896,7 +896,7 @@ G A release. 2021-04-02 - 3-Clause BSD License + BSD-3-Clause @@ -911,7 +911,7 @@ G A release. 2021-04-02 - 3-Clause BSD License + BSD-3-Clause @@ -926,7 +926,7 @@ G A release. 2021-05-03 - 3-Clause BSD License + BSD-3-Clause @@ -941,7 +941,7 @@ G A release. 2021-05-05 - 3-Clause BSD License + BSD-3-Clause @@ -956,7 +956,7 @@ G A release. 2021-05-06 - 3-Clause BSD License + BSD-3-Clause @@ -971,7 +971,7 @@ G A release. 2021-05-07 - 3-Clause BSD License + BSD-3-Clause @@ -986,7 +986,7 @@ G A release. 2021-05-11 - 3-Clause BSD License + BSD-3-Clause @@ -1001,7 +1001,7 @@ G A release. 2021-05-19 - 3-Clause BSD License + BSD-3-Clause * Fixed PHP memory leaks and arginfo errors. (#8614) * Fixed JSON parser to allow multiple values from the same oneof as long as @@ -1019,7 +1019,7 @@ G A release. 2021-05-25 - 3-Clause BSD License + BSD-3-Clause @@ -1034,7 +1034,7 @@ G A release. 2021-06-04 - 3-Clause BSD License + BSD-3-Clause @@ -1049,7 +1049,7 @@ G A release. 2021-08-18 - 3-Clause BSD License + BSD-3-Clause @@ -1064,7 +1064,7 @@ G A release. 2021-08-27 - 3-Clause BSD License + BSD-3-Clause @@ -1079,7 +1079,7 @@ G A release. 2021-09-13 - 3-Clause BSD License + BSD-3-Clause @@ -1094,6 +1094,111 @@ G A release. 2021-10-04 + BSD-3-Clause + + + + + + 3.19.0RC1 + 3.19.0 + + + beta + beta + + 2021-10-15 + + BSD-3-Clause + + + + + + 3.19.0RC2 + 3.19.0 + + + beta + beta + + 2021-10-18 + + BSD-3-Clause + + + + + + 3.19.0 + 3.19.0 + + + stable + stable + + 2021-10-19 + + BSD-3-Clause + + + + + + 3.19.1 + 3.19.1 + + + stable + stable + + 2021-10-28 + + BSD-3-Clause + + + + + + 3.19.2 + 3.19.2 + + + stable + stable + + 2022-01-05 + + BSD-3-Clause + + + + + + 3.19.3 + 3.19.3 + + + stable + stable + + 2022-01-11 + + BSD-3-Clause + + + + + + 3.19.4 + 3.19.4 + + + stable + stable + + 2022-01-28 + 3-Clause BSD License diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index a668fe0c6d5ca..925faa645a564 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -5968,7 +5968,7 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { } /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit, 8); + l->size = div_round_up(hasbit + 1, 8); /* Allocate non-oneof fields. */ for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it); diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 8b5c8aa8570e3..41ae2718b461e 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -91,7 +91,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() -#define PHP_PROTOBUF_VERSION "3.18.1" +#define PHP_PROTOBUF_VERSION "3.19.4" // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: diff --git a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php index ea0edc55575aa..d71def9984757 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php @@ -184,6 +184,7 @@ public static function initOnce() { ->optional('packed', \Google\Protobuf\Internal\GPBType::BOOL, 2) ->optional('jstype', \Google\Protobuf\Internal\GPBType::ENUM, 6, 'google.protobuf.internal.FieldOptions.JSType') ->optional('lazy', \Google\Protobuf\Internal\GPBType::BOOL, 5) + ->optional('unverified_lazy', \Google\Protobuf\Internal\GPBType::BOOL, 15) ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 3) ->optional('weak', \Google\Protobuf\Internal\GPBType::BOOL, 10) ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php index 9cf6f10cfd2a7..5e99bff173c93 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php @@ -58,7 +58,6 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. - * TODO(kenton): Base-64 encode? * * Generated from protobuf field optional string default_value = 7; */ @@ -133,7 +132,6 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. - * TODO(kenton): Base-64 encode? * @type int $oneof_index * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. @@ -390,7 +388,6 @@ public function setExtendee($var) * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. - * TODO(kenton): Base-64 encode? * * Generated from protobuf field optional string default_value = 7; * @return string @@ -415,7 +412,6 @@ public function clearDefaultValue() * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. - * TODO(kenton): Base-64 encode? * * Generated from protobuf field optional string default_value = 7; * @param string $var diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php index c6c63a9665acc..5fe7a19d1f58c 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions.php @@ -74,10 +74,22 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * implementation must either *always* check its required fields, or *never* * check its required fields, regardless of whether or not the message has * been parsed. + * As of 2021, lazy does no correctness checks on the byte stream during + * parsing. This may lead to crashes if and when an invalid byte stream is + * finally parsed upon access. + * TODO(b/211906113): Enable validation on lazy fields. * * Generated from protobuf field optional bool lazy = 5 [default = false]; */ protected $lazy = null; + /** + * unverified_lazy does no correctness checks on the byte stream. This should + * only be used where lazy with verification is prohibitive for performance + * reasons. + * + * Generated from protobuf field optional bool unverified_lazy = 15 [default = false]; + */ + protected $unverified_lazy = null; /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -153,6 +165,14 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * implementation must either *always* check its required fields, or *never* * check its required fields, regardless of whether or not the message has * been parsed. + * As of 2021, lazy does no correctness checks on the byte stream during + * parsing. This may lead to crashes if and when an invalid byte stream is + * finally parsed upon access. + * TODO(b/211906113): Enable validation on lazy fields. + * @type bool $unverified_lazy + * unverified_lazy does no correctness checks on the byte stream. This should + * only be used where lazy with verification is prohibitive for performance + * reasons. * @type bool $deprecated * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -334,6 +354,10 @@ public function setJstype($var) * implementation must either *always* check its required fields, or *never* * check its required fields, regardless of whether or not the message has * been parsed. + * As of 2021, lazy does no correctness checks on the byte stream during + * parsing. This may lead to crashes if and when an invalid byte stream is + * finally parsed upon access. + * TODO(b/211906113): Enable validation on lazy fields. * * Generated from protobuf field optional bool lazy = 5 [default = false]; * @return bool @@ -378,6 +402,10 @@ public function clearLazy() * implementation must either *always* check its required fields, or *never* * check its required fields, regardless of whether or not the message has * been parsed. + * As of 2021, lazy does no correctness checks on the byte stream during + * parsing. This may lead to crashes if and when an invalid byte stream is + * finally parsed upon access. + * TODO(b/211906113): Enable validation on lazy fields. * * Generated from protobuf field optional bool lazy = 5 [default = false]; * @param bool $var @@ -391,6 +419,46 @@ public function setLazy($var) return $this; } + /** + * unverified_lazy does no correctness checks on the byte stream. This should + * only be used where lazy with verification is prohibitive for performance + * reasons. + * + * Generated from protobuf field optional bool unverified_lazy = 15 [default = false]; + * @return bool + */ + public function getUnverifiedLazy() + { + return isset($this->unverified_lazy) ? $this->unverified_lazy : false; + } + + public function hasUnverifiedLazy() + { + return isset($this->unverified_lazy); + } + + public function clearUnverifiedLazy() + { + unset($this->unverified_lazy); + } + + /** + * unverified_lazy does no correctness checks on the byte stream. This should + * only be used where lazy with verification is prohibitive for performance + * reasons. + * + * Generated from protobuf field optional bool unverified_lazy = 15 [default = false]; + * @param bool $var + * @return $this + */ + public function setUnverifiedLazy($var) + { + GPBUtil::checkBool($var); + $this->unverified_lazy = $var; + + return $this; + } + /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php index 837f05215ddce..a6101dcbfb2ba 100644 --- a/php/tests/GeneratedClassTest.php +++ b/php/tests/GeneratedClassTest.php @@ -9,6 +9,7 @@ use Bar\TestLegacyMessage; use Bar\TestLegacyMessage_NestedEnum; use Bar\TestLegacyMessage_NestedMessage; +use Foo\Test32Fields; use Foo\TestEnum; use Foo\TestIncludeNamespaceMessage; use Foo\TestIncludePrefixMessage; @@ -1849,4 +1850,13 @@ public function testNoExceptionWithVarDump() $this->assertTrue(true); } + + public function testIssue9440() + { + $m = new Test32Fields(); + $m->setId(8); + $this->assertEquals(8, $m->getId()); + $m->setVersion('1'); + $this->assertEquals(8, $m->getId()); + } } diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index 609b8cfe0cdc4..421292ab52876 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -306,3 +306,38 @@ message TestBytesValue { int32 int32_field = 4; } } + +message Test32Fields { + optional uint32 id = 1; + optional uint32 random_name_a0 = 2; + optional uint32 random_name_a1 = 3; + optional uint32 random_name_a2 = 4; + optional uint32 random_name_a3 = 5; + optional uint32 random_name_a4 = 6; + optional uint32 random_name_a5 = 7; + optional uint32 random_name_a6 = 8; + optional uint32 random_name_a7 = 9; + optional uint32 random_name_a8 = 10; + optional uint32 random_name_a9 = 11; + optional uint32 random_name_b0 = 12; + optional uint32 random_name_b1 = 13; + optional uint32 random_name_b2 = 14; + optional uint32 random_name_b3 = 15; + optional uint32 random_name_b4 = 16; + optional uint32 random_name_b5 = 17; + optional uint32 random_name_b6 = 18; + optional uint32 random_name_b7 = 19; + optional uint32 random_name_b8 = 20; + optional uint32 random_name_b9 = 21; + optional uint32 random_name_c0 = 22; + optional uint32 random_name_c1 = 23; + optional uint32 random_name_c2 = 24; + optional uint32 random_name_c3 = 25; + optional uint32 random_name_c4 = 26; + optional uint32 random_name_c5 = 27; + optional uint32 random_name_c6 = 28; + optional uint32 random_name_c7 = 29; + optional uint32 random_name_c8 = 30; + optional uint32 random_name_c9 = 31; + optional string version = 32; +} diff --git a/protobuf-lite.pc.in b/protobuf-lite.pc.in index 68a2bb455ba3b..f92e4ad9d7c80 100644 --- a/protobuf-lite.pc.in +++ b/protobuf-lite.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: Protocol Buffers Description: Google's Data Interchange Format Version: @VERSION@ -Libs: -L${libdir} -lprotobuf-lite @PTHREAD_LIBS@ -Cflags: -I${includedir} @PTHREAD_CFLAGS@ +Libs: -L${libdir} -lprotobuf-lite +Cflags: -I${includedir} Conflicts: protobuf diff --git a/protobuf.bzl b/protobuf.bzl index 9716128121573..826b6100b8932 100644 --- a/protobuf.bzl +++ b/protobuf.bzl @@ -80,7 +80,14 @@ def _proto_gen_impl(ctx): source_dir = _SourceDir(ctx) gen_dir = _GenDir(ctx).rstrip("/") if source_dir: - import_flags = depset(direct=["-I" + source_dir, "-I" + gen_dir]) + has_sources = any([src.is_source for src in srcs]) + has_generated = any([not src.is_source for src in srcs]) + import_flags = [] + if has_sources: + import_flags += ["-I" + source_dir] + if has_generated: + import_flags += ["-I" + gen_dir] + import_flags = depset(direct=import_flags) else: import_flags = depset(direct=["-I."]) @@ -259,9 +266,9 @@ def cc_proto_library( deps = [], cc_libs = [], include = None, - protoc = "@com_google_protobuf//:protoc", + protoc = Label("//:protoc"), use_grpc_plugin = False, - default_runtime = "@com_google_protobuf//:protobuf", + default_runtime = Label("//:protobuf"), **kargs): """Bazel rule to create a C++ protobuf library from proto source files @@ -379,7 +386,7 @@ internal_gen_well_known_protos_java = rule( "_protoc": attr.label( executable = True, cfg = "exec", - default = "@com_google_protobuf//:protoc", + default = "//:protoc", ), }, ) @@ -422,8 +429,8 @@ def py_proto_library( py_libs = [], py_extra_srcs = [], include = None, - default_runtime = "@com_google_protobuf//:protobuf_python", - protoc = "@com_google_protobuf//:protoc", + default_runtime = Label("//:protobuf_python"), + protoc = Label("//:protoc"), use_grpc_plugin = False, **kargs): """Bazel rule to create a Python protobuf library from proto source files diff --git a/protobuf.pc.in b/protobuf.pc.in index 055a9d0563918..e9bef5d0fe4a4 100644 --- a/protobuf.pc.in +++ b/protobuf.pc.in @@ -6,8 +6,8 @@ includedir=@includedir@ Name: Protocol Buffers Description: Google's Data Interchange Format Version: @VERSION@ -Libs: -L${libdir} -lprotobuf @PTHREAD_LIBS@ +Libs: -L${libdir} -lprotobuf Libs.private: @LIBS@ -Cflags: -I${includedir} @PTHREAD_CFLAGS@ +Cflags: -I${includedir} Conflicts: protobuf-lite diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index ec9d8e9362654..7e2caa3302ed1 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -2,6 +2,18 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +PROTOBUF_MAVEN_ARTIFACTS = [ + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.code.gson:gson:2.8.9", + "com.google.errorprone:error_prone_annotations:2.3.2", + "com.google.j2objc:j2objc-annotations:1.3", + "com.google.guava:guava:30.1.1-jre", + "com.google.guava:guava-testlib:30.1.1-jre", + "com.google.truth:truth:1.1.2", + "junit:junit:4.12", + "org.easymock:easymock:3.2", +] + def protobuf_deps(): """Loads common dependencies needed to compile the protobuf library.""" @@ -18,20 +30,12 @@ def protobuf_deps(): if not native.existing_rule("zlib"): http_archive( name = "zlib", - build_file = "@com_google_protobuf//:third_party/zlib.BUILD", + build_file = Label("//:third_party/zlib.BUILD"), sha256 = "629380c90a77b964d896ed37163f5c3a34f6e6d897311f1df2a7016355c45eff", strip_prefix = "zlib-1.2.11", urls = ["https://github.com/madler/zlib/archive/v1.2.11.tar.gz"], ) - if not native.existing_rule("six"): - http_archive( - name = "six", - build_file = "@com_google_protobuf//:third_party/six.BUILD", - sha256 = "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73", - urls = ["https://pypi.python.org/packages/source/s/six/six-1.12.0.tar.gz"], - ) - if not native.existing_rule("rules_cc"): http_archive( name = "rules_cc", @@ -59,15 +63,31 @@ def protobuf_deps(): if not native.existing_rule("rules_python"): http_archive( name = "rules_python", - sha256 = "e5470e92a18aa51830db99a4d9c492cc613761d5bdb7131c04bd92b9834380f6", - strip_prefix = "rules_python-4b84ad270387a7c439ebdccfd530e2339601ef27", - urls = ["https://github.com/bazelbuild/rules_python/archive/4b84ad270387a7c439ebdccfd530e2339601ef27.tar.gz"], + sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0", + urls = ["https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz"], ) if not native.existing_rule("rules_jvm_external"): - http_archive( + http_archive( name = "rules_jvm_external", sha256 = "f36441aa876c4f6427bfb2d1f2d723b48e9d930b62662bf723ddfb8fc80f0140", strip_prefix = "rules_jvm_external-4.1", urls = ["https://github.com/bazelbuild/rules_jvm_external/archive/4.1.zip"], ) + + if not native.existing_rule("rules_pkg"): + http_archive( + name = "rules_pkg", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.5.1/rules_pkg-0.5.1.tar.gz", + "https://github.com/bazelbuild/rules_pkg/releases/download/0.5.1/rules_pkg-0.5.1.tar.gz", + ], + sha256 = "a89e203d3cf264e564fcb96b6e06dd70bc0557356eb48400ce4b5d97c2c3720d", + ) + + if not native.existing_rule("io_bazel_rules_kotlin"): + http_archive( + name = "io_bazel_rules_kotlin", + urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v1.5.0-beta-4/rules_kotlin_release.tgz"], + sha256 = "6cbd4e5768bdfae1598662e40272729ec9ece8b7bded8f0d2c81c8ff96dc139d", + ) diff --git a/protobuf_version.bzl b/protobuf_version.bzl index 7f6d71460ca26..9ae134074173a 100644 --- a/protobuf_version.bzl +++ b/protobuf_version.bzl @@ -1 +1 @@ -PROTOBUF_VERSION = '3.18.1' +PROTOBUF_VERSION = '3.19.4' diff --git a/protoc-artifacts/build-zip.sh b/protoc-artifacts/build-zip.sh index 7d1923e6e608e..1d977259f3ea7 100755 --- a/protoc-artifacts/build-zip.sh +++ b/protoc-artifacts/build-zip.sh @@ -16,6 +16,7 @@ release page. If the target is protoc, well-known type .proto files will also be included. Each invocation will create 8 zip packages: dist/--win32.zip dist/--win64.zip + dist/--osx-aarch_64.zip dist/--osx-x86_64.zip dist/--linux-x86_32.zip dist/--linux-x86_64.zip @@ -33,6 +34,7 @@ VERSION_NUMBER=$2 declare -a FILE_NAMES=( \ win32.zip windows-x86_32.exe \ win64.zip windows-x86_64.exe \ + osx-aarch_64.zip osx-aarch_64.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 \ diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml index c3aa37771f3ed..1d0d18ef0f087 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -8,7 +8,7 @@ com.google.protobuf protoc - 3.18.1 + 3.19.4 pom Protobuf Compiler @@ -19,7 +19,7 @@ https://developers.google.com/protocol-buffers/ - 3-Clause BSD License + BSD-3-Clause https://opensource.org/licenses/BSD-3-Clause repo diff --git a/python/.repo-metadata.json b/python/.repo-metadata.json deleted file mode 100644 index c8d71a84ec593..0000000000000 --- a/python/.repo-metadata.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "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/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index 61c242f9dff07..9615a582fb58e 100644 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -617,6 +617,26 @@ def camelcase_name(self): self._camelcase_name = _ToCamelCase(self.name) return self._camelcase_name + @property + def has_presence(self): + """Whether the field distinguishes between unpopulated and default values. + + Raises: + RuntimeError: singular field that is not linked with message nor file. + """ + if self.label == FieldDescriptor.LABEL_REPEATED: + return False + if (self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE or + self.containing_oneof): + return True + if hasattr(self.file, 'syntax'): + return self.file.syntax == 'proto2' + if hasattr(self.message_type, 'syntax'): + return self.message_type.syntax == 'proto2' + raise RuntimeError( + 'has_presence is not ready to use because field %s is not' + ' linked with message type nor file' % self.full_name) + @staticmethod def ProtoTypeToCppProtoType(proto_type): """Converts from a Python proto type to a C++ Proto Type. @@ -879,6 +899,8 @@ class MethodDescriptor(DescriptorBase): accepts. output_type (Descriptor): The descriptor of the message that this method returns. + client_streaming (bool): Whether this method uses client streaming. + server_streaming (bool): Whether this method uses server streaming. options (descriptor_pb2.MethodOptions or None): Method options message, or None to use default method options. """ @@ -886,14 +908,32 @@ class MethodDescriptor(DescriptorBase): 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, + def __new__(cls, + name, + full_name, + index, + containing_service, + input_type, + output_type, + client_streaming=False, + server_streaming=False, + 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, + def __init__(self, + name, + full_name, + index, + containing_service, + input_type, + output_type, + client_streaming=False, + server_streaming=False, + options=None, + serialized_options=None, create_key=None): """The arguments are as described in the description of MethodDescriptor attributes above. @@ -911,6 +951,8 @@ def __init__(self, name, full_name, index, containing_service, self.containing_service = containing_service self.input_type = input_type self.output_type = output_type + self.client_streaming = client_streaming + self.server_streaming = server_streaming def CopyToProto(self, proto): """Copies this to a descriptor_pb2.MethodDescriptorProto. diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index a6955ce81e855..62b4307b34b6d 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -1213,6 +1213,8 @@ def _MakeMethodDescriptor(self, method_proto, service_name, package, scope, containing_service=None, input_type=input_type, output_type=output_type, + client_streaming=method_proto.client_streaming, + server_streaming=method_proto.server_streaming, options=_OptionsOrNone(method_proto), # pylint: disable=protected-access create_key=descriptor._internal_create_key) diff --git a/python/google/protobuf/internal/_parameterized.py b/python/google/protobuf/internal/_parameterized.py index 2229671ed6bb8..6b6ba657e6b10 100755 --- a/python/google/protobuf/internal/_parameterized.py +++ b/python/google/protobuf/internal/_parameterized.py @@ -357,7 +357,7 @@ class TestGeneratorMetaclass(type): def __new__(mcs, class_name, bases, dct): dct['_id_suffix'] = id_suffix = {} - for name, obj in dct.items(): + for name, obj in dct.copy().items(): if (name.startswith(unittest.TestLoader.testMethodPrefix) and _NonStringIterable(obj)): iterator = iter(obj) @@ -389,9 +389,8 @@ def _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator): id_suffix[new_name] = getattr(func, '__x_extra_id__', '') -class TestCase(unittest.TestCase): +class TestCase(unittest.TestCase, metaclass=TestGeneratorMetaclass): """Base class for test cases using the parameters decorator.""" - __metaclass__ = TestGeneratorMetaclass def _OriginalName(self): return self._testMethodName.split(_SEPARATOR)[0] diff --git a/python/google/protobuf/internal/api_implementation.cc b/python/google/protobuf/internal/api_implementation.cc index 6532a8140575b..241942eb3ceb4 100644 --- a/python/google/protobuf/internal/api_implementation.cc +++ b/python/google/protobuf/internal/api_implementation.cc @@ -81,24 +81,24 @@ static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, kModuleName, kModuleDocstring, -1, - NULL, - NULL, - NULL, - NULL, - NULL}; + nullptr, + nullptr, + nullptr, + nullptr, + nullptr}; extern "C" { PyMODINIT_FUNC PyInit__api_implementation() { PyObject* module = PyModule_Create(&_module); - if (module == NULL) { - return NULL; + if (module == nullptr) { + return nullptr; } // Adds the module variable "api_version". if (PyModule_AddIntConstant(module, const_cast(kImplVersionName), kImplVersion)) { Py_DECREF(module); - return NULL; + return nullptr; } return module; diff --git a/python/google/protobuf/internal/builder.py b/python/google/protobuf/internal/builder.py new file mode 100644 index 0000000000000..64353ee4af602 --- /dev/null +++ b/python/google/protobuf/internal/builder.py @@ -0,0 +1,130 @@ +# 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. + +"""Builds descriptors, message classes and services for generated _pb2.py. + +This file is only called in python generated _pb2.py files. It builds +descriptors, message classes and services that users can directly use +in generated code. +""" + +__author__ = 'jieluo@google.com (Jie Luo)' + +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database + +_sym_db = _symbol_database.Default() + + +def BuildMessageAndEnumDescriptors(file_des, module): + """Builds message and enum descriptors. + + Args: + file_des: FileDescriptor of the .proto file + module: Generated _pb2 module + """ + + def BuildNestedDescriptors(msg_des, prefix): + for (name, nested_msg) in msg_des.nested_types_by_name.items(): + module_name = prefix + name.upper() + module[module_name] = nested_msg + BuildNestedDescriptors(nested_msg, module_name + '_') + for enum_des in msg_des.enum_types: + module[prefix + enum_des.name.upper()] = enum_des + + for (name, msg_des) in file_des.message_types_by_name.items(): + module_name = '_' + name.upper() + module[module_name] = msg_des + BuildNestedDescriptors(msg_des, module_name + '_') + + +def BuildTopDescriptorsAndMessages(file_des, module_name, module): + """Builds top level descriptors and message classes. + + Args: + file_des: FileDescriptor of the .proto file + module_name: str, the name of generated _pb2 module + module: Generated _pb2 module + """ + + def BuildMessage(msg_des): + create_dict = {} + for (name, nested_msg) in msg_des.nested_types_by_name.items(): + create_dict[name] = BuildMessage(nested_msg) + create_dict['DESCRIPTOR'] = msg_des + create_dict['__module__'] = module_name + message_class = _reflection.GeneratedProtocolMessageType( + msg_des.name, (_message.Message,), create_dict) + _sym_db.RegisterMessage(message_class) + return message_class + + # top level enums + for (name, enum_des) in file_des.enum_types_by_name.items(): + module['_' + name.upper()] = enum_des + module[name] = enum_type_wrapper.EnumTypeWrapper(enum_des) + for enum_value in enum_des.values: + module[enum_value.name] = enum_value.number + + # top level extensions + for (name, extension_des) in file_des.extensions_by_name.items(): + module[name.upper() + '_FIELD_NUMBER'] = extension_des.number + module[name] = extension_des + + # services + for (name, service) in file_des.services_by_name.items(): + module['_' + name.upper()] = service + + # Build messages. + for (name, msg_des) in file_des.message_types_by_name.items(): + module[name] = BuildMessage(msg_des) + + +def BuildServices(file_des, module_name, module): + """Builds services classes and services stub class. + + Args: + file_des: FileDescriptor of the .proto file + module_name: str, the name of generated _pb2 module + module: Generated _pb2 module + """ + # pylint: disable=g-import-not-at-top + from google.protobuf import service as _service + from google.protobuf import service_reflection + # pylint: enable=g-import-not-at-top + for (name, service) in file_des.services_by_name.items(): + module[name] = service_reflection.GeneratedServiceType( + name, (_service.Service,), + dict(DESCRIPTOR=service, __module__=module_name)) + stub_name = name + '_Stub' + module[stub_name] = service_reflection.GeneratedServiceStubType( + stub_name, (module[name],), + dict(DESCRIPTOR=service, __module__=module_name)) diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py index f0c06df8dd1c4..29fbb53d2fce4 100644 --- a/python/google/protobuf/internal/containers.py +++ b/python/google/protobuf/internal/containers.py @@ -40,19 +40,37 @@ includes groups and nested messages. """ -__author__ = 'petar@google.com (Petar Petrov)' - import collections.abc - - -class BaseContainer(object): - +import copy +import pickle +from typing import ( + Any, + Iterable, + Iterator, + List, + MutableMapping, + MutableSequence, + NoReturn, + Optional, + Sequence, + TypeVar, + Union, + overload, +) + + +_T = TypeVar('_T') +_K = TypeVar('_K') +_V = TypeVar('_V') + + +class BaseContainer(Sequence[_T]): """Base container class.""" # Minimizes memory usage and disallows assignment to other attributes. __slots__ = ['_message_listener', '_values'] - def __init__(self, message_listener): + def __init__(self, message_listener: Any) -> None: """ Args: message_listener: A MessageListener implementation. @@ -62,26 +80,33 @@ def __init__(self, message_listener): self._message_listener = message_listener self._values = [] + @overload + def __getitem__(self, key: int) -> _T: + ... + + @overload + def __getitem__(self, key: slice) -> List[_T]: + ... + def __getitem__(self, key): """Retrieves item by the specified key.""" return self._values[key] - def __len__(self): + def __len__(self) -> int: """Returns the number of elements in the container.""" return len(self._values) - def __ne__(self, other): + def __ne__(self, other: Any) -> bool: """Checks if another instance isn't equal to this one.""" # The concrete classes should define __eq__. return not self == other - def __hash__(self): - raise TypeError('unhashable object') + __hash__ = None - def __repr__(self): + def __repr__(self) -> str: return repr(self._values) - def sort(self, *args, **kwargs): + def sort(self, *args, **kwargs) -> None: # Continue to support the old sort_function keyword argument. # This is expected to be a rare occurrence, so use LBYL to avoid # the overhead of actually catching KeyError. @@ -89,20 +114,26 @@ def sort(self, *args, **kwargs): kwargs['cmp'] = kwargs.pop('sort_function') self._values.sort(*args, **kwargs) - def reverse(self): + def reverse(self) -> None: self._values.reverse() +# TODO(slebedev): Remove this. BaseContainer does *not* conform to +# MutableSequence, only its subclasses do. collections.abc.MutableSequence.register(BaseContainer) -class RepeatedScalarFieldContainer(BaseContainer): +class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]): """Simple, type-checked, list-like container for holding repeated scalars.""" # Disallows assignment to other attributes. __slots__ = ['_type_checker'] - def __init__(self, message_listener, type_checker): + def __init__( + self, + message_listener: Any, + type_checker: Any, + ) -> None: """Args: message_listener: A MessageListener implementation. The @@ -111,24 +142,23 @@ def __init__(self, message_listener, type_checker): type_checker: A type_checkers.ValueChecker instance to run on elements inserted into this container. """ - super(RepeatedScalarFieldContainer, self).__init__(message_listener) + super().__init__(message_listener) self._type_checker = type_checker - def append(self, value): + def append(self, value: _T) -> None: """Appends an item to the list. Similar to list.append().""" self._values.append(self._type_checker.CheckValue(value)) if not self._message_listener.dirty: self._message_listener.Modified() - def insert(self, key, value): + def insert(self, key: int, value: _T) -> None: """Inserts the item at the specified position. Similar to list.insert().""" self._values.insert(key, self._type_checker.CheckValue(value)) if not self._message_listener.dirty: self._message_listener.Modified() - def extend(self, elem_seq): + def extend(self, elem_seq: Iterable[_T]) -> None: """Extends by appending the given iterable. Similar to list.extend().""" - if elem_seq is None: return try: @@ -145,57 +175,52 @@ def extend(self, elem_seq): self._values.extend(new_values) self._message_listener.Modified() - def MergeFrom(self, other): + def MergeFrom( + self, + other: Union['RepeatedScalarFieldContainer[_T]', Iterable[_T]], + ) -> None: """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) + self._values.extend(other) self._message_listener.Modified() - def remove(self, elem): + def remove(self, elem: _T): """Removes an item from the list. Similar to list.remove().""" self._values.remove(elem) self._message_listener.Modified() - def pop(self, key=-1): + def pop(self, key: Optional[int] = -1) -> _T: """Removes and returns an item at a given index. Similar to list.pop().""" value = self._values[key] self.__delitem__(key) return value - def __setitem__(self, key, value): + @overload + def __setitem__(self, key: int, value: _T) -> None: + ... + + @overload + def __setitem__(self, key: slice, value: Iterable[_T]) -> None: + ... + + def __setitem__(self, key, value) -> None: """Sets the item on the specified position.""" - if isinstance(key, slice): # PY3 + if isinstance(key, slice): if key.step is not None: raise ValueError('Extended slices not supported') - self.__setslice__(key.start, key.stop, value) + self._values[key] = map(self._type_checker.CheckValue, value) + self._message_listener.Modified() else: self._values[key] = self._type_checker.CheckValue(value) self._message_listener.Modified() - def __getslice__(self, start, stop): - """Retrieves the subset of items from between the specified indices.""" - return self._values[start:stop] - - def __setslice__(self, start, stop, values): - """Sets the subset of items from between the specified indices.""" - new_values = [] - for value in values: - new_values.append(self._type_checker.CheckValue(value)) - self._values[start:stop] = new_values - self._message_listener.Modified() - - def __delitem__(self, key): + def __delitem__(self, key: Union[int, slice]) -> None: """Deletes the item at the specified position.""" del self._values[key] self._message_listener.Modified() - def __delslice__(self, start, stop): - """Deletes the subset of items from between the specified indices.""" - del self._values[start:stop] - self._message_listener.Modified() - - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: """Compares the current instance with another one.""" if self is other: return True @@ -205,15 +230,28 @@ def __eq__(self, other): # We are presumably comparing against some other sequence type. return other == self._values + def __deepcopy__( + self, + unused_memo: Any = None, + ) -> 'RepeatedScalarFieldContainer[_T]': + clone = RepeatedScalarFieldContainer( + copy.deepcopy(self._message_listener), self._type_checker) + clone.MergeFrom(self) + return clone + + def __reduce__(self, **kwargs) -> NoReturn: + raise pickle.PickleError( + "Can't pickle repeated scalar fields, convert to list first") -class RepeatedCompositeFieldContainer(BaseContainer): +# TODO(slebedev): Constrain T to be a subtype of Message. +class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]): """Simple, list-like container for holding repeated composite fields.""" # Disallows assignment to other attributes. __slots__ = ['_message_descriptor'] - def __init__(self, message_listener, message_descriptor): + def __init__(self, message_listener: Any, message_descriptor: Any) -> None: """ Note that we pass in a descriptor instead of the generated directly, since at the time we construct a _RepeatedCompositeFieldContainer we @@ -228,10 +266,10 @@ def __init__(self, message_listener, message_descriptor): that should be present in this container. We'll use the _concrete_class field of this descriptor when the client calls add(). """ - super(RepeatedCompositeFieldContainer, self).__init__(message_listener) + super().__init__(message_listener) self._message_descriptor = message_descriptor - def add(self, **kwargs): + def add(self, **kwargs: Any) -> _T: """Adds a new element at the end of the list and returns it. Keyword arguments may be used to initialize the element. """ @@ -242,7 +280,7 @@ def add(self, **kwargs): self._message_listener.Modified() return new_element - def append(self, value): + def append(self, value: _T) -> None: """Appends one element by copying the message.""" new_element = self._message_descriptor._concrete_class() new_element._SetListener(self._message_listener) @@ -251,7 +289,7 @@ def append(self, value): if not self._message_listener.dirty: self._message_listener.Modified() - def insert(self, key, value): + def insert(self, key: int, value: _T) -> None: """Inserts the item at the specified position by copying.""" new_element = self._message_descriptor._concrete_class() new_element._SetListener(self._message_listener) @@ -260,7 +298,7 @@ def insert(self, key, value): if not self._message_listener.dirty: self._message_listener.Modified() - def extend(self, elem_seq): + def extend(self, elem_seq: Iterable[_T]) -> None: """Extends by appending the given sequence of elements of the same type as this one, copying each individual message. @@ -275,38 +313,47 @@ def extend(self, elem_seq): values.append(new_element) listener.Modified() - def MergeFrom(self, other): + def MergeFrom( + self, + other: Union['RepeatedCompositeFieldContainer[_T]', Iterable[_T]], + ) -> None: """Appends the contents of another repeated field of the same type to this one, copying each individual message. """ - self.extend(other._values) + self.extend(other) - def remove(self, elem): + def remove(self, elem: _T) -> None: """Removes an item from the list. Similar to list.remove().""" self._values.remove(elem) self._message_listener.Modified() - def pop(self, key=-1): + def pop(self, key: Optional[int] = -1) -> _T: """Removes and returns an item at a given index. Similar to list.pop().""" value = self._values[key] self.__delitem__(key) return value - def __getslice__(self, start, stop): - """Retrieves the subset of items from between the specified indices.""" - return self._values[start:stop] + @overload + def __setitem__(self, key: int, value: _T) -> None: + ... + + @overload + def __setitem__(self, key: slice, value: Iterable[_T]) -> None: + ... + + def __setitem__(self, key, value): + # This method is implemented to make RepeatedCompositeFieldContainer + # structurally compatible with typing.MutableSequence. It is + # otherwise unsupported and will always raise an error. + raise TypeError( + f'{self.__class__.__name__} object does not support item assignment') - def __delitem__(self, key): + def __delitem__(self, key: Union[int, slice]) -> None: """Deletes the item at the specified position.""" del self._values[key] self._message_listener.Modified() - def __delslice__(self, start, stop): - """Deletes the subset of items from between the specified indices.""" - del self._values[start:stop] - self._message_listener.Modified() - - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: """Compares the current instance with another one.""" if self is other: return True @@ -316,16 +363,20 @@ def __eq__(self, other): return self._values == other._values -class ScalarMap(collections.abc.MutableMapping): - +class ScalarMap(MutableMapping[_K, _V]): """Simple, type-checked, dict-like container for holding repeated scalars.""" # Disallows assignment to other attributes. __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener', '_entry_descriptor'] - def __init__(self, message_listener, key_checker, value_checker, - entry_descriptor): + def __init__( + self, + message_listener: Any, + key_checker: Any, + value_checker: Any, + entry_descriptor: Any, + ) -> None: """ Args: message_listener: A MessageListener implementation. @@ -343,7 +394,7 @@ def __init__(self, message_listener, key_checker, value_checker, self._entry_descriptor = entry_descriptor self._values = {} - def __getitem__(self, key): + def __getitem__(self, key: _K) -> _V: try: return self._values[key] except KeyError: @@ -352,12 +403,20 @@ def __getitem__(self, key): self._values[key] = val return val - def __contains__(self, item): + def __contains__(self, item: _K) -> bool: # We check the key's type to match the strong-typing flavor of the API. # Also this makes it easier to match the behavior of the C++ implementation. self._key_checker.CheckValue(item) return item in self._values + @overload + def get(self, key: _K) -> Optional[_V]: + ... + + @overload + def get(self, key: _K, default: _T) -> Union[_V, _T]: + ... + # We need to override this explicitly, because our defaultdict-like behavior # will make the default implementation (from our base class) always insert # the key. @@ -367,30 +426,30 @@ def get(self, key, default=None): else: return default - def __setitem__(self, key, value): + def __setitem__(self, key: _K, value: _V) -> _T: checked_key = self._key_checker.CheckValue(key) checked_value = self._value_checker.CheckValue(value) self._values[checked_key] = checked_value self._message_listener.Modified() - def __delitem__(self, key): + def __delitem__(self, key: _K) -> None: del self._values[key] self._message_listener.Modified() - def __len__(self): + def __len__(self) -> int: return len(self._values) - def __iter__(self): + def __iter__(self) -> Iterator[_K]: return iter(self._values) - def __repr__(self): + def __repr__(self) -> str: return repr(self._values) - def MergeFrom(self, other): + def MergeFrom(self, other: 'ScalarMap[_K, _V]') -> None: self._values.update(other._values) self._message_listener.Modified() - def InvalidateIterators(self): + def InvalidateIterators(self) -> None: # It appears that the only way to reliably invalidate iterators to # self._values is to ensure that its size changes. original = self._values @@ -398,24 +457,28 @@ def InvalidateIterators(self): original[None] = None # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self): + def clear(self) -> None: self._values.clear() self._message_listener.Modified() - def GetEntryClass(self): + def GetEntryClass(self) -> Any: return self._entry_descriptor._concrete_class -class MessageMap(collections.abc.MutableMapping): - +class MessageMap(MutableMapping[_K, _V]): """Simple, type-checked, dict-like container for with submessage values.""" # Disallows assignment to other attributes. __slots__ = ['_key_checker', '_values', '_message_listener', '_message_descriptor', '_entry_descriptor'] - def __init__(self, message_listener, message_descriptor, key_checker, - entry_descriptor): + def __init__( + self, + message_listener: Any, + message_descriptor: Any, + key_checker: Any, + entry_descriptor: Any, + ) -> None: """ Args: message_listener: A MessageListener implementation. @@ -433,7 +496,7 @@ def __init__(self, message_listener, message_descriptor, key_checker, self._entry_descriptor = entry_descriptor self._values = {} - def __getitem__(self, key): + def __getitem__(self, key: _K) -> _V: key = self._key_checker.CheckValue(key) try: return self._values[key] @@ -442,10 +505,9 @@ def __getitem__(self, key): new_element._SetListener(self._message_listener) self._values[key] = new_element self._message_listener.Modified() - return new_element - def get_or_create(self, key): + def get_or_create(self, key: _K) -> _V: """get_or_create() is an alias for getitem (ie. map[key]). Args: @@ -459,6 +521,14 @@ def get_or_create(self, key): """ return self[key] + @overload + def get(self, key: _K) -> Optional[_V]: + ... + + @overload + def get(self, key: _K, default: _T) -> Union[_V, _T]: + ... + # We need to override this explicitly, because our defaultdict-like behavior # will make the default implementation (from our base class) always insert # the key. @@ -468,28 +538,28 @@ def get(self, key, default=None): else: return default - def __contains__(self, item): + def __contains__(self, item: _K) -> bool: item = self._key_checker.CheckValue(item) return item in self._values - def __setitem__(self, key, value): + def __setitem__(self, key: _K, value: _V) -> NoReturn: raise ValueError('May not set values directly, call my_map[key].foo = 5') - def __delitem__(self, key): + def __delitem__(self, key: _K) -> None: key = self._key_checker.CheckValue(key) del self._values[key] self._message_listener.Modified() - def __len__(self): + def __len__(self) -> int: return len(self._values) - def __iter__(self): + def __iter__(self) -> Iterator[_K]: return iter(self._values) - def __repr__(self): + def __repr__(self) -> str: return repr(self._values) - def MergeFrom(self, other): + def MergeFrom(self, other: 'MessageMap[_K, _V]') -> None: # pylint: disable=protected-access for key in other._values: # According to documentation: "When parsing from the wire or when merging, @@ -500,7 +570,7 @@ def MergeFrom(self, other): # self._message_listener.Modified() not required here, because # mutations to submessages already propagate. - def InvalidateIterators(self): + def InvalidateIterators(self) -> None: # It appears that the only way to reliably invalidate iterators to # self._values is to ensure that its size changes. original = self._values @@ -508,16 +578,15 @@ def InvalidateIterators(self): original[None] = None # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self): + def clear(self) -> None: self._values.clear() self._message_listener.Modified() - def GetEntryClass(self): + def GetEntryClass(self) -> Any: return self._entry_descriptor._concrete_class -class _UnknownField(object): - +class _UnknownField: """A parsed unknown field.""" # Disallows assignment to other attributes. @@ -542,12 +611,11 @@ def __eq__(self, other): self._data == other._data) -class UnknownFieldRef(object): +class UnknownFieldRef: # pylint: disable=missing-class-docstring def __init__(self, parent, index): self._parent = parent self._index = index - return def _check_valid(self): if not self._parent: @@ -576,8 +644,7 @@ def data(self): return self._parent._internal_get(self._index)._data -class UnknownFieldSet(object): - +class UnknownFieldSet: """UnknownField container""" # Disallows assignment to other attributes. diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index 88d7136bc86ab..d026a7472811f 100644 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -51,6 +51,28 @@ name: 'TestEmptyMessage' """ +TEST_FILE_DESCRIPTOR_DEBUG = """syntax = "proto2"; + +package protobuf_unittest; + +message NestedMessage { + enum ForeignEnum { + FOREIGN_FOO = 4; + FOREIGN_BAR = 5; + FOREIGN_BAZ = 6; + } + optional int32 bb = 1; +} + +message ResponseMessage { +} + +service Service { + rpc CallMethod(.protobuf_unittest.NestedMessage) returns (.protobuf_unittest.ResponseMessage); +} + +""" + warnings.simplefilter('error', DeprecationWarning) @@ -121,6 +143,13 @@ def testContainingTypeFixups(self): def testContainingServiceFixups(self): self.assertEqual(self.my_service, self.my_method.containing_service) + @unittest.skipIf( + api_implementation.Type() != 'cpp', + 'GetDebugString is only available with the cpp implementation', + ) + def testGetDebugString(self): + self.assertEqual(self.my_file.GetDebugString(), TEST_FILE_DESCRIPTOR_DEBUG) + def testGetOptions(self): self.assertEqual(self.my_enum.GetOptions(), descriptor_pb2.EnumOptions()) @@ -523,6 +552,7 @@ def CheckFieldDescriptor(self, field_descriptor): self.assertIn(field_descriptor, {field_descriptor: None}) self.assertEqual(None, field_descriptor.extension_scope) self.assertEqual(None, field_descriptor.enum_type) + self.assertTrue(field_descriptor.has_presence) if api_implementation.Type() == 'cpp': # For test coverage only self.assertEqual(field_descriptor.id, field_descriptor.id) diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index af3713fcb5a2d..3545563957a35 100644 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -697,8 +697,7 @@ def testAnyMessageDescriptorPoolMissingType(self): json_format.MessageToJson(message, True, descriptor_pool=empty_pool) self.assertEqual( 'Can not find message descriptor by type_url:' - ' type.googleapis.com/protobuf_unittest.OneString.', - str(cm.exception)) + ' type.googleapis.com/protobuf_unittest.OneString', str(cm.exception)) def testWellKnownInAnyMessage(self): message = any_pb2.Any() @@ -815,14 +814,15 @@ def testParseNull(self): # Null is not allowed to be used as an element in repeated field. self.assertRaisesRegexp( json_format.ParseError, - 'Failed to parse repeatedInt32Value field: ' - 'null is not allowed to be used as an element in a repeated field.', - json_format.Parse, - '{"repeatedInt32Value":[1, null]}', - parsed_message) - self.CheckError('{"repeatedMessageValue":[null]}', - 'Failed to parse repeatedMessageValue field: null is not' - ' allowed to be used as an element in a repeated field.') + r'Failed to parse repeatedInt32Value field: ' + r'null is not allowed to be used as an element in a repeated field ' + r'at TestMessage.repeatedInt32Value\[1\].', json_format.Parse, + '{"repeatedInt32Value":[1, null]}', parsed_message) + self.CheckError( + '{"repeatedMessageValue":[null]}', + r'Failed to parse repeatedMessageValue field: null is not' + r' allowed to be used as an element in a repeated field ' + r'at TestMessage.repeatedMessageValue\[0\].') def testNanFloat(self): message = json_format_proto3_pb2.TestMessage() @@ -840,9 +840,9 @@ def testParseDoubleToFloat(self): 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.') + self.CheckError( + text, r'Failed to parse repeatedFloatValue field: ' + r'Float value too large at TestMessage.repeatedFloatValue\[0\].') def testFloatPrecision(self): message = json_format_proto3_pb2.TestMessage() @@ -895,7 +895,7 @@ def testParseEnumValue(self): self.CheckError( '{"enumValue": "baz"}', 'Failed to parse enumValue field: Invalid enum value baz ' - 'for enum type proto3.EnumType.') + 'for enum type proto3.EnumType at TestMessage.enumValue.') # Proto3 accepts numeric unknown enums. text = '{"enumValue": 12345}' json_format.Parse(text, message) @@ -904,8 +904,9 @@ def testParseEnumValue(self): self.assertRaisesRegexp( json_format.ParseError, 'Failed to parse optionalNestedEnum field: Invalid enum value 12345 ' - 'for enum type protobuf_unittest.TestAllTypes.NestedEnum.', - json_format.Parse, '{"optionalNestedEnum": 12345}', message) + 'for enum type protobuf_unittest.TestAllTypes.NestedEnum at ' + 'TestAllTypes.optionalNestedEnum.', json_format.Parse, + '{"optionalNestedEnum": 12345}', message) def testBytes(self): message = json_format_proto3_pb2.TestMessage() @@ -928,9 +929,10 @@ def testParseBadIdentifer(self): self.CheckError('{int32Value: 1}', (r'Failed to load JSON: Expecting property name' r'( enclosed in double quotes)?: line 1')) - self.CheckError('{"unknownName": 1}', - 'Message type "proto3.TestMessage" has no field named ' - '"unknownName".') + self.CheckError( + '{"unknownName": 1}', + 'Message type "proto3.TestMessage" has no field named ' + '"unknownName" at "TestMessage".') def testIgnoreUnknownField(self): text = '{"unknownName": 1}' @@ -950,33 +952,34 @@ def testDuplicateField(self): 'Failed to load JSON: duplicate key int32Value.') def testInvalidBoolValue(self): - self.CheckError('{"boolValue": 1}', - 'Failed to parse boolValue field: ' - 'Expected true or false without quotes.') - self.CheckError('{"boolValue": "true"}', - 'Failed to parse boolValue field: ' - 'Expected true or false without quotes.') + self.CheckError( + '{"boolValue": 1}', 'Failed to parse boolValue field: ' + 'Expected true or false without quotes at TestMessage.boolValue.') + self.CheckError( + '{"boolValue": "true"}', 'Failed to parse boolValue field: ' + 'Expected true or false without quotes at TestMessage.boolValue.') def testInvalidIntegerValue(self): message = json_format_proto3_pb2.TestMessage() text = '{"int32Value": 0x12345}' self.assertRaises(json_format.ParseError, json_format.Parse, text, message) - self.CheckError('{"int32Value": 1.5}', - 'Failed to parse int32Value field: ' - 'Couldn\'t parse integer: 1.5.') + self.CheckError( + '{"int32Value": 1.5}', 'Failed to parse int32Value field: ' + 'Couldn\'t parse integer: 1.5 at TestMessage.int32Value.') self.CheckError('{"int32Value": 012345}', (r'Failed to load JSON: Expecting \'?,\'? delimiter: ' r'line 1.')) - self.CheckError('{"int32Value": " 1 "}', - 'Failed to parse int32Value field: ' - 'Couldn\'t parse integer: " 1 ".') - self.CheckError('{"int32Value": "1 "}', - 'Failed to parse int32Value field: ' - 'Couldn\'t parse integer: "1 ".') - self.CheckError('{"int32Value": false}', - 'Failed to parse int32Value field: Bool value False ' - 'is not acceptable for integer field.') + self.CheckError( + '{"int32Value": " 1 "}', 'Failed to parse int32Value field: ' + 'Couldn\'t parse integer: " 1 " at TestMessage.int32Value.') + self.CheckError( + '{"int32Value": "1 "}', 'Failed to parse int32Value field: ' + 'Couldn\'t parse integer: "1 " at TestMessage.int32Value.') + self.CheckError( + '{"int32Value": false}', + 'Failed to parse int32Value field: Bool value False ' + 'is not acceptable for integer field at TestMessage.int32Value.') self.CheckError('{"int32Value": 12345678901234567890}', 'Failed to parse int32Value field: Value out of range: ' '12345678901234567890.') @@ -985,9 +988,9 @@ def testInvalidIntegerValue(self): 'Value out of range: -1.') def testInvalidFloatValue(self): - self.CheckError('{"floatValue": "nan"}', - 'Failed to parse floatValue field: Couldn\'t ' - 'parse float "nan", use "NaN" instead.') + self.CheckError( + '{"floatValue": "nan"}', 'Failed to parse floatValue field: Couldn\'t ' + 'parse float "nan", use "NaN" instead at TestMessage.floatValue.') self.CheckError('{"floatValue": NaN}', 'Failed to parse floatValue field: Couldn\'t ' 'parse NaN, use quoted "NaN" instead.') @@ -1008,9 +1011,10 @@ def testInvalidFloatValue(self): 'Failed to parse floatValue field: Float value too small.') def testInvalidRepeated(self): - self.CheckError('{"repeatedInt32Value": 12345}', - (r'Failed to parse repeatedInt32Value field: repeated field' - r' repeatedInt32Value must be in \[\] which is 12345.')) + self.CheckError( + '{"repeatedInt32Value": 12345}', + (r'Failed to parse repeatedInt32Value field: repeated field' + r' repeatedInt32Value must be in \[\] which is 12345 at TestMessage.')) def testInvalidMap(self): message = json_format_proto3_pb2.TestMap() @@ -1028,8 +1032,8 @@ def testInvalidMap(self): text = '{"boolMap": {"null": 1}}' self.assertRaisesRegexp( json_format.ParseError, - 'Failed to parse boolMap field: Expected "true" or "false", not null.', - json_format.Parse, text, message) + 'Failed to parse boolMap field: Expected "true" or "false", not null at ' + 'TestMap.boolMap.key', json_format.Parse, text, message) text = r'{"stringMap": {"a": 3, "\u0061": 2}}' self.assertRaisesRegexp( json_format.ParseError, @@ -1039,17 +1043,16 @@ def testInvalidMap(self): self.assertRaisesRegexp( json_format.ParseError, 'Failed to parse stringMap field: Map field string_map must be ' - 'in a dict which is 0.', - json_format.Parse, text, message) + 'in a dict which is 0 at TestMap.stringMap.', json_format.Parse, text, + message) def testInvalidTimestamp(self): message = json_format_proto3_pb2.TestTimestamp() text = '{"value": "10000-01-01T00:00:00.00Z"}' self.assertRaisesRegexp( - json_format.ParseError, - 'Failed to parse value field: ' + json_format.ParseError, 'Failed to parse value field: ' 'time data \'10000-01-01T00:00:00\' does not match' - ' format \'%Y-%m-%dT%H:%M:%S\'.', + ' format \'%Y-%m-%dT%H:%M:%S\' at TestTimestamp.value.', json_format.Parse, text, message) text = '{"value": "1970-01-01T00:00:00.0123456789012Z"}' self.assertRaisesRegexp( @@ -1080,16 +1083,15 @@ def testInvalidTimestamp(self): self.assertEqual( 'Failed to parse value field: ' 'time data \'0001-01-01t00:00:00\' does not match format ' - '\'%Y-%m-%dT%H:%M:%S\', lowercase \'t\' is not accepted.', - str(e.exception)) + '\'%Y-%m-%dT%H:%M:%S\', lowercase \'t\' is not accepted ' + 'at TestTimestamp.value.', str(e.exception)) def testInvalidOneof(self): message = json_format_proto3_pb2.TestOneof() text = '{"oneofInt32Value": 1, "oneofStringValue": "2"}' self.assertRaisesRegexp( - json_format.ParseError, - 'Message type "proto3.TestOneof"' - ' should not have multiple "oneof_value" oneof fields.', + json_format.ParseError, 'Message type "proto3.TestOneof"' + ' should not have multiple "oneof_value" oneof fields at "TestOneof".', json_format.Parse, text, message) def testInvalidListValue(self): @@ -1097,15 +1099,27 @@ def testInvalidListValue(self): text = '{"value": 1234}' self.assertRaisesRegexp( json_format.ParseError, - r'Failed to parse value field: ListValue must be in \[\] which is 1234', + r'Failed to parse value field: ListValue must be in \[\] which is ' + '1234 at TestListValue.value.', json_format.Parse, text, message) + class UnknownClass(object): + + def __str__(self): + return 'v' + self.assertRaisesRegex( + json_format.ParseError, + r' at TestListValue.value\[1\].fake.', + json_format.ParseDict, + {'value': ['hello', {'fake': UnknownClass()}]}, message) + def testInvalidStruct(self): message = json_format_proto3_pb2.TestStruct() text = '{"value": 1234}' self.assertRaisesRegexp( json_format.ParseError, - 'Failed to parse value field: Struct must be in a dict which is 1234', + 'Failed to parse value field: Struct must be in a dict which is ' + '1234 at TestStruct.value', json_format.Parse, text, message) def testTimestampInvalidStringValue(self): @@ -1140,16 +1154,14 @@ def testInvalidAny(self): 'value', json_format.Parse, text, message) text = '{"value": 1234}' - self.assertRaisesRegexp( - json_format.ParseError, - '@type is missing when parsing any message.', - json_format.Parse, text, message) + self.assertRaisesRegex(json_format.ParseError, + '@type is missing when parsing any message at Any', + json_format.Parse, text, message) text = '{"@type": "type.googleapis.com/MessageNotExist", "value": 1234}' - self.assertRaisesRegexp( - TypeError, - 'Can not find message descriptor by type_url: ' - 'type.googleapis.com/MessageNotExist.', - json_format.Parse, text, message) + self.assertRaisesRegex( + json_format.ParseError, 'Can not find message descriptor by type_url: ' + 'type.googleapis.com/MessageNotExist at Any', json_format.Parse, text, + message) # Only last part is to be used: b/25630112 text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",' r'"value": 1234}') @@ -1225,7 +1237,9 @@ def testParseDictAnyDescriptorPoolMissingType(self): self.assertEqual( str(cm.exception), 'Failed to parse any_value field: Can not find message descriptor by' - ' type_url: type.googleapis.com/proto3.MessageType..') + ' type_url: type.googleapis.com/proto3.MessageType at ' + 'TestAny.any_value.' + ) def testParseDictUnknownValueType(self): class UnknownClass(object): @@ -1271,6 +1285,18 @@ def testSortKeys(self): 'uint32Value': 4, 'stringValue': 'bla'}, indent=2, sort_keys=True)) + def testNestedRecursiveLimit(self): + message = unittest_pb2.NestedTestAllTypes() + self.assertRaisesRegex( + json_format.ParseError, + 'Message too deep. Max recursion depth is 3', + json_format.Parse, + '{"child": {"child": {"child" : {}}}}', + message, + max_recursion_depth=3) + # The following one can pass + json_format.Parse('{"payload": {}, "child": {"child":{}}}', + message, max_recursion_depth=3) if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index 6ed1f20ef5f4d..e8d86a2df8961 100644 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -59,6 +59,7 @@ from google.protobuf import unittest_pb2 from google.protobuf import unittest_proto3_arena_pb2 from google.protobuf import descriptor_pb2 +from google.protobuf import descriptor from google.protobuf import descriptor_pool from google.protobuf import message_factory from google.protobuf import text_format @@ -1147,16 +1148,32 @@ def testExtendStringWithIterable(self, message_module): m.repeated_string.extend(MessageTest.TestIterable(['3', '4'])) self.assertSequenceEqual(['', '1', '2', '3', '4'], m.repeated_string) + class TestIndex(object): + """This index object mimics the behavior of numpy.int64 and other types.""" + + def __init__(self, value=None): + self.value = value + + def __index__(self): + return self.value + + def testRepeatedIndexingWithIntIndex(self, message_module): + msg = message_module.TestAllTypes() + msg.repeated_int32.extend([1, 2, 3]) + self.assertEqual(1, msg.repeated_int32[MessageTest.TestIndex(0)]) + + def testRepeatedIndexingWithNegative1IntIndex(self, message_module): + msg = message_module.TestAllTypes() + msg.repeated_int32.extend([1, 2, 3]) + self.assertEqual(3, msg.repeated_int32[MessageTest.TestIndex(-1)]) + + def testRepeatedIndexingWithNegative1Int(self, message_module): + msg = message_module.TestAllTypes() + msg.repeated_int32.extend([1, 2, 3]) + self.assertEqual(3, msg.repeated_int32[-1]) + def testPickleRepeatedScalarContainer(self, message_module): - # TODO(tibell): The pure-Python implementation support pickling of - # scalar containers in *some* cases. For now the cpp2 version - # throws an exception to avoid a segfault. Investigate if we - # want to support pickling of these fields. - # - # For more information see: https://b2.corp.google.com/u/0/issues/18677897 - if (api_implementation.Type() != 'cpp' or - api_implementation.Version() == 2): - return + # Pickle repeated scalar container is not supported. m = message_module.TestAllTypes() with self.assertRaises(pickle.PickleError) as _: pickle.dumps(m.repeated_int32, pickle.HIGHEST_PROTOCOL) @@ -1658,6 +1675,26 @@ def testProto3Optional(self): self.assertEqual(msg.WhichOneof('_optional_int32'), None) + # Test has presence: + for field in test_proto3_optional_pb2.TestProto3Optional.DESCRIPTOR.fields: + self.assertTrue(field.has_presence) + for field in unittest_pb2.TestAllTypes.DESCRIPTOR.fields: + if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: + self.assertFalse(field.has_presence) + else: + self.assertTrue(field.has_presence) + proto3_descriptor = unittest_proto3_arena_pb2.TestAllTypes.DESCRIPTOR + repeated_field = proto3_descriptor.fields_by_name['repeated_int32'] + self.assertFalse(repeated_field.has_presence) + singular_field = proto3_descriptor.fields_by_name['optional_int32'] + self.assertFalse(singular_field.has_presence) + optional_field = proto3_descriptor.fields_by_name['proto3_optional_int32'] + self.assertTrue(optional_field.has_presence) + message_field = proto3_descriptor.fields_by_name['optional_nested_message'] + self.assertTrue(message_field.has_presence) + oneof_field = proto3_descriptor.fields_by_name['oneof_uint32'] + self.assertTrue(oneof_field.has_presence) + def testAssignUnknownEnum(self): """Assigning an unknown enum value is allowed and preserves the value.""" m = unittest_proto3_arena_pb2.TestAllTypes() diff --git a/python/google/protobuf/internal/missing_enum_values.proto b/python/google/protobuf/internal/missing_enum_values.proto index 5c0f499dba069..37baca7e538df 100644 --- a/python/google/protobuf/internal/missing_enum_values.proto +++ b/python/google/protobuf/internal/missing_enum_values.proto @@ -44,9 +44,7 @@ message TestEnumValues { } message TestMissingEnumValues { - enum NestedEnum { - TWO = 2; - } + enum NestedEnum { TWO = 2; } optional NestedEnum optional_nested_enum = 1; repeated NestedEnum repeated_nested_enum = 2; repeated NestedEnum packed_nested_enum = 3 [packed = true]; @@ -55,3 +53,4 @@ message TestMissingEnumValues { message JustString { required string dummy = 1; } + diff --git a/python/google/protobuf/internal/python_protobuf.cc b/python/google/protobuf/internal/python_protobuf.cc index e823bf228ca23..26e3a8b98d3e1 100644 --- a/python/google/protobuf/internal/python_protobuf.cc +++ b/python/google/protobuf/internal/python_protobuf.cc @@ -36,8 +36,12 @@ namespace google { namespace protobuf { namespace python { -static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) { return NULL; } -static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) { return NULL; } +static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) { + return nullptr; +} +static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) { + return nullptr; +} // This is initialized with a default, stub implementation. // If python-google.protobuf.cc is loaded, the function pointer is overridden diff --git a/python/google/protobuf/internal/well_known_types.py b/python/google/protobuf/internal/well_known_types.py index 30ff12588f4df..b581ab750a39a 100644 --- a/python/google/protobuf/internal/well_known_types.py +++ b/python/google/protobuf/internal/well_known_types.py @@ -42,8 +42,7 @@ import calendar import collections.abc -from datetime import datetime -from datetime import timedelta +import datetime from google.protobuf.descriptor import FieldDescriptor @@ -89,7 +88,9 @@ def Is(self, descriptor): return '/' in self.type_url and self.TypeName() == descriptor.full_name -_EPOCH_DATETIME = datetime.utcfromtimestamp(0) +_EPOCH_DATETIME_NAIVE = datetime.datetime.utcfromtimestamp(0) +_EPOCH_DATETIME_AWARE = datetime.datetime.fromtimestamp( + 0, tz=datetime.timezone.utc) class Timestamp(object): @@ -109,7 +110,7 @@ def ToJsonString(self): total_sec = self.seconds + (self.nanos - nanos) // _NANOS_PER_SECOND seconds = total_sec % _SECONDS_PER_DAY days = (total_sec - seconds) // _SECONDS_PER_DAY - dt = datetime(1970, 1, 1) + timedelta(days, seconds) + dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(days, seconds) result = dt.isoformat() if (nanos % 1e9) == 0: @@ -159,8 +160,8 @@ def FromJsonString(self, value): raise ValueError( 'time data \'{0}\' does not match format \'%Y-%m-%dT%H:%M:%S\', ' 'lowercase \'t\' is not accepted'.format(second_value)) - date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT) - td = date_object - datetime(1970, 1, 1) + date_object = datetime.datetime.strptime(second_value, _TIMESTAMPFOMAT) + td = date_object - datetime.datetime(1970, 1, 1) seconds = td.seconds + td.days * _SECONDS_PER_DAY if len(nano_value) > 9: raise ValueError( @@ -191,7 +192,7 @@ def FromJsonString(self, value): def GetCurrentTime(self): """Get the current UTC into Timestamp.""" - self.FromDatetime(datetime.utcnow()) + self.FromDatetime(datetime.datetime.utcnow()) def ToNanoseconds(self): """Converts Timestamp to nanoseconds since epoch.""" @@ -231,14 +232,32 @@ def FromSeconds(self, seconds): self.seconds = seconds self.nanos = 0 - def ToDatetime(self): - """Converts Timestamp to datetime.""" - return _EPOCH_DATETIME + timedelta( - seconds=self.seconds, microseconds=_RoundTowardZero( - self.nanos, _NANOS_PER_MICROSECOND)) + def ToDatetime(self, tzinfo=None): + """Converts Timestamp to a datetime. + + Args: + tzinfo: A datetime.tzinfo subclass; defaults to None. + + Returns: + If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone + information, i.e. not aware that it's UTC). + + Otherwise, returns a timezone-aware datetime in the input timezone. + """ + delta = datetime.timedelta( + seconds=self.seconds, + microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND)) + if tzinfo is None: + return _EPOCH_DATETIME_NAIVE + delta + else: + return _EPOCH_DATETIME_AWARE.astimezone(tzinfo) + delta def FromDatetime(self, dt): - """Converts datetime to Timestamp.""" + """Converts datetime to Timestamp. + + Args: + dt: A datetime. If it's timezone-naive, it's assumed to be in UTC. + """ # Using this guide: http://wiki.python.org/moin/WorkingWithTime # And this conversion guide: http://docs.python.org/library/time.html @@ -363,7 +382,7 @@ def FromSeconds(self, seconds): def ToTimedelta(self): """Converts Duration to timedelta.""" - return timedelta( + return datetime.timedelta( seconds=self.seconds, microseconds=_RoundTowardZero( self.nanos, _NANOS_PER_MICROSECOND)) diff --git a/python/google/protobuf/internal/well_known_types_test.py b/python/google/protobuf/internal/well_known_types_test.py index d2632f9ceab6f..37aec7e7bffbc 100644 --- a/python/google/protobuf/internal/well_known_types_test.py +++ b/python/google/protobuf/internal/well_known_types_test.py @@ -36,6 +36,8 @@ import datetime import unittest +import dateutil.tz + from google.protobuf import any_pb2 from google.protobuf import duration_pb2 from google.protobuf import field_mask_pb2 @@ -48,9 +50,11 @@ from google.protobuf.internal import well_known_types from google.protobuf import descriptor from google.protobuf import text_format +from google3.pyglib import datelib +from google.protobuf.internal import _parameterized -class TimeUtilTestBase(unittest.TestCase): +class TimeUtilTestBase(_parameterized.TestCase): def CheckTimestampConversion(self, message, text): self.assertEqual(text, message.ToJsonString()) @@ -233,43 +237,68 @@ def testDurationIntegerConversion(self): message.FromNanoseconds(-1999) self.assertEqual(-1, message.ToMicroseconds()) - def testDatetimeConverison(self): + def testTimezoneNaiveDatetimeConversion(self): message = timestamp_pb2.Timestamp() - dt = datetime.datetime(1970, 1, 1) - message.FromDatetime(dt) - self.assertEqual(dt, message.ToDatetime()) + naive_utc_epoch = datetime.datetime(1970, 1, 1) + message.FromDatetime(naive_utc_epoch) + self.assertEqual(0, message.seconds) + self.assertEqual(0, message.nanos) + + self.assertEqual(naive_utc_epoch, message.ToDatetime()) + + naive_epoch_morning = datetime.datetime(1970, 1, 1, 8, 0, 0, 1) + message.FromDatetime(naive_epoch_morning) + self.assertEqual(8 * 3600, message.seconds) + self.assertEqual(1000, message.nanos) + + self.assertEqual(naive_epoch_morning, message.ToDatetime()) message.FromMilliseconds(1999) + self.assertEqual(1, message.seconds) + self.assertEqual(999_000_000, message.nanos) + self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0, 1, 999000), message.ToDatetime()) - dt = datetime.datetime(2555, 2, 22, 1, 2, 3, 456789) - message.FromDatetime(dt) - self.assertEqual(dt, message.ToDatetime()) - - dt = datetime.datetime.max - message.FromDatetime(dt) - self.assertEqual(dt, message.ToDatetime()) + naive_future = datetime.datetime(2555, 2, 22, 1, 2, 3, 456789) + message.FromDatetime(naive_future) + self.assertEqual(naive_future, message.ToDatetime()) - def testDatetimeConversionWithTimezone(self): - class TZ(datetime.tzinfo): + naive_end_of_time = datetime.datetime.max + message.FromDatetime(naive_end_of_time) + self.assertEqual(naive_end_of_time, message.ToDatetime()) - def utcoffset(self, _): - return datetime.timedelta(hours=1) + # Two hours after the Unix Epoch, around the world. + @_parameterized.named_parameters( + ('London', [1970, 1, 1, 2], dateutil.tz.UTC), + ('Tokyo', [1970, 1, 1, 11], dateutil.tz.gettz('Japan')), + ('LA', [1969, 12, 31, 18], dateutil.tz.gettz('US/Pacific')), + ) + def testTimezoneAwareDatetimeConversion(self, date_parts, tzinfo): + original_datetime = datelib.CreateDatetime(*date_parts, tzinfo=tzinfo) - def dst(self, _): - return datetime.timedelta(0) - - def tzname(self, _): - return 'UTC+1' + message = timestamp_pb2.Timestamp() + message.FromDatetime(original_datetime) + self.assertEqual(7200, message.seconds) + self.assertEqual(0, message.nanos) - message1 = timestamp_pb2.Timestamp() - dt = datetime.datetime(1970, 1, 1, 1, tzinfo=TZ()) - message1.FromDatetime(dt) - message2 = timestamp_pb2.Timestamp() - dt = datetime.datetime(1970, 1, 1, 0) - message2.FromDatetime(dt) - self.assertEqual(message1, message2) + # ToDatetime() with no parameters produces a naive UTC datetime, i.e. it not + # only loses the original timezone information (e.g. US/Pacific) as it's + # "normalised" to UTC, but also drops the information that the datetime + # represents a UTC one. + naive_datetime = message.ToDatetime() + self.assertEqual(datetime.datetime(1970, 1, 1, 2), naive_datetime) + self.assertIsNone(naive_datetime.tzinfo) + self.assertNotEqual(original_datetime, naive_datetime) # not even for UTC! + + # In contrast, ToDatetime(tzinfo=) produces an aware datetime in the given + # timezone. + aware_datetime = message.ToDatetime(tzinfo=tzinfo) + self.assertEqual(original_datetime, aware_datetime) + self.assertEqual( + datelib.CreateDatetime(1970, 1, 1, 2, tzinfo=dateutil.tz.UTC), + aware_datetime) + self.assertEqual(tzinfo, aware_datetime.tzinfo) def testTimedeltaConversion(self): message = duration_pb2.Duration() diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index b3e85933e9609..bf2a17d61d1a3 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -226,7 +226,7 @@ def _RegularMessageToJsonObject(self, message, js): else: recorded_key = 'false' else: - recorded_key = key + recorded_key = str(key) js_map[recorded_key] = self._FieldToJsonObject( v_field, value[key]) js[name] = js_map @@ -395,12 +395,16 @@ def _CreateMessageFromTypeUrl(type_url, descriptor_pool): message_descriptor = pool.FindMessageTypeByName(type_name) except KeyError: raise TypeError( - 'Can not find message descriptor by type_url: {0}.'.format(type_url)) + 'Can not find message descriptor by type_url: {0}'.format(type_url)) message_class = db.GetPrototype(message_descriptor) return message_class() -def Parse(text, message, ignore_unknown_fields=False, descriptor_pool=None): +def Parse(text, + message, + ignore_unknown_fields=False, + descriptor_pool=None, + max_recursion_depth=100): """Parses a JSON representation of a protocol message into a message. Args: @@ -408,7 +412,10 @@ def Parse(text, message, ignore_unknown_fields=False, descriptor_pool=None): message: A protocol buffer message to merge into. ignore_unknown_fields: If True, do not raise errors for unknown fields. descriptor_pool: A Descriptor Pool for resolving types. If None use the - default. + default. + max_recursion_depth: max recursion depth of JSON message to be + deserialized. JSON messages over this depth will fail to be + deserialized. Default value is 100. Returns: The same message passed as argument. @@ -422,13 +429,15 @@ def Parse(text, message, ignore_unknown_fields=False, descriptor_pool=None): js = json.loads(text, object_pairs_hook=_DuplicateChecker) except ValueError as e: raise ParseError('Failed to load JSON: {0}.'.format(str(e))) - return ParseDict(js, message, ignore_unknown_fields, descriptor_pool) + return ParseDict(js, message, ignore_unknown_fields, descriptor_pool, + max_recursion_depth) def ParseDict(js_dict, message, ignore_unknown_fields=False, - descriptor_pool=None): + descriptor_pool=None, + max_recursion_depth=100): """Parses a JSON dictionary representation into a message. Args: @@ -437,12 +446,15 @@ def ParseDict(js_dict, ignore_unknown_fields: If True, do not raise errors for unknown fields. descriptor_pool: A Descriptor Pool for resolving types. If None use the default. + max_recursion_depth: max recursion depth of JSON message to be + deserialized. JSON messages over this depth will fail to be + deserialized. Default value is 100. Returns: The same message passed as argument. """ - parser = _Parser(ignore_unknown_fields, descriptor_pool) - parser.ConvertMessage(js_dict, message) + parser = _Parser(ignore_unknown_fields, descriptor_pool, max_recursion_depth) + parser.ConvertMessage(js_dict, message, '') return message @@ -452,35 +464,47 @@ def ParseDict(js_dict, class _Parser(object): """JSON format parser for protocol message.""" - def __init__(self, ignore_unknown_fields, descriptor_pool): + def __init__(self, ignore_unknown_fields, descriptor_pool, + max_recursion_depth): self.ignore_unknown_fields = ignore_unknown_fields self.descriptor_pool = descriptor_pool + self.max_recursion_depth = max_recursion_depth + self.recursion_depth = 0 - def ConvertMessage(self, value, message): + def ConvertMessage(self, value, message, path): """Convert a JSON object into a message. Args: value: A JSON object. message: A WKT or regular protocol message to record the data. + path: parent path to log parse error info. Raises: ParseError: In case of convert problems. """ + self.recursion_depth += 1 + if self.recursion_depth > self.max_recursion_depth: + raise ParseError('Message too deep. Max recursion depth is {0}'.format( + self.max_recursion_depth)) message_descriptor = message.DESCRIPTOR full_name = message_descriptor.full_name + if not path: + path = message_descriptor.name if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value, message) + self._ConvertWrapperMessage(value, message, path) elif full_name in _WKTJSONMETHODS: - methodcaller(_WKTJSONMETHODS[full_name][1], value, message)(self) + methodcaller(_WKTJSONMETHODS[full_name][1], value, message, path)(self) else: - self._ConvertFieldValuePair(value, message) + self._ConvertFieldValuePair(value, message, path) + self.recursion_depth -= 1 - def _ConvertFieldValuePair(self, js, message): + def _ConvertFieldValuePair(self, js, message, path): """Convert field value pairs into regular message. Args: js: A JSON object to convert the field value pairs. message: A regular protocol message to record the data. + path: parent path to log parse error info. Raises: ParseError: In case of problems converting. @@ -496,8 +520,9 @@ def _ConvertFieldValuePair(self, js, message): field = message_descriptor.fields_by_name.get(name, None) if not field and _VALID_EXTENSION_NAME.match(name): if not message_descriptor.is_extendable: - raise ParseError('Message type {0} does not have extensions'.format( - message_descriptor.full_name)) + raise ParseError( + 'Message type {0} does not have extensions at {1}'.format( + message_descriptor.full_name, path)) identifier = name[1:-1] # strip [] brackets # pylint: disable=protected-access field = message.Extensions._FindExtensionByName(identifier) @@ -513,14 +538,14 @@ def _ConvertFieldValuePair(self, js, message): if self.ignore_unknown_fields: continue raise ParseError( - ('Message type "{0}" has no field named "{1}".\n' - ' Available Fields(except extensions): {2}').format( - message_descriptor.full_name, name, + ('Message type "{0}" has no field named "{1}" at "{2}".\n' + ' Available Fields(except extensions): "{3}"').format( + message_descriptor.full_name, name, path, [f.json_name for f in message_descriptor.fields])) if name in names: raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" fields.'.format( - message.DESCRIPTOR.full_name, name)) + '"{1}" fields at "{2}".'.format( + message.DESCRIPTOR.full_name, name, path)) names.append(name) value = js[name] # Check no other oneof field is parsed. @@ -528,8 +553,9 @@ def _ConvertFieldValuePair(self, js, message): oneof_name = field.containing_oneof.name if oneof_name in names: raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" oneof fields.'.format( - message.DESCRIPTOR.full_name, oneof_name)) + '"{1}" oneof fields at "{2}".'.format( + message.DESCRIPTOR.full_name, oneof_name, + path)) names.append(oneof_name) if value is None: @@ -547,42 +573,51 @@ def _ConvertFieldValuePair(self, js, message): # Parse field value. if _IsMapEntry(field): message.ClearField(field.name) - self._ConvertMapFieldValue(value, message, field) + self._ConvertMapFieldValue(value, message, field, + '{0}.{1}'.format(path, name)) elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED: message.ClearField(field.name) if not isinstance(value, list): raise ParseError('repeated field {0} must be in [] which is ' - '{1}.'.format(name, value)) + '{1} at {2}'.format(name, value, path)) if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: # Repeated message field. - for item in value: + for index, item in enumerate(value): sub_message = getattr(message, field.name).add() # None is a null_value in Value. if (item is None and sub_message.DESCRIPTOR.full_name != 'google.protobuf.Value'): raise ParseError('null is not allowed to be used as an element' - ' in a repeated field.') - self.ConvertMessage(item, sub_message) + ' in a repeated field at {0}.{1}[{2}]'.format( + path, name, index)) + self.ConvertMessage(item, sub_message, + '{0}.{1}[{2}]'.format(path, name, index)) else: # Repeated scalar field. - for item in value: + for index, item in enumerate(value): if item is None: raise ParseError('null is not allowed to be used as an element' - ' in a repeated field.') + ' in a repeated field at {0}.{1}[{2}]'.format( + path, name, index)) getattr(message, field.name).append( - _ConvertScalarFieldValue(item, field)) + _ConvertScalarFieldValue( + item, field, '{0}.{1}[{2}]'.format(path, name, index))) elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: if field.is_extension: sub_message = message.Extensions[field] else: sub_message = getattr(message, field.name) sub_message.SetInParent() - self.ConvertMessage(value, sub_message) + self.ConvertMessage(value, sub_message, '{0}.{1}'.format(path, name)) else: if field.is_extension: - message.Extensions[field] = _ConvertScalarFieldValue(value, field) + message.Extensions[field] = _ConvertScalarFieldValue( + value, field, '{0}.{1}'.format(path, name)) else: - setattr(message, field.name, _ConvertScalarFieldValue(value, field)) + setattr( + message, field.name, + _ConvertScalarFieldValue(value, field, + '{0}.{1}'.format(path, name))) except ParseError as e: if field and field.containing_oneof is None: raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) @@ -593,46 +628,52 @@ def _ConvertFieldValuePair(self, js, message): except TypeError as e: raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - def _ConvertAnyMessage(self, value, message): + def _ConvertAnyMessage(self, value, message, path): """Convert a JSON representation into Any message.""" if isinstance(value, dict) and not value: return try: type_url = value['@type'] except KeyError: - raise ParseError('@type is missing when parsing any message.') + raise ParseError( + '@type is missing when parsing any message at {0}'.format(path)) - sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) + try: + sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) + except TypeError as e: + raise ParseError('{0} at {1}'.format(e, path)) message_descriptor = sub_message.DESCRIPTOR full_name = message_descriptor.full_name if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value['value'], sub_message) + self._ConvertWrapperMessage(value['value'], sub_message, + '{0}.value'.format(path)) elif full_name in _WKTJSONMETHODS: - methodcaller( - _WKTJSONMETHODS[full_name][1], value['value'], sub_message)(self) + methodcaller(_WKTJSONMETHODS[full_name][1], value['value'], sub_message, + '{0}.value'.format(path))( + self) else: del value['@type'] - self._ConvertFieldValuePair(value, sub_message) + self._ConvertFieldValuePair(value, sub_message, path) value['@type'] = type_url # Sets Any message message.value = sub_message.SerializeToString() message.type_url = type_url - def _ConvertGenericMessage(self, value, message): + def _ConvertGenericMessage(self, value, message, path): """Convert a JSON representation into message with FromJsonString.""" # Duration, Timestamp, FieldMask have a FromJsonString method to do the # conversion. Users can also call the method directly. try: message.FromJsonString(value) except ValueError as e: - raise ParseError(e) + raise ParseError('{0} at {1}'.format(e, path)) - def _ConvertValueMessage(self, value, message): + def _ConvertValueMessage(self, value, message, path): """Convert a JSON representation into Value message.""" if isinstance(value, dict): - self._ConvertStructMessage(value, message.struct_value) + self._ConvertStructMessage(value, message.struct_value, path) elif isinstance(value, list): - self. _ConvertListValueMessage(value, message.list_value) + self._ConvertListValueMessage(value, message.list_value, path) elif value is None: message.null_value = 0 elif isinstance(value, bool): @@ -642,68 +683,76 @@ def _ConvertValueMessage(self, value, message): elif isinstance(value, _INT_OR_FLOAT): message.number_value = value else: - raise ParseError('Value {0} has unexpected type {1}.'.format( - value, type(value))) + raise ParseError('Value {0} has unexpected type {1} at {2}'.format( + value, type(value), path)) - def _ConvertListValueMessage(self, value, message): + def _ConvertListValueMessage(self, value, message, path): """Convert a JSON representation into ListValue message.""" if not isinstance(value, list): - raise ParseError( - 'ListValue must be in [] which is {0}.'.format(value)) + raise ParseError('ListValue must be in [] which is {0} at {1}'.format( + value, path)) message.ClearField('values') - for item in value: - self._ConvertValueMessage(item, message.values.add()) + for index, item in enumerate(value): + self._ConvertValueMessage(item, message.values.add(), + '{0}[{1}]'.format(path, index)) - def _ConvertStructMessage(self, value, message): + def _ConvertStructMessage(self, value, message, path): """Convert a JSON representation into Struct message.""" if not isinstance(value, dict): - raise ParseError( - 'Struct must be in a dict which is {0}.'.format(value)) + raise ParseError('Struct must be in a dict which is {0} at {1}'.format( + value, path)) # Clear will mark the struct as modified so it will be created even if # there are no values. message.Clear() for key in value: - self._ConvertValueMessage(value[key], message.fields[key]) + self._ConvertValueMessage(value[key], message.fields[key], + '{0}.{1}'.format(path, key)) return - def _ConvertWrapperMessage(self, value, message): + def _ConvertWrapperMessage(self, value, message, path): """Convert a JSON representation into Wrapper message.""" field = message.DESCRIPTOR.fields_by_name['value'] - setattr(message, 'value', _ConvertScalarFieldValue(value, field)) + setattr( + message, 'value', + _ConvertScalarFieldValue(value, field, path='{0}.value'.format(path))) - def _ConvertMapFieldValue(self, value, message, field): + def _ConvertMapFieldValue(self, value, message, field, path): """Convert map field value for a message map field. Args: value: A JSON object to convert the map field value. message: A protocol message to record the converted data. field: The descriptor of the map field to be converted. + path: parent path to log parse error info. Raises: ParseError: In case of convert problems. """ if not isinstance(value, dict): raise ParseError( - 'Map field {0} must be in a dict which is {1}.'.format( - field.name, value)) + 'Map field {0} must be in a dict which is {1} at {2}'.format( + field.name, value, path)) key_field = field.message_type.fields_by_name['key'] value_field = field.message_type.fields_by_name['value'] for key in value: - key_value = _ConvertScalarFieldValue(key, key_field, True) + key_value = _ConvertScalarFieldValue(key, key_field, + '{0}.key'.format(path), True) if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self.ConvertMessage(value[key], getattr( - message, field.name)[key_value]) + self.ConvertMessage(value[key], + getattr(message, field.name)[key_value], + '{0}[{1}]'.format(path, key_value)) else: getattr(message, field.name)[key_value] = _ConvertScalarFieldValue( - value[key], value_field) + value[key], value_field, path='{0}[{1}]'.format(path, key_value)) -def _ConvertScalarFieldValue(value, field, require_str=False): +def _ConvertScalarFieldValue(value, field, path, require_str=False): """Convert a single scalar field value. Args: value: A scalar value to convert the scalar field value. field: The descriptor of the field to convert. + path: parent path to log parse error info. require_str: If True, the field value must be a str. Returns: @@ -712,44 +761,47 @@ def _ConvertScalarFieldValue(value, field, require_str=False): Raises: ParseError: In case of convert problems. """ - if field.cpp_type in _INT_TYPES: - return _ConvertInteger(value) - elif field.cpp_type in _FLOAT_TYPES: - return _ConvertFloat(value, field) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - return _ConvertBool(value, require_str) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - if isinstance(value, str): - encoded = value.encode('utf-8') + try: + if field.cpp_type in _INT_TYPES: + return _ConvertInteger(value) + elif field.cpp_type in _FLOAT_TYPES: + return _ConvertFloat(value, field) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: + return _ConvertBool(value, require_str) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: + if field.type == descriptor.FieldDescriptor.TYPE_BYTES: + if isinstance(value, str): + encoded = value.encode('utf-8') + else: + encoded = value + # Add extra padding '=' + padded_value = encoded + b'=' * (4 - len(encoded) % 4) + return base64.urlsafe_b64decode(padded_value) else: - encoded = value - # Add extra padding '=' - padded_value = encoded + b'=' * (4 - len(encoded) % 4) - return base64.urlsafe_b64decode(padded_value) - else: - # Checking for unpaired surrogates appears to be unreliable, - # depending on the specific Python version, so we check manually. - if _UNPAIRED_SURROGATE_PATTERN.search(value): - raise ParseError('Unpaired surrogate') - return value - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - # Convert an enum value. - enum_value = field.enum_type.values_by_name.get(value, None) - if enum_value is None: - try: - number = int(value) - enum_value = field.enum_type.values_by_number.get(number, None) - except ValueError: - raise ParseError('Invalid enum value {0} for enum type {1}.'.format( - value, field.enum_type.full_name)) + # Checking for unpaired surrogates appears to be unreliable, + # depending on the specific Python version, so we check manually. + if _UNPAIRED_SURROGATE_PATTERN.search(value): + raise ParseError('Unpaired surrogate') + return value + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: + # Convert an enum value. + enum_value = field.enum_type.values_by_name.get(value, None) if enum_value is None: - if field.file.syntax == 'proto3': - # Proto3 accepts unknown enums. - return number - raise ParseError('Invalid enum value {0} for enum type {1}.'.format( - value, field.enum_type.full_name)) - return enum_value.number + try: + number = int(value) + enum_value = field.enum_type.values_by_number.get(number, None) + except ValueError: + raise ParseError('Invalid enum value {0} for enum type {1}'.format( + value, field.enum_type.full_name)) + if enum_value is None: + if field.file.syntax == 'proto3': + # Proto3 accepts unknown enums. + return number + raise ParseError('Invalid enum value {0} for enum type {1}'.format( + value, field.enum_type.full_name)) + return enum_value.number + except ParseError as e: + raise ParseError('{0} at {1}'.format(e, path)) def _ConvertInteger(value): @@ -765,14 +817,14 @@ def _ConvertInteger(value): ParseError: If an integer couldn't be consumed. """ if isinstance(value, float) and not value.is_integer(): - raise ParseError('Couldn\'t parse integer: {0}.'.format(value)) + raise ParseError('Couldn\'t parse integer: {0}'.format(value)) if isinstance(value, str) and value.find(' ') != -1: - raise ParseError('Couldn\'t parse integer: "{0}".'.format(value)) + raise ParseError('Couldn\'t parse integer: "{0}"'.format(value)) if isinstance(value, bool): raise ParseError('Bool value {0} is not acceptable for ' - 'integer field.'.format(value)) + 'integer field'.format(value)) return int(value) @@ -781,14 +833,14 @@ def _ConvertFloat(value, field): """Convert an floating point number.""" if isinstance(value, float): if math.isnan(value): - raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead.') + raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead') if math.isinf(value): if value > 0: raise ParseError('Couldn\'t parse Infinity or value too large, ' - 'use quoted "Infinity" instead.') + 'use quoted "Infinity" instead') else: raise ParseError('Couldn\'t parse -Infinity or value too small, ' - 'use quoted "-Infinity" instead.') + 'use quoted "-Infinity" instead') if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: # pylint: disable=protected-access if value > type_checkers._FLOAT_MAX: @@ -797,7 +849,7 @@ def _ConvertFloat(value, field): 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.') + raise ParseError('Couldn\'t parse float "nan", use "NaN" instead') try: # Assume Python compatible syntax. return float(value) @@ -810,7 +862,7 @@ def _ConvertFloat(value, field): elif value == _NAN: return float('nan') else: - raise ParseError('Couldn\'t parse float: {0}.'.format(value)) + raise ParseError('Couldn\'t parse float: {0}'.format(value)) def _ConvertBool(value, require_str): @@ -832,10 +884,10 @@ def _ConvertBool(value, require_str): elif value == 'false': return False else: - raise ParseError('Expected "true" or "false", not {0}.'.format(value)) + raise ParseError('Expected "true" or "false", not {0}'.format(value)) if not isinstance(value, bool): - raise ParseError('Expected true or false without quotes.') + raise ParseError('Expected true or false without quotes') return value _WKTJSONMETHODS = { diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 9708b84013fba..cbf6887200a1b 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -49,12 +49,13 @@ #include #include -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -94,17 +95,17 @@ bool _CalledFromGeneratedFile(int stacklevel) { // This check is not critical and is somewhat difficult to implement correctly // in PyPy. PyFrameObject* frame = PyEval_GetFrame(); - if (frame == NULL) { + if (frame == nullptr) { return false; } while (stacklevel-- > 0) { frame = frame->f_back; - if (frame == NULL) { + if (frame == nullptr) { return false; } } - if (frame->f_code->co_filename == NULL) { + if (frame->f_code->co_filename == nullptr) { return false; } char* filename; @@ -235,23 +236,23 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { const Descriptor *message_type = options.GetDescriptor(); CMessageClass* message_class = message_factory::GetOrCreateMessageClass( message_factory, message_type); - if (message_class == NULL) { + if (message_class == nullptr) { PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s", message_type->full_name().c_str()); - return NULL; + return nullptr; } ScopedPyObjectPtr args(PyTuple_New(0)); ScopedPyObjectPtr value( - PyObject_Call(message_class->AsPyObject(), args.get(), NULL)); + PyObject_Call(message_class->AsPyObject(), args.get(), nullptr)); Py_DECREF(message_class); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } if (!PyObject_TypeCheck(value.get(), CMessage_Type)) { PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s", message_type->full_name().c_str(), Py_TYPE(value.get())->tp_name); - return NULL; + return nullptr; } CMessage* cmsg = reinterpret_cast(value.get()); @@ -263,7 +264,7 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { // Reparse options string! XXX call cmessage::MergeFromString if (!Reparse(message_factory, options, cmsg->message)) { PyErr_Format(PyExc_ValueError, "Error reparsing Options message"); - return NULL; + return nullptr; } } @@ -287,7 +288,7 @@ static PyObject* CopyToPythonProto(const DescriptorClass *descriptor, message->message->GetDescriptor() != self_descriptor) { PyErr_Format(PyExc_TypeError, "Not a %s message", self_descriptor->full_name().c_str()); - return NULL; + return nullptr; } cmessage::AssureWritable(message); DescriptorProtoClass* descriptor_message = @@ -323,7 +324,7 @@ typedef struct PyBaseDescriptor { typedef struct PyFileDescriptor { PyBaseDescriptor base; - // The cached version of serialized pb. Either NULL, or a Bytes string. + // The cached version of serialized pb. Either null, or a Bytes string. // We own the reference. PyObject *serialized_pb; } PyFileDescriptor; @@ -344,9 +345,9 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, if (was_created) { *was_created = false; } - if (descriptor == NULL) { + if (descriptor == nullptr) { PyErr_BadInternalCall(); - return NULL; + return nullptr; } // See if the object is in the map of interned descriptors @@ -360,8 +361,8 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, // Create a new descriptor object PyBaseDescriptor* py_descriptor = PyObject_GC_New( PyBaseDescriptor, type); - if (py_descriptor == NULL) { - return NULL; + if (py_descriptor == nullptr) { + return nullptr; } py_descriptor->descriptor = descriptor; @@ -372,10 +373,10 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, // Ensures that the DescriptorPool stays alive. PyDescriptorPool* pool = GetDescriptorPool_FromPool( GetFileDescriptor(descriptor)->pool()); - if (pool == NULL) { + if (pool == nullptr) { // Don't DECREF, the object is not fully initialized. PyObject_Del(py_descriptor); - return NULL; + return nullptr; } Py_INCREF(pool); py_descriptor->pool = pool; @@ -409,7 +410,7 @@ static int GcClear(PyObject* pself) { } static PyGetSetDef Getters[] = { - {NULL} + {nullptr}, }; PyTypeObject PyBaseDescriptor_Type = { @@ -419,29 +420,29 @@ PyTypeObject PyBaseDescriptor_Type = { 0, // tp_itemsize (destructor)Dealloc, // tp_dealloc 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags "Descriptors base class", // tp_doc GcTraverse, // tp_traverse GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members Getters, // tp_getset }; @@ -450,7 +451,7 @@ PyTypeObject PyBaseDescriptor_Type = { const void* PyDescriptor_AsVoidPtr(PyObject* obj) { if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast(obj)->descriptor; } @@ -612,19 +613,18 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) { const char *enum_name; int number; - if (!PyArg_ParseTuple(args, "si", &enum_name, &number)) - return NULL; + if (!PyArg_ParseTuple(args, "si", &enum_name, &number)) return nullptr; const EnumDescriptor *enum_type = _GetDescriptor(self)->FindEnumTypeByName(enum_name); - if (enum_type == NULL) { + if (enum_type == nullptr) { PyErr_SetString(PyExc_KeyError, enum_name); - return NULL; + return nullptr; } const EnumValueDescriptor *enum_value = enum_type->FindValueByNumber(number); - if (enum_value == NULL) { + if (enum_value == nullptr) { PyErr_Format(PyExc_KeyError, "%d", number); - return NULL; + return nullptr; } return PyString_FromCppString(enum_value->name()); } @@ -635,94 +635,98 @@ static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) { } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Last name"}, - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"}, - { "file", (getter)GetFile, NULL, "File descriptor"}, - - { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"}, - { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"}, - { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL, - "Fields by camelCase name"}, - { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"}, - { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"}, - { "nested_types_by_name", (getter)GetNestedTypesByName, NULL, - "Nested types by name"}, - { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"}, - { "extensions_by_name", (getter)GetExtensionsByName, NULL, - "Extensions by name"}, - { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"}, - { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"}, - { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, - "Enum types by name"}, - { "enum_values_by_name", (getter)GetEnumValuesByName, NULL, - "Enum values by name"}, - { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"}, - { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"}, - { "containing_type", (getter)GetContainingType, (setter)SetContainingType, - "Containing type"}, - { "is_extendable", (getter)IsExtendable, (setter)NULL}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, - {NULL} + {"name", (getter)GetName, nullptr, "Last name"}, + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"_concrete_class", (getter)GetConcreteClass, nullptr, "concrete class"}, + {"file", (getter)GetFile, nullptr, "File descriptor"}, + + {"fields", (getter)GetFieldsSeq, nullptr, "Fields sequence"}, + {"fields_by_name", (getter)GetFieldsByName, nullptr, "Fields by name"}, + {"fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, nullptr, + "Fields by camelCase name"}, + {"fields_by_number", (getter)GetFieldsByNumber, nullptr, + "Fields by number"}, + {"nested_types", (getter)GetNestedTypesSeq, nullptr, + "Nested types sequence"}, + {"nested_types_by_name", (getter)GetNestedTypesByName, nullptr, + "Nested types by name"}, + {"extensions", (getter)GetExtensions, nullptr, "Extensions Sequence"}, + {"extensions_by_name", (getter)GetExtensionsByName, nullptr, + "Extensions by name"}, + {"extension_ranges", (getter)GetExtensionRanges, nullptr, + "Extension ranges"}, + {"enum_types", (getter)GetEnumsSeq, nullptr, "Enum sequence"}, + {"enum_types_by_name", (getter)GetEnumTypesByName, nullptr, + "Enum types by name"}, + {"enum_values_by_name", (getter)GetEnumValuesByName, nullptr, + "Enum values by name"}, + {"oneofs_by_name", (getter)GetOneofsByName, nullptr, "Oneofs by name"}, + {"oneofs", (getter)GetOneofsSeq, nullptr, "Oneofs by name"}, + {"containing_type", (getter)GetContainingType, (setter)SetContainingType, + "Containing type"}, + {"is_extendable", (getter)IsExtendable, (setter) nullptr}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {"EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS}, + {nullptr}, }; } // namespace message_descriptor PyTypeObject PyMessageDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".MessageDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Message Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - message_descriptor::Methods, // tp_methods - 0, // tp_members - message_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".MessageDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Message Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + message_descriptor::Methods, // tp_methods + nullptr, // tp_members + message_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyMessageDescriptor_FromDescriptor( const Descriptor* message_descriptor) { - return descriptor::NewInternedDescriptor( - &PyMessageDescriptor_Type, message_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyMessageDescriptor_Type, + message_descriptor, nullptr); } const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast( reinterpret_cast(obj)->descriptor); @@ -850,7 +854,7 @@ static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) { default: PyErr_Format(PyExc_NotImplementedError, "default value for %s", _GetDescriptor(self)->full_name().c_str()); - return NULL; + return nullptr; } return result; } @@ -941,6 +945,14 @@ static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("has_options"); } +static PyObject* GetHasPresence(PyBaseDescriptor* self, void* closure) { + if (_GetDescriptor(self)->has_presence()) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } @@ -956,89 +968,91 @@ static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, } static PyGetSetDef Getters[] = { - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "name", (getter)GetName, NULL, "Unqualified name"}, - { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"}, - { "json_name", (getter)GetJsonName, NULL, "Json name"}, - { "file", (getter)GetFile, NULL, "File Descriptor"}, - { "type", (getter)GetType, NULL, "C++ Type"}, - { "cpp_type", (getter)GetCppType, NULL, "C++ Type"}, - { "label", (getter)GetLabel, NULL, "Label"}, - { "number", (getter)GetNumber, NULL, "Number"}, - { "index", (getter)GetIndex, NULL, "Index"}, - { "default_value", (getter)GetDefaultValue, NULL, "Default Value"}, - { "has_default_value", (getter)HasDefaultValue}, - { "is_extension", (getter)IsExtension, NULL, "ID"}, - { "id", (getter)GetID, NULL, "ID"}, - { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"}, - - { "message_type", (getter)GetMessageType, (setter)SetMessageType, - "Message type"}, - { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"}, - { "containing_type", (getter)GetContainingType, (setter)SetContainingType, - "Containing type"}, - { "extension_scope", (getter)GetExtensionScope, (setter)NULL, - "Extension scope"}, - { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof, - "Containing oneof"}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - {NULL} + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"name", (getter)GetName, nullptr, "Unqualified name"}, + {"camelcase_name", (getter)GetCamelcaseName, nullptr, "Camelcase name"}, + {"json_name", (getter)GetJsonName, nullptr, "Json name"}, + {"file", (getter)GetFile, nullptr, "File Descriptor"}, + {"type", (getter)GetType, nullptr, "C++ Type"}, + {"cpp_type", (getter)GetCppType, nullptr, "C++ Type"}, + {"label", (getter)GetLabel, nullptr, "Label"}, + {"number", (getter)GetNumber, nullptr, "Number"}, + {"index", (getter)GetIndex, nullptr, "Index"}, + {"default_value", (getter)GetDefaultValue, nullptr, "Default Value"}, + {"has_default_value", (getter)HasDefaultValue}, + {"is_extension", (getter)IsExtension, nullptr, "ID"}, + {"id", (getter)GetID, nullptr, "ID"}, + {"_cdescriptor", (getter)GetCDescriptor, nullptr, "HAACK REMOVE ME"}, + + {"message_type", (getter)GetMessageType, (setter)SetMessageType, + "Message type"}, + {"enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"}, + {"containing_type", (getter)GetContainingType, (setter)SetContainingType, + "Containing type"}, + {"extension_scope", (getter)GetExtensionScope, (setter) nullptr, + "Extension scope"}, + {"containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof, + "Containing oneof"}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"has_presence", (getter)GetHasPresence, (setter) nullptr, "Has Presence"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {nullptr}, }; } // namespace field_descriptor PyTypeObject PyFieldDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".FieldDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Field Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - field_descriptor::Methods, // tp_methods - 0, // tp_members - field_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".FieldDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Field Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + field_descriptor::Methods, // tp_methods + nullptr, // tp_members + field_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyFieldDescriptor_FromDescriptor( const FieldDescriptor* field_descriptor) { - return descriptor::NewInternedDescriptor( - &PyFieldDescriptor_Type, field_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyFieldDescriptor_Type, + field_descriptor, nullptr); } const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast( reinterpret_cast(obj)->descriptor); @@ -1124,76 +1138,77 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { } static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {nullptr}, }; static PyGetSetDef Getters[] = { - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "name", (getter)GetName, NULL, "last name"}, - { "file", (getter)GetFile, NULL, "File descriptor"}, - { "values", (getter)GetEnumvaluesSeq, NULL, "values"}, - { "values_by_name", (getter)GetEnumvaluesByName, NULL, - "Enum values by name"}, - { "values_by_number", (getter)GetEnumvaluesByNumber, NULL, - "Enum values by number"}, - - { "containing_type", (getter)GetContainingType, (setter)SetContainingType, - "Containing type"}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - {NULL} + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"name", (getter)GetName, nullptr, "last name"}, + {"file", (getter)GetFile, nullptr, "File descriptor"}, + {"values", (getter)GetEnumvaluesSeq, nullptr, "values"}, + {"values_by_name", (getter)GetEnumvaluesByName, nullptr, + "Enum values by name"}, + {"values_by_number", (getter)GetEnumvaluesByNumber, nullptr, + "Enum values by number"}, + + {"containing_type", (getter)GetContainingType, (setter)SetContainingType, + "Containing type"}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {nullptr}, }; } // namespace enum_descriptor PyTypeObject PyEnumDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".EnumDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Enum Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - enum_descriptor::Methods, // tp_methods - 0, // tp_members - enum_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".EnumDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Enum Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + enum_descriptor::Methods, // tp_methods + nullptr, // tp_members + enum_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyEnumDescriptor_FromDescriptor( const EnumDescriptor* enum_descriptor) { - return descriptor::NewInternedDescriptor( - &PyEnumDescriptor_Type, enum_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyEnumDescriptor_Type, + enum_descriptor, nullptr); } const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast( reinterpret_cast(obj)->descriptor); @@ -1251,63 +1266,64 @@ static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "name"}, - { "number", (getter)GetNumber, NULL, "number"}, - { "index", (getter)GetIndex, NULL, "index"}, - { "type", (getter)GetType, NULL, "index"}, - - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - {NULL} + {"name", (getter)GetName, nullptr, "name"}, + {"number", (getter)GetNumber, nullptr, "number"}, + {"index", (getter)GetIndex, nullptr, "index"}, + {"type", (getter)GetType, nullptr, "index"}, + + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {nullptr}, }; } // namespace enumvalue_descriptor PyTypeObject PyEnumValueDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".EnumValueDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A EnumValue Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - enumvalue_descriptor::Methods, // tp_methods - 0, // tp_members - enumvalue_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".EnumValueDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A EnumValue Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + enumvalue_descriptor::Methods, // tp_methods + nullptr, // tp_members + enumvalue_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyEnumValueDescriptor_FromDescriptor( const EnumValueDescriptor* enumvalue_descriptor) { - return descriptor::NewInternedDescriptor( - &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyEnumValueDescriptor_Type, + enumvalue_descriptor, nullptr); } namespace file_descriptor { @@ -1339,7 +1355,7 @@ static PyObject* GetPackage(PyFileDescriptor *self, void *closure) { static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) { PyObject *serialized_pb = self->serialized_pb; - if (serialized_pb != NULL) { + if (serialized_pb != nullptr) { Py_INCREF(serialized_pb); return serialized_pb; } @@ -1349,8 +1365,8 @@ static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) { file_proto.SerializePartialToString(&contents); self->serialized_pb = PyBytes_FromStringAndSize( contents.c_str(), contents.size()); - if (self->serialized_pb == NULL) { - return NULL; + if (self->serialized_pb == nullptr) { + return nullptr; } Py_INCREF(self->serialized_pb); return self->serialized_pb; @@ -1393,6 +1409,10 @@ static int SetHasOptions(PyFileDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("has_options"); } +static PyObject* GetDebugString(PyFileDescriptor* self) { + return PyString_FromCppString(_GetDescriptor(self)->DebugString()); +} + static PyObject* GetOptions(PyFileDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } @@ -1417,31 +1437,36 @@ static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) { } static PyGetSetDef Getters[] = { - { "pool", (getter)GetPool, NULL, "pool"}, - { "name", (getter)GetName, NULL, "name"}, - { "package", (getter)GetPackage, NULL, "package"}, - { "serialized_pb", (getter)GetSerializedPb}, - { "message_types_by_name", (getter)GetMessageTypesByName, NULL, - "Messages by name"}, - { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"}, - { "extensions_by_name", (getter)GetExtensionsByName, NULL, - "Extensions by name"}, - { "services_by_name", (getter)GetServicesByName, NULL, "Services by name"}, - { "dependencies", (getter)GetDependencies, NULL, "Dependencies"}, - { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"}, - - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, - {NULL} + {"pool", (getter)GetPool, nullptr, "pool"}, + {"name", (getter)GetName, nullptr, "name"}, + {"package", (getter)GetPackage, nullptr, "package"}, + {"serialized_pb", (getter)GetSerializedPb}, + {"message_types_by_name", (getter)GetMessageTypesByName, nullptr, + "Messages by name"}, + {"enum_types_by_name", (getter)GetEnumTypesByName, nullptr, + "Enums by name"}, + {"extensions_by_name", (getter)GetExtensionsByName, nullptr, + "Extensions by name"}, + {"services_by_name", (getter)GetServicesByName, nullptr, + "Services by name"}, + {"dependencies", (getter)GetDependencies, nullptr, "Dependencies"}, + {"public_dependencies", (getter)GetPublicDependencies, nullptr, + "Dependencies"}, + + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - {NULL} + {"GetDebugString", (PyCFunction)GetDebugString, METH_NOARGS}, + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {nullptr}, }; } // namespace file_descriptor @@ -1453,45 +1478,45 @@ PyTypeObject PyFileDescriptor_Type = { 0, // tp_itemsize (destructor)file_descriptor::Dealloc, // tp_dealloc 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT, // tp_flags "A File Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext + nullptr, // tp_iter + nullptr, // tp_iternext file_descriptor::Methods, // tp_methods - 0, // tp_members + nullptr, // tp_members file_descriptor::Getters, // tp_getset &descriptor::PyBaseDescriptor_Type, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new PyObject_GC_Del, // tp_free }; PyObject* PyFileDescriptor_FromDescriptor( const FileDescriptor* file_descriptor) { return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor, - NULL); + nullptr); } PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( @@ -1499,8 +1524,8 @@ PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( bool was_created; PyObject* py_descriptor = descriptor::NewInternedDescriptor( &PyFileDescriptor_Type, file_descriptor, &was_created); - if (py_descriptor == NULL) { - return NULL; + if (py_descriptor == nullptr) { + return nullptr; } if (was_created) { PyFileDescriptor* cfile_descriptor = @@ -1517,7 +1542,7 @@ PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast( reinterpret_cast(obj)->descriptor); @@ -1565,6 +1590,7 @@ static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) { Py_RETURN_FALSE; } } + static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("has_options"); @@ -1585,64 +1611,65 @@ static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Name"}, - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "index", (getter)GetIndex, NULL, "Index"}, - - { "containing_type", (getter)GetContainingType, NULL, "Containing type"}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - { "fields", (getter)GetFields, NULL, "Fields"}, - {NULL} + {"name", (getter)GetName, nullptr, "Name"}, + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"index", (getter)GetIndex, nullptr, "Index"}, + + {"containing_type", (getter)GetContainingType, nullptr, "Containing type"}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {"fields", (getter)GetFields, nullptr, "Fields"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {nullptr}, }; } // namespace oneof_descriptor PyTypeObject PyOneofDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".OneofDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Oneof Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - oneof_descriptor::Methods, // tp_methods - 0, // tp_members - oneof_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".OneofDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Oneof Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + oneof_descriptor::Methods, // tp_methods + nullptr, // tp_members + oneof_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyOneofDescriptor_FromDescriptor( const OneofDescriptor* oneof_descriptor) { - return descriptor::NewInternedDescriptor( - &PyOneofDescriptor_Type, oneof_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyOneofDescriptor_Type, + oneof_descriptor, nullptr); } namespace service_descriptor { @@ -1681,14 +1708,14 @@ static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const MethodDescriptor* method_descriptor = _GetDescriptor(self)->FindMethodByName(StringParam(name, name_size)); - if (method_descriptor == NULL) { + if (method_descriptor == nullptr) { PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name); - return NULL; + return nullptr; } return PyMethodDescriptor_FromDescriptor(method_descriptor); @@ -1704,69 +1731,69 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Name", NULL}, - { "full_name", (getter)GetFullName, NULL, "Full name", NULL}, - { "file", (getter)GetFile, NULL, "File descriptor"}, - { "index", (getter)GetIndex, NULL, "Index", NULL}, - - { "methods", (getter)GetMethods, NULL, "Methods", NULL}, - { "methods_by_name", (getter)GetMethodsByName, NULL, "Methods by name", NULL}, - {NULL} + {"name", (getter)GetName, nullptr, "Name", nullptr}, + {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr}, + {"file", (getter)GetFile, nullptr, "File descriptor"}, + {"index", (getter)GetIndex, nullptr, "Index", nullptr}, + {"methods", (getter)GetMethods, nullptr, "Methods", nullptr}, + {"methods_by_name", (getter)GetMethodsByName, nullptr, "Methods by name", + nullptr}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {"FindMethodByName", (PyCFunction)FindMethodByName, METH_O}, + {nullptr}, }; } // namespace service_descriptor PyTypeObject PyServiceDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".ServiceDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Service Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - service_descriptor::Methods, // tp_methods - 0, // tp_members - service_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".ServiceDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Service Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + service_descriptor::Methods, // tp_methods + nullptr, // tp_members + service_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyServiceDescriptor_FromDescriptor( const ServiceDescriptor* service_descriptor) { - return descriptor::NewInternedDescriptor( - &PyServiceDescriptor_Type, service_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyServiceDescriptor_Type, + service_descriptor, nullptr); } const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyServiceDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a ServiceDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast( reinterpret_cast(obj)->descriptor); @@ -1808,6 +1835,14 @@ static PyObject* GetOutputType(PyBaseDescriptor *self, void *closure) { return PyMessageDescriptor_FromDescriptor(output_type); } +static PyObject* GetClientStreaming(PyBaseDescriptor* self, void* closure) { + return PyBool_FromLong(_GetDescriptor(self)->client_streaming() ? 1 : 0); +} + +static PyObject* GetServerStreaming(PyBaseDescriptor* self, void* closure) { + return PyBool_FromLong(_GetDescriptor(self)->server_streaming() ? 1 : 0); +} + static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } @@ -1817,62 +1852,66 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Name", NULL}, - { "full_name", (getter)GetFullName, NULL, "Full name", NULL}, - { "index", (getter)GetIndex, NULL, "Index", NULL}, - { "containing_service", (getter)GetContainingService, NULL, - "Containing service", NULL}, - { "input_type", (getter)GetInputType, NULL, "Input type", NULL}, - { "output_type", (getter)GetOutputType, NULL, "Output type", NULL}, - {NULL} + {"name", (getter)GetName, nullptr, "Name", nullptr}, + {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr}, + {"index", (getter)GetIndex, nullptr, "Index", nullptr}, + {"containing_service", (getter)GetContainingService, nullptr, + "Containing service", nullptr}, + {"input_type", (getter)GetInputType, nullptr, "Input type", nullptr}, + {"output_type", (getter)GetOutputType, nullptr, "Output type", nullptr}, + {"client_streaming", (getter)GetClientStreaming, nullptr, + "Client streaming", nullptr}, + {"server_streaming", (getter)GetServerStreaming, nullptr, + "Server streaming", nullptr}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {nullptr}, }; } // namespace method_descriptor PyTypeObject PyMethodDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".MethodDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Method Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - method_descriptor::Methods, // tp_methods - 0, // tp_members - method_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".MethodDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Method Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + method_descriptor::Methods, // tp_methods + nullptr, // tp_members + method_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyMethodDescriptor_FromDescriptor( const MethodDescriptor* method_descriptor) { - return descriptor::NewInternedDescriptor( - &PyMethodDescriptor_Type, method_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyMethodDescriptor_Type, + method_descriptor, nullptr); } // Add a enum values to a type dictionary. @@ -1881,7 +1920,7 @@ static bool AddEnumValues(PyTypeObject *type, for (int i = 0; i < enum_descriptor->value_count(); ++i) { const EnumValueDescriptor* value = enum_descriptor->value(i); ScopedPyObjectPtr obj(PyLong_FromLong(value->number())); - if (obj == NULL) { + if (obj == nullptr) { return false; } if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) < diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc index b084f5b8121b2..adb169094776f 100644 --- a/python/google/protobuf/pyext/descriptor_containers.cc +++ b/python/google/protobuf/pyext/descriptor_containers.cc @@ -57,12 +57,13 @@ #include #include -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -157,59 +158,56 @@ namespace descriptor { // Returns the C++ item descriptor for a given Python key. // When the descriptor is found, return true and set *item. -// When the descriptor is not found, return true, but set *item to NULL. +// When the descriptor is not found, return true, but set *item to null. // On error, returns false with an exception set. static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) { switch (self->kind) { - case PyContainer::KIND_BYNAME: - { - char* name; - Py_ssize_t name_size; - if (PyString_AsStringAndSize(key, &name, &name_size) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - // Not a string, cannot be in the container. - PyErr_Clear(); - *item = NULL; - return true; - } - return false; + case PyContainer::KIND_BYNAME: { + char* name; + Py_ssize_t name_size; + if (PyString_AsStringAndSize(key, &name, &name_size) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + // Not a string, cannot be in the container. + PyErr_Clear(); + *item = nullptr; + return true; } - *item = self->container_def->get_by_name_fn( - self, StringParam(name, name_size)); - return true; + return false; } - case PyContainer::KIND_BYCAMELCASENAME: - { - char* camelcase_name; - Py_ssize_t name_size; - if (PyString_AsStringAndSize(key, &camelcase_name, &name_size) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - // Not a string, cannot be in the container. - PyErr_Clear(); - *item = NULL; - return true; - } - return false; + *item = self->container_def->get_by_name_fn(self, + StringParam(name, name_size)); + return true; + } + case PyContainer::KIND_BYCAMELCASENAME: { + char* camelcase_name; + Py_ssize_t name_size; + if (PyString_AsStringAndSize(key, &camelcase_name, &name_size) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + // Not a string, cannot be in the container. + PyErr_Clear(); + *item = nullptr; + return true; } - *item = self->container_def->get_by_camelcase_name_fn( - self, StringParam(camelcase_name, name_size)); - return true; + return false; } - case PyContainer::KIND_BYNUMBER: - { - Py_ssize_t number = PyNumber_AsSsize_t(key, NULL); - if (number == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - // Not a number, cannot be in the container. - PyErr_Clear(); - *item = NULL; - return true; - } - return false; + *item = self->container_def->get_by_camelcase_name_fn( + self, StringParam(camelcase_name, name_size)); + return true; + } + case PyContainer::KIND_BYNUMBER: { + Py_ssize_t number = PyNumber_AsSsize_t(key, nullptr); + if (number == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + // Not a number, cannot be in the container. + PyErr_Clear(); + *item = nullptr; + return true; } - *item = self->container_def->get_by_number_fn(self, number); - return true; + return false; } + *item = self->container_def->get_by_number_fn(self, number); + return true; + } default: PyErr_SetNone(PyExc_NotImplementedError); return false; @@ -221,25 +219,22 @@ static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) { static PyObject* _NewKey_ByIndex(PyContainer* self, Py_ssize_t index) { const void* item = self->container_def->get_by_index_fn(self, index); switch (self->kind) { - case PyContainer::KIND_BYNAME: - { + case PyContainer::KIND_BYNAME: { const std::string& name(self->container_def->get_item_name_fn(item)); return PyUnicode_FromStringAndSize(name.c_str(), name.size()); - } - case PyContainer::KIND_BYCAMELCASENAME: - { + } + case PyContainer::KIND_BYCAMELCASENAME: { const std::string& name( self->container_def->get_item_camelcase_name_fn(item)); return PyUnicode_FromStringAndSize(name.c_str(), name.size()); - } - case PyContainer::KIND_BYNUMBER: - { - int value = self->container_def->get_item_number_fn(item); - return PyLong_FromLong(value); - } + } + case PyContainer::KIND_BYNUMBER: { + int value = self->container_def->get_item_number_fn(item); + return PyLong_FromLong(value); + } default: PyErr_SetNone(PyExc_NotImplementedError); - return NULL; + return nullptr; } } @@ -257,13 +252,13 @@ static Py_ssize_t Length(PyContainer* self) { // The DescriptorMapping type. static PyObject* Subscript(PyContainer* self, PyObject* key) { - const void* item = NULL; + const void* item = nullptr; if (!_GetItemByKey(self, key, &item)) { - return NULL; + return nullptr; } if (!item) { PyErr_SetObject(PyExc_KeyError, key); - return NULL; + return nullptr; } return self->container_def->new_object_from_item_fn(item); } @@ -285,7 +280,7 @@ static PyMappingMethods MappingMappingMethods = { }; static int Contains(PyContainer* self, PyObject* key) { - const void* item = NULL; + const void* item = nullptr; if (!_GetItemByKey(self, key, &item)) { return -1; } @@ -344,11 +339,11 @@ static int DescriptorSequence_Equal(PyContainer* self, PyObject* other) { } for (int index = 0; index < size; index++) { ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index)); - if (value1 == NULL) { + if (value1 == nullptr) { return -1; } PyObject* value2 = PyList_GetItem(other, index); - if (value2 == NULL) { + if (value2 == nullptr) { return -1; } int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ); @@ -388,15 +383,15 @@ static int DescriptorMapping_Equal(PyContainer* self, PyObject* other) { } for (int index = 0; index < size; index++) { ScopedPyObjectPtr key(_NewKey_ByIndex(self, index)); - if (key == NULL) { + if (key == nullptr) { return -1; } ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index)); - if (value1 == NULL) { + if (value1 == nullptr) { return -1; } PyObject* value2 = PyDict_GetItem(other, key.get()); - if (value2 == NULL) { + if (value2 == nullptr) { // Not found in the other dictionary return 0; } @@ -426,7 +421,7 @@ static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) { result = DescriptorMapping_Equal(self, other); } if (result < 0) { - return NULL; + return nullptr; } if (result ^ (opid == Py_NE)) { Py_RETURN_TRUE; @@ -436,28 +431,28 @@ static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) { } static PySequenceMethods MappingSequenceMethods = { - 0, // sq_length - 0, // sq_concat - 0, // sq_repeat - 0, // sq_item - 0, // sq_slice - 0, // sq_ass_item - 0, // sq_ass_slice - (objobjproc)Contains, // sq_contains + nullptr, // sq_length + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + (objobjproc)Contains, // sq_contains }; static PyObject* Get(PyContainer* self, PyObject* args) { PyObject* key; PyObject* default_value = Py_None; if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) { - return NULL; + return nullptr; } const void* item; if (!_GetItemByKey(self, key, &item)) { - return NULL; + return nullptr; } - if (item == NULL) { + if (item == nullptr) { Py_INCREF(default_value); return default_value; } @@ -467,13 +462,13 @@ static PyObject* Get(PyContainer* self, PyObject* args) { static PyObject* Keys(PyContainer* self, PyObject* args) { Py_ssize_t count = Length(self); ScopedPyObjectPtr list(PyList_New(count)); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } for (Py_ssize_t index = 0; index < count; ++index) { PyObject* key = _NewKey_ByIndex(self, index); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } PyList_SET_ITEM(list.get(), index, key); } @@ -483,13 +478,13 @@ static PyObject* Keys(PyContainer* self, PyObject* args) { static PyObject* Values(PyContainer* self, PyObject* args) { Py_ssize_t count = Length(self); ScopedPyObjectPtr list(PyList_New(count)); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } for (Py_ssize_t index = 0; index < count; ++index) { PyObject* value = _NewObj_ByIndex(self, index); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } PyList_SET_ITEM(list.get(), index, value); } @@ -499,22 +494,22 @@ static PyObject* Values(PyContainer* self, PyObject* args) { static PyObject* Items(PyContainer* self, PyObject* args) { Py_ssize_t count = Length(self); ScopedPyObjectPtr list(PyList_New(count)); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } for (Py_ssize_t index = 0; index < count; ++index) { ScopedPyObjectPtr obj(PyTuple_New(2)); - if (obj == NULL) { - return NULL; + if (obj == nullptr) { + return nullptr; } PyObject* key = _NewKey_ByIndex(self, index); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } PyTuple_SET_ITEM(obj.get(), 0, key); PyObject* value = _NewObj_ByIndex(self, index); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } PyTuple_SET_ITEM(obj.get(), 1, value); PyList_SET_ITEM(list.get(), index, obj.release()); @@ -539,56 +534,55 @@ static PyObject* IterItems(PyContainer* self, PyObject* args) { } static PyMethodDef MappingMethods[] = { - { "get", (PyCFunction)Get, METH_VARARGS, }, - { "keys", (PyCFunction)Keys, METH_NOARGS, }, - { "values", (PyCFunction)Values, METH_NOARGS, }, - { "items", (PyCFunction)Items, METH_NOARGS, }, - { "iterkeys", (PyCFunction)IterKeys, METH_NOARGS, }, - { "itervalues", (PyCFunction)IterValues, METH_NOARGS, }, - { "iteritems", (PyCFunction)IterItems, METH_NOARGS, }, - {NULL} + {"get", (PyCFunction)Get, METH_VARARGS}, + {"keys", (PyCFunction)Keys, METH_NOARGS}, + {"values", (PyCFunction)Values, METH_NOARGS}, + {"items", (PyCFunction)Items, METH_NOARGS}, + {"iterkeys", (PyCFunction)IterKeys, METH_NOARGS}, + {"itervalues", (PyCFunction)IterValues, METH_NOARGS}, + {"iteritems", (PyCFunction)IterItems, METH_NOARGS}, + {nullptr}, }; PyTypeObject DescriptorMapping_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "DescriptorMapping", // tp_name - sizeof(PyContainer), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)ContainerRepr, // tp_repr - 0, // tp_as_number - &MappingSequenceMethods, // tp_as_sequence - &MappingMappingMethods, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - 0, // tp_doc - 0, // tp_traverse - 0, // tp_clear - (richcmpfunc)RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - (getiterfunc)Iter, // tp_iter - 0, // tp_iternext - MappingMethods, // 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 - 0, // tp_alloc - 0, // tp_new - 0, // tp_free + PyVarObject_HEAD_INIT(&PyType_Type, 0) "DescriptorMapping", // tp_name + sizeof(PyContainer), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_pkrint + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)ContainerRepr, // tp_repr + nullptr, // tp_as_number + &MappingSequenceMethods, // tp_as_sequence + &MappingMappingMethods, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + (richcmpfunc)RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + (getiterfunc)Iter, // tp_iter + nullptr, // tp_iternext + MappingMethods, // 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 + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_free }; // The DescriptorSequence type. @@ -599,7 +593,7 @@ static PyObject* GetItem(PyContainer* self, Py_ssize_t index) { } if (index < 0 || index >= Length(self)) { PyErr_SetString(PyExc_IndexError, "index out of range"); - return NULL; + return nullptr; } return _NewObj_ByIndex(self, index); } @@ -609,15 +603,14 @@ SeqSubscript(PyContainer* 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; return GetItem(self, index); } // Materialize the list and delegate the operation to it. ScopedPyObjectPtr list(PyObject_CallFunctionObjArgs( - reinterpret_cast(&PyList_Type), self, NULL)); - if (list == NULL) { - return NULL; + reinterpret_cast(&PyList_Type), self, nullptr)); + if (list == nullptr) { + return nullptr; } return Py_TYPE(list.get())->tp_as_mapping->mp_subscript(list.get(), item); } @@ -632,7 +625,7 @@ int Find(PyContainer* self, PyObject* item) { // a specific item belongs to only one sequence, depending on its position in // the .proto file definition. const void* descriptor_ptr = PyDescriptor_AsVoidPtr(item); - if (descriptor_ptr == NULL) { + if (descriptor_ptr == nullptr) { PyErr_Clear(); // Not a descriptor, it cannot be in the list. return -1; @@ -668,7 +661,7 @@ static PyObject* Index(PyContainer* self, PyObject* item) { if (position < 0) { // Not found PyErr_SetNone(PyExc_ValueError); - return NULL; + return nullptr; } else { return PyLong_FromLong(position); } @@ -701,7 +694,7 @@ static PyObject* Append(PyContainer* self, PyObject* args) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not a mutable sequence", Py_TYPE(self)->tp_name); - return NULL; + return nullptr; } static PyObject* Reversed(PyContainer* self, PyObject* args) { @@ -710,77 +703,76 @@ static PyObject* Reversed(PyContainer* self, PyObject* args) { } static PyMethodDef SeqMethods[] = { - { "index", (PyCFunction)Index, METH_O, }, - { "count", (PyCFunction)Count, METH_O, }, - { "append", (PyCFunction)Append, METH_O, }, - { "__reversed__", (PyCFunction)Reversed, METH_NOARGS, }, - {NULL} + {"index", (PyCFunction)Index, METH_O}, + {"count", (PyCFunction)Count, METH_O}, + {"append", (PyCFunction)Append, METH_O}, + {"__reversed__", (PyCFunction)Reversed, METH_NOARGS}, + {nullptr}, }; static PySequenceMethods SeqSequenceMethods = { - (lenfunc)Length, // sq_length - 0, // sq_concat - 0, // sq_repeat - (ssizeargfunc)GetItem, // sq_item - 0, // sq_slice - 0, // sq_ass_item - 0, // sq_ass_slice - (objobjproc)SeqContains, // sq_contains + (lenfunc)Length, // sq_length + nullptr, // sq_concat + nullptr, // sq_repeat + (ssizeargfunc)GetItem, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + (objobjproc)SeqContains, // sq_contains }; static PyMappingMethods SeqMappingMethods = { - (lenfunc)Length, // mp_length - (binaryfunc)SeqSubscript, // mp_subscript - 0, // mp_ass_subscript + (lenfunc)Length, // mp_length + (binaryfunc)SeqSubscript, // mp_subscript + nullptr, // mp_ass_subscript }; PyTypeObject DescriptorSequence_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "DescriptorSequence", // tp_name - sizeof(PyContainer), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)ContainerRepr, // tp_repr - 0, // tp_as_number - &SeqSequenceMethods, // tp_as_sequence - &SeqMappingMethods, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - 0, // tp_doc - 0, // tp_traverse - 0, // tp_clear - (richcmpfunc)RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - SeqMethods, // 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 - 0, // tp_alloc - 0, // tp_new - 0, // tp_free + PyVarObject_HEAD_INIT(&PyType_Type, 0) "DescriptorSequence", // tp_name + sizeof(PyContainer), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)ContainerRepr, // tp_repr + nullptr, // tp_as_number + &SeqSequenceMethods, // tp_as_sequence + &SeqMappingMethods, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + (richcmpfunc)RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + SeqMethods, // 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 + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_free }; static PyObject* NewMappingByName( DescriptorContainerDef* container_def, const void* descriptor) { PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -791,8 +783,8 @@ static PyObject* NewMappingByName( static PyObject* NewMappingByCamelcaseName( DescriptorContainerDef* container_def, const void* descriptor) { PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -802,14 +794,14 @@ static PyObject* NewMappingByCamelcaseName( static PyObject* NewMappingByNumber( DescriptorContainerDef* container_def, const void* descriptor) { - if (container_def->get_by_number_fn == NULL || - container_def->get_item_number_fn == NULL) { + if (container_def->get_by_number_fn == nullptr || + container_def->get_item_number_fn == nullptr) { PyErr_SetNone(PyExc_NotImplementedError); - return NULL; + return nullptr; } PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -820,8 +812,8 @@ static PyObject* NewMappingByNumber( static PyObject* NewSequence( DescriptorContainerDef* container_def, const void* descriptor) { PyContainer* self = PyObject_New(PyContainer, &DescriptorSequence_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -839,8 +831,8 @@ static void Iterator_Dealloc(PyContainerIterator* self) { static PyObject* Iterator_Next(PyContainerIterator* self) { int count = self->container->container_def->count_fn(self->container); if (self->index >= count) { - // Return NULL with no exception to indicate the end. - return NULL; + // Return null with no exception to indicate the end. + return nullptr; } int index = self->index; self->index += 1; @@ -851,80 +843,79 @@ static PyObject* Iterator_Next(PyContainerIterator* self) { return _NewObj_ByIndex(self->container, index); case PyContainerIterator::KIND_ITERVALUE_REVERSED: return _NewObj_ByIndex(self->container, count - index - 1); - case PyContainerIterator::KIND_ITERITEM: - { - PyObject* obj = PyTuple_New(2); - if (obj == NULL) { - return NULL; - } - PyObject* key = _NewKey_ByIndex(self->container, index); - if (key == NULL) { - Py_DECREF(obj); - return NULL; - } - PyTuple_SET_ITEM(obj, 0, key); - PyObject* value = _NewObj_ByIndex(self->container, index); - if (value == NULL) { - Py_DECREF(obj); - return NULL; - } - PyTuple_SET_ITEM(obj, 1, value); - return obj; + case PyContainerIterator::KIND_ITERITEM: { + PyObject* obj = PyTuple_New(2); + if (obj == nullptr) { + return nullptr; + } + PyObject* key = _NewKey_ByIndex(self->container, index); + if (key == nullptr) { + Py_DECREF(obj); + return nullptr; } + PyTuple_SET_ITEM(obj, 0, key); + PyObject* value = _NewObj_ByIndex(self->container, index); + if (value == nullptr) { + Py_DECREF(obj); + return nullptr; + } + PyTuple_SET_ITEM(obj, 1, value); + return obj; + } default: PyErr_SetNone(PyExc_NotImplementedError); - return NULL; + return nullptr; } } static PyTypeObject ContainerIterator_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "DescriptorContainerIterator", // tp_name - sizeof(PyContainerIterator), // tp_basicsize - 0, // tp_itemsize - (destructor)Iterator_Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - 0, // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - PyObject_SelfIter, // tp_iter - (iternextfunc)Iterator_Next, // tp_iternext - 0, // 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 - 0, // tp_alloc - 0, // tp_new - 0, // tp_free + PyVarObject_HEAD_INIT(&PyType_Type, + 0) "DescriptorContainerIterator", // tp_name + sizeof(PyContainerIterator), // tp_basicsize + 0, // tp_itemsize + (destructor)Iterator_Dealloc, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PyObject_SelfIter, // tp_iter + (iternextfunc)Iterator_Next, // tp_iternext + nullptr, // 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 + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_free }; static PyObject* NewContainerIterator(PyContainer* container, PyContainerIterator::IterKind kind) { PyContainerIterator* self = PyObject_New(PyContainerIterator, &ContainerIterator_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(container); self->container = container; @@ -992,17 +983,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageFields", - Count, - GetByIndex, - GetByName, - GetByCamelcaseName, - GetByNumber, - NewObjectFromItem, - GetItemName, - GetItemCamelcaseName, - GetItemNumber, - GetItemIndex, + "MessageFields", Count, GetByIndex, GetByName, + GetByCamelcaseName, GetByNumber, NewObjectFromItem, GetItemName, + GetItemCamelcaseName, GetItemNumber, GetItemIndex, }; } // namespace fields @@ -1053,17 +1036,17 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageNestedTypes", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageNestedTypes", + Count, + GetByIndex, + GetByName, + nullptr, + nullptr, + NewObjectFromItem, + GetItemName, + nullptr, + nullptr, + GetItemIndex, }; } // namespace nested_types @@ -1105,17 +1088,17 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageNestedEnums", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageNestedEnums", + Count, + GetByIndex, + GetByName, + nullptr, + nullptr, + NewObjectFromItem, + GetItemName, + nullptr, + nullptr, + GetItemIndex, }; } // namespace enums @@ -1154,7 +1137,7 @@ static const void* GetByName(PyContainer* self, ConstStringParam name) { static const void* GetByIndex(PyContainer* self, int index) { // This is not optimal, but the number of enums *types* in a given message // is small. This function is only used when iterating over the mapping. - const EnumDescriptor* enum_type = NULL; + const EnumDescriptor* enum_type = nullptr; int enum_type_count = GetDescriptor(self)->enum_type_count(); for (int i = 0; i < enum_type_count; ++i) { enum_type = GetDescriptor(self)->enum_type(i); @@ -1180,17 +1163,8 @@ static const std::string& GetItemName(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageEnumValues", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - NULL, + "MessageEnumValues", Count, GetByIndex, GetByName, nullptr, nullptr, + NewObjectFromItem, GetItemName, nullptr, nullptr, nullptr, }; } // namespace enumvalues @@ -1228,17 +1202,17 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageExtensions", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageExtensions", + Count, + GetByIndex, + GetByName, + nullptr, + nullptr, + NewObjectFromItem, + GetItemName, + nullptr, + nullptr, + GetItemIndex, }; } // namespace extensions @@ -1280,17 +1254,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageOneofs", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageOneofs", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace oneofs @@ -1351,17 +1317,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "EnumValues", - Count, - GetByIndex, - GetByName, - NULL, - GetByNumber, - NewObjectFromItem, - GetItemName, - NULL, - GetItemNumber, - GetItemIndex, + "EnumValues", Count, GetByIndex, GetByName, + nullptr, GetByNumber, NewObjectFromItem, GetItemName, + nullptr, GetItemNumber, GetItemIndex, }; } // namespace enumvalues @@ -1409,17 +1367,8 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "OneofFields", - Count, - GetByIndex, - NULL, - NULL, - NULL, - NewObjectFromItem, - NULL, - NULL, - NULL, - GetItemIndex, + "OneofFields", Count, GetByIndex, nullptr, nullptr, nullptr, + NewObjectFromItem, nullptr, nullptr, nullptr, GetItemIndex, }; } // namespace fields @@ -1467,17 +1416,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "ServiceMethods", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "ServiceMethods", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace methods @@ -1529,17 +1470,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileMessages", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileMessages", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace messages @@ -1577,17 +1510,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileEnums", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileEnums", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace enums @@ -1625,17 +1550,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileExtensions", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileExtensions", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace extensions @@ -1673,17 +1590,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileServices", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileServices", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace services @@ -1709,17 +1618,8 @@ static PyObject* NewObjectFromItem(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileDependencies", - Count, - GetByIndex, - NULL, - NULL, - NULL, - NewObjectFromItem, - NULL, - NULL, - NULL, - NULL, + "FileDependencies", Count, GetByIndex, nullptr, nullptr, nullptr, + NewObjectFromItem, nullptr, nullptr, nullptr, nullptr, }; } // namespace dependencies @@ -1745,17 +1645,8 @@ static PyObject* NewObjectFromItem(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FilePublicDependencies", - Count, - GetByIndex, - NULL, - NULL, - NULL, - NewObjectFromItem, - NULL, - NULL, - NULL, - NULL, + "FilePublicDependencies", Count, GetByIndex, nullptr, nullptr, nullptr, + NewObjectFromItem, nullptr, nullptr, nullptr, nullptr, }; } // namespace public_dependencies diff --git a/python/google/protobuf/pyext/descriptor_database.cc b/python/google/protobuf/pyext/descriptor_database.cc index da1c84a465828..f87f23d772cde 100644 --- a/python/google/protobuf/pyext/descriptor_database.cc +++ b/python/google/protobuf/pyext/descriptor_database.cc @@ -56,7 +56,7 @@ PyDescriptorDatabase::~PyDescriptorDatabase() { Py_DECREF(py_database_); } // Handles all kinds of Python errors, which are simply logged. static bool GetFileDescriptorProto(PyObject* py_descriptor, FileDescriptorProto* output) { - if (py_descriptor == NULL) { + if (py_descriptor == nullptr) { if (PyErr_ExceptionMatches(PyExc_KeyError)) { // Expected error: item was simply not found. PyErr_Clear(); @@ -83,8 +83,8 @@ static bool GetFileDescriptorProto(PyObject* py_descriptor, // Slow path: serialize the message. This allows to use databases which // use a different implementation of FileDescriptorProto. ScopedPyObjectPtr serialized_pb( - PyObject_CallMethod(py_descriptor, "SerializeToString", NULL)); - if (serialized_pb == NULL) { + PyObject_CallMethod(py_descriptor, "SerializeToString", nullptr)); + if (serialized_pb == nullptr) { GOOGLE_LOG(ERROR) << "DescriptorDatabase method did not return a FileDescriptorProto"; PyErr_Print(); @@ -134,7 +134,7 @@ bool PyDescriptorDatabase::FindFileContainingExtension( FileDescriptorProto* output) { ScopedPyObjectPtr py_method( PyObject_GetAttrString(py_database_, "FindFileContainingExtension")); - if (py_method == NULL) { + if (py_method == nullptr) { // This method is not implemented, returns without error. PyErr_Clear(); return false; @@ -153,7 +153,7 @@ bool PyDescriptorDatabase::FindAllExtensionNumbers( const std::string& containing_type, std::vector* output) { ScopedPyObjectPtr py_method( PyObject_GetAttrString(py_database_, "FindAllExtensionNumbers")); - if (py_method == NULL) { + if (py_method == nullptr) { // This method is not implemented, returns without error. PyErr_Clear(); return false; @@ -161,7 +161,7 @@ bool PyDescriptorDatabase::FindAllExtensionNumbers( ScopedPyObjectPtr py_list( PyObject_CallFunction(py_method.get(), "s#", containing_type.c_str(), containing_type.size())); - if (py_list == NULL) { + if (py_list == nullptr) { PyErr_Print(); return false; } diff --git a/python/google/protobuf/pyext/descriptor_database.h b/python/google/protobuf/pyext/descriptor_database.h index d2d9f8e506dff..d1bd7a3c19536 100644 --- a/python/google/protobuf/pyext/descriptor_database.h +++ b/python/google/protobuf/pyext/descriptor_database.h @@ -42,17 +42,18 @@ namespace python { class PyDescriptorDatabase : public DescriptorDatabase { public: explicit PyDescriptorDatabase(PyObject* py_database); - ~PyDescriptorDatabase(); + ~PyDescriptorDatabase() override; // Implement the abstract interface. All these functions fill the output // with a copy of FileDescriptorProto. // Find a file by file name. - bool FindFileByName(const std::string& filename, FileDescriptorProto* output); + bool FindFileByName(const std::string& filename, + FileDescriptorProto* output) override; // Find the file that declares the given fully-qualified symbol name. bool FindFileContainingSymbol(const std::string& symbol_name, - FileDescriptorProto* output); + FileDescriptorProto* output) override; // Find the file which defines an extension extending the given message type // with the given field number. @@ -60,14 +61,14 @@ class PyDescriptorDatabase : public DescriptorDatabase { // Python objects are not required to implement this method. bool FindFileContainingExtension(const std::string& containing_type, int field_number, - FileDescriptorProto* output); + FileDescriptorProto* output) override; // Finds the tag numbers used by all known extensions of // containing_type, and appends them to output in an undefined // order. // Python objects are not required to implement this method. bool FindAllExtensionNumbers(const std::string& containing_type, - std::vector* output); + std::vector* output) override; private: // The python object that implements the database. The reference is owned. diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index 5ec6269cd434a..5b0ceebfa48ca 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -43,12 +43,13 @@ #include #include -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -98,13 +99,13 @@ class BuildFileErrorCollector : public DescriptorPool::ErrorCollector { static PyDescriptorPool* _CreateDescriptorPool() { PyDescriptorPool* cpool = PyObject_GC_New( PyDescriptorPool, &PyDescriptorPool_Type); - if (cpool == NULL) { - return NULL; + if (cpool == nullptr) { + return nullptr; } cpool->error_collector = nullptr; - cpool->underlay = NULL; - cpool->database = NULL; + cpool->underlay = nullptr; + cpool->database = nullptr; cpool->is_owned = false; cpool->is_mutable = false; @@ -112,9 +113,9 @@ static PyDescriptorPool* _CreateDescriptorPool() { cpool->py_message_factory = message_factory::NewMessageFactory( &PyMessageFactory_Type, cpool); - if (cpool->py_message_factory == NULL) { + if (cpool->py_message_factory == nullptr) { Py_DECREF(cpool); - return NULL; + return nullptr; } PyObject_GC_Track(cpool); @@ -130,8 +131,8 @@ static PyDescriptorPool* _CreateDescriptorPool() { static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay( const DescriptorPool* underlay) { PyDescriptorPool* cpool = _CreateDescriptorPool(); - if (cpool == NULL) { - return NULL; + if (cpool == nullptr) { + return nullptr; } cpool->pool = new DescriptorPool(underlay); cpool->is_owned = true; @@ -142,7 +143,7 @@ static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay( std::make_pair(cpool->pool, cpool)).second) { // Should never happen -- would indicate an internal error / bug. PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered"); - return NULL; + return nullptr; } return cpool; @@ -151,10 +152,10 @@ static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay( static PyDescriptorPool* PyDescriptorPool_NewWithDatabase( DescriptorDatabase* database) { PyDescriptorPool* cpool = _CreateDescriptorPool(); - if (cpool == NULL) { - return NULL; + if (cpool == nullptr) { + return nullptr; } - if (database != NULL) { + if (database != nullptr) { cpool->error_collector = new BuildFileErrorCollector(); cpool->pool = new DescriptorPool(database, cpool->error_collector); cpool->is_mutable = false; @@ -168,7 +169,7 @@ static PyDescriptorPool* PyDescriptorPool_NewWithDatabase( if (!descriptor_pool_map->insert(std::make_pair(cpool->pool, cpool)).second) { // Should never happen -- would indicate an internal error / bug. PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered"); - return NULL; + return nullptr; } return cpool; @@ -177,13 +178,13 @@ static PyDescriptorPool* PyDescriptorPool_NewWithDatabase( // The public DescriptorPool constructor. static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - static const char* kwlist[] = {"descriptor_db", 0}; - PyObject* py_database = NULL; + static const char* kwlist[] = {"descriptor_db", nullptr}; + PyObject* py_database = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", const_cast(kwlist), &py_database)) { - return NULL; + return nullptr; } - DescriptorDatabase* database = NULL; + DescriptorDatabase* database = nullptr; if (py_database && py_database != Py_None) { database = new PyDescriptorDatabase(py_database); } @@ -229,24 +230,24 @@ PyObject* SetErrorFromCollector(DescriptorPool::ErrorCollector* self, PyErr_Format(PyExc_KeyError, "Couldn't build file for %s %.200s\n%s", error_type, name, error_collector->error_message.c_str()); error_collector->Clear(); - return NULL; + return nullptr; } PyErr_Format(PyExc_KeyError, "Couldn't find %s %.200s", error_type, name); - return NULL; + return nullptr; } static PyObject* FindMessageByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const Descriptor* message_descriptor = reinterpret_cast(self)->pool->FindMessageTypeByName( StringParam(name, name_size)); - if (message_descriptor == NULL) { + if (message_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast(self)->error_collector, name, "message"); @@ -263,14 +264,14 @@ static PyObject* FindFileByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } PyDescriptorPool* py_pool = reinterpret_cast(self); const FileDescriptor* file_descriptor = py_pool->pool->FindFileByName(StringParam(name, name_size)); - if (file_descriptor == NULL) { + if (file_descriptor == nullptr) { return SetErrorFromCollector(py_pool->error_collector, name, "file"); } return PyFileDescriptor_FromDescriptor(file_descriptor); @@ -280,12 +281,12 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const FieldDescriptor* field_descriptor = self->pool->FindFieldByName(StringParam(name, name_size)); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "field"); } @@ -301,12 +302,12 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const FieldDescriptor* field_descriptor = self->pool->FindExtensionByName(StringParam(name, name_size)); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "extension field"); } @@ -323,12 +324,12 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const EnumDescriptor* enum_descriptor = self->pool->FindEnumTypeByName(StringParam(name, name_size)); - if (enum_descriptor == NULL) { + if (enum_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "enum"); } @@ -344,12 +345,12 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const OneofDescriptor* oneof_descriptor = self->pool->FindOneofByName(StringParam(name, name_size)); - if (oneof_descriptor == NULL) { + if (oneof_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "oneof"); } @@ -365,13 +366,13 @@ static PyObject* FindServiceByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const ServiceDescriptor* service_descriptor = reinterpret_cast(self)->pool->FindServiceByName( StringParam(name, name_size)); - if (service_descriptor == NULL) { + if (service_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast(self)->error_collector, name, "service"); @@ -385,13 +386,13 @@ static PyObject* FindMethodByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const MethodDescriptor* method_descriptor = reinterpret_cast(self)->pool->FindMethodByName( StringParam(name, name_size)); - if (method_descriptor == NULL) { + if (method_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast(self)->error_collector, name, "method"); @@ -405,13 +406,13 @@ static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const FileDescriptor* file_descriptor = reinterpret_cast(self)->pool->FindFileContainingSymbol( StringParam(name, name_size)); - if (file_descriptor == NULL) { + if (file_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast(self)->error_collector, name, "symbol"); @@ -425,18 +426,18 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) { PyObject* message_descriptor; int number; if (!PyArg_ParseTuple(args, "Oi", &message_descriptor, &number)) { - return NULL; + return nullptr; } const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor( message_descriptor); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } const FieldDescriptor* extension_descriptor = reinterpret_cast(self)->pool->FindExtensionByNumber( descriptor, number); - if (extension_descriptor == NULL) { + if (extension_descriptor == nullptr) { BuildFileErrorCollector* error_collector = reinterpret_cast( reinterpret_cast(self)->error_collector); @@ -444,10 +445,10 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) { PyErr_Format(PyExc_KeyError, "Couldn't build file for Extension %.d\n%s", number, error_collector->error_message.c_str()); error_collector->Clear(); - return NULL; + return nullptr; } PyErr_Format(PyExc_KeyError, "Couldn't find Extension %d", number); - return NULL; + return nullptr; } @@ -456,8 +457,8 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) { static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) { const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(arg); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } std::vector extensions; @@ -465,13 +466,13 @@ static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) { descriptor, &extensions); ScopedPyObjectPtr result(PyList_New(extensions.size())); - if (result == NULL) { - return NULL; + if (result == nullptr) { + return nullptr; } for (int i = 0; i < extensions.size(); i++) { PyObject* extension = PyFieldDescriptor_FromDescriptor(extensions[i]); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } PyList_SET_ITEM(result.get(), i, extension); // Steals the reference. } @@ -491,7 +492,7 @@ static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) { const FileDescriptor* file_descriptor = PyFileDescriptor_AsDescriptor(descriptor); if (!file_descriptor) { - return NULL; + return nullptr; } if (file_descriptor != reinterpret_cast(self)->pool->FindFileByName( @@ -499,7 +500,7 @@ static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The file descriptor %s does not belong to this pool", file_descriptor->name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -508,7 +509,7 @@ static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) { const Descriptor* message_descriptor = PyMessageDescriptor_AsDescriptor(descriptor); if (!message_descriptor) { - return NULL; + return nullptr; } if (message_descriptor != reinterpret_cast(self)->pool->FindMessageTypeByName( @@ -516,7 +517,7 @@ static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The message descriptor %s does not belong to this pool", message_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -525,7 +526,7 @@ static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) { const EnumDescriptor* enum_descriptor = PyEnumDescriptor_AsDescriptor(descriptor); if (!enum_descriptor) { - return NULL; + return nullptr; } if (enum_descriptor != reinterpret_cast(self)->pool->FindEnumTypeByName( @@ -533,7 +534,7 @@ static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The enum descriptor %s does not belong to this pool", enum_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -542,7 +543,7 @@ static PyObject* AddExtensionDescriptor(PyObject* self, PyObject* descriptor) { const FieldDescriptor* extension_descriptor = PyFieldDescriptor_AsDescriptor(descriptor); if (!extension_descriptor) { - return NULL; + return nullptr; } if (extension_descriptor != reinterpret_cast(self)->pool->FindExtensionByName( @@ -550,7 +551,7 @@ static PyObject* AddExtensionDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The extension descriptor %s does not belong to this pool", extension_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -559,7 +560,7 @@ static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) { const ServiceDescriptor* service_descriptor = PyServiceDescriptor_AsDescriptor(descriptor); if (!service_descriptor) { - return NULL; + return nullptr; } if (service_descriptor != reinterpret_cast(self)->pool->FindServiceByName( @@ -567,7 +568,7 @@ static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The service descriptor %s does not belong to this pool", service_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -578,12 +579,12 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { char* message_type; Py_ssize_t message_len; - if (self->database != NULL) { + if (self->database != nullptr) { PyErr_SetString( PyExc_ValueError, "Cannot call Add on a DescriptorPool that uses a DescriptorDatabase. " "Add your file to the underlying database."); - return NULL; + return nullptr; } if (!self->is_mutable) { PyErr_SetString( @@ -593,22 +594,22 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { } if (PyBytes_AsStringAndSize(serialized_pb, &message_type, &message_len) < 0) { - return NULL; + return nullptr; } FileDescriptorProto file_proto; if (!file_proto.ParseFromArray(message_type, message_len)) { PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!"); - return NULL; + return nullptr; } // If the file was already part of a C++ library, all its descriptors are in // the underlying pool. No need to do anything else. - const FileDescriptor* generated_file = NULL; + const FileDescriptor* generated_file = nullptr; if (self->underlay) { generated_file = self->underlay->FindFileByName(file_proto.name()); } - if (generated_file != NULL) { + if (generated_file != nullptr) { return PyFileDescriptor_FromDescriptorWithSerializedPb( generated_file, serialized_pb); } @@ -618,11 +619,11 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { // Pool is mutable, we can remove the "const". const_cast(self->pool) ->BuildFileCollectingErrors(file_proto, &error_collector); - if (descriptor == NULL) { + if (descriptor == nullptr) { PyErr_Format(PyExc_TypeError, "Couldn't build proto file into descriptor pool!\n%s", error_collector.error_message.c_str()); - return NULL; + return nullptr; } @@ -632,56 +633,56 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { static PyObject* Add(PyObject* self, PyObject* file_descriptor_proto) { ScopedPyObjectPtr serialized_pb( - PyObject_CallMethod(file_descriptor_proto, "SerializeToString", NULL)); - if (serialized_pb == NULL) { - return NULL; + PyObject_CallMethod(file_descriptor_proto, "SerializeToString", nullptr)); + if (serialized_pb == nullptr) { + return nullptr; } return AddSerializedFile(self, serialized_pb.get()); } static PyMethodDef Methods[] = { - { "Add", Add, METH_O, - "Adds the FileDescriptorProto and its types to this pool." }, - { "AddSerializedFile", AddSerializedFile, METH_O, - "Adds a serialized FileDescriptorProto to this pool." }, - - // TODO(amauryfa): Understand why the Python implementation differs from - // this one, ask users to use another API and deprecate these functions. - { "AddFileDescriptor", AddFileDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddDescriptor", AddDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddEnumDescriptor", AddEnumDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddExtensionDescriptor", AddExtensionDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddServiceDescriptor", AddServiceDescriptor, METH_O, - "No-op. Add() must have been called before." }, - - { "FindFileByName", FindFileByName, METH_O, - "Searches for a file descriptor by its .proto name." }, - { "FindMessageTypeByName", FindMessageByName, METH_O, - "Searches for a message descriptor by full name." }, - { "FindFieldByName", FindFieldByNameMethod, METH_O, - "Searches for a field descriptor by full name." }, - { "FindExtensionByName", FindExtensionByNameMethod, METH_O, - "Searches for extension descriptor by full name." }, - { "FindEnumTypeByName", FindEnumTypeByNameMethod, METH_O, - "Searches for enum type descriptor by full name." }, - { "FindOneofByName", FindOneofByNameMethod, METH_O, - "Searches for oneof descriptor by full name." }, - { "FindServiceByName", FindServiceByName, METH_O, - "Searches for service descriptor by full name." }, - { "FindMethodByName", FindMethodByName, METH_O, - "Searches for method descriptor by full name." }, - - { "FindFileContainingSymbol", FindFileContainingSymbol, METH_O, - "Gets the FileDescriptor containing the specified symbol." }, - { "FindExtensionByNumber", FindExtensionByNumber, METH_VARARGS, - "Gets the extension descriptor for the given number." }, - { "FindAllExtensions", FindAllExtensions, METH_O, - "Gets all known extensions of the given message descriptor." }, - {NULL} + {"Add", Add, METH_O, + "Adds the FileDescriptorProto and its types to this pool."}, + {"AddSerializedFile", AddSerializedFile, METH_O, + "Adds a serialized FileDescriptorProto to this pool."}, + + // TODO(amauryfa): Understand why the Python implementation differs from + // this one, ask users to use another API and deprecate these functions. + {"AddFileDescriptor", AddFileDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddDescriptor", AddDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddEnumDescriptor", AddEnumDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddExtensionDescriptor", AddExtensionDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddServiceDescriptor", AddServiceDescriptor, METH_O, + "No-op. Add() must have been called before."}, + + {"FindFileByName", FindFileByName, METH_O, + "Searches for a file descriptor by its .proto name."}, + {"FindMessageTypeByName", FindMessageByName, METH_O, + "Searches for a message descriptor by full name."}, + {"FindFieldByName", FindFieldByNameMethod, METH_O, + "Searches for a field descriptor by full name."}, + {"FindExtensionByName", FindExtensionByNameMethod, METH_O, + "Searches for extension descriptor by full name."}, + {"FindEnumTypeByName", FindEnumTypeByNameMethod, METH_O, + "Searches for enum type descriptor by full name."}, + {"FindOneofByName", FindOneofByNameMethod, METH_O, + "Searches for oneof descriptor by full name."}, + {"FindServiceByName", FindServiceByName, METH_O, + "Searches for service descriptor by full name."}, + {"FindMethodByName", FindMethodByName, METH_O, + "Searches for method descriptor by full name."}, + + {"FindFileContainingSymbol", FindFileContainingSymbol, METH_O, + "Gets the FileDescriptor containing the specified symbol."}, + {"FindExtensionByNumber", FindExtensionByNumber, METH_VARARGS, + "Gets the extension descriptor for the given number."}, + {"FindAllExtensions", FindAllExtensions, METH_O, + "Gets all known extensions of the given message descriptor."}, + {nullptr}, }; } // namespace cdescriptor_pool @@ -693,44 +694,44 @@ PyTypeObject PyDescriptorPool_Type = { 0, // tp_itemsize cdescriptor_pool::Dealloc, // tp_dealloc 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags "A Descriptor Pool", // tp_doc cdescriptor_pool::GcTraverse, // tp_traverse cdescriptor_pool::GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext + nullptr, // tp_iter + nullptr, // tp_iternext cdescriptor_pool::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc + nullptr, // tp_init + nullptr, // tp_alloc cdescriptor_pool::New, // tp_new PyObject_GC_Del, // tp_free }; // This is the DescriptorPool which contains all the definitions from the // generated _pb2.py modules. -static PyDescriptorPool* python_generated_pool = NULL; +static PyDescriptorPool* python_generated_pool = nullptr; bool InitDescriptorPool() { if (PyType_Ready(&PyDescriptorPool_Type) < 0) @@ -743,7 +744,7 @@ bool InitDescriptorPool() { new std::unordered_map; python_generated_pool = cdescriptor_pool::PyDescriptorPool_NewWithUnderlay( DescriptorPool::generated_pool()); - if (python_generated_pool == NULL) { + if (python_generated_pool == nullptr) { delete descriptor_pool_map; return false; } @@ -774,7 +775,7 @@ PyDescriptorPool* GetDescriptorPool_FromPool(const DescriptorPool* pool) { descriptor_pool_map->find(pool); if (it == descriptor_pool_map->end()) { PyErr_SetString(PyExc_KeyError, "Unknown descriptor pool"); - return NULL; + return nullptr; } return it->second; } diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc index b36c723266f2b..760fc91f492cb 100644 --- a/python/google/protobuf/pyext/extension_dict.cc +++ b/python/google/protobuf/pyext/extension_dict.cc @@ -49,12 +49,13 @@ #include #include -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -130,11 +131,11 @@ static void DeallocExtensionIterator(PyObject* _self) { PyObject* subscript(ExtensionDict* self, PyObject* key) { const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) { - return NULL; + return nullptr; } if (descriptor->label() != FieldDescriptor::LABEL_REPEATED && @@ -154,8 +155,8 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) { // TODO(plabatut): consider building the class on the fly! ContainerBase* sub_message = cmessage::InternalGetSubMessage( self->parent, descriptor); - if (sub_message == NULL) { - return NULL; + if (sub_message == nullptr) { + return nullptr; } (*self->parent->composite_fields)[descriptor] = sub_message; return sub_message->AsPyObject(); @@ -178,33 +179,33 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) { descriptor->message_type()); ScopedPyObjectPtr message_class_handler( reinterpret_cast(message_class)); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } ContainerBase* py_container = repeated_composite_container::NewContainer( self->parent, descriptor, message_class); - if (py_container == NULL) { - return NULL; + if (py_container == nullptr) { + return nullptr; } (*self->parent->composite_fields)[descriptor] = py_container; return py_container->AsPyObject(); } else { ContainerBase* py_container = repeated_scalar_container::NewContainer( self->parent, descriptor); - if (py_container == NULL) { - return NULL; + if (py_container == nullptr) { + return nullptr; } (*self->parent->composite_fields)[descriptor] = py_container; return py_container->AsPyObject(); } } PyErr_SetString(PyExc_ValueError, "control reached unexpected line"); - return NULL; + return nullptr; } int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) { const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key); - if (descriptor == NULL) { + if (descriptor == nullptr) { return -1; } if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) { @@ -232,13 +233,13 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { char* name; Py_ssize_t name_size; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool; const FieldDescriptor* message_extension = pool->pool->FindExtensionByName(StringParam(name, name_size)); - if (message_extension == NULL) { + if (message_extension == nullptr) { // Is is the name of a message set extension? const Descriptor* message_descriptor = pool->pool->FindMessageTypeByName(StringParam(name, name_size)); @@ -252,7 +253,7 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { } } } - if (message_extension == NULL) { + if (message_extension == nullptr) { Py_RETURN_NONE; } @@ -262,13 +263,13 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* arg) { int64_t number = PyLong_AsLong(arg); if (number == -1 && PyErr_Occurred()) { - return NULL; + return nullptr; } PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool; const FieldDescriptor* message_extension = pool->pool->FindExtensionByNumber( self->parent->message->GetDescriptor(), number); - if (message_extension == NULL) { + if (message_extension == nullptr) { Py_RETURN_NONE; } @@ -307,8 +308,8 @@ static int Contains(PyObject* _self, PyObject* key) { ExtensionDict* NewExtensionDict(CMessage *parent) { ExtensionDict* self = reinterpret_cast( PyType_GenericAlloc(&ExtensionDict_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -340,12 +341,12 @@ static PyObject* RichCompare(ExtensionDict* self, PyObject* other, int opid) { } static PySequenceMethods SeqMethods = { (lenfunc)len, // sq_length - 0, // sq_concat - 0, // sq_repeat - 0, // sq_item - 0, // sq_slice - 0, // sq_ass_item - 0, // sq_ass_slice + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice (objobjproc)Contains, // sq_contains }; @@ -360,7 +361,7 @@ static PyMethodDef Methods[] = { EDMETHOD(_FindExtensionByName, METH_O, "Finds an extension by name."), EDMETHOD(_FindExtensionByNumber, METH_O, "Finds an extension by field number."), - {NULL, NULL}, + {nullptr, nullptr}, }; } // namespace extension_dict @@ -372,36 +373,36 @@ PyTypeObject ExtensionDict_Type = { 0, // tp_itemsize (destructor)extension_dict::dealloc, // tp_dealloc 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number &extension_dict::SeqMethods, // tp_as_sequence &extension_dict::MpMethods, // tp_as_mapping PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT, // tp_flags "An extension dict", // tp_doc - 0, // tp_traverse - 0, // tp_clear + nullptr, // tp_traverse + nullptr, // tp_clear (richcmpfunc)extension_dict::RichCompare, // tp_richcompare 0, // tp_weaklistoffset extension_dict::GetIter, // tp_iter - 0, // tp_iternext + nullptr, // tp_iternext extension_dict::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init + nullptr, // tp_init }; PyObject* IterNext(PyObject* _self) { @@ -439,36 +440,36 @@ PyTypeObject ExtensionIterator_Type = { 0, // tp_itemsize extension_dict::DeallocExtensionIterator, // tp_dealloc 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT, // tp_flags "A scalar map iterator", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare 0, // tp_weaklistoffset PyObject_SelfIter, // tp_iter IterNext, // tp_iternext - 0, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // 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 - 0, // tp_init + nullptr, // tp_init }; } // namespace python } // namespace protobuf diff --git a/python/google/protobuf/pyext/field.cc b/python/google/protobuf/pyext/field.cc index 5eab3ef2bc486..611ac8ac1e6ce 100644 --- a/python/google/protobuf/pyext/field.cc +++ b/python/google/protobuf/pyext/field.cc @@ -47,7 +47,7 @@ static PyObject* Repr(PyMessageFieldProperty* self) { static PyObject* DescrGet(PyMessageFieldProperty* self, PyObject* obj, PyObject* type) { - if (obj == NULL) { + if (obj == nullptr) { Py_INCREF(self); return reinterpret_cast(self); } @@ -57,7 +57,7 @@ static PyObject* DescrGet(PyMessageFieldProperty* self, PyObject* obj, static int DescrSet(PyMessageFieldProperty* self, PyObject* obj, PyObject* value) { - if (value == NULL) { + if (value == nullptr) { PyErr_SetString(PyExc_AttributeError, "Cannot delete field attribute"); return -1; } @@ -75,50 +75,51 @@ static PyObject* GetDoc(PyMessageFieldProperty* self, void* closure) { } static PyGetSetDef Getters[] = { - {"DESCRIPTOR", (getter)GetDescriptor, NULL, "Field descriptor"}, - {"__doc__", (getter)GetDoc, NULL, NULL}, - {NULL}}; + {"DESCRIPTOR", (getter)GetDescriptor, nullptr, "Field descriptor"}, + {"__doc__", (getter)GetDoc, nullptr, nullptr}, + {nullptr}, +}; } // namespace field static PyTypeObject _CFieldProperty_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) // head - FULL_MODULE_NAME ".FieldProperty", // tp_name - sizeof(PyMessageFieldProperty), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)field::Repr, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "Field property of a Message", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members - field::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - (descrgetfunc)field::DescrGet, // tp_descr_get - (descrsetfunc)field::DescrSet, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new + PyVarObject_HEAD_INIT(&PyType_Type, 0) // head + FULL_MODULE_NAME ".FieldProperty", // tp_name + sizeof(PyMessageFieldProperty), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)field::Repr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "Field property of a Message", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + field::Getters, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + (descrgetfunc)field::DescrGet, // tp_descr_get + (descrsetfunc)field::DescrSet, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new }; PyTypeObject* CFieldProperty_Type = &_CFieldProperty_Type; @@ -126,8 +127,8 @@ PyObject* NewFieldProperty(const FieldDescriptor* field_descriptor) { // Create a new descriptor object PyMessageFieldProperty* property = PyObject_New(PyMessageFieldProperty, CFieldProperty_Type); - if (property == NULL) { - return NULL; + if (property == nullptr) { + return nullptr; } property->field_descriptor = field_descriptor; return reinterpret_cast(property); diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc index 053a78e4f6382..c953c6594f9c1 100644 --- a/python/google/protobuf/pyext/map_container.cc +++ b/python/google/protobuf/pyext/map_container.cc @@ -187,7 +187,7 @@ static PyObject* MapKeyToPython(MapContainer* self, const MapKey& key) { PyErr_Format( PyExc_SystemError, "Couldn't convert type %d to value", field_descriptor->cpp_type()); - return NULL; + return nullptr; } } @@ -219,7 +219,7 @@ PyObject* MapValueRefToPython(MapContainer* self, const MapValueRef& value) { PyErr_Format( PyExc_SystemError, "Couldn't convert type %d to value", field_descriptor->cpp_type()); - return NULL; + return nullptr; } } @@ -283,7 +283,7 @@ static bool PythonToMapValueRef(MapContainer* self, PyObject* obj, const EnumDescriptor* enum_descriptor = field_descriptor->enum_type(); const EnumValueDescriptor* enum_value = enum_descriptor->FindValueByNumber(value); - if (enum_value != NULL) { + if (enum_value != nullptr) { value_ref->SetEnumValue(value); return true; } else { @@ -362,7 +362,7 @@ PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { MapKey map_key; if (!PythonToMapKey(self, key, &map_key)) { - return NULL; + return nullptr; } if (reflection->ContainsMapKey(*message, self->parent_field_descriptor, @@ -378,14 +378,14 @@ PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { MapContainer* NewScalarMapContainer( CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } PyObject* obj(PyType_GenericAlloc(ScalarMapContainer_Type, 0)); - if (obj == NULL) { + if (obj == nullptr) { PyErr_Format(PyExc_RuntimeError, "Could not allocate new container."); - return NULL; + return nullptr; } MapContainer* self = GetMap(obj); @@ -408,7 +408,7 @@ PyObject* MapReflectionFriend::ScalarMapGetItem(PyObject* _self, MapValueRef value; if (!PythonToMapKey(self, key, &map_key)) { - return NULL; + return nullptr; } if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, @@ -460,22 +460,22 @@ static PyObject* ScalarMapGet(PyObject* self, PyObject* args, PyObject* kwargs) { static const char* kwlist[] = {"key", "default", nullptr}; PyObject* key; - PyObject* default_value = NULL; + PyObject* default_value = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", const_cast(kwlist), &key, &default_value)) { - return NULL; + return nullptr; } ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key)); - if (is_present.get() == NULL) { - return NULL; + if (is_present.get() == nullptr) { + return nullptr; } if (PyObject_IsTrue(is_present.get())) { return MapReflectionFriend::ScalarMapGetItem(self, key); } else { - if (default_value != NULL) { + if (default_value != nullptr) { Py_INCREF(default_value); return default_value; } else { @@ -486,8 +486,8 @@ static PyObject* ScalarMapGet(PyObject* self, PyObject* args, PyObject* MapReflectionFriend::ScalarMapToStr(PyObject* _self) { ScopedPyObjectPtr dict(PyDict_New()); - if (dict == NULL) { - return NULL; + if (dict == nullptr) { + return nullptr; } ScopedPyObjectPtr key; ScopedPyObjectPtr value; @@ -500,15 +500,15 @@ PyObject* MapReflectionFriend::ScalarMapToStr(PyObject* _self) { it != reflection->MapEnd(message, self->parent_field_descriptor); ++it) { key.reset(MapKeyToPython(self, it.GetKey())); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } value.reset(MapValueRefToPython(self, it.GetValueRef())); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } if (PyDict_SetItem(dict.get(), key.get(), value.get()) < 0) { - return NULL; + return nullptr; } } return PyObject_Repr(dict.get()); @@ -542,7 +542,7 @@ static PyMethodDef ScalarMapMethods[] = { { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, "Outputs picklable representation of the repeated field." }, */ - {NULL, NULL}, + {nullptr, nullptr}, }; PyTypeObject* ScalarMapContainer_Type; @@ -554,7 +554,7 @@ static PyType_Slot ScalarMapContainer_Type_slots[] = { {Py_tp_methods, (void*)ScalarMapMethods}, {Py_tp_iter, (void*)MapReflectionFriend::GetIterator}, {Py_tp_repr, (void*)MapReflectionFriend::ScalarMapToStr}, - {0, 0}, + {0, nullptr}, }; PyType_Spec ScalarMapContainer_Type_spec = { @@ -579,13 +579,13 @@ MessageMapContainer* NewMessageMapContainer( CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor, CMessageClass* message_class) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } PyObject* obj = PyType_GenericAlloc(MessageMapContainer_Type, 0); - if (obj == NULL) { + if (obj == nullptr) { PyErr_SetString(PyExc_RuntimeError, "Could not allocate new container."); - return NULL; + return nullptr; } MessageMapContainer* self = GetMessageMap(obj); @@ -660,7 +660,7 @@ PyObject* MapReflectionFriend::MessageMapGetItem(PyObject* _self, MapValueRef value; if (!PythonToMapKey(self, key, &map_key)) { - return NULL; + return nullptr; } if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, @@ -673,8 +673,8 @@ PyObject* MapReflectionFriend::MessageMapGetItem(PyObject* _self, PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) { ScopedPyObjectPtr dict(PyDict_New()); - if (dict == NULL) { - return NULL; + if (dict == nullptr) { + return nullptr; } ScopedPyObjectPtr key; ScopedPyObjectPtr value; @@ -687,15 +687,15 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) { it != reflection->MapEnd(message, self->parent_field_descriptor); ++it) { key.reset(MapKeyToPython(self, it.GetKey())); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } value.reset(GetCMessage(self, it.MutableValueRef()->MutableMessageValue())); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } if (PyDict_SetItem(dict.get(), key.get(), value.get()) < 0) { - return NULL; + return nullptr; } } return PyObject_Repr(dict.get()); @@ -704,22 +704,22 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) { PyObject* MessageMapGet(PyObject* self, PyObject* args, PyObject* kwargs) { static const char* kwlist[] = {"key", "default", nullptr}; PyObject* key; - PyObject* default_value = NULL; + PyObject* default_value = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", const_cast(kwlist), &key, &default_value)) { - return NULL; + return nullptr; } ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key)); - if (is_present.get() == NULL) { - return NULL; + if (is_present.get() == nullptr) { + return nullptr; } if (PyObject_IsTrue(is_present.get())) { return MapReflectionFriend::MessageMapGetItem(self, key); } else { - if (default_value != NULL) { + if (default_value != nullptr) { Py_INCREF(default_value); return default_value; } else { @@ -759,7 +759,7 @@ static PyMethodDef MessageMapMethods[] = { { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, "Outputs picklable representation of the repeated field." }, */ - {NULL, NULL}, + {nullptr, nullptr}, }; PyTypeObject* MessageMapContainer_Type; @@ -771,7 +771,7 @@ static PyType_Slot MessageMapContainer_Type_slots[] = { {Py_tp_methods, (void*)MessageMapMethods}, {Py_tp_iter, (void*)MapReflectionFriend::GetIterator}, {Py_tp_repr, (void*)MapReflectionFriend::MessageMapToStr}, - {0, 0}}; + {0, nullptr}}; PyType_Spec MessageMapContainer_Type_spec = { FULL_MODULE_NAME ".MessageMapContainer", sizeof(MessageMapContainer), 0, @@ -787,7 +787,7 @@ PyObject* MapReflectionFriend::GetIterator(PyObject *_self) { MapContainer* self = GetMap(_self); ScopedPyObjectPtr obj(PyType_GenericAlloc(&MapIterator_Type, 0)); - if (obj == NULL) { + if (obj == nullptr) { return PyErr_Format(PyExc_KeyError, "Could not allocate iterator"); } @@ -824,8 +824,8 @@ PyObject* MapReflectionFriend::IterNext(PyObject* _self) { "Map cleared during iteration."); } - if (self->iter.get() == NULL) { - return NULL; + if (self->iter.get() == nullptr) { + return nullptr; } Message* message = self->container->GetMutableMessage(); @@ -833,7 +833,7 @@ PyObject* MapReflectionFriend::IterNext(PyObject* _self) { if (*self->iter == reflection->MapEnd(message, self->container->parent_field_descriptor)) { - return NULL; + return nullptr; } PyObject* ret = MapKeyToPython(self->container, self->iter->GetKey()); @@ -852,60 +852,60 @@ static void DeallocMapIterator(PyObject* _self) { } PyTypeObject MapIterator_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".MapIterator", // tp_name - sizeof(MapIterator), // tp_basicsize - 0, // tp_itemsize - DeallocMapIterator, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A scalar map iterator", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - PyObject_SelfIter, // tp_iter - MapReflectionFriend::IterNext, // tp_iternext - 0, // 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 + ".MapIterator", // tp_name + sizeof(MapIterator), // tp_basicsize + 0, // tp_itemsize + DeallocMapIterator, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A scalar map iterator", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PyObject_SelfIter, // tp_iter + MapReflectionFriend::IterNext, // tp_iternext + nullptr, // 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 }; bool InitMapContainers() { // ScalarMapContainer_Type derives from our MutableMapping type. ScopedPyObjectPtr abc(PyImport_ImportModule("collections.abc")); - if (abc == NULL) { + if (abc == nullptr) { return false; } ScopedPyObjectPtr mutable_mapping( PyObject_GetAttrString(abc.get(), "MutableMapping")); - if (mutable_mapping == NULL) { + if (mutable_mapping == nullptr) { return false; } Py_INCREF(mutable_mapping.get()); ScopedPyObjectPtr bases(PyTuple_Pack(1, mutable_mapping.get())); - if (bases == NULL) { + if (bases == nullptr) { return false; } diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index cb48faa440bf5..f7a69a763cce2 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -79,12 +79,13 @@ #define PyString_AsString(ob) \ (PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob)) -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -108,7 +109,7 @@ static PyObject* kDESCRIPTOR; PyObject* EnumTypeWrapper_class; static PyObject* PythonMessage_class; static PyObject* kEmptyWeakref; -static PyObject* WKT_classes = NULL; +static PyObject* WKT_classes = nullptr; namespace message_meta { @@ -129,7 +130,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); ++i) { const FieldDescriptor* field_descriptor = descriptor->field(i); ScopedPyObjectPtr property(NewFieldProperty(field_descriptor)); - if (property == NULL) { + if (property == nullptr) { return -1; } if (PyObject_SetAttrString(cls, field_descriptor->name().c_str(), @@ -143,13 +144,13 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { const EnumDescriptor* enum_descriptor = descriptor->enum_type(i); ScopedPyObjectPtr enum_type( PyEnumDescriptor_FromDescriptor(enum_descriptor)); - if (enum_type == NULL) { + if (enum_type == nullptr) { return -1; } // Add wrapped enum type to message class. ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs( - EnumTypeWrapper_class, enum_type.get(), NULL)); - if (wrapped == NULL) { + EnumTypeWrapper_class, enum_type.get(), nullptr)); + if (wrapped == nullptr) { return -1; } if (PyObject_SetAttrString( @@ -163,7 +164,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { enum_descriptor->value(j); ScopedPyObjectPtr value_number( PyLong_FromLong(enum_value_descriptor->number())); - if (value_number == NULL) { + if (value_number == nullptr) { return -1; } if (PyObject_SetAttrString(cls, enum_value_descriptor->name().c_str(), @@ -181,7 +182,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { for (int i = 0; i < descriptor->extension_count(); ++i) { const google::protobuf::FieldDescriptor* field = descriptor->extension(i); ScopedPyObjectPtr extension_field(PyFieldDescriptor_FromDescriptor(field)); - if (extension_field == NULL) { + if (extension_field == nullptr) { return -1; } @@ -196,7 +197,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { } static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - static const char* kwlist[] = {"name", "bases", "dict", 0}; + static const char* kwlist[] = {"name", "bases", "dict", nullptr}; PyObject *bases, *dict; const char* name; @@ -204,7 +205,7 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { if (!PyArg_ParseTupleAndKeywords( args, kwargs, "sO!O!:type", const_cast(kwlist), &name, &PyTuple_Type, &bases, &PyDict_Type, &dict)) { - return NULL; + return nullptr; } // Check bases: only (), or (message.Message,) are allowed @@ -213,7 +214,7 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { PyTuple_GET_ITEM(bases, 0) == PythonMessage_class))) { PyErr_SetString(PyExc_TypeError, "A Message class can only inherit from Message"); - return NULL; + return nullptr; } // Check dict['DESCRIPTOR'] @@ -236,25 +237,25 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { // Messages have no __dict__ ScopedPyObjectPtr slots(PyTuple_New(0)); if (PyDict_SetItemString(dict, "__slots__", slots.get()) < 0) { - return NULL; + return nullptr; } // Build the arguments to the base metaclass. // We change the __bases__ classes. ScopedPyObjectPtr new_args; - if (WKT_classes == NULL) { + if (WKT_classes == nullptr) { ScopedPyObjectPtr well_known_types(PyImport_ImportModule( "google.protobuf.internal.well_known_types")); - GOOGLE_DCHECK(well_known_types != NULL); + GOOGLE_DCHECK(well_known_types != nullptr); WKT_classes = PyObject_GetAttrString(well_known_types.get(), "WKTBASES"); - GOOGLE_DCHECK(WKT_classes != NULL); + GOOGLE_DCHECK(WKT_classes != nullptr); } PyObject* well_known_class = PyDict_GetItemString( WKT_classes, message_descriptor->full_name().c_str()); - if (well_known_class == NULL) { + if (well_known_class == nullptr) { new_args.reset(Py_BuildValue("s(OO)O", name, CMessage_Type, PythonMessage_class, dict)); } else { @@ -262,21 +263,21 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { PythonMessage_class, well_known_class, dict)); } - if (new_args == NULL) { - return NULL; + if (new_args == nullptr) { + return nullptr; } // Call the base metaclass. - ScopedPyObjectPtr result(PyType_Type.tp_new(type, new_args.get(), NULL)); - if (result == NULL) { - return NULL; + ScopedPyObjectPtr result(PyType_Type.tp_new(type, new_args.get(), nullptr)); + if (result == nullptr) { + return nullptr; } CMessageClass* newtype = reinterpret_cast(result.get()); // Cache the descriptor, both as Python object and as C++ pointer. const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(py_descriptor); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } Py_INCREF(py_descriptor); newtype->py_message_descriptor = py_descriptor; @@ -285,8 +286,8 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { // use the MessageFactory optionally passed in the class dict. PyDescriptorPool* py_descriptor_pool = GetDescriptorPool_FromPool(descriptor->file()->pool()); - if (py_descriptor_pool == NULL) { - return NULL; + if (py_descriptor_pool == nullptr) { + return nullptr; } newtype->py_message_factory = py_descriptor_pool->py_message_factory; Py_INCREF(newtype->py_message_factory); @@ -296,12 +297,12 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { // MessageFactory is fully implemented in C++. if (message_factory::RegisterMessageClass(newtype->py_message_factory, descriptor, newtype) < 0) { - return NULL; + return nullptr; } // Continue with type initialization: add other descriptors, enum values... if (AddDescriptors(result.get(), descriptor) < 0) { - return NULL; + return nullptr; } return result.release(); } @@ -329,11 +330,11 @@ static int GcClear(PyObject* pself) { // The _extensions_by_name dictionary is built on every access. // TODO(amauryfa): Migrate all users to pool.FindAllExtensions() static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) { - if (self->message_descriptor == NULL) { + if (self->message_descriptor == nullptr) { // This is the base Message object, simply raise AttributeError. PyErr_SetString(PyExc_AttributeError, "Base Message class has no DESCRIPTOR"); - return NULL; + return nullptr; } const PyDescriptorPool* pool = self->py_message_factory->pool; @@ -345,12 +346,12 @@ static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) { for (int i = 0; i < extensions.size(); i++) { ScopedPyObjectPtr extension( PyFieldDescriptor_FromDescriptor(extensions[i])); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } if (PyDict_SetItemString(result.get(), extensions[i]->full_name().c_str(), extension.get()) < 0) { - return NULL; + return nullptr; } } return result.release(); @@ -359,11 +360,11 @@ static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) { // The _extensions_by_number dictionary is built on every access. // TODO(amauryfa): Migrate all users to pool.FindExtensionByNumber() static PyObject* GetExtensionsByNumber(CMessageClass *self, void *closure) { - if (self->message_descriptor == NULL) { + if (self->message_descriptor == nullptr) { // This is the base Message object, simply raise AttributeError. PyErr_SetString(PyExc_AttributeError, "Base Message class has no DESCRIPTOR"); - return NULL; + return nullptr; } const PyDescriptorPool* pool = self->py_message_factory->pool; @@ -375,24 +376,24 @@ static PyObject* GetExtensionsByNumber(CMessageClass *self, void *closure) { for (int i = 0; i < extensions.size(); i++) { ScopedPyObjectPtr extension( PyFieldDescriptor_FromDescriptor(extensions[i])); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } ScopedPyObjectPtr number(PyLong_FromLong(extensions[i]->number())); - if (number == NULL) { - return NULL; + if (number == nullptr) { + return nullptr; } if (PyDict_SetItem(result.get(), number.get(), extension.get()) < 0) { - return NULL; + return nullptr; } } return result.release(); } static PyGetSetDef Getters[] = { - {"_extensions_by_name", (getter)GetExtensionsByName, NULL}, - {"_extensions_by_number", (getter)GetExtensionsByNumber, NULL}, - {NULL} + {"_extensions_by_name", (getter)GetExtensionsByName, nullptr}, + {"_extensions_by_number", (getter)GetExtensionsByNumber, nullptr}, + {nullptr}, }; // Compute some class attributes on the fly: @@ -420,17 +421,17 @@ static PyObject* GetClassAttribute(CMessageClass *self, PyObject* name) { } } PyErr_SetObject(PyExc_AttributeError, name); - return NULL; + return nullptr; } static PyObject* GetAttr(CMessageClass* self, PyObject* name) { PyObject* result = CMessageClass_Type->tp_base->tp_getattro( reinterpret_cast(self), name); - if (result != NULL) { + if (result != nullptr) { return result; } if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return NULL; + return nullptr; } PyErr_Clear(); @@ -458,37 +459,37 @@ static PyTypeObject _CMessageClass_Type = { 0, // tp_itemsize message_meta::Dealloc, // tp_dealloc 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str (getattrofunc)message_meta::GetAttr, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, // tp_flags "The metaclass of ProtocolMessages", // tp_doc message_meta::GcTraverse, // tp_traverse message_meta::GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members message_meta::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc + nullptr, // tp_init + nullptr, // tp_alloc message_meta::New, // tp_new }; PyTypeObject* CMessageClass_Type = &_CMessageClass_Type; @@ -496,15 +497,15 @@ PyTypeObject* CMessageClass_Type = &_CMessageClass_Type; static CMessageClass* CheckMessageClass(PyTypeObject* cls) { if (!PyObject_TypeCheck(cls, CMessageClass_Type)) { PyErr_Format(PyExc_TypeError, "Class %s is not a Message", cls->tp_name); - return NULL; + return nullptr; } return reinterpret_cast(cls); } static const Descriptor* GetMessageDescriptor(PyTypeObject* cls) { CMessageClass* type = CheckMessageClass(cls); - if (type == NULL) { - return NULL; + if (type == nullptr) { + return nullptr; } return type->message_descriptor; } @@ -607,7 +608,7 @@ bool CheckAndGetInteger(PyObject* arg, T* value) { // Signed case. PY_LONG_LONG long_result; PyNumberMethods *nb; - if ((nb = arg->ob_type->tp_as_number) != NULL && nb->nb_int != NULL) { + if ((nb = arg->ob_type->tp_as_number) != nullptr && nb->nb_int != nullptr) { // PyLong_AsLongLong requires it to be a long or to have an __int__() // method. long_result = PyLong_AsLongLong(arg); @@ -672,7 +673,7 @@ bool CheckAndGetBool(PyObject* arg, bool* value) { // valid UTF-8. bool IsValidUTF8(PyObject* obj) { if (PyBytes_Check(obj)) { - PyObject* unicode = PyUnicode_FromEncodedObject(obj, "utf-8", NULL); + PyObject* unicode = PyUnicode_FromEncodedObject(obj, "utf-8", nullptr); // Clear the error indicator; we report our own error when desired. PyErr_Clear(); @@ -697,7 +698,7 @@ PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) { if (descriptor->type() == FieldDescriptor::TYPE_STRING) { if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) { FormatTypeError(arg, "bytes, unicode"); - return NULL; + return nullptr; } if (!IsValidUTF8(arg) && !AllowInvalidUTF8(descriptor)) { @@ -708,21 +709,21 @@ PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) { "unicode objects before being added.", PyString_AsString(repr)); Py_DECREF(repr); - return NULL; + return nullptr; } } else if (!PyBytes_Check(arg)) { FormatTypeError(arg, "bytes"); - return NULL; + return nullptr; } - PyObject* encoded_string = NULL; + PyObject* encoded_string = nullptr; if (descriptor->type() == FieldDescriptor::TYPE_STRING) { if (PyBytes_Check(arg)) { // The bytes were already validated as correctly encoded UTF-8 above. encoded_string = arg; // Already encoded. Py_INCREF(encoded_string); } else { - encoded_string = PyUnicode_AsEncodedString(arg, "utf-8", NULL); + encoded_string = PyUnicode_AsEncodedString(arg, "utf-8", nullptr); } } else { // In this case field type is "bytes". @@ -741,7 +742,7 @@ bool CheckAndSetString( int index) { ScopedPyObjectPtr encoded_string(CheckString(arg, descriptor)); - if (encoded_string.get() == NULL) { + if (encoded_string.get() == nullptr) { return false; } @@ -769,12 +770,13 @@ PyObject* ToStringObject(const FieldDescriptor* descriptor, return PyBytes_FromStringAndSize(value.c_str(), value.length()); } - PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL); + PyObject* result = + PyUnicode_DecodeUTF8(value.c_str(), value.length(), nullptr); // If the string can't be decoded in UTF-8, just return a string object that // contains the raw bytes. This can't happen if the value was assigned using // the members of the Python message object, but can happen if the values were // parsed from the wire (binary). - if (result == NULL) { + if (result == nullptr) { PyErr_Clear(); result = PyBytes_FromStringAndSize(value.c_str(), value.length()); } @@ -864,7 +866,7 @@ int FixupMessageAfterMerge(CMessage* self) { // Making a message writable int AssureWritable(CMessage* self) { - if (self == NULL || !self->read_only) { + if (self == nullptr || !self->read_only) { return 0; } @@ -887,7 +889,7 @@ int AssureWritable(CMessage* self) { Message* mutable_message = reflection->MutableMessage( parent_message, self->parent_field_descriptor, GetFactoryForMessage(self->parent)->message_factory); - if (mutable_message == NULL) { + if (mutable_message == nullptr) { return -1; } self->message = mutable_message; @@ -906,7 +908,7 @@ const FieldDescriptor* GetExtensionDescriptor(PyObject* extension) { // allow input which is not a field descriptor, and simply pretend it does // not exist. PyErr_SetObject(PyExc_KeyError, extension); - return NULL; + return nullptr; } return PyFieldDescriptor_AsDescriptor(extension); } @@ -917,20 +919,20 @@ static PyObject* GetIntegerEnumValue(const FieldDescriptor& descriptor, PyObject* value) { if (PyUnicode_Check(value)) { const EnumDescriptor* enum_descriptor = descriptor.enum_type(); - if (enum_descriptor == NULL) { + if (enum_descriptor == nullptr) { PyErr_SetString(PyExc_TypeError, "not an enum field"); - return NULL; + return nullptr; } char* enum_label; Py_ssize_t size; if (PyString_AsStringAndSize(value, &enum_label, &size) < 0) { - return NULL; + return nullptr; } const EnumValueDescriptor* enum_value_descriptor = enum_descriptor->FindValueByName(StringParam(enum_label, size)); - if (enum_value_descriptor == NULL) { + if (enum_value_descriptor == nullptr) { PyErr_Format(PyExc_ValueError, "unknown enum label \"%s\"", enum_label); - return NULL; + return nullptr; } return PyLong_FromLong(enum_value_descriptor->number()); } @@ -1038,12 +1040,12 @@ int DeleteRepeatedField( // Initializes fields of a message. Used in constructors. int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { - if (args != NULL && PyTuple_Size(args) != 0) { + if (args != nullptr && PyTuple_Size(args) != 0) { PyErr_SetString(PyExc_TypeError, "No positional arguments allowed"); return -1; } - if (kwargs == NULL) { + if (kwargs == nullptr) { return 0; } @@ -1057,7 +1059,7 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { } ScopedPyObjectPtr property( PyObject_GetAttr(reinterpret_cast(Py_TYPE(self)), name)); - if (property == NULL || + if (property == nullptr || !PyObject_TypeCheck(property.get(), CFieldProperty_Type)) { PyErr_Format(PyExc_ValueError, "Protocol message %s has no \"%s\" field.", self->message->GetDescriptor()->name().c_str(), @@ -1074,23 +1076,24 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { if (descriptor->is_map()) { ScopedPyObjectPtr map(GetFieldValue(self, descriptor)); const FieldDescriptor* value_descriptor = - descriptor->message_type()->FindFieldByName("value"); + descriptor->message_type()->map_value(); if (value_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { - PyErr_Format(PyExc_TypeError, "Argument %s is not iterable", PyString_AsString(name)); + if (iter == nullptr) { + PyErr_Format(PyExc_TypeError, "Argument %s is not iterable", + PyString_AsString(name)); return -1; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { ScopedPyObjectPtr source_value(PyObject_GetItem(value, next.get())); ScopedPyObjectPtr dest_value(PyObject_GetItem(map.get(), next.get())); - if (source_value.get() == NULL || dest_value.get() == NULL) { + if (source_value.get() == nullptr || dest_value.get() == nullptr) { return -1; } ScopedPyObjectPtr ok(PyObject_CallMethod( dest_value.get(), "MergeFrom", "O", source_value.get())); - if (ok.get() == NULL) { + if (ok.get() == nullptr) { return -1; } } @@ -1098,36 +1101,36 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { ScopedPyObjectPtr function_return; function_return.reset( PyObject_CallMethod(map.get(), "update", "O", value)); - if (function_return.get() == NULL) { + if (function_return.get() == nullptr) { return -1; } } } else if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) { ScopedPyObjectPtr container(GetFieldValue(self, descriptor)); - if (container == NULL) { + if (container == nullptr) { return -1; } if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { RepeatedCompositeContainer* rc_container = reinterpret_cast(container.get()); ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); return -1; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { - PyObject* kwargs = (PyDict_Check(next.get()) ? next.get() : NULL); + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { + PyObject* kwargs = (PyDict_Check(next.get()) ? next.get() : nullptr); ScopedPyObjectPtr new_msg( - repeated_composite_container::Add(rc_container, NULL, kwargs)); - if (new_msg == NULL) { + repeated_composite_container::Add(rc_container, nullptr, kwargs)); + if (new_msg == nullptr) { return -1; } - if (kwargs == NULL) { + if (kwargs == nullptr) { // next was not a dict, it's a message we need to merge ScopedPyObjectPtr merged(MergeFrom( reinterpret_cast(new_msg.get()), next.get())); - if (merged.get() == NULL) { + if (merged.get() == nullptr) { return -1; } } @@ -1140,20 +1143,20 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { RepeatedScalarContainer* rs_container = reinterpret_cast(container.get()); ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); return -1; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { ScopedPyObjectPtr enum_value( GetIntegerEnumValue(*descriptor, next.get())); - if (enum_value == NULL) { + if (enum_value == nullptr) { return -1; } ScopedPyObjectPtr new_msg(repeated_scalar_container::Append( rs_container, enum_value.get())); - if (new_msg == NULL) { + if (new_msg == nullptr) { return -1; } } @@ -1164,26 +1167,25 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { } else { if (ScopedPyObjectPtr(repeated_scalar_container::Extend( reinterpret_cast(container.get()), - value)) == - NULL) { + value)) == nullptr) { return -1; } } } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { ScopedPyObjectPtr message(GetFieldValue(self, descriptor)); - if (message == NULL) { + if (message == nullptr) { return -1; } CMessage* cmessage = reinterpret_cast(message.get()); if (PyDict_Check(value)) { // Make the message exist even if the dict is empty. AssureWritable(cmessage); - if (InitAttributes(cmessage, NULL, value) < 0) { + if (InitAttributes(cmessage, nullptr, value) < 0) { return -1; } } else { ScopedPyObjectPtr merged(MergeFrom(cmessage, value)); - if (merged == NULL) { + if (merged == nullptr) { return -1; } } @@ -1191,7 +1193,7 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { ScopedPyObjectPtr new_val; if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { new_val.reset(GetIntegerEnumValue(*descriptor, value)); - if (new_val == NULL) { + if (new_val == nullptr) { return -1; } value = new_val.get(); @@ -1209,19 +1211,19 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { CMessage* NewEmptyMessage(CMessageClass* type) { CMessage* self = reinterpret_cast( PyType_GenericAlloc(&type->super.ht_type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } - self->message = NULL; - self->parent = NULL; - self->parent_field_descriptor = NULL; + self->message = nullptr; + self->parent = nullptr; + self->parent_field_descriptor = nullptr; self->read_only = false; - self->composite_fields = NULL; - self->child_submessages = NULL; + self->composite_fields = nullptr; + self->child_submessages = nullptr; - self->unknown_field_set = NULL; + self->unknown_field_set = nullptr; return self; } @@ -1313,30 +1315,27 @@ static void Dealloc(CMessage* self) { PyObject* IsInitialized(CMessage* self, PyObject* args) { - PyObject* errors = NULL; + PyObject* errors = nullptr; if (!PyArg_ParseTuple(args, "|O", &errors)) { - return NULL; + return nullptr; } if (self->message->IsInitialized()) { Py_RETURN_TRUE; } - if (errors != NULL) { + if (errors != nullptr) { ScopedPyObjectPtr initialization_errors( FindInitializationErrors(self)); - if (initialization_errors == NULL) { - return NULL; + if (initialization_errors == nullptr) { + return nullptr; } ScopedPyObjectPtr extend_name(PyUnicode_FromString("extend")); - if (extend_name == NULL) { - return NULL; + if (extend_name == nullptr) { + return nullptr; } ScopedPyObjectPtr result(PyObject_CallMethodObjArgs( - errors, - extend_name.get(), - initialization_errors.get(), - NULL)); - if (result == NULL) { - return NULL; + errors, extend_name.get(), initialization_errors.get(), nullptr)); + if (result == nullptr) { + return nullptr; } } Py_RETURN_FALSE; @@ -1363,17 +1362,17 @@ const FieldDescriptor* FindFieldWithOneofs(const Message* message, const Descriptor* descriptor = message->GetDescriptor(); const FieldDescriptor* field_descriptor = descriptor->FindFieldByName(field_name); - if (field_descriptor != NULL) { + if (field_descriptor != nullptr) { return field_descriptor; } const OneofDescriptor* oneof_desc = descriptor->FindOneofByName(field_name); - if (oneof_desc != NULL) { + if (oneof_desc != nullptr) { *in_oneof = true; return message->GetReflection()->GetOneofFieldDescriptor(*message, oneof_desc); } - return NULL; + return nullptr; } bool CheckHasPresence(const FieldDescriptor* field_descriptor, bool in_oneof) { @@ -1401,25 +1400,25 @@ PyObject* HasField(CMessage* self, PyObject* arg) { Py_ssize_t size; field_name = const_cast(PyUnicode_AsUTF8AndSize(arg, &size)); if (!field_name) { - return NULL; + return nullptr; } Message* message = self->message; bool is_in_oneof; const FieldDescriptor* field_descriptor = FindFieldWithOneofs(message, StringParam(field_name, size), &is_in_oneof); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { if (!is_in_oneof) { PyErr_Format(PyExc_ValueError, "Protocol message %s has no field %s.", message->GetDescriptor()->name().c_str(), field_name); - return NULL; + return nullptr; } else { Py_RETURN_FALSE; } } if (!CheckHasPresence(field_descriptor, is_in_oneof)) { - return NULL; + return nullptr; } if (message->GetReflection()->HasField(*message, field_descriptor)) { @@ -1431,8 +1430,8 @@ PyObject* HasField(CMessage* self, PyObject* arg) { PyObject* ClearExtension(CMessage* self, PyObject* extension) { const FieldDescriptor* descriptor = GetExtensionDescriptor(extension); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } if (ClearFieldByDescriptor(self, descriptor) < 0) { return nullptr; @@ -1442,8 +1441,8 @@ PyObject* ClearExtension(CMessage* self, PyObject* extension) { PyObject* HasExtension(CMessage* self, PyObject* extension) { const FieldDescriptor* descriptor = GetExtensionDescriptor(extension); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } int has_field = HasFieldByDescriptor(self, descriptor); if (has_field < 0) { @@ -1586,20 +1585,20 @@ PyObject* ClearField(CMessage* self, PyObject* arg) { char* field_name; Py_ssize_t field_size; if (PyString_AsStringAndSize(arg, &field_name, &field_size) < 0) { - return NULL; + return nullptr; } AssureWritable(self); bool is_in_oneof; const FieldDescriptor* field_descriptor = FindFieldWithOneofs( self->message, StringParam(field_name, field_size), &is_in_oneof); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { if (is_in_oneof) { // We gave the name of a oneof, and none of its fields are set. Py_RETURN_NONE; } else { PyErr_Format(PyExc_ValueError, "Protocol message has no \"%s\" field.", field_name); - return NULL; + return nullptr; } } @@ -1626,7 +1625,7 @@ PyObject* Clear(CMessage* self) { } if (InternalReparentFields(self, messages_to_release, containers_to_release) < 0) { - return NULL; + return nullptr; } if (self->unknown_field_set) { unknown_fields::Clear( @@ -1640,7 +1639,7 @@ PyObject* Clear(CMessage* self) { // --------------------------------------------------------------------- static std::string GetMessageName(CMessage* self) { - if (self->parent_field_descriptor != NULL) { + if (self->parent_field_descriptor != nullptr) { return self->parent_field_descriptor->full_name(); } else { return self->message->GetDescriptor()->full_name(); @@ -1651,33 +1650,33 @@ static PyObject* InternalSerializeToString( CMessage* self, PyObject* args, PyObject* kwargs, bool require_initialized) { // Parse the "deterministic" kwarg; defaults to False. - static const char* kwlist[] = {"deterministic", 0}; + static const char* kwlist[] = {"deterministic", nullptr}; PyObject* deterministic_obj = Py_None; if (!PyArg_ParseTupleAndKeywords( args, kwargs, "|O", const_cast(kwlist), &deterministic_obj)) { - return NULL; + return nullptr; } // Preemptively convert to a bool first, so we don't need to back out of // allocating memory if this raises an exception. // NOTE: This is unused later if deterministic == Py_None, but that's fine. int deterministic = PyObject_IsTrue(deterministic_obj); if (deterministic < 0) { - return NULL; + return nullptr; } if (require_initialized && !self->message->IsInitialized()) { ScopedPyObjectPtr errors(FindInitializationErrors(self)); - if (errors == NULL) { - return NULL; + if (errors == nullptr) { + return nullptr; } ScopedPyObjectPtr comma(PyUnicode_FromString(",")); - if (comma == NULL) { - return NULL; + if (comma == nullptr) { + return nullptr; } ScopedPyObjectPtr joined( PyObject_CallMethod(comma.get(), "join", "O", errors.get())); - if (joined == NULL) { - return NULL; + if (joined == nullptr) { + return nullptr; } // TODO(haberman): this is a (hopefully temporary) hack. The unit testing @@ -1689,19 +1688,19 @@ static PyObject* InternalSerializeToString( // again every time. ScopedPyObjectPtr message_module(PyImport_ImportModule( "google.protobuf.message")); - if (message_module.get() == NULL) { - return NULL; + if (message_module.get() == nullptr) { + return nullptr; } ScopedPyObjectPtr encode_error( PyObject_GetAttrString(message_module.get(), "EncodeError")); - if (encode_error.get() == NULL) { - return NULL; + if (encode_error.get() == nullptr) { + return nullptr; } PyErr_Format(encode_error.get(), "Message %s is missing required fields: %s", GetMessageName(self).c_str(), PyString_AsString(joined.get())); - return NULL; + return nullptr; } // Ok, arguments parsed and errors checked, now encode to a string @@ -1718,9 +1717,9 @@ static PyObject* InternalSerializeToString( return nullptr; } - PyObject* result = PyBytes_FromStringAndSize(NULL, size); - if (result == NULL) { - return NULL; + PyObject* result = PyBytes_FromStringAndSize(nullptr, size); + if (result == nullptr) { + return nullptr; } io::ArrayOutputStream out(PyBytes_AS_STRING(result), size); io::CodedOutputStream coded_out(&out); @@ -1794,7 +1793,7 @@ static PyObject* ToStr(CMessage* self) { std::string output; if (!printer.PrintToString(*self->message, &output)) { PyErr_SetString(PyExc_ValueError, "Unable to convert message to str"); - return NULL; + return nullptr; } return PyUnicode_FromString(output.c_str()); } @@ -1807,7 +1806,7 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), Py_TYPE(arg)->tp_name); - return NULL; + return nullptr; } other_message = reinterpret_cast(arg); @@ -1818,7 +1817,7 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), other_message->message->GetDescriptor()->full_name().c_str()); - return NULL; + return nullptr; } AssureWritable(self); @@ -1826,7 +1825,7 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) { // Child message might be lazily created before MergeFrom. Make sure they // are mutable at this point if child messages are really created. if (FixupMessageAfterMerge(self) < 0) { - return NULL; + return nullptr; } Py_RETURN_NONE; @@ -1840,7 +1839,7 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), Py_TYPE(arg)->tp_name); - return NULL; + return nullptr; } other_message = reinterpret_cast(arg); @@ -1856,7 +1855,7 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), other_message->message->GetDescriptor()->full_name().c_str()); - return NULL; + return nullptr; } AssureWritable(self); @@ -1876,7 +1875,7 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) { if (!arg || !PyBool_Check(arg)) { PyErr_SetString(PyExc_TypeError, "Argument to SetAllowOversizeProtos must be boolean"); - return NULL; + return nullptr; } allow_oversize_protos = PyObject_IsTrue(arg); if (allow_oversize_protos) { @@ -1889,7 +1888,7 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) { static PyObject* MergeFromString(CMessage* self, PyObject* arg) { Py_buffer data; if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) < 0) { - return NULL; + return nullptr; } AssureWritable(self); @@ -1911,19 +1910,29 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) { // Child message might be lazily created before MergeFrom. Make sure they // are mutable at this point if child messages are really created. if (FixupMessageAfterMerge(self) < 0) { - return NULL; + return nullptr; } // Python makes distinction in error message, between a general parse failure // and in-correct ending on a terminating tag. Hence we need to be a bit more // explicit in our correctness checks. - if (ptr == nullptr || ctx.BytesUntilLimit(ptr) < 0) { - // Parse error or the parser overshoot the limit. + if (ptr == nullptr) { + // Parse error. PyErr_Format( DecodeError_class, "Error parsing message with type '%s'", self->GetMessageClass()->message_descriptor->full_name().c_str()); + return nullptr; + } + if (ctx.BytesUntilLimit(ptr) < 0) { + // The parser overshot the limit. + PyErr_Format( + DecodeError_class, + "Error parsing message as the message exceeded the protobuf limit " + "with type '%s'", + self->GetMessageClass()->message_descriptor->full_name().c_str()); return NULL; } + // ctx has an explicit limit set (length of string_view), so we have to // check we ended at that limit. if (!ctx.EndedAtLimit()) { @@ -1936,8 +1945,8 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) { } static PyObject* ParseFromString(CMessage* self, PyObject* arg) { - if (ScopedPyObjectPtr(Clear(self)) == NULL) { - return NULL; + if (ScopedPyObjectPtr(Clear(self)) == nullptr) { + return nullptr; } return MergeFromString(self, arg); } @@ -1949,25 +1958,25 @@ static PyObject* ByteSize(CMessage* self, PyObject* args) { PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle) { const FieldDescriptor* descriptor = GetExtensionDescriptor(extension_handle); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } if (!PyObject_TypeCheck(cls, CMessageClass_Type)) { PyErr_Format(PyExc_TypeError, "Expected a message class, got %s", cls->ob_type->tp_name); - return NULL; + return nullptr; } CMessageClass *message_class = reinterpret_cast(cls); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } // If the extension was already registered, check that it is the same. const FieldDescriptor* existing_extension = message_class->py_message_factory->pool->pool->FindExtensionByNumber( descriptor->containing_type(), descriptor->number()); - if (existing_extension != NULL && existing_extension != descriptor) { + if (existing_extension != nullptr && existing_extension != descriptor) { PyErr_SetString(PyExc_ValueError, "Double registration of Extensions"); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -1980,20 +1989,19 @@ static PyObject* SetInParent(CMessage* self, PyObject* args) { static PyObject* WhichOneof(CMessage* self, PyObject* arg) { Py_ssize_t name_size; char *name_data; - if (PyString_AsStringAndSize(arg, &name_data, &name_size) < 0) - return NULL; + if (PyString_AsStringAndSize(arg, &name_data, &name_size) < 0) return nullptr; const OneofDescriptor* oneof_desc = self->message->GetDescriptor()->FindOneofByName( StringParam(name_data, name_size)); - if (oneof_desc == NULL) { + if (oneof_desc == nullptr) { PyErr_Format(PyExc_ValueError, "Protocol message has no oneof \"%s\" field.", name_data); - return NULL; + return nullptr; } const FieldDescriptor* field_in_oneof = self->message->GetReflection()->GetOneofFieldDescriptor( *self->message, oneof_desc); - if (field_in_oneof == NULL) { + if (field_in_oneof == nullptr) { Py_RETURN_NONE; } else { const std::string& name = field_in_oneof->name(); @@ -2009,8 +2017,8 @@ static PyObject* ListFields(CMessage* self) { // Normally, the list will be exactly the size of the fields. ScopedPyObjectPtr all_fields(PyList_New(fields.size())); - if (all_fields == NULL) { - return NULL; + if (all_fields == nullptr) { + return nullptr; } // When there are unknown extensions, the py list will *not* contain @@ -2019,36 +2027,36 @@ static PyObject* ListFields(CMessage* self) { Py_ssize_t actual_size = 0; for (size_t i = 0; i < fields.size(); ++i) { ScopedPyObjectPtr t(PyTuple_New(2)); - if (t == NULL) { - return NULL; + if (t == nullptr) { + return nullptr; } if (fields[i]->is_extension()) { ScopedPyObjectPtr extension_field( PyFieldDescriptor_FromDescriptor(fields[i])); - if (extension_field == NULL) { - return NULL; + if (extension_field == nullptr) { + return nullptr; } // With C++ descriptors, the field can always be retrieved, but for // unknown extensions which have not been imported in Python code, there // is no message class and we cannot retrieve the value. // TODO(amauryfa): consider building the class on the fly! - if (fields[i]->message_type() != NULL && - message_factory::GetMessageClass( - GetFactoryForMessage(self), - fields[i]->message_type()) == NULL) { + if (fields[i]->message_type() != nullptr && + message_factory::GetMessageClass(GetFactoryForMessage(self), + fields[i]->message_type()) == + nullptr) { PyErr_Clear(); continue; } - ScopedPyObjectPtr extensions(GetExtensionDict(self, NULL)); - if (extensions == NULL) { - return NULL; + ScopedPyObjectPtr extensions(GetExtensionDict(self, nullptr)); + if (extensions == nullptr) { + return nullptr; } // 'extension' reference later stolen by PyTuple_SET_ITEM. PyObject* extension = PyObject_GetItem( extensions.get(), extension_field.get()); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } PyTuple_SET_ITEM(t.get(), 0, extension_field.release()); // Steals reference to 'extension' @@ -2057,14 +2065,14 @@ static PyObject* ListFields(CMessage* self) { // Normal field ScopedPyObjectPtr field_descriptor( PyFieldDescriptor_FromDescriptor(fields[i])); - if (field_descriptor == NULL) { - return NULL; + if (field_descriptor == nullptr) { + return nullptr; } PyObject* field_value = GetFieldValue(self, fields[i]); - if (field_value == NULL) { + if (field_value == nullptr) { PyErr_SetString(PyExc_ValueError, fields[i]->name().c_str()); - return NULL; + return nullptr; } PyTuple_SET_ITEM(t.get(), 0, field_descriptor.release()); PyTuple_SET_ITEM(t.get(), 1, field_value); @@ -2073,9 +2081,9 @@ static PyObject* ListFields(CMessage* self) { ++actual_size; } if (static_cast(actual_size) != fields.size() && - (PyList_SetSlice(all_fields.get(), actual_size, fields.size(), NULL) < + (PyList_SetSlice(all_fields.get(), actual_size, fields.size(), nullptr) < 0)) { - return NULL; + return nullptr; } return all_fields.release(); } @@ -2092,16 +2100,16 @@ PyObject* FindInitializationErrors(CMessage* self) { message->FindInitializationErrors(&errors); PyObject* error_list = PyList_New(errors.size()); - if (error_list == NULL) { - return NULL; + if (error_list == nullptr) { + return nullptr; } for (size_t i = 0; i < errors.size(); ++i) { const std::string& error = errors[i]; PyObject* error_string = PyUnicode_FromStringAndSize(error.c_str(), error.length()); - if (error_string == NULL) { + if (error_string == nullptr) { Py_DECREF(error_list); - return NULL; + return nullptr; } PyList_SET_ITEM(error_list, i, error_string); } @@ -2147,10 +2155,10 @@ PyObject* InternalGetScalar(const Message* message, const Reflection* reflection = message->GetReflection(); if (!CheckFieldBelongsToMessage(field_descriptor, message)) { - return NULL; + return nullptr; } - PyObject* result = NULL; + PyObject* result = nullptr; switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { int32_t value = reflection->GetInt32(*message, field_descriptor); @@ -2218,13 +2226,13 @@ CMessage* InternalGetSubMessage( factory, field_descriptor->message_type()); ScopedPyObjectPtr message_class_owner( reinterpret_cast(message_class)); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } CMessage* cmsg = cmessage::NewEmptyMessage(message_class); - if (cmsg == NULL) { - return NULL; + if (cmsg == nullptr) { + return nullptr; } Py_INCREF(self); @@ -2310,7 +2318,7 @@ int InternalSetNonOneofScalar( 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->SetEnum(message, field_descriptor, enum_value); } else { PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value); @@ -2345,37 +2353,37 @@ int InternalSetScalar( } PyObject* FromString(PyTypeObject* cls, PyObject* serialized) { - PyObject* py_cmsg = PyObject_CallObject( - reinterpret_cast(cls), NULL); - if (py_cmsg == NULL) { - return NULL; + PyObject* py_cmsg = + PyObject_CallObject(reinterpret_cast(cls), nullptr); + if (py_cmsg == nullptr) { + return nullptr; } CMessage* cmsg = reinterpret_cast(py_cmsg); ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized)); - if (py_length == NULL) { + if (py_length == nullptr) { Py_DECREF(py_cmsg); - return NULL; + return nullptr; } return py_cmsg; } PyObject* DeepCopy(CMessage* self, PyObject* arg) { - PyObject* clone = PyObject_CallObject( - reinterpret_cast(Py_TYPE(self)), NULL); - if (clone == NULL) { - return NULL; + PyObject* clone = + PyObject_CallObject(reinterpret_cast(Py_TYPE(self)), nullptr); + if (clone == nullptr) { + return nullptr; } if (!PyObject_TypeCheck(clone, CMessage_Type)) { Py_DECREF(clone); - return NULL; + return nullptr; } - if (ScopedPyObjectPtr(MergeFrom( - reinterpret_cast(clone), - reinterpret_cast(self))) == NULL) { + if (ScopedPyObjectPtr(MergeFrom(reinterpret_cast(clone), + reinterpret_cast(self))) == + nullptr) { Py_DECREF(clone); - return NULL; + return nullptr; } return clone; } @@ -2384,23 +2392,24 @@ PyObject* ToUnicode(CMessage* self) { // Lazy import to prevent circular dependencies ScopedPyObjectPtr text_format( PyImport_ImportModule("google.protobuf.text_format")); - if (text_format == NULL) { - return NULL; + if (text_format == nullptr) { + return nullptr; } ScopedPyObjectPtr method_name(PyUnicode_FromString("MessageToString")); - if (method_name == NULL) { - return NULL; + if (method_name == nullptr) { + return nullptr; } Py_INCREF(Py_True); ScopedPyObjectPtr encoded(PyObject_CallMethodObjArgs( - text_format.get(), method_name.get(), self, Py_True, NULL)); + text_format.get(), method_name.get(), self, Py_True, nullptr)); Py_DECREF(Py_True); - if (encoded == NULL) { - return NULL; + if (encoded == nullptr) { + return nullptr; } - PyObject* decoded = PyUnicode_FromEncodedObject(encoded.get(), "utf-8", NULL); - if (decoded == NULL) { - return NULL; + PyObject* decoded = + PyUnicode_FromEncodedObject(encoded.get(), "utf-8", nullptr); + if (decoded == nullptr) { + return nullptr; } return decoded; } @@ -2412,7 +2421,7 @@ PyObject* _CheckCalledFromGeneratedFile(PyObject* unused, PyErr_SetString(PyExc_TypeError, "Descriptors should not be created directly, " "but only retrieved from their parent."); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -2423,20 +2432,20 @@ static PyObject* GetExtensionDict(CMessage* self, void *closure) { const Descriptor* descriptor = GetMessageDescriptor(Py_TYPE(self)); if (!descriptor->extension_range_count()) { PyErr_SetNone(PyExc_AttributeError); - return NULL; + return nullptr; } if (!self->composite_fields) { self->composite_fields = new CMessage::CompositeFieldsMap(); } if (!self->composite_fields) { - return NULL; + return nullptr; } ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self); return reinterpret_cast(extension_dict); } static PyObject* UnknownFieldSet(CMessage* self) { - if (self->unknown_field_set == NULL) { + if (self->unknown_field_set == nullptr) { self->unknown_field_set = unknown_fields::NewPyUnknownFields(self); } else { Py_INCREF(self->unknown_field_set); @@ -2455,75 +2464,70 @@ static PyObject* GetExtensionsByNumber(CMessage *self, void *closure) { } static PyGetSetDef Getters[] = { - {"Extensions", (getter)GetExtensionDict, NULL, "Extension dict"}, - {"_extensions_by_name", (getter)GetExtensionsByName, NULL}, - {"_extensions_by_number", (getter)GetExtensionsByNumber, NULL}, - {NULL} + {"Extensions", (getter)GetExtensionDict, nullptr, "Extension dict"}, + {"_extensions_by_name", (getter)GetExtensionsByName, nullptr}, + {"_extensions_by_number", (getter)GetExtensionsByNumber, nullptr}, + {nullptr}, }; - static PyMethodDef Methods[] = { - { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, - "Makes a deep copy of the class." }, - { "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS, - "Outputs a unicode representation of the message." }, - { "ByteSize", (PyCFunction)ByteSize, METH_NOARGS, - "Returns the size of the message in bytes." }, - { "Clear", (PyCFunction)Clear, METH_NOARGS, - "Clears the message." }, - { "ClearExtension", (PyCFunction)ClearExtension, METH_O, - "Clears a message field." }, - { "ClearField", (PyCFunction)ClearField, METH_O, - "Clears a message field." }, - { "CopyFrom", (PyCFunction)CopyFrom, METH_O, - "Copies a protocol message into the current message." }, - { "DiscardUnknownFields", (PyCFunction)DiscardUnknownFields, METH_NOARGS, - "Discards the unknown fields." }, - { "FindInitializationErrors", (PyCFunction)FindInitializationErrors, - METH_NOARGS, - "Finds unset required fields." }, - { "FromString", (PyCFunction)FromString, METH_O | METH_CLASS, - "Creates new method instance from given serialized data." }, - { "HasExtension", (PyCFunction)HasExtension, METH_O, - "Checks if a message field is set." }, - { "HasField", (PyCFunction)HasField, METH_O, - "Checks if a message field is set." }, - { "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS, - "Checks if all required fields of a protocol message are set." }, - { "ListFields", (PyCFunction)ListFields, METH_NOARGS, - "Lists all set fields of a message." }, - { "MergeFrom", (PyCFunction)MergeFrom, METH_O, - "Merges a protocol message into the current message." }, - { "MergeFromString", (PyCFunction)MergeFromString, METH_O, - "Merges a serialized message into the current message." }, - { "ParseFromString", (PyCFunction)ParseFromString, METH_O, - "Parses a serialized message into the current message." }, - { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS, - "Registers an extension with the current message." }, - { "SerializePartialToString", (PyCFunction)SerializePartialToString, - METH_VARARGS | METH_KEYWORDS, - "Serializes the message to a string, even if it isn't initialized." }, - { "SerializeToString", (PyCFunction)SerializeToString, - METH_VARARGS | METH_KEYWORDS, - "Serializes the message to a string, only for initialized messages." }, - { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS, - "Sets the has bit of the given field in its parent message." }, - { "UnknownFields", (PyCFunction)UnknownFieldSet, METH_NOARGS, - "Parse unknown field set"}, - { "WhichOneof", (PyCFunction)WhichOneof, METH_O, - "Returns the name of the field set inside a oneof, " - "or None if no field is set." }, - - // Static Methods. - { "_CheckCalledFromGeneratedFile", (PyCFunction)_CheckCalledFromGeneratedFile, - METH_NOARGS | METH_STATIC, - "Raises TypeError if the caller is not in a _pb2.py file."}, - { NULL, NULL} -}; + {"__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, + "Makes a deep copy of the class."}, + {"__unicode__", (PyCFunction)ToUnicode, METH_NOARGS, + "Outputs a unicode representation of the message."}, + {"ByteSize", (PyCFunction)ByteSize, METH_NOARGS, + "Returns the size of the message in bytes."}, + {"Clear", (PyCFunction)Clear, METH_NOARGS, "Clears the message."}, + {"ClearExtension", (PyCFunction)ClearExtension, METH_O, + "Clears a message field."}, + {"ClearField", (PyCFunction)ClearField, METH_O, "Clears a message field."}, + {"CopyFrom", (PyCFunction)CopyFrom, METH_O, + "Copies a protocol message into the current message."}, + {"DiscardUnknownFields", (PyCFunction)DiscardUnknownFields, METH_NOARGS, + "Discards the unknown fields."}, + {"FindInitializationErrors", (PyCFunction)FindInitializationErrors, + METH_NOARGS, "Finds unset required fields."}, + {"FromString", (PyCFunction)FromString, METH_O | METH_CLASS, + "Creates new method instance from given serialized data."}, + {"HasExtension", (PyCFunction)HasExtension, METH_O, + "Checks if a message field is set."}, + {"HasField", (PyCFunction)HasField, METH_O, + "Checks if a message field is set."}, + {"IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS, + "Checks if all required fields of a protocol message are set."}, + {"ListFields", (PyCFunction)ListFields, METH_NOARGS, + "Lists all set fields of a message."}, + {"MergeFrom", (PyCFunction)MergeFrom, METH_O, + "Merges a protocol message into the current message."}, + {"MergeFromString", (PyCFunction)MergeFromString, METH_O, + "Merges a serialized message into the current message."}, + {"ParseFromString", (PyCFunction)ParseFromString, METH_O, + "Parses a serialized message into the current message."}, + {"RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS, + "Registers an extension with the current message."}, + {"SerializePartialToString", (PyCFunction)SerializePartialToString, + METH_VARARGS | METH_KEYWORDS, + "Serializes the message to a string, even if it isn't initialized."}, + {"SerializeToString", (PyCFunction)SerializeToString, + METH_VARARGS | METH_KEYWORDS, + "Serializes the message to a string, only for initialized messages."}, + {"SetInParent", (PyCFunction)SetInParent, METH_NOARGS, + "Sets the has bit of the given field in its parent message."}, + {"UnknownFields", (PyCFunction)UnknownFieldSet, METH_NOARGS, + "Parse unknown field set"}, + {"WhichOneof", (PyCFunction)WhichOneof, METH_O, + "Returns the name of the field set inside a oneof, " + "or None if no field is set."}, + + // Static Methods. + {"_CheckCalledFromGeneratedFile", + (PyCFunction)_CheckCalledFromGeneratedFile, METH_NOARGS | METH_STATIC, + "Raises TypeError if the caller is not in a _pb2.py file."}, + {nullptr, nullptr}}; bool SetCompositeField(CMessage* self, const FieldDescriptor* field, ContainerBase* value) { - if (self->composite_fields == NULL) { + if (self->composite_fields == nullptr) { self->composite_fields = new CMessage::CompositeFieldsMap(); } (*self->composite_fields)[field] = value; @@ -2531,7 +2535,7 @@ bool SetCompositeField(CMessage* self, const FieldDescriptor* field, } bool SetSubmessage(CMessage* self, CMessage* submessage) { - if (self->child_submessages == NULL) { + if (self->child_submessages == nullptr) { self->child_submessages = new CMessage::SubMessagesMap(); } (*self->child_submessages)[submessage->message] = submessage; @@ -2542,11 +2546,11 @@ PyObject* GetAttr(PyObject* pself, PyObject* name) { CMessage* self = reinterpret_cast(pself); PyObject* result = PyObject_GenericGetAttr( reinterpret_cast(self), name); - if (result != NULL) { + if (result != nullptr) { return result; } if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return NULL; + return nullptr; } PyErr_Clear(); @@ -2571,7 +2575,7 @@ PyObject* GetFieldValue(CMessage* self, "descriptor to field '%s' doesn't apply to '%s' object", field_descriptor->full_name().c_str(), Py_TYPE(self)->tp_name); - return NULL; + return nullptr; } if (!field_descriptor->is_repeated() && @@ -2582,12 +2586,12 @@ PyObject* GetFieldValue(CMessage* self, ContainerBase* py_container = nullptr; if (field_descriptor->is_map()) { const Descriptor* entry_type = field_descriptor->message_type(); - const FieldDescriptor* value_type = entry_type->FindFieldByName("value"); + const FieldDescriptor* value_type = entry_type->map_value(); if (value_type->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { CMessageClass* value_class = message_factory::GetMessageClass( GetFactoryForMessage(self), value_type->message_type()); - if (value_class == NULL) { - return NULL; + if (value_class == nullptr) { + return nullptr; } py_container = NewMessageMapContainer(self, field_descriptor, value_class); @@ -2598,8 +2602,8 @@ PyObject* GetFieldValue(CMessage* self, if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { CMessageClass* message_class = message_factory::GetMessageClass( GetFactoryForMessage(self), field_descriptor->message_type()); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } py_container = repeated_composite_container::NewContainer( self, field_descriptor, message_class); @@ -2614,12 +2618,12 @@ PyObject* GetFieldValue(CMessage* self, PyErr_SetString(PyExc_SystemError, "Should never happen"); } - if (py_container == NULL) { - return NULL; + if (py_container == nullptr) { + return nullptr; } if (!SetCompositeField(self, field_descriptor, py_container)) { Py_DECREF(py_container); - return NULL; + return nullptr; } return py_container->AsPyObject(); } @@ -2695,8 +2699,8 @@ CMessage* CMessage::BuildSubMessageFromPointer( } else { cmsg = cmessage::NewEmptyMessage(message_class); - if (cmsg == NULL) { - return NULL; + if (cmsg == nullptr) { + return nullptr; } cmsg->message = sub_message; Py_INCREF(this); @@ -2725,47 +2729,47 @@ CMessage* CMessage::MaybeReleaseSubMessage(Message* sub_message) { return released; } -static CMessageClass _CMessage_Type = { { { - PyVarObject_HEAD_INIT(&_CMessageClass_Type, 0) - FULL_MODULE_NAME ".CMessage", // tp_name - sizeof(CMessage), // tp_basicsize - 0, // tp_itemsize - (destructor)cmessage::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)cmessage::ToStr, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - (reprfunc)cmessage::ToStr, // tp_str - cmessage::GetAttr, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_VERSION_TAG, // tp_flags - "A ProtocolMessage", // tp_doc - 0, // tp_traverse - 0, // tp_clear - (richcmpfunc)cmessage::RichCompare, // tp_richcompare - offsetof(CMessage, weakreflist), // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - cmessage::Methods, // tp_methods - 0, // tp_members - cmessage::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - (initproc)cmessage::Init, // tp_init - 0, // tp_alloc - cmessage::New, // tp_new -} } }; +static CMessageClass _CMessage_Type = {{{ + PyVarObject_HEAD_INIT(&_CMessageClass_Type, 0) FULL_MODULE_NAME + ".CMessage", // tp_name + sizeof(CMessage), // tp_basicsize + 0, // tp_itemsize + (destructor)cmessage::Dealloc, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)cmessage::ToStr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + (reprfunc)cmessage::ToStr, // tp_str + cmessage::GetAttr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_VERSION_TAG, // tp_flags + "A ProtocolMessage", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + (richcmpfunc)cmessage::RichCompare, // tp_richcompare + offsetof(CMessage, weakreflist), // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + cmessage::Methods, // tp_methods + nullptr, // tp_members + cmessage::Getters, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + (initproc)cmessage::Init, // tp_init + nullptr, // tp_alloc + cmessage::New, // tp_new +}}}; PyTypeObject* CMessage_Type = &_CMessage_Type.super.ht_type; // --- Exposing the C proto living inside Python proto to C code: @@ -2775,18 +2779,18 @@ Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg); static const Message* GetCProtoInsidePyProtoImpl(PyObject* msg) { const Message* message = PyMessage_GetMessagePointer(msg); - if (message == NULL) { + if (message == nullptr) { PyErr_Clear(); - return NULL; + return nullptr; } return message; } static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { Message* message = PyMessage_GetMutableMessagePointer(msg); - if (message == NULL) { + if (message == nullptr) { PyErr_Clear(); - return NULL; + return nullptr; } return message; } @@ -2794,7 +2798,7 @@ static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { const Message* PyMessage_GetMessagePointer(PyObject* msg) { if (!PyObject_TypeCheck(msg, CMessage_Type)) { PyErr_SetString(PyExc_TypeError, "Not a Message instance"); - return NULL; + return nullptr; } CMessage* cmsg = reinterpret_cast(msg); return cmsg->message; @@ -2803,7 +2807,7 @@ const Message* PyMessage_GetMessagePointer(PyObject* msg) { Message* PyMessage_GetMutableMessagePointer(PyObject* msg) { if (!PyObject_TypeCheck(msg, CMessage_Type)) { PyErr_SetString(PyExc_TypeError, "Not a Message instance"); - return NULL; + return nullptr; } CMessage* cmsg = reinterpret_cast(msg); @@ -2817,7 +2821,7 @@ Message* PyMessage_GetMutableMessagePointer(PyObject* msg) { PyErr_SetString(PyExc_ValueError, "Cannot reliably get a mutable pointer " "to a message with extra references"); - return NULL; + return nullptr; } cmessage::AssureWritable(cmsg); return cmsg->message; @@ -2890,8 +2894,8 @@ void InitGlobals() { // also be freed and reset to NULL during finalization. kDESCRIPTOR = PyUnicode_FromString("DESCRIPTOR"); - PyObject *dummy_obj = PySet_New(NULL); - kEmptyWeakref = PyWeakref_NewRef(dummy_obj, NULL); + PyObject* dummy_obj = PySet_New(nullptr); + kEmptyWeakref = PyWeakref_NewRef(dummy_obj, nullptr); Py_DECREF(dummy_obj); } @@ -2958,22 +2962,22 @@ bool InitProto2MessageModule(PyObject *m) { // Register them as MutableSequence. ScopedPyObjectPtr collections(PyImport_ImportModule("collections.abc")); - if (collections == NULL) { + if (collections == nullptr) { return false; } ScopedPyObjectPtr mutable_sequence( PyObject_GetAttrString(collections.get(), "MutableSequence")); - if (mutable_sequence == NULL) { + if (mutable_sequence == nullptr) { return false; } if (ScopedPyObjectPtr( PyObject_CallMethod(mutable_sequence.get(), "register", "O", - &RepeatedScalarContainer_Type)) == NULL) { + &RepeatedScalarContainer_Type)) == nullptr) { return false; } if (ScopedPyObjectPtr( PyObject_CallMethod(mutable_sequence.get(), "register", "O", - &RepeatedCompositeContainer_Type)) == NULL) { + &RepeatedCompositeContainer_Type)) == nullptr) { return false; } } @@ -3042,7 +3046,7 @@ bool InitProto2MessageModule(PyObject *m) { PyObject* enum_type_wrapper = PyImport_ImportModule( "google.protobuf.internal.enum_type_wrapper"); - if (enum_type_wrapper == NULL) { + if (enum_type_wrapper == nullptr) { return false; } EnumTypeWrapper_class = @@ -3051,7 +3055,7 @@ bool InitProto2MessageModule(PyObject *m) { PyObject* message_module = PyImport_ImportModule( "google.protobuf.message"); - if (message_module == NULL) { + if (message_module == nullptr) { return false; } EncodeError_class = PyObject_GetAttrString(message_module, "EncodeError"); @@ -3060,7 +3064,7 @@ bool InitProto2MessageModule(PyObject *m) { Py_DECREF(message_module); PyObject* pickle_module = PyImport_ImportModule("pickle"); - if (pickle_module == NULL) { + if (pickle_module == nullptr) { return false; } PickleError_class = PyObject_GetAttrString(pickle_module, "PickleError"); diff --git a/python/google/protobuf/pyext/message_factory.cc b/python/google/protobuf/pyext/message_factory.cc index 30dfab88dc06b..64f9fed5e5436 100644 --- a/python/google/protobuf/pyext/message_factory.cc +++ b/python/google/protobuf/pyext/message_factory.cc @@ -38,12 +38,13 @@ #include #include -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -54,8 +55,8 @@ namespace message_factory { PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool) { PyMessageFactory* factory = reinterpret_cast( PyType_GenericAlloc(type, 0)); - if (factory == NULL) { - return NULL; + if (factory == nullptr) { + return nullptr; } DynamicMessageFactory* message_factory = new DynamicMessageFactory(); @@ -72,25 +73,25 @@ PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool) } PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - static const char* kwlist[] = {"pool", 0}; - PyObject* pool = NULL; + static const char* kwlist[] = {"pool", nullptr}; + PyObject* pool = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", const_cast(kwlist), &pool)) { - return NULL; + return nullptr; } ScopedPyObjectPtr owned_pool; - if (pool == NULL || pool == Py_None) { + if (pool == nullptr || pool == Py_None) { owned_pool.reset(PyObject_CallFunction( - reinterpret_cast(&PyDescriptorPool_Type), NULL)); - if (owned_pool == NULL) { - return NULL; + reinterpret_cast(&PyDescriptorPool_Type), nullptr)); + if (owned_pool == nullptr) { + return nullptr; } pool = owned_pool.get(); } else { if (!PyObject_TypeCheck(pool, &PyDescriptorPool_Type)) { PyErr_Format(PyExc_TypeError, "Expected a DescriptorPool, got %s", pool->ob_type->tp_name); - return NULL; + return nullptr; } } @@ -161,8 +162,8 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, } ScopedPyObjectPtr py_descriptor( PyMessageDescriptor_FromDescriptor(descriptor)); - if (py_descriptor == NULL) { - return NULL; + if (py_descriptor == nullptr) { + return nullptr; } // Create a new message class. ScopedPyObjectPtr args(Py_BuildValue( @@ -170,24 +171,24 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, "DESCRIPTOR", py_descriptor.get(), "__module__", Py_None, "message_factory", self)); - if (args == NULL) { - return NULL; + if (args == nullptr) { + return nullptr; } ScopedPyObjectPtr message_class(PyObject_CallObject( reinterpret_cast(CMessageClass_Type), args.get())); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } // Create messages class for the messages used by the fields, and registers // all extensions for these messages during the recursion. for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) { const Descriptor* sub_descriptor = descriptor->field(field_idx)->message_type(); - // It is NULL if the field type is not a message. - if (sub_descriptor != NULL) { + // It is null if the field type is not a message. + if (sub_descriptor != nullptr) { CMessageClass* result = GetOrCreateMessageClass(self, sub_descriptor); - if (result == NULL) { - return NULL; + if (result == nullptr) { + return nullptr; } Py_DECREF(result); } @@ -199,17 +200,17 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, ScopedPyObjectPtr py_extended_class( GetOrCreateMessageClass(self, extension->containing_type()) ->AsPyObject()); - if (py_extended_class == NULL) { - return NULL; + if (py_extended_class == nullptr) { + return nullptr; } ScopedPyObjectPtr py_extension(PyFieldDescriptor_FromDescriptor(extension)); - if (py_extension == NULL) { - return NULL; + if (py_extension == nullptr) { + return nullptr; } ScopedPyObjectPtr result(cmessage::RegisterExtension( py_extended_class.get(), py_extension.get())); - if (result == NULL) { - return NULL; + if (result == nullptr) { + return nullptr; } } return reinterpret_cast(message_class.release()); @@ -223,14 +224,15 @@ CMessageClass* GetMessageClass(PyMessageFactory* self, if (ret == self->classes_by_descriptor->end()) { PyErr_Format(PyExc_TypeError, "No message class registered for '%s'", message_descriptor->full_name().c_str()); - return NULL; + return nullptr; } else { return ret->second; } } static PyMethodDef Methods[] = { - {NULL}}; + {nullptr}, +}; static PyObject* GetPool(PyMessageFactory* self, void* closure) { Py_INCREF(self->pool); @@ -238,8 +240,8 @@ static PyObject* GetPool(PyMessageFactory* self, void* closure) { } static PyGetSetDef Getters[] = { - {"pool", (getter)GetPool, NULL, "DescriptorPool"}, - {NULL} + {"pool", (getter)GetPool, nullptr, "DescriptorPool"}, + {nullptr}, }; } // namespace message_factory @@ -251,37 +253,37 @@ PyTypeObject PyMessageFactory_Type = { 0, // tp_itemsize message_factory::Dealloc, // tp_dealloc 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, // tp_flags "A static Message Factory", // tp_doc message_factory::GcTraverse, // tp_traverse message_factory::GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext + nullptr, // tp_iter + nullptr, // tp_iternext message_factory::Methods, // tp_methods - 0, // tp_members + nullptr, // tp_members message_factory::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc + nullptr, // tp_init + nullptr, // tp_alloc message_factory::New, // tp_new PyObject_GC_Del, // tp_free }; diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc index 971d2bad70be9..1f953fc7838ae 100644 --- a/python/google/protobuf/pyext/message_module.cc +++ b/python/google/protobuf/pyext/message_module.cc @@ -93,28 +93,28 @@ static PyMethodDef ModuleMethods[] = { (PyCFunction)google::protobuf::python::cmessage::SetAllowOversizeProtos, METH_O, "Enable/disable oversize proto parsing."}, // DO NOT USE: For migration and testing only. - {NULL, NULL}}; + {nullptr, nullptr}}; static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, "_message", module_docstring, -1, ModuleMethods, /* m_methods */ - NULL, - NULL, - NULL, - NULL}; + nullptr, + nullptr, + nullptr, + nullptr}; PyMODINIT_FUNC PyInit__message() { PyObject* m; m = PyModule_Create(&_module); - if (m == NULL) { - return NULL; + if (m == nullptr) { + return nullptr; } if (!google::protobuf::python::InitProto2MessageModule(m)) { Py_DECREF(m); - return NULL; + return nullptr; } // Adds the C++ API @@ -126,7 +126,7 @@ PyMODINIT_FUNC PyInit__message() { })) { PyModule_AddObject(m, "proto_API", api); } else { - return NULL; + return nullptr; } return m; diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc index 2e8ff4b425f17..0b63f822566a6 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.cc +++ b/python/google/protobuf/pyext/repeated_composite_container.cc @@ -40,12 +40,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include namespace google { @@ -74,17 +74,15 @@ PyObject* Add(RepeatedCompositeContainer* self, PyObject* args, if (cmessage::AssureWritable(self->parent) == -1) return nullptr; Message* message = self->parent->message; - Message* sub_message = - message->GetReflection()->AddMessage( - message, - self->parent_field_descriptor, - self->child_message_class->py_message_factory->message_factory); + Message* sub_message = message->GetReflection()->AddMessage( + message, self->parent_field_descriptor, + self->child_message_class->py_message_factory->message_factory); CMessage* cmsg = self->parent->BuildSubMessageFromPointer( self->parent_field_descriptor, sub_message, self->child_message_class); if (cmessage::InitAttributes(cmsg, args, kwargs) < 0) { - message->GetReflection()->RemoveLast( - message, self->parent_field_descriptor); + message->GetReflection()->RemoveLast(message, + self->parent_field_descriptor); Py_DECREF(cmsg); return nullptr; } @@ -108,8 +106,7 @@ static PyObject* AddMessage(RepeatedCompositeContainer* self, PyObject* value) { if (py_cmsg == nullptr) return nullptr; CMessage* cmsg = reinterpret_cast(py_cmsg); if (ScopedPyObjectPtr(cmessage::MergeFrom(cmsg, value)) == nullptr) { - reflection->RemoveLast( - message, self->parent_field_descriptor); + reflection->RemoveLast(message, self->parent_field_descriptor); Py_DECREF(cmsg); return nullptr; } @@ -152,7 +149,7 @@ static PyObject* Insert(PyObject* pself, PyObject* args) { Py_ssize_t end_index = index; if (end_index < 0) end_index += length; if (end_index < 0) end_index = 0; - for (Py_ssize_t i = length; i > end_index; i --) { + for (Py_ssize_t i = length; i > end_index; i--) { reflection->SwapElements(message, field_descriptor, i, i - 1); } @@ -268,8 +265,7 @@ static PyObject* SubscriptMethod(PyObject* self, PyObject* slice) { return Subscript(reinterpret_cast(self), slice); } -int AssignSubscript(RepeatedCompositeContainer* self, - PyObject* slice, +int AssignSubscript(RepeatedCompositeContainer* self, PyObject* slice, PyObject* value) { if (value != nullptr) { PyErr_SetString(PyExc_TypeError, "does not support assignment"); @@ -368,27 +364,22 @@ static void ReorderAttached(RepeatedCompositeContainer* self, const FieldDescriptor* descriptor = self->parent_field_descriptor; const Py_ssize_t length = Length(reinterpret_cast(self)); - // We need to rearrange things to match python's sort order. Because there - // was already an O(n*log(n)) step in python and a bunch of reflection, we - // expect an O(n**2) step in C++ won't hurt too much. + // We need to rearrange things to match python's sort order. + for (Py_ssize_t i = 0; i < length; ++i) { + reflection->UnsafeArenaReleaseLast(message, descriptor); + } for (Py_ssize_t i = 0; i < length; ++i) { Message* child_message = reinterpret_cast(PyList_GET_ITEM(child_list, i))->message; - for (Py_ssize_t j = i; j < length; ++j) { - if (child_message == - &reflection->GetRepeatedMessage(*message, descriptor, j)) { - reflection->SwapElements(message, descriptor, i, j); - break; - } - } + reflection->UnsafeArenaAddAllocatedMessage(message, descriptor, + child_message); } } // Returns 0 if successful; returns -1 and sets an exception if // unsuccessful. -static int SortPythonMessages(RepeatedCompositeContainer* self, - PyObject* args, - PyObject* kwds) { +static int SortPythonMessages(RepeatedCompositeContainer* self, PyObject* args, + PyObject* kwds) { ScopedPyObjectPtr child_list( PySequence_List(reinterpret_cast(self))); if (child_list == nullptr) { @@ -486,9 +477,8 @@ PyObject* DeepCopy(PyObject* pself, PyObject* arg) { } // The private constructor of RepeatedCompositeContainer objects. -RepeatedCompositeContainer *NewContainer( - CMessage* parent, - const FieldDescriptor* parent_field_descriptor, +RepeatedCompositeContainer* NewContainer( + CMessage* parent, const FieldDescriptor* parent_field_descriptor, CMessageClass* child_message_class) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { return nullptr; @@ -525,9 +515,9 @@ static PySequenceMethods SqMethods = { }; static PyMappingMethods MpMethods = { - Length, /* mp_length */ - SubscriptMethod, /* mp_subscript */ - AssignSubscriptMethod, /* mp_ass_subscript */ + Length, /* mp_length */ + SubscriptMethod, /* mp_subscript */ + AssignSubscriptMethod, /* mp_ass_subscript */ }; static PyMethodDef Methods[] = { @@ -555,14 +545,14 @@ static PyMethodDef Methods[] = { 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 + ".RepeatedCompositeContainer", // tp_name + sizeof(RepeatedCompositeContainer), // tp_basicsize + 0, // tp_itemsize + repeated_composite_container::Dealloc, // tp_dealloc #if PY_VERSION_HEX >= 0x03080000 - 0, // tp_vectorcall_offset + 0, // tp_vectorcall_offset #else - nullptr, // tp_print + nullptr, // tp_print #endif nullptr, // tp_getattr nullptr, // tp_setattr diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc index 4b6d12a9fcfe1..f4a8df2c4a57c 100644 --- a/python/google/protobuf/pyext/repeated_scalar_container.cc +++ b/python/google/protobuf/pyext/repeated_scalar_container.cc @@ -274,6 +274,11 @@ static PyObject* Subscript(PyObject* pself, PyObject* slice) { bool return_list = false; if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); + } else if (PyIndex_Check(slice)) { + from = to = PyNumber_AsSsize_t(slice, PyExc_ValueError); + if (from == -1 && PyErr_Occurred()) { + return nullptr; + } } else if (PySlice_Check(slice)) { length = Len(pself); if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) == diff --git a/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/python/google/protobuf/pyext/scoped_pyobject_ptr.h index 6f7fc29813f98..e6ea7e33e5905 100644 --- a/python/google/protobuf/pyext/scoped_pyobject_ptr.h +++ b/python/google/protobuf/pyext/scoped_pyobject_ptr.h @@ -47,7 +47,7 @@ class ScopedPythonPtr { public: // Takes the ownership of the specified object to ScopedPythonPtr. // The reference count of the specified py_object is not incremented. - explicit ScopedPythonPtr(PyObjectStruct* py_object = NULL) + explicit ScopedPythonPtr(PyObjectStruct* py_object = nullptr) : ptr_(py_object) {} // If a PyObject is owned, decrement its reference count. @@ -69,7 +69,7 @@ class ScopedPythonPtr { // The caller now owns the returned reference. PyObjectStruct* release() { PyObject* p = ptr_; - ptr_ = NULL; + ptr_ = nullptr; return p; } diff --git a/python/google/protobuf/pyext/unknown_fields.cc b/python/google/protobuf/pyext/unknown_fields.cc index 7f4fb23edf81e..00ac67ae37ac3 100644 --- a/python/google/protobuf/pyext/unknown_fields.cc +++ b/python/google/protobuf/pyext/unknown_fields.cc @@ -49,7 +49,7 @@ namespace unknown_fields { static Py_ssize_t Len(PyObject* pself) { PyUnknownFields* self = reinterpret_cast(pself); - if (self->fields == NULL) { + if (self->fields == nullptr) { PyErr_Format(PyExc_ValueError, "UnknownFields does not exist. " "The parent message might be cleared."); @@ -64,7 +64,7 @@ void Clear(PyUnknownFields* self) { it != self->sub_unknown_fields.end(); it++) { Clear(*it); } - self->fields = NULL; + self->fields = nullptr; self->sub_unknown_fields.clear(); } @@ -74,11 +74,11 @@ PyObject* NewPyUnknownFieldRef(PyUnknownFields* parent, static PyObject* Item(PyObject* pself, Py_ssize_t index) { PyUnknownFields* self = reinterpret_cast(pself); - if (self->fields == NULL) { + if (self->fields == nullptr) { PyErr_Format(PyExc_ValueError, "UnknownFields does not exist. " "The parent message might be cleared."); - return NULL; + return nullptr; } Py_ssize_t total_size = self->fields->field_count(); if (index < 0) { @@ -88,7 +88,7 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { PyErr_Format(PyExc_IndexError, "index (%zd) out of range", index); - return NULL; + return nullptr; } return unknown_fields::NewPyUnknownFieldRef(self, index); @@ -97,8 +97,8 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { PyObject* NewPyUnknownFields(CMessage* c_message) { PyUnknownFields* self = reinterpret_cast( PyType_GenericAlloc(&PyUnknownFields_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } // Call "placement new" to initialize PyUnknownFields. new (self) PyUnknownFields; @@ -116,8 +116,8 @@ PyObject* NewPyUnknownFieldRef(PyUnknownFields* parent, Py_ssize_t index) { PyUnknownFieldRef* self = reinterpret_cast( PyType_GenericAlloc(&PyUnknownFieldRef_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -142,53 +142,53 @@ static void Dealloc(PyObject* pself) { } static PySequenceMethods SqMethods = { - Len, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - Item, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ + Len, /* sq_length */ + nullptr, /* sq_concat */ + nullptr, /* sq_repeat */ + Item, /* sq_item */ + nullptr, /* sq_slice */ + nullptr, /* sq_ass_item */ }; } // namespace unknown_fields PyTypeObject PyUnknownFields_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".PyUnknownFields", // tp_name - sizeof(PyUnknownFields), // tp_basicsize - 0, // tp_itemsize - unknown_fields::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - &unknown_fields::SqMethods, // tp_as_sequence - 0, // 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 - "unknown field set", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // 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 + ".PyUnknownFields", // tp_name + sizeof(PyUnknownFields), // tp_basicsize + 0, // tp_itemsize + unknown_fields::Dealloc, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + &unknown_fields::SqMethods, // tp_as_sequence + nullptr, // 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 + "unknown field set", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // 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 unknown_field { @@ -196,8 +196,8 @@ static PyObject* PyUnknownFields_FromUnknownFieldSet( PyUnknownFields* parent, const UnknownFieldSet& fields) { PyUnknownFields* self = reinterpret_cast( PyType_GenericAlloc(&PyUnknownFields_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } // Call "placement new" to initialize PyUnknownFields. new (self) PyUnknownFields; @@ -212,26 +212,26 @@ static PyObject* PyUnknownFields_FromUnknownFieldSet( const UnknownField* GetUnknownField(PyUnknownFieldRef* self) { const UnknownFieldSet* fields = self->parent->fields; - if (fields == NULL) { + if (fields == nullptr) { PyErr_Format(PyExc_ValueError, "UnknownField does not exist. " "The parent message might be cleared."); - return NULL; + return nullptr; } ssize_t total_size = fields->field_count(); if (self->index >= total_size) { PyErr_Format(PyExc_ValueError, "UnknownField does not exist. " "The parent message might be cleared."); - return NULL; + return nullptr; } return &fields->field(self->index); } static PyObject* GetFieldNumber(PyUnknownFieldRef* self, void *closure) { const UnknownField* unknown_field = GetUnknownField(self); - if (unknown_field == NULL) { - return NULL; + if (unknown_field == nullptr) { + return nullptr; } return PyLong_FromLong(unknown_field->number()); } @@ -239,8 +239,8 @@ static PyObject* GetFieldNumber(PyUnknownFieldRef* self, void *closure) { using internal::WireFormatLite; static PyObject* GetWireType(PyUnknownFieldRef* self, void *closure) { const UnknownField* unknown_field = GetUnknownField(self); - if (unknown_field == NULL) { - return NULL; + if (unknown_field == nullptr) { + return nullptr; } // Assign a default value to suppress may-uninitialized warnings (errors @@ -268,19 +268,19 @@ static PyObject* GetWireType(PyUnknownFieldRef* self, void *closure) { static PyObject* GetData(PyUnknownFieldRef* self, void *closure) { const UnknownField* field = GetUnknownField(self); - if (field == NULL) { - return NULL; + if (field == nullptr) { + return nullptr; } - PyObject* data = NULL; + PyObject* data = nullptr; switch (field->type()) { case UnknownField::TYPE_VARINT: - data = PyLong_FromLong(field->varint()); + data = PyLong_FromUnsignedLongLong(field->varint()); break; case UnknownField::TYPE_FIXED32: - data = PyLong_FromLong(field->fixed32()); + data = PyLong_FromUnsignedLong(field->fixed32()); break; case UnknownField::TYPE_FIXED64: - data = PyLong_FromLong(field->fixed64()); + data = PyLong_FromUnsignedLongLong(field->fixed64()); break; case UnknownField::TYPE_LENGTH_DELIMITED: data = PyBytes_FromStringAndSize(field->length_delimited().data(), @@ -301,54 +301,53 @@ static void Dealloc(PyObject* pself) { } static PyGetSetDef Getters[] = { - {"field_number", (getter)GetFieldNumber, NULL}, - {"wire_type", (getter)GetWireType, NULL}, - {"data", (getter)GetData, NULL}, - {NULL} + {"field_number", (getter)GetFieldNumber, nullptr}, + {"wire_type", (getter)GetWireType, nullptr}, + {"data", (getter)GetData, nullptr}, + {nullptr}, }; } // namespace unknown_field PyTypeObject PyUnknownFieldRef_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".PyUnknownFieldRef", // tp_name - sizeof(PyUnknownFieldRef), // tp_basicsize - 0, // tp_itemsize - unknown_field::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // 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 - "unknown field", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members - unknown_field::Getters, // 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 + ".PyUnknownFieldRef", // tp_name + sizeof(PyUnknownFieldRef), // tp_basicsize + 0, // tp_itemsize + unknown_field::Dealloc, // tp_dealloc + 0, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // 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 + "unknown field", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + unknown_field::Getters, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; - } // namespace python } // namespace protobuf } // namespace google diff --git a/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py b/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py index 515ded2334e38..88b8d45e62cb1 100644 --- a/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py +++ b/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py @@ -120,7 +120,7 @@ def finalize_options(self): 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'))) + files.extend(glob.glob(os.path.join(self.source_dir, '**', '*.proto'), recursive=True)) 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) diff --git a/python/protobuf_distutils/setup.py b/python/protobuf_distutils/setup.py index 1092930fa5ee6..9a19032910116 100644 --- a/python/protobuf_distutils/setup.py +++ b/python/protobuf_distutils/setup.py @@ -46,7 +46,7 @@ packages=find_packages(), maintainer='protobuf@googlegroups.com', maintainer_email='protobuf@googlegroups.com', - license='3-Clause BSD License', + license='BSD-3-Clause', classifiers=[ "Framework :: Setuptools Plugin", "Operating System :: OS Independent", diff --git a/python/tox.ini b/python/tox.ini index 88dd842e82198..7142b86f0fdf0 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{35,36,37,38,39}-{cpp,python} + py{35,36,37,38,39,310}-{cpp,python} [testenv] usedevelop=true @@ -14,7 +14,7 @@ setenv = commands = python setup.py -q build_py python: python setup.py -q build - py{35,36,37,38,39}-cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + py{35,36,37,38,39,310}-cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --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/Gemfile b/ruby/Gemfile index 76b23ad91d1ef..fa75df1563230 100644 --- a/ruby/Gemfile +++ b/ruby/Gemfile @@ -1,5 +1,3 @@ source 'https://rubygems.org' gemspec - -gem "irb", "~> 1.1", "< 1.2.0" if RUBY_VERSION < "2.5" diff --git a/ruby/Rakefile b/ruby/Rakefile index 8aae2ee872a1f..762dc2c00d80d 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -80,6 +80,14 @@ if RUBY_PLATFORM == "java" end else + unless ENV['IN_DOCKER'] == 'true' + # We need utf8_range in-tree. + FileUtils.mkdir_p("ext/google/protobuf_c/third_party/utf8_range") + FileUtils.cp("../third_party/utf8_range/utf8_range.h", "ext/google/protobuf_c/third_party/utf8_range") + FileUtils.cp("../third_party/utf8_range/utf8_range.c", "ext/google/protobuf_c/third_party/utf8_range") + FileUtils.cp("../third_party/utf8_range/LICENSE", "ext/google/protobuf_c/third_party/utf8_range") + end + Rake::ExtensionTask.new("protobuf_c", spec) do |ext| unless RUBY_PLATFORM =~ /darwin/ # TODO: also set "no_native to true" for mac if possible. As is, @@ -93,7 +101,7 @@ else ext.cross_platform = [ 'x86-mingw32', 'x64-mingw32', 'x86_64-linux', 'x86-linux', - 'universal-darwin' + 'x86_64-darwin', 'arm64-darwin', ] end @@ -117,7 +125,7 @@ else ['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=3.0.0:2.7.0:2.6.0:2.5.0:2.4.0:2.3.0 + IN_DOCKER=true rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem RUBY_CC_VERSION=3.0.0:2.7.0:2.6.0:2.5.0 EOT end end @@ -125,7 +133,7 @@ else if RUBY_PLATFORM =~ /darwin/ task 'gem:native' do system "rake genproto" - system "rake cross native gem RUBY_CC_VERSION=3.0.0:2.7.0:2.6.0:2.5.1:2.4.0:2.3.0" + system "rake cross native gem RUBY_CC_VERSION=3.0.0:2.7.0:2.6.0:2.5.1" end else task 'gem:native' => [:genproto, 'gem:windows', 'gem:java'] diff --git a/ruby/ext/google/protobuf_c/convert.c b/ruby/ext/google/protobuf_c/convert.c index 8bcf6eee00673..8b98aeeb56971 100644 --- a/ruby/ext/google/protobuf_c/convert.c +++ b/ruby/ext/google/protobuf_c/convert.c @@ -31,7 +31,7 @@ // ----------------------------------------------------------------------------- // Ruby <-> upb data conversion functions. // -// This file Also contains a few other assorted algorithms on upb_msgval. +// This file Also contains a few other assorted algorithms on upb_MessageValue. // // None of the algorithms in this file require any access to the internal // representation of Ruby or upb objects. @@ -42,10 +42,10 @@ #include "message.h" #include "protobuf.h" -static upb_strview Convert_StringData(VALUE str, upb_arena *arena) { - upb_strview ret; +static upb_StringView Convert_StringData(VALUE str, upb_Arena* arena) { + upb_StringView ret; if (arena) { - char *ptr = upb_arena_malloc(arena, RSTRING_LEN(str)); + char* ptr = upb_Arena_Malloc(arena, RSTRING_LEN(str)); memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str)); ret.data = ptr; } else { @@ -57,13 +57,11 @@ static upb_strview Convert_StringData(VALUE str, upb_arena *arena) { } static bool is_ruby_num(VALUE value) { - return (TYPE(value) == T_FLOAT || - TYPE(value) == T_FIXNUM || + return (TYPE(value) == T_FLOAT || TYPE(value) == T_FIXNUM || TYPE(value) == T_BIGNUM); } -static void Convert_CheckInt(const char* name, upb_fieldtype_t type, - VALUE val) { +static void Convert_CheckInt(const char* name, upb_CType type, VALUE val) { if (!is_ruby_num(val)) { rb_raise(cTypeError, "Expected number type for integral field '%s' (given %s).", name, @@ -82,7 +80,7 @@ static void Convert_CheckInt(const char* name, upb_fieldtype_t type, name, rb_class2name(CLASS_OF(val))); } } - if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) { + if (type == kUpb_CType_UInt32 || type == kUpb_CType_UInt64) { if (NUM2DBL(val) < 0) { rb_raise( rb_eRangeError, @@ -93,26 +91,31 @@ static void Convert_CheckInt(const char* name, upb_fieldtype_t type, } static int32_t Convert_ToEnum(VALUE value, const char* name, - const upb_enumdef* e) { + const upb_EnumDef* e) { int32_t val; switch (TYPE(value)) { case T_FLOAT: case T_FIXNUM: case T_BIGNUM: - Convert_CheckInt(name, UPB_TYPE_INT32, value); + Convert_CheckInt(name, kUpb_CType_Int32, value); val = NUM2INT(value); break; - case T_STRING: - if (!upb_enumdef_ntoi(e, RSTRING_PTR(value), RSTRING_LEN(value), &val)) { - goto unknownval; - } + case T_STRING: { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize( + e, RSTRING_PTR(value), RSTRING_LEN(value)); + if (!ev) goto unknownval; + val = upb_EnumValueDef_Number(ev); break; - case T_SYMBOL: - if (!upb_enumdef_ntoiz(e, rb_id2name(SYM2ID(value)), &val)) { + } + case T_SYMBOL: { + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByName(e, rb_id2name(SYM2ID(value))); + if (!ev) goto unknownval; - } + val = upb_EnumValueDef_Number(ev); break; + } default: rb_raise(cTypeError, "Expected number or symbol type for enum field '%s'.", name); @@ -124,47 +127,52 @@ static int32_t Convert_ToEnum(VALUE value, const char* name, rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name); } -upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info, - upb_arena* arena) { - upb_msgval ret; +upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name, + TypeInfo type_info, upb_Arena* arena) { + upb_MessageValue ret; switch (type_info.type) { - case UPB_TYPE_FLOAT: + case kUpb_CType_Float: if (!is_ruby_num(value)) { - rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).", - name, rb_class2name(CLASS_OF(value))); + rb_raise(cTypeError, + "Expected number type for float field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); } ret.float_val = NUM2DBL(value); break; - case UPB_TYPE_DOUBLE: + case kUpb_CType_Double: if (!is_ruby_num(value)) { - rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).", - name, rb_class2name(CLASS_OF(value))); + rb_raise(cTypeError, + "Expected number type for double field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); } ret.double_val = NUM2DBL(value); break; - case UPB_TYPE_BOOL: { + case kUpb_CType_Bool: { if (value == Qtrue) { ret.bool_val = 1; } else if (value == Qfalse) { ret.bool_val = 0; } else { - rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).", - name, rb_class2name(CLASS_OF(value))); + rb_raise(cTypeError, + "Invalid argument for boolean field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); } break; } - case UPB_TYPE_STRING: { + case kUpb_CType_String: { VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding()); if (CLASS_OF(value) == rb_cSymbol) { value = rb_funcall(value, rb_intern("to_s"), 0); } else if (CLASS_OF(value) != rb_cString) { - rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).", - name, rb_class2name(CLASS_OF(value))); + rb_raise(cTypeError, + "Invalid argument for string field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); } if (rb_obj_encoding(value) != utf8) { - // Note: this will not duplicate underlying string data unless necessary. + // Note: this will not duplicate underlying string data unless + // necessary. value = rb_str_encode(value, utf8, 0, Qnil); if (rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) { @@ -175,15 +183,17 @@ upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info, ret.str_val = Convert_StringData(value, arena); break; } - case UPB_TYPE_BYTES: { + case kUpb_CType_Bytes: { VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding()); if (CLASS_OF(value) != rb_cString) { - rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).", - name, rb_class2name(CLASS_OF(value))); + rb_raise(cTypeError, + "Invalid argument for bytes field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); } if (rb_obj_encoding(value) != bytes) { - // Note: this will not duplicate underlying string data unless necessary. + // Note: this will not duplicate underlying string data unless + // necessary. // TODO(haberman): is this really necessary to get raw bytes? value = rb_str_encode(value, bytes, 0, Qnil); } @@ -191,33 +201,33 @@ upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info, ret.str_val = Convert_StringData(value, arena); break; } - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: ret.msg_val = Message_GetUpbMessage(value, type_info.def.msgdef, name, arena); break; - case UPB_TYPE_ENUM: + case kUpb_CType_Enum: ret.int32_val = Convert_ToEnum(value, name, type_info.def.enumdef); break; - case UPB_TYPE_INT32: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT32: - case UPB_TYPE_UINT64: + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: Convert_CheckInt(name, type_info.type, value); switch (type_info.type) { - case UPB_TYPE_INT32: - ret.int32_val = NUM2INT(value); - break; - case UPB_TYPE_INT64: - ret.int64_val = NUM2LL(value); - break; - case UPB_TYPE_UINT32: - ret.uint32_val = NUM2UINT(value); - break; - case UPB_TYPE_UINT64: - ret.uint64_val = NUM2ULL(value); - break; - default: - break; + case kUpb_CType_Int32: + ret.int32_val = NUM2INT(value); + break; + case kUpb_CType_Int64: + ret.int64_val = NUM2LL(value); + break; + case kUpb_CType_UInt32: + ret.uint32_val = NUM2UINT(value); + break; + case kUpb_CType_UInt64: + ret.uint64_val = NUM2ULL(value); + break; + default: + break; } break; default: @@ -227,45 +237,46 @@ upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info, return ret; } -VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena) { +VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info, + VALUE arena) { switch (type_info.type) { - case UPB_TYPE_FLOAT: + case kUpb_CType_Float: return DBL2NUM(upb_val.float_val); - case UPB_TYPE_DOUBLE: + case kUpb_CType_Double: return DBL2NUM(upb_val.double_val); - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return upb_val.bool_val ? Qtrue : Qfalse; - case UPB_TYPE_INT32: + case kUpb_CType_Int32: return INT2NUM(upb_val.int32_val); - case UPB_TYPE_INT64: + case kUpb_CType_Int64: return LL2NUM(upb_val.int64_val); - case UPB_TYPE_UINT32: + case kUpb_CType_UInt32: return UINT2NUM(upb_val.uint32_val); - case UPB_TYPE_UINT64: + case kUpb_CType_UInt64: return ULL2NUM(upb_val.int64_val); - case UPB_TYPE_ENUM: { - const char* name = - upb_enumdef_iton(type_info.def.enumdef, upb_val.int32_val); - if (name) { - return ID2SYM(rb_intern(name)); + case kUpb_CType_Enum: { + const upb_EnumValueDef *ev = upb_EnumDef_FindValueByNumber( + type_info.def.enumdef, upb_val.int32_val); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); } else { return INT2NUM(upb_val.int32_val); } } - case UPB_TYPE_STRING: { + case kUpb_CType_String: { VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); rb_enc_associate(str_rb, rb_utf8_encoding()); rb_obj_freeze(str_rb); return str_rb; } - case UPB_TYPE_BYTES: { + case kUpb_CType_Bytes: { VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); rb_enc_associate(str_rb, rb_ascii8bit_encoding()); rb_obj_freeze(str_rb); return str_rb; } - case UPB_TYPE_MESSAGE: - return Message_GetRubyWrapper((upb_msg*)upb_val.msg_val, + case kUpb_CType_Message: + return Message_GetRubyWrapper((upb_Message*)upb_val.msg_val, type_info.def.msgdef, arena); default: rb_raise(rb_eRuntimeError, "Convert_UpbToRuby(): Unexpected type %d", @@ -273,24 +284,24 @@ VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena) { } } -upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info, - upb_arena* arena) { - upb_msgval new_msgval; +upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info, + upb_Arena* arena) { + upb_MessageValue new_msgval; switch (type_info.type) { default: memcpy(&new_msgval, &msgval, sizeof(msgval)); break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { + case kUpb_CType_String: + case kUpb_CType_Bytes: { size_t n = msgval.str_val.size; - char *mem = upb_arena_malloc(arena, n); + char* mem = upb_Arena_Malloc(arena, n); new_msgval.str_val.data = mem; new_msgval.str_val.size = n; memcpy(mem, msgval.str_val.data, n); break; } - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: new_msgval.msg_val = Message_deep_copy(msgval.msg_val, type_info.def.msgdef, arena); break; @@ -299,48 +310,50 @@ upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info, return new_msgval; } -bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info) { +bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + TypeInfo type_info) { switch (type_info.type) { - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return memcmp(&val1, &val2, 1) == 0; - case UPB_TYPE_FLOAT: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_ENUM: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: return memcmp(&val1, &val2, 4) == 0; - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: return memcmp(&val1, &val2, 8) == 0; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_String: + case kUpb_CType_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: + memcmp(val1.str_val.data, val2.str_val.data, val1.str_val.size) == + 0; + case kUpb_CType_Message: return Message_Equal(val1.msg_val, val2.msg_val, type_info.def.msgdef); default: rb_raise(rb_eRuntimeError, "Internal error, unexpected type"); } } -uint64_t Msgval_GetHash(upb_msgval val, TypeInfo type_info, uint64_t seed) { +uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info, + uint64_t seed) { switch (type_info.type) { - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return Wyhash(&val, 1, seed, kWyhashSalt); - case UPB_TYPE_FLOAT: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_ENUM: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: return Wyhash(&val, 4, seed, kWyhashSalt); - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: return Wyhash(&val, 8, seed, kWyhashSalt); - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_String: + case kUpb_CType_Bytes: return Wyhash(val.str_val.data, val.str_val.size, seed, kWyhashSalt); - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: return Message_Hash(val.msg_val, type_info.def.msgdef, seed); default: rb_raise(rb_eRuntimeError, "Internal error, unexpected type"); diff --git a/ruby/ext/google/protobuf_c/convert.h b/ruby/ext/google/protobuf_c/convert.h index cda18a0547f48..e48c979455e74 100644 --- a/ruby/ext/google/protobuf_c/convert.h +++ b/ruby/ext/google/protobuf_c/convert.h @@ -36,7 +36,7 @@ #include "protobuf.h" #include "ruby-upb.h" -// Converts |ruby_val| to a upb_msgval according to |type_info|. +// Converts |ruby_val| to a upb_MessageValue according to |type_info|. // // The |arena| parameter indicates the lifetime of the container where this // value will be assigned. It is used as follows: @@ -47,8 +47,8 @@ // - If type is message and the Ruby value is a message instance, we will fuse // the message's arena into |arena|, to ensure that this message outlives the // container. -upb_msgval Convert_RubyToUpb(VALUE ruby_val, const char *name, - TypeInfo type_info, upb_arena *arena); +upb_MessageValue Convert_RubyToUpb(VALUE ruby_val, const char *name, + TypeInfo type_info, upb_Arena *arena); // Converts |upb_val| to a Ruby VALUE according to |type_info|. This may involve // creating a Ruby wrapper object. @@ -56,17 +56,20 @@ upb_msgval Convert_RubyToUpb(VALUE ruby_val, const char *name, // The |arena| parameter indicates the arena that owns the lifetime of // |upb_val|. Any Ruby wrapper object that is created will reference |arena| // and ensure it outlives the wrapper. -VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena); +VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info, + VALUE arena); // Creates a deep copy of |msgval| in |arena|. -upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info, - upb_arena *arena); +upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info, + upb_Arena *arena); // Returns true if |val1| and |val2| are equal. Their type is given by // |type_info|. -bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info); +bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + TypeInfo type_info); -// Returns a hash value for the given upb_msgval. -uint64_t Msgval_GetHash(upb_msgval val, TypeInfo type_info, uint64_t seed); +// Returns a hash value for the given upb_MessageValue. +uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info, + uint64_t seed); #endif // RUBY_PROTOBUF_CONVERT_H_ diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c index fd32cce66587f..aaa8b4dc7af03 100644 --- a/ruby/ext/google/protobuf_c/defs.c +++ b/ruby/ext/google/protobuf_c/defs.c @@ -41,11 +41,11 @@ // instances. // ----------------------------------------------------------------------------- -static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def); -static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def); -static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def); -static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def); -static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def); +static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def); +static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def); +static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def); +static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def); +static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def); // A distinct object that is not accessible from Ruby. We use this as a // constructor argument to enforce that certain objects cannot be created from @@ -74,7 +74,7 @@ static VALUE rb_str_maybe_null(const char* s) { typedef struct { VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor. - upb_symtab* symtab; + upb_DefPool* symtab; } DescriptorPool; VALUE cDescriptorPool = Qnil; @@ -90,14 +90,14 @@ static void DescriptorPool_mark(void* _self) { static void DescriptorPool_free(void* _self) { DescriptorPool* self = _self; - upb_symtab_free(self->symtab); + upb_DefPool_Free(self->symtab); xfree(self); } static const rb_data_type_t DescriptorPool_type = { - "Google::Protobuf::DescriptorPool", - {DescriptorPool_mark, DescriptorPool_free, NULL}, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::DescriptorPool", + {DescriptorPool_mark, DescriptorPool_free, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static DescriptorPool* ruby_to_DescriptorPool(VALUE val) { @@ -107,8 +107,8 @@ static DescriptorPool* ruby_to_DescriptorPool(VALUE val) { } // Exposed to other modules in defs.h. -const upb_symtab *DescriptorPool_GetSymtab(VALUE desc_pool_rb) { - DescriptorPool *pool = ruby_to_DescriptorPool(desc_pool_rb); +const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb) { + DescriptorPool* pool = ruby_to_DescriptorPool(desc_pool_rb); return pool->symtab; } @@ -126,7 +126,7 @@ static VALUE DescriptorPool_alloc(VALUE klass) { ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self); self->def_to_descriptor = rb_hash_new(); - self->symtab = upb_symtab_new(); + self->symtab = upb_DefPool_New(); ObjectCache_Add(self->symtab, ret); return ret; @@ -143,7 +143,7 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self, DescriptorPool* self = ruby_to_DescriptorPool(_self); Check_Type(serialized_file_proto, T_STRING); VALUE arena_rb = Arena_new(); - upb_arena *arena = Arena_get(arena_rb); + upb_Arena* arena = Arena_get(arena_rb); google_protobuf_FileDescriptorProto* file_proto = google_protobuf_FileDescriptorProto_parse( RSTRING_PTR(serialized_file_proto), @@ -151,13 +151,13 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self, if (!file_proto) { rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto"); } - upb_status status; - upb_status_clear(&status); - const upb_filedef* filedef = - upb_symtab_addfile(self->symtab, file_proto, &status); + upb_Status status; + upb_Status_Clear(&status); + const upb_FileDef* filedef = + upb_DefPool_AddFile(self->symtab, file_proto, &status); if (!filedef) { rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s", - upb_status_errmsg(&status)); + upb_Status_ErrorMessage(&status)); } return get_filedef_obj(_self, filedef); } @@ -172,15 +172,15 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self, static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) { DescriptorPool* self = ruby_to_DescriptorPool(_self); const char* name_str = get_str(name); - const upb_msgdef* msgdef; - const upb_enumdef* enumdef; + const upb_MessageDef* msgdef; + const upb_EnumDef* enumdef; - msgdef = upb_symtab_lookupmsg(self->symtab, name_str); + msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str); if (msgdef) { return get_msgdef_obj(_self, msgdef); } - enumdef = upb_symtab_lookupenum(self->symtab, name_str); + enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str); if (enumdef) { return get_enumdef_obj(_self, enumdef); } @@ -202,8 +202,7 @@ static VALUE DescriptorPool_generated_pool(VALUE _self) { } static void DescriptorPool_register(VALUE module) { - VALUE klass = rb_define_class_under( - module, "DescriptorPool", rb_cObject); + VALUE klass = rb_define_class_under(module, "DescriptorPool", rb_cObject); rb_define_alloc_func(klass, DescriptorPool_alloc); rb_define_method(klass, "add_serialized_file", DescriptorPool_add_serialized_file, 1); @@ -222,7 +221,7 @@ static void DescriptorPool_register(VALUE module) { // ----------------------------------------------------------------------------- typedef struct { - const upb_msgdef* msgdef; + const upb_MessageDef* msgdef; VALUE klass; VALUE descriptor_pool; } Descriptor; @@ -236,9 +235,9 @@ static void Descriptor_mark(void* _self) { } static const rb_data_type_t Descriptor_type = { - "Google::Protobuf::Descriptor", - {Descriptor_mark, RUBY_DEFAULT_FREE, NULL}, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::Descriptor", + {Descriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static Descriptor* ruby_to_Descriptor(VALUE val) { @@ -281,7 +280,7 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie, } self->descriptor_pool = descriptor_pool; - self->msgdef = (const upb_msgdef*)NUM2ULL(ptr); + self->msgdef = (const upb_MessageDef*)NUM2ULL(ptr); return Qnil; } @@ -294,7 +293,8 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie, */ static VALUE Descriptor_file_descriptor(VALUE _self) { Descriptor* self = ruby_to_Descriptor(_self); - return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef)); + return get_filedef_obj(self->descriptor_pool, + upb_MessageDef_File(self->msgdef)); } /* @@ -306,7 +306,7 @@ static VALUE Descriptor_file_descriptor(VALUE _self) { */ static VALUE Descriptor_name(VALUE _self) { Descriptor* self = ruby_to_Descriptor(_self); - return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef)); + return rb_str_maybe_null(upb_MessageDef_FullName(self->msgdef)); } /* @@ -318,11 +318,9 @@ static VALUE Descriptor_name(VALUE _self) { static VALUE Descriptor_each(VALUE _self) { Descriptor* self = ruby_to_Descriptor(_self); - upb_msg_field_iter it; - for (upb_msg_field_begin(&it, self->msgdef); - !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* field = upb_msg_iter_field(&it); + int n = upb_MessageDef_FieldCount(self->msgdef); + for (int i = 0; i < n; i++) { + const upb_FieldDef* field = upb_MessageDef_Field(self->msgdef, i); VALUE obj = get_fielddef_obj(self->descriptor_pool, field); rb_yield(obj); } @@ -339,7 +337,7 @@ static VALUE Descriptor_each(VALUE _self) { static VALUE Descriptor_lookup(VALUE _self, VALUE name) { Descriptor* self = ruby_to_Descriptor(_self); const char* s = get_str(name); - const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s); + const upb_FieldDef* field = upb_MessageDef_FindFieldByName(self->msgdef, s); if (field == NULL) { return Qnil; } @@ -356,11 +354,9 @@ static VALUE Descriptor_lookup(VALUE _self, VALUE name) { static VALUE Descriptor_each_oneof(VALUE _self) { Descriptor* self = ruby_to_Descriptor(_self); - upb_msg_oneof_iter it; - for (upb_msg_oneof_begin(&it, self->msgdef); - !upb_msg_oneof_done(&it); - upb_msg_oneof_next(&it)) { - const upb_oneofdef* oneof = upb_msg_iter_oneof(&it); + int n = upb_MessageDef_OneofCount(self->msgdef); + for (int i = 0; i < n; i++) { + const upb_OneofDef* oneof = upb_MessageDef_Oneof(self->msgdef, i); VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof); rb_yield(obj); } @@ -377,7 +373,7 @@ static VALUE Descriptor_each_oneof(VALUE _self) { static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) { Descriptor* self = ruby_to_Descriptor(_self); const char* s = get_str(name); - const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s); + const upb_OneofDef* oneof = upb_MessageDef_FindOneofByName(self->msgdef, s); if (oneof == NULL) { return Qnil; } @@ -399,8 +395,7 @@ static VALUE Descriptor_msgclass(VALUE _self) { } static void Descriptor_register(VALUE module) { - VALUE klass = rb_define_class_under( - module, "Descriptor", rb_cObject); + VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject); rb_define_alloc_func(klass, Descriptor_alloc); rb_define_method(klass, "initialize", Descriptor_initialize, 3); rb_define_method(klass, "each", Descriptor_each, 0); @@ -420,8 +415,8 @@ static void Descriptor_register(VALUE module) { // ----------------------------------------------------------------------------- typedef struct { - const upb_filedef* filedef; - VALUE descriptor_pool; // Owns the upb_filedef. + const upb_FileDef* filedef; + VALUE descriptor_pool; // Owns the upb_FileDef. } FileDescriptor; static VALUE cFileDescriptor = Qnil; @@ -432,9 +427,9 @@ static void FileDescriptor_mark(void* _self) { } static const rb_data_type_t FileDescriptor_type = { - "Google::Protobuf::FileDescriptor", - {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::FileDescriptor", + {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static FileDescriptor* ruby_to_FileDescriptor(VALUE val) { @@ -459,7 +454,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) { * to a builder. */ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie, - VALUE descriptor_pool, VALUE ptr) { + VALUE descriptor_pool, VALUE ptr) { FileDescriptor* self = ruby_to_FileDescriptor(_self); if (cookie != c_only_cookie) { @@ -468,7 +463,7 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie, } self->descriptor_pool = descriptor_pool; - self->filedef = (const upb_filedef*)NUM2ULL(ptr); + self->filedef = (const upb_FileDef*)NUM2ULL(ptr); return Qnil; } @@ -481,7 +476,7 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie, */ static VALUE FileDescriptor_name(VALUE _self) { FileDescriptor* self = ruby_to_FileDescriptor(_self); - const char* name = upb_filedef_name(self->filedef); + const char* name = upb_FileDef_Name(self->filedef); return name == NULL ? Qnil : rb_str_new2(name); } @@ -497,16 +492,18 @@ static VALUE FileDescriptor_name(VALUE _self) { static VALUE FileDescriptor_syntax(VALUE _self) { FileDescriptor* self = ruby_to_FileDescriptor(_self); - switch (upb_filedef_syntax(self->filedef)) { - case UPB_SYNTAX_PROTO3: return ID2SYM(rb_intern("proto3")); - case UPB_SYNTAX_PROTO2: return ID2SYM(rb_intern("proto2")); - default: return Qnil; + switch (upb_FileDef_Syntax(self->filedef)) { + case kUpb_Syntax_Proto3: + return ID2SYM(rb_intern("proto3")); + case kUpb_Syntax_Proto2: + return ID2SYM(rb_intern("proto2")); + default: + return Qnil; } } static void FileDescriptor_register(VALUE module) { - VALUE klass = rb_define_class_under( - module, "FileDescriptor", rb_cObject); + VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject); rb_define_alloc_func(klass, FileDescriptor_alloc); rb_define_method(klass, "initialize", FileDescriptor_initialize, 3); rb_define_method(klass, "name", FileDescriptor_name, 0); @@ -520,8 +517,8 @@ static void FileDescriptor_register(VALUE module) { // ----------------------------------------------------------------------------- typedef struct { - const upb_fielddef* fielddef; - VALUE descriptor_pool; // Owns the upb_fielddef. + const upb_FieldDef* fielddef; + VALUE descriptor_pool; // Owns the upb_FieldDef. } FieldDescriptor; static VALUE cFieldDescriptor = Qnil; @@ -532,9 +529,9 @@ static void FieldDescriptor_mark(void* _self) { } static const rb_data_type_t FieldDescriptor_type = { - "Google::Protobuf::FieldDescriptor", - {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::FieldDescriptor", + {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) { @@ -573,7 +570,7 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie, } self->descriptor_pool = descriptor_pool; - self->fielddef = (const upb_fielddef*)NUM2ULL(ptr); + self->fielddef = (const upb_FieldDef*)NUM2ULL(ptr); return Qnil; } @@ -586,31 +583,31 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie, */ static VALUE FieldDescriptor_name(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - return rb_str_maybe_null(upb_fielddef_name(self->fielddef)); + return rb_str_maybe_null(upb_FieldDef_Name(self->fielddef)); } // Non-static, exposed to other .c files. -upb_fieldtype_t ruby_to_fieldtype(VALUE type) { +upb_CType ruby_to_fieldtype(VALUE type) { if (TYPE(type) != T_SYMBOL) { rb_raise(rb_eArgError, "Expected symbol for field type."); } -#define CONVERT(upb, ruby) \ - if (SYM2ID(type) == rb_intern( # ruby )) { \ - return UPB_TYPE_ ## upb; \ +#define CONVERT(upb, ruby) \ + if (SYM2ID(type) == rb_intern(#ruby)) { \ + return kUpb_CType_##upb; \ } - CONVERT(FLOAT, float); - CONVERT(DOUBLE, double); - CONVERT(BOOL, bool); - CONVERT(STRING, string); - CONVERT(BYTES, bytes); - CONVERT(MESSAGE, message); - CONVERT(ENUM, enum); - CONVERT(INT32, int32); - CONVERT(INT64, int64); - CONVERT(UINT32, uint32); - CONVERT(UINT64, uint64); + CONVERT(Float, float); + CONVERT(Double, double); + CONVERT(Bool, bool); + CONVERT(String, string); + CONVERT(Bytes, bytes); + CONVERT(Message, message); + CONVERT(Enum, enum); + CONVERT(Int32, int32); + CONVERT(Int64, int64); + CONVERT(UInt32, uint32); + CONVERT(UInt64, uint64); #undef CONVERT @@ -618,28 +615,29 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) { return 0; } -static VALUE descriptortype_to_ruby(upb_descriptortype_t type) { +static VALUE descriptortype_to_ruby(upb_FieldType type) { switch (type) { -#define CONVERT(upb, ruby) \ - case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby )); - CONVERT(FLOAT, float); - CONVERT(DOUBLE, double); - CONVERT(BOOL, bool); - CONVERT(STRING, string); - CONVERT(BYTES, bytes); - CONVERT(MESSAGE, message); - CONVERT(GROUP, group); - CONVERT(ENUM, enum); - CONVERT(INT32, int32); - CONVERT(INT64, int64); - CONVERT(UINT32, uint32); - CONVERT(UINT64, uint64); - CONVERT(SINT32, sint32); - CONVERT(SINT64, sint64); - CONVERT(FIXED32, fixed32); - CONVERT(FIXED64, fixed64); - CONVERT(SFIXED32, sfixed32); - CONVERT(SFIXED64, sfixed64); +#define CONVERT(upb, ruby) \ + case kUpb_FieldType_##upb: \ + return ID2SYM(rb_intern(#ruby)); + CONVERT(Float, float); + CONVERT(Double, double); + CONVERT(Bool, bool); + CONVERT(String, string); + CONVERT(Bytes, bytes); + CONVERT(Message, message); + CONVERT(Group, group); + CONVERT(Enum, enum); + CONVERT(Int32, int32); + CONVERT(Int64, int64); + CONVERT(UInt32, uint32); + CONVERT(UInt64, uint64); + CONVERT(SInt32, sint32); + CONVERT(SInt64, sint64); + CONVERT(Fixed32, fixed32); + CONVERT(Fixed64, fixed64); + CONVERT(SFixed32, sfixed32); + CONVERT(SFixed64, sfixed64); #undef CONVERT } return Qnil; @@ -657,7 +655,7 @@ static VALUE descriptortype_to_ruby(upb_descriptortype_t type) { */ static VALUE FieldDescriptor__type(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef)); + return descriptortype_to_ruby(upb_FieldDef_Type(self->fielddef)); } /* @@ -668,17 +666,16 @@ static VALUE FieldDescriptor__type(VALUE _self) { */ static VALUE FieldDescriptor_default(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - const upb_fielddef *f = self->fielddef; - upb_msgval default_val = {0}; - if (upb_fielddef_issubmsg(f)) { + const upb_FieldDef* f = self->fielddef; + upb_MessageValue default_val = {0}; + if (upb_FieldDef_IsSubMessage(f)) { return Qnil; - } else if (!upb_fielddef_isseq(f)) { - default_val = upb_fielddef_default(f); + } else if (!upb_FieldDef_IsRepeated(f)) { + default_val = upb_FieldDef_Default(f); } return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil); } - /* * call-seq: * FieldDescriptor.json_name => json_name @@ -687,8 +684,8 @@ static VALUE FieldDescriptor_default(VALUE _self) { */ static VALUE FieldDescriptor_json_name(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - const upb_fielddef *f = self->fielddef; - const char *json_name = upb_fielddef_jsonname(f); + const upb_FieldDef* f = self->fielddef; + const char* json_name = upb_FieldDef_JsonName(f); return rb_str_new2(json_name); } @@ -703,13 +700,14 @@ static VALUE FieldDescriptor_json_name(VALUE _self) { */ static VALUE FieldDescriptor_label(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - switch (upb_fielddef_label(self->fielddef)) { -#define CONVERT(upb, ruby) \ - case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby )); + switch (upb_FieldDef_Label(self->fielddef)) { +#define CONVERT(upb, ruby) \ + case kUpb_Label_##upb: \ + return ID2SYM(rb_intern(#ruby)); - CONVERT(OPTIONAL, optional); - CONVERT(REQUIRED, required); - CONVERT(REPEATED, repeated); + CONVERT(Optional, optional); + CONVERT(Required, required); + CONVERT(Repeated, repeated); #undef CONVERT } @@ -725,7 +723,7 @@ static VALUE FieldDescriptor_label(VALUE _self) { */ static VALUE FieldDescriptor_number(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - return INT2NUM(upb_fielddef_number(self->fielddef)); + return INT2NUM(upb_FieldDef_Number(self->fielddef)); } /* @@ -739,13 +737,13 @@ static VALUE FieldDescriptor_number(VALUE _self) { */ static VALUE FieldDescriptor_submsg_name(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - switch (upb_fielddef_type(self->fielddef)) { - case UPB_TYPE_ENUM: + switch (upb_FieldDef_CType(self->fielddef)) { + case kUpb_CType_Enum: return rb_str_new2( - upb_enumdef_fullname(upb_fielddef_enumsubdef(self->fielddef))); - case UPB_TYPE_MESSAGE: + upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(self->fielddef))); + case kUpb_CType_Message: return rb_str_new2( - upb_msgdef_fullname(upb_fielddef_msgsubdef(self->fielddef))); + upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(self->fielddef))); default: return Qnil; } @@ -762,13 +760,13 @@ static VALUE FieldDescriptor_submsg_name(VALUE _self) { */ static VALUE FieldDescriptor_subtype(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - switch (upb_fielddef_type(self->fielddef)) { - case UPB_TYPE_ENUM: + switch (upb_FieldDef_CType(self->fielddef)) { + case kUpb_CType_Enum: return get_enumdef_obj(self->descriptor_pool, - upb_fielddef_enumsubdef(self->fielddef)); - case UPB_TYPE_MESSAGE: + upb_FieldDef_EnumSubDef(self->fielddef)); + case kUpb_CType_Message: return get_msgdef_obj(self->descriptor_pool, - upb_fielddef_msgsubdef(self->fielddef)); + upb_FieldDef_MessageSubDef(self->fielddef)); default: return Qnil; } @@ -783,11 +781,11 @@ static VALUE FieldDescriptor_subtype(VALUE _self) { */ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - const upb_msgdef *m; + const upb_MessageDef* m; Message_Get(msg_rb, &m); - if (m != upb_fielddef_containingtype(self->fielddef)) { + if (m != upb_FieldDef_ContainingType(self->fielddef)) { rb_raise(cTypeError, "get method called on wrong message type"); } @@ -803,16 +801,16 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) { */ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - const upb_msgdef *m; - const upb_msgdef *msg = Message_Get(msg_rb, &m); + const upb_MessageDef* m; + const upb_MessageDef* msg = Message_Get(msg_rb, &m); - if (m != upb_fielddef_containingtype(self->fielddef)) { + if (m != upb_FieldDef_ContainingType(self->fielddef)) { rb_raise(cTypeError, "has method called on wrong message type"); - } else if (!upb_fielddef_haspresence(self->fielddef)) { + } else if (!upb_FieldDef_HasPresence(self->fielddef)) { rb_raise(rb_eArgError, "does not track presence"); } - return upb_msg_has(msg, self->fielddef) ? Qtrue : Qfalse; + return upb_Message_Has(msg, self->fielddef) ? Qtrue : Qfalse; } /* @@ -823,14 +821,14 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) { */ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - const upb_msgdef *m; - upb_msgdef *msg = Message_GetMutable(msg_rb, &m); + const upb_MessageDef* m; + upb_MessageDef* msg = Message_GetMutable(msg_rb, &m); - if (m != upb_fielddef_containingtype(self->fielddef)) { + if (m != upb_FieldDef_ContainingType(self->fielddef)) { rb_raise(cTypeError, "has method called on wrong message type"); } - upb_msg_clearfield(msg, self->fielddef); + upb_Message_ClearField(msg, self->fielddef); return Qnil; } @@ -844,24 +842,23 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) { */ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); - const upb_msgdef *m; - upb_msgdef *msg = Message_GetMutable(msg_rb, &m); - upb_arena *arena = Arena_get(Message_GetArena(msg_rb)); - upb_msgval msgval; + const upb_MessageDef* m; + upb_MessageDef* msg = Message_GetMutable(msg_rb, &m); + upb_Arena* arena = Arena_get(Message_GetArena(msg_rb)); + upb_MessageValue msgval; - if (m != upb_fielddef_containingtype(self->fielddef)) { + if (m != upb_FieldDef_ContainingType(self->fielddef)) { rb_raise(cTypeError, "set method called on wrong message type"); } - msgval = Convert_RubyToUpb(value, upb_fielddef_name(self->fielddef), + msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef), TypeInfo_get(self->fielddef), arena); - upb_msg_set(msg, self->fielddef, msgval, arena); + upb_Message_Set(msg, self->fielddef, msgval, arena); return Qnil; } static void FieldDescriptor_register(VALUE module) { - VALUE klass = rb_define_class_under( - module, "FieldDescriptor", rb_cObject); + VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject); rb_define_alloc_func(klass, FieldDescriptor_alloc); rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3); rb_define_method(klass, "name", FieldDescriptor_name, 0); @@ -885,8 +882,8 @@ static void FieldDescriptor_register(VALUE module) { // ----------------------------------------------------------------------------- typedef struct { - const upb_oneofdef* oneofdef; - VALUE descriptor_pool; // Owns the upb_oneofdef. + const upb_OneofDef* oneofdef; + VALUE descriptor_pool; // Owns the upb_OneofDef. } OneofDescriptor; static VALUE cOneofDescriptor = Qnil; @@ -930,7 +927,7 @@ static VALUE OneofDescriptor_alloc(VALUE klass) { * Creates a descriptor wrapper object. May only be called from C. */ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie, - VALUE descriptor_pool, VALUE ptr) { + VALUE descriptor_pool, VALUE ptr) { OneofDescriptor* self = ruby_to_OneofDescriptor(_self); if (cookie != c_only_cookie) { @@ -939,7 +936,7 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie, } self->descriptor_pool = descriptor_pool; - self->oneofdef = (const upb_oneofdef*)NUM2ULL(ptr); + self->oneofdef = (const upb_OneofDef*)NUM2ULL(ptr); return Qnil; } @@ -952,7 +949,7 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie, */ static VALUE OneofDescriptor_name(VALUE _self) { OneofDescriptor* self = ruby_to_OneofDescriptor(_self); - return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef)); + return rb_str_maybe_null(upb_OneofDef_Name(self->oneofdef)); } /* @@ -963,11 +960,10 @@ static VALUE OneofDescriptor_name(VALUE _self) { */ static VALUE OneofDescriptor_each(VALUE _self) { OneofDescriptor* self = ruby_to_OneofDescriptor(_self); - upb_oneof_iter it; - for (upb_oneof_begin(&it, self->oneofdef); - !upb_oneof_done(&it); - upb_oneof_next(&it)) { - const upb_fielddef* f = upb_oneof_iter_field(&it); + + int n = upb_OneofDef_FieldCount(self->oneofdef); + for (int i = 0; i < n; i++) { + const upb_FieldDef* f = upb_OneofDef_Field(self->oneofdef, i); VALUE obj = get_fielddef_obj(self->descriptor_pool, f); rb_yield(obj); } @@ -975,8 +971,7 @@ static VALUE OneofDescriptor_each(VALUE _self) { } static void OneofDescriptor_register(VALUE module) { - VALUE klass = rb_define_class_under( - module, "OneofDescriptor", rb_cObject); + VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject); rb_define_alloc_func(klass, OneofDescriptor_alloc); rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3); rb_define_method(klass, "name", OneofDescriptor_name, 0); @@ -991,9 +986,9 @@ static void OneofDescriptor_register(VALUE module) { // ----------------------------------------------------------------------------- typedef struct { - const upb_enumdef* enumdef; - VALUE module; // begins as nil - VALUE descriptor_pool; // Owns the upb_enumdef. + const upb_EnumDef* enumdef; + VALUE module; // begins as nil + VALUE descriptor_pool; // Owns the upb_EnumDef. } EnumDescriptor; static VALUE cEnumDescriptor = Qnil; @@ -1005,9 +1000,9 @@ static void EnumDescriptor_mark(void* _self) { } static const rb_data_type_t EnumDescriptor_type = { - "Google::Protobuf::EnumDescriptor", - {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::EnumDescriptor", + {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) { @@ -1026,8 +1021,8 @@ static VALUE EnumDescriptor_alloc(VALUE klass) { } // Exposed to other modules in defs.h. -const upb_enumdef *EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) { - EnumDescriptor *desc = ruby_to_EnumDescriptor(enum_desc_rb); +const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) { + EnumDescriptor* desc = ruby_to_EnumDescriptor(enum_desc_rb); return desc->enumdef; } @@ -1047,7 +1042,7 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie, } self->descriptor_pool = descriptor_pool; - self->enumdef = (const upb_enumdef*)NUM2ULL(ptr); + self->enumdef = (const upb_EnumDef*)NUM2ULL(ptr); return Qnil; } @@ -1061,7 +1056,7 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie, static VALUE EnumDescriptor_file_descriptor(VALUE _self) { EnumDescriptor* self = ruby_to_EnumDescriptor(_self); return get_filedef_obj(self->descriptor_pool, - upb_enumdef_file(self->enumdef)); + upb_EnumDef_File(self->enumdef)); } /* @@ -1072,7 +1067,7 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) { */ static VALUE EnumDescriptor_name(VALUE _self) { EnumDescriptor* self = ruby_to_EnumDescriptor(_self); - return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef)); + return rb_str_maybe_null(upb_EnumDef_FullName(self->enumdef)); } /* @@ -1084,10 +1079,11 @@ static VALUE EnumDescriptor_name(VALUE _self) { */ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) { EnumDescriptor* self = ruby_to_EnumDescriptor(_self); - const char* name_str= rb_id2name(SYM2ID(name)); - int32_t val = 0; - if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) { - return INT2NUM(val); + const char* name_str = rb_id2name(SYM2ID(name)); + const upb_EnumValueDef *ev = + upb_EnumDef_FindValueByName(self->enumdef, name_str); + if (ev) { + return INT2NUM(upb_EnumValueDef_Number(ev)); } else { return Qnil; } @@ -1103,9 +1099,9 @@ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) { static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) { EnumDescriptor* self = ruby_to_EnumDescriptor(_self); int32_t val = NUM2INT(number); - const char* name = upb_enumdef_iton(self->enumdef, val); - if (name != NULL) { - return ID2SYM(rb_intern(name)); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(self->enumdef, val); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); } else { return Qnil; } @@ -1121,12 +1117,11 @@ static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) { static VALUE EnumDescriptor_each(VALUE _self) { EnumDescriptor* self = ruby_to_EnumDescriptor(_self); - upb_enum_iter it; - for (upb_enum_begin(&it, self->enumdef); - !upb_enum_done(&it); - upb_enum_next(&it)) { - VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it))); - VALUE number = INT2NUM(upb_enum_iter_number(&it)); + int n = upb_EnumDef_ValueCount(self->enumdef); + for (int i = 0; i < n; i++) { + const upb_EnumValueDef* ev = upb_EnumDef_Value(self->enumdef, i); + VALUE key = ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + VALUE number = INT2NUM(upb_EnumValueDef_Number(ev)); rb_yield_values(2, key, number); } @@ -1148,8 +1143,7 @@ static VALUE EnumDescriptor_enummodule(VALUE _self) { } static void EnumDescriptor_register(VALUE module) { - VALUE klass = rb_define_class_under( - module, "EnumDescriptor", rb_cObject); + VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject); rb_define_alloc_func(klass, EnumDescriptor_alloc); rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3); rb_define_method(klass, "name", EnumDescriptor_name, 0); @@ -1176,7 +1170,7 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) { if (def == Qnil) { // Lazily create wrapper object. - VALUE args[3] = { c_only_cookie, _descriptor_pool, key }; + VALUE args[3] = {c_only_cookie, _descriptor_pool, key}; def = rb_class_new_instance(3, args, klass); rb_hash_aset(descriptor_pool->def_to_descriptor, key, def); } @@ -1184,23 +1178,23 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) { return def; } -static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) { +static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def) { return get_def_obj(descriptor_pool, def, cDescriptor); } -static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) { +static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def) { return get_def_obj(descriptor_pool, def, cEnumDescriptor); } -static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) { +static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def) { return get_def_obj(descriptor_pool, def, cFieldDescriptor); } -static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) { +static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def) { return get_def_obj(descriptor_pool, def, cFileDescriptor); } -static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) { +static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) { return get_def_obj(descriptor_pool, def, cOneofDescriptor); } @@ -1210,8 +1204,8 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) { // Functions exposed to other modules in defs.h. -VALUE Descriptor_DefToClass(const upb_msgdef *m) { - const upb_symtab *symtab = upb_filedef_symtab(upb_msgdef_file(m)); +VALUE Descriptor_DefToClass(const upb_MessageDef* m) { + const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m)); VALUE pool = ObjectCache_Get(symtab); PBRUBY_ASSERT(pool != Qnil); VALUE desc_rb = get_msgdef_obj(pool, m); @@ -1219,15 +1213,16 @@ VALUE Descriptor_DefToClass(const upb_msgdef *m) { return desc->klass; } -const upb_msgdef *Descriptor_GetMsgDef(VALUE desc_rb) { +const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb) { const Descriptor* desc = ruby_to_Descriptor(desc_rb); return desc->msgdef; } -VALUE TypeInfo_InitArg(int argc, VALUE *argv, int skip_arg) { +VALUE TypeInfo_InitArg(int argc, VALUE* argv, int skip_arg) { if (argc > skip_arg) { if (argc > 1 + skip_arg) { - rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", skip_arg + 1); + rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", + skip_arg + 1); } return argv[skip_arg]; } else { @@ -1239,7 +1234,7 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, VALUE* type_class, VALUE* init_arg) { TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])}; - if (ret.type == UPB_TYPE_MESSAGE || ret.type == UPB_TYPE_ENUM) { + if (ret.type == kUpb_CType_Message || ret.type == kUpb_CType_Enum) { *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2); if (argc < 2 + skip_arg) { @@ -1257,11 +1252,11 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, "class or enum as returned by the DescriptorPool."); } - if (ret.type == UPB_TYPE_MESSAGE) { + if (ret.type == kUpb_CType_Message) { ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef; Message_CheckClass(klass); } else { - PBRUBY_ASSERT(ret.type == UPB_TYPE_ENUM); + PBRUBY_ASSERT(ret.type == kUpb_CType_Enum); ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef; } } else { diff --git a/ruby/ext/google/protobuf_c/defs.h b/ruby/ext/google/protobuf_c/defs.h index 97a94bb7b5453..f559cb0b9defb 100644 --- a/ruby/ext/google/protobuf_c/defs.h +++ b/ruby/ext/google/protobuf_c/defs.h @@ -40,9 +40,9 @@ // TypeInfo // ----------------------------------------------------------------------------- -// This bundles a upb_fieldtype_t and msgdef/enumdef when appropriate. This is +// This bundles a upb_CType and msgdef/enumdef when appropriate. This is // convenient for functions that need type information but cannot necessarily -// assume a upb_fielddef will be available. +// assume a upb_FieldDef will be available. // // For example, Google::Protobuf::Map and Google::Protobuf::RepeatedField can // be constructed with type information alone: @@ -51,21 +51,21 @@ // Google::Protobuf::RepeatedField.new(:message, FooMessage) typedef struct { - upb_fieldtype_t type; + upb_CType type; union { - const upb_msgdef* msgdef; // When type == UPB_TYPE_MESSAGE - const upb_enumdef* enumdef; // When type == UPB_TYPE_ENUM + const upb_MessageDef* msgdef; // When type == kUpb_CType_Message + const upb_EnumDef* enumdef; // When type == kUpb_CType_Enum } def; } TypeInfo; -static inline TypeInfo TypeInfo_get(const upb_fielddef *f) { - TypeInfo ret = {upb_fielddef_type(f), {NULL}}; +static inline TypeInfo TypeInfo_get(const upb_FieldDef* f) { + TypeInfo ret = {upb_FieldDef_CType(f), {NULL}}; switch (ret.type) { - case UPB_TYPE_MESSAGE: - ret.def.msgdef = upb_fielddef_msgsubdef(f); + case kUpb_CType_Message: + ret.def.msgdef = upb_FieldDef_MessageSubDef(f); break; - case UPB_TYPE_ENUM: - ret.def.enumdef = upb_fielddef_enumsubdef(f); + case kUpb_CType_Enum: + ret.def.enumdef = upb_FieldDef_EnumSubDef(f); break; default: break; @@ -76,9 +76,9 @@ static inline TypeInfo TypeInfo_get(const upb_fielddef *f) { TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, VALUE* type_class, VALUE* init_arg); -static inline TypeInfo TypeInfo_from_type(upb_fieldtype_t type) { +static inline TypeInfo TypeInfo_from_type(upb_CType type) { TypeInfo ret = {type}; - assert(type != UPB_TYPE_MESSAGE && type != UPB_TYPE_ENUM); + assert(type != kUpb_CType_Message && type != kUpb_CType_Enum); return ret; } @@ -86,17 +86,17 @@ static inline TypeInfo TypeInfo_from_type(upb_fieldtype_t type) { // Other utilities // ----------------------------------------------------------------------------- -VALUE Descriptor_DefToClass(const upb_msgdef *m); +VALUE Descriptor_DefToClass(const upb_MessageDef* m); // Returns the underlying msgdef, enumdef, or symtab (respectively) for the // given Descriptor, EnumDescriptor, or DescriptorPool Ruby object. -const upb_enumdef *EnumDescriptor_GetEnumDef(VALUE enum_desc_rb); -const upb_symtab *DescriptorPool_GetSymtab(VALUE desc_pool_rb); -const upb_msgdef *Descriptor_GetMsgDef(VALUE desc_rb); +const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb); +const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb); +const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb); // Returns a upb field type for the given Ruby symbol -// (eg. :float => UPB_TYPE_FLOAT). -upb_fieldtype_t ruby_to_fieldtype(VALUE type); +// (eg. :float => kUpb_CType_Float). +upb_CType ruby_to_fieldtype(VALUE type); // The singleton generated pool (a DescriptorPool object). extern VALUE generated_pool; diff --git a/ruby/ext/google/protobuf_c/extconf.rb b/ruby/ext/google/protobuf_c/extconf.rb index ec17787f79fd4..d8f081a431db0 100755 --- a/ruby/ext/google/protobuf_c/extconf.rb +++ b/ruby/ext/google/protobuf_c/extconf.rb @@ -2,6 +2,10 @@ require 'mkmf' +ext_name = "google/protobuf_c" + +dir_config(ext_name) + if RUBY_PLATFORM =~ /darwin/ || RUBY_PLATFORM =~ /linux/ $CFLAGS += " -std=gnu99 -O3 -DNDEBUG -fvisibility=hidden -Wall -Wsign-compare -Wno-declaration-after-statement" else @@ -14,7 +18,11 @@ $LDFLAGS += " -Wl,-wrap,memcpy" end -$objs = ["protobuf.o", "convert.o", "defs.o", "message.o", - "repeated_field.o", "map.o", "ruby-upb.o", "wrap_memcpy.o"] +$VPATH << "$(srcdir)/third_party/utf8_range" +$INCFLAGS << "$(srcdir)/third_party/utf8_range" + +$srcs = ["protobuf.c", "convert.c", "defs.c", "message.c", + "repeated_field.c", "map.c", "ruby-upb.c", "wrap_memcpy.c", + "utf8_range.c"] -create_makefile("google/protobuf_c") +create_makefile(ext_name) diff --git a/ruby/ext/google/protobuf_c/map.c b/ruby/ext/google/protobuf_c/map.c index d5b47e4e18c29..5d30319c198e6 100644 --- a/ruby/ext/google/protobuf_c/map.c +++ b/ruby/ext/google/protobuf_c/map.c @@ -34,7 +34,7 @@ #include "protobuf.h" // ----------------------------------------------------------------------------- -// Basic map operations on top of upb_map. +// Basic map operations on top of upb_Map. // // 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 @@ -48,8 +48,8 @@ // ----------------------------------------------------------------------------- typedef struct { - const upb_map *map; // Can convert to mutable when non-frozen. - upb_fieldtype_t key_type; + const upb_Map* map; // Can convert to mutable when non-frozen. + upb_CType key_type; TypeInfo value_type_info; VALUE value_type_class; VALUE arena; @@ -62,9 +62,9 @@ static void Map_mark(void* _self) { } const rb_data_type_t Map_type = { - "Google::Protobuf::Map", - { Map_mark, RUBY_DEFAULT_FREE, NULL }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::Map", + {Map_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; VALUE cMap; @@ -84,8 +84,8 @@ static VALUE Map_alloc(VALUE klass) { return TypedData_Wrap_Struct(klass, &Map_type, self); } -VALUE Map_GetRubyWrapper(upb_map* map, upb_fieldtype_t key_type, - TypeInfo value_type, VALUE arena) { +VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type, TypeInfo value_type, + VALUE arena) { PBRUBY_ASSERT(map); VALUE val = ObjectCache_Get(map); @@ -99,8 +99,8 @@ VALUE Map_GetRubyWrapper(upb_map* map, upb_fieldtype_t key_type, self->arena = arena; self->key_type = key_type; self->value_type_info = value_type; - if (self->value_type_info.type == UPB_TYPE_MESSAGE) { - const upb_msgdef *val_m = self->value_type_info.def.msgdef; + if (self->value_type_info.type == kUpb_CType_Message) { + const upb_MessageDef* val_m = self->value_type_info.def.msgdef; self->value_type_class = Descriptor_DefToClass(val_m); } } @@ -108,9 +108,9 @@ VALUE Map_GetRubyWrapper(upb_map* map, upb_fieldtype_t key_type, return val; } -static VALUE Map_new_this_type(Map *from) { +static VALUE Map_new_this_type(Map* from) { VALUE arena_rb = Arena_new(); - upb_map* map = upb_map_new(Arena_get(arena_rb), from->key_type, + upb_Map* map = upb_Map_New(Arena_get(arena_rb), from->key_type, from->value_type_info.type); VALUE ret = Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb); @@ -125,22 +125,22 @@ static TypeInfo Map_keyinfo(Map* self) { return ret; } -static upb_map *Map_GetMutable(VALUE _self) { +static upb_Map* Map_GetMutable(VALUE _self) { rb_check_frozen(_self); - return (upb_map*)ruby_to_Map(_self)->map; + return (upb_Map*)ruby_to_Map(_self)->map; } -VALUE Map_CreateHash(const upb_map* map, upb_fieldtype_t key_type, +VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type, TypeInfo val_info) { VALUE hash = rb_hash_new(); - size_t iter = UPB_MAP_BEGIN; + size_t iter = kUpb_Map_Begin; TypeInfo key_info = TypeInfo_from_type(key_type); if (!map) return hash; - while (upb_mapiter_next(map, &iter)) { - upb_msgval key = upb_mapiter_key(map, iter); - upb_msgval val = upb_mapiter_value(map, iter); + while (upb_MapIterator_Next(map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(map, iter); + upb_MessageValue val = upb_MapIterator_Value(map, iter); VALUE key_val = Convert_UpbToRuby(key, key_info, Qnil); VALUE val_val = Scalar_CreateHash(val, val_info); rb_hash_aset(hash, key_val, val_val); @@ -152,25 +152,26 @@ VALUE Map_CreateHash(const upb_map* map, upb_fieldtype_t key_type, VALUE Map_deep_copy(VALUE obj) { Map* self = ruby_to_Map(obj); VALUE new_arena_rb = Arena_new(); - upb_arena *arena = Arena_get(new_arena_rb); - upb_map* new_map = - upb_map_new(arena, self->key_type, self->value_type_info.type); - size_t iter = UPB_MAP_BEGIN; - while (upb_mapiter_next(self->map, &iter)) { - upb_msgval key = upb_mapiter_key(self->map, iter); - upb_msgval val = upb_mapiter_value(self->map, iter); - upb_msgval val_copy = Msgval_DeepCopy(val, self->value_type_info, arena); - upb_map_set(new_map, key, val_copy, arena); + upb_Arena* arena = Arena_get(new_arena_rb); + upb_Map* new_map = + upb_Map_New(arena, self->key_type, self->value_type_info.type); + size_t iter = kUpb_Map_Begin; + while (upb_MapIterator_Next(self->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(self->map, iter); + upb_MessageValue val = upb_MapIterator_Value(self->map, iter); + upb_MessageValue val_copy = + Msgval_DeepCopy(val, self->value_type_info, arena); + upb_Map_Set(new_map, key, val_copy, arena); } return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info, new_arena_rb); } -const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field, - upb_arena* arena) { - const upb_fielddef* key_field = map_field_key(field); - const upb_fielddef* value_field = map_field_value(field); +const upb_Map* Map_GetUpbMap(VALUE val, const upb_FieldDef* field, + upb_Arena* arena) { + const upb_FieldDef* key_field = map_field_key(field); + const upb_FieldDef* value_field = map_field_value(field); TypeInfo value_type_info = TypeInfo_get(value_field); Map* self; @@ -180,7 +181,7 @@ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field, } self = ruby_to_Map(val); - if (self->key_type != upb_fielddef_type(key_field)) { + if (self->key_type != upb_FieldDef_CType(key_field)) { rb_raise(cTypeError, "Map key type does not match field's key type"); } if (self->value_type_info.type != value_type_info.type) { @@ -194,16 +195,16 @@ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field, return self->map; } -void Map_Inspect(StringBuilder* b, const upb_map* map, upb_fieldtype_t key_type, +void Map_Inspect(StringBuilder* b, const upb_Map* map, upb_CType key_type, TypeInfo val_type) { bool first = true; TypeInfo key_type_info = {key_type}; StringBuilder_Printf(b, "{"); if (map) { - 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); + size_t iter = kUpb_Map_Begin; + while (upb_MapIterator_Next(map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(map, iter); + upb_MessageValue val = upb_MapIterator_Value(map, iter); if (first) { first = false; } else { @@ -219,10 +220,12 @@ void Map_Inspect(StringBuilder* b, const upb_map* map, upb_fieldtype_t key_type, static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) { Map* self = ruby_to_Map(_self); - upb_arena *arena = Arena_get(self->arena); - upb_msgval key_val = Convert_RubyToUpb(key, "", Map_keyinfo(self), arena); - upb_msgval val_val = Convert_RubyToUpb(val, "", self->value_type_info, arena); - upb_map_set(Map_GetMutable(_self), key_val, val_val, arena); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue key_val = + Convert_RubyToUpb(key, "", Map_keyinfo(self), arena); + upb_MessageValue val_val = + Convert_RubyToUpb(val, "", self->value_type_info, arena); + upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena); return ST_CONTINUE; } @@ -234,9 +237,9 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) { RTYPEDDATA_TYPE(hashmap) == &Map_type) { Map* self = ruby_to_Map(_self); Map* other = ruby_to_Map(hashmap); - upb_arena *arena = Arena_get(self->arena); - upb_msg *self_msg = Map_GetMutable(_self); - size_t iter = UPB_MAP_BEGIN; + upb_Arena* arena = Arena_get(self->arena); + upb_Message* self_msg = Map_GetMutable(_self); + size_t iter = kUpb_Map_Begin; Arena_fuse(other->arena, arena); @@ -246,10 +249,10 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) { rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types"); } - while (upb_mapiter_next(other->map, &iter)) { - upb_msgval key = upb_mapiter_key(other->map, iter); - upb_msgval val = upb_mapiter_value(other->map, iter); - upb_map_set(self_msg, key, val, arena); + while (upb_MapIterator_Next(other->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(other->map, iter); + upb_MessageValue val = upb_MapIterator_Value(other->map, iter); + upb_Map_Set(self_msg, key, val, arena); } } else { rb_raise(rb_eArgError, "Unknown type merging into Map"); @@ -305,20 +308,20 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) { // Check that the key type is an allowed type. switch (self->key_type) { - case UPB_TYPE_INT32: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT32: - case UPB_TYPE_UINT64: - case UPB_TYPE_BOOL: - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + case kUpb_CType_Bool: + case kUpb_CType_String: + case kUpb_CType_Bytes: // These are OK. break; default: rb_raise(rb_eArgError, "Invalid key type for map."); } - self->map = upb_map_new(Arena_get(self->arena), self->key_type, + self->map = upb_Map_New(Arena_get(self->arena), self->key_type, self->value_type_info.type); ObjectCache_Add(self->map, _self); @@ -339,11 +342,11 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) { */ static VALUE Map_each(VALUE _self) { Map* self = ruby_to_Map(_self); - size_t iter = UPB_MAP_BEGIN; + size_t iter = kUpb_Map_Begin; - while (upb_mapiter_next(self->map, &iter)) { - upb_msgval key = upb_mapiter_key(self->map, iter); - upb_msgval val = upb_mapiter_value(self->map, iter); + while (upb_MapIterator_Next(self->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(self->map, iter); + upb_MessageValue val = upb_MapIterator_Value(self->map, iter); VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); rb_yield_values(2, key_val, val_val); @@ -360,11 +363,11 @@ static VALUE Map_each(VALUE _self) { */ static VALUE Map_keys(VALUE _self) { Map* self = ruby_to_Map(_self); - size_t iter = UPB_MAP_BEGIN; + size_t iter = kUpb_Map_Begin; VALUE ret = rb_ary_new(); - while (upb_mapiter_next(self->map, &iter)) { - upb_msgval key = upb_mapiter_key(self->map, iter); + while (upb_MapIterator_Next(self->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(self->map, iter); VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); rb_ary_push(ret, key_val); } @@ -380,11 +383,11 @@ static VALUE Map_keys(VALUE _self) { */ static VALUE Map_values(VALUE _self) { Map* self = ruby_to_Map(_self); - size_t iter = UPB_MAP_BEGIN; + size_t iter = kUpb_Map_Begin; VALUE ret = rb_ary_new(); - while (upb_mapiter_next(self->map, &iter)) { - upb_msgval val = upb_mapiter_value(self->map, iter); + while (upb_MapIterator_Next(self->map, &iter)) { + upb_MessageValue val = upb_MapIterator_Value(self->map, iter); VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); rb_ary_push(ret, val_val); } @@ -401,10 +404,11 @@ static VALUE Map_values(VALUE _self) { */ static VALUE Map_index(VALUE _self, VALUE key) { Map* self = ruby_to_Map(_self); - upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); - upb_msgval val; + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val; - if (upb_map_get(self->map, key_upb, &val)) { + if (upb_Map_Get(self->map, key_upb, &val)) { return Convert_UpbToRuby(val, self->value_type_info, self->arena); } else { return Qnil; @@ -421,11 +425,13 @@ static VALUE Map_index(VALUE _self, VALUE key) { */ static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) { Map* self = ruby_to_Map(_self); - upb_arena *arena = Arena_get(self->arena); - upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); - upb_msgval val_upb = Convert_RubyToUpb(val, "", self->value_type_info, arena); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val_upb = + Convert_RubyToUpb(val, "", self->value_type_info, arena); - upb_map_set(Map_GetMutable(_self), key_upb, val_upb, arena); + upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena); return val; } @@ -439,9 +445,10 @@ static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) { */ static VALUE Map_has_key(VALUE _self, VALUE key) { Map* self = ruby_to_Map(_self); - upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); - if (upb_map_get(self->map, key_upb, NULL)) { + if (upb_Map_Get(self->map, key_upb, NULL)) { return Qtrue; } else { return Qfalse; @@ -457,21 +464,22 @@ static VALUE Map_has_key(VALUE _self, VALUE key) { */ static VALUE Map_delete(VALUE _self, VALUE key) { Map* self = ruby_to_Map(_self); - upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); - upb_msgval val_upb; + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val_upb; VALUE ret; rb_check_frozen(_self); - // TODO(haberman): make upb_map_delete() also capable of returning the deleted + // TODO(haberman): make upb_Map_Delete() also capable of returning the deleted // value. - if (upb_map_get(self->map, key_upb, &val_upb)) { + if (upb_Map_Get(self->map, key_upb, &val_upb)) { ret = Convert_UpbToRuby(val_upb, self->value_type_info, self->arena); } else { ret = Qnil; } - upb_map_delete(Map_GetMutable(_self), key_upb); + upb_Map_Delete(Map_GetMutable(_self), key_upb); return ret; } @@ -483,7 +491,7 @@ static VALUE Map_delete(VALUE _self, VALUE key) { * Removes all entries from the map. */ static VALUE Map_clear(VALUE _self) { - upb_map_clear(Map_GetMutable(_self)); + upb_Map_Clear(Map_GetMutable(_self)); return Qnil; } @@ -495,7 +503,7 @@ static VALUE Map_clear(VALUE _self) { */ static VALUE Map_length(VALUE _self) { Map* self = ruby_to_Map(_self); - return ULL2NUM(upb_map_size(self->map)); + return ULL2NUM(upb_Map_Size(self->map)); } /* @@ -509,16 +517,16 @@ static VALUE Map_dup(VALUE _self) { Map* self = ruby_to_Map(_self); VALUE new_map_rb = Map_new_this_type(self); Map* new_self = ruby_to_Map(new_map_rb); - size_t iter = UPB_MAP_BEGIN; - upb_arena *arena = Arena_get(new_self->arena); - upb_map *new_map = Map_GetMutable(new_map_rb); + size_t iter = kUpb_Map_Begin; + upb_Arena* arena = Arena_get(new_self->arena); + upb_Map* new_map = Map_GetMutable(new_map_rb); Arena_fuse(self->arena, arena); - while (upb_mapiter_next(self->map, &iter)) { - upb_msgval key = upb_mapiter_key(self->map, iter); - upb_msgval val = upb_mapiter_value(self->map, iter); - upb_map_set(new_map, key, val, arena); + while (upb_MapIterator_Next(self->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(self->map, iter); + upb_MessageValue val = upb_MapIterator_Value(self->map, iter); + upb_Map_Set(new_map, key, val, arena); } return new_map_rb; @@ -559,18 +567,18 @@ VALUE Map_eq(VALUE _self, VALUE _other) { self->value_type_class != other->value_type_class) { return Qfalse; } - if (upb_map_size(self->map) != upb_map_size(other->map)) { + if (upb_Map_Size(self->map) != upb_Map_Size(other->map)) { return Qfalse; } // For each member of self, check that an equal member exists at the same key // in other. - size_t iter = UPB_MAP_BEGIN; - while (upb_mapiter_next(self->map, &iter)) { - upb_msgval key = upb_mapiter_key(self->map, iter); - upb_msgval val = upb_mapiter_value(self->map, iter); - upb_msgval other_val; - if (!upb_map_get(other->map, key, &other_val)) { + size_t iter = kUpb_Map_Begin; + while (upb_MapIterator_Next(self->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(self->map, iter); + upb_MessageValue val = upb_MapIterator_Value(self->map, iter); + upb_MessageValue other_val; + if (!upb_Map_Get(other->map, key, &other_val)) { // Not present in other map. return Qfalse; } @@ -609,11 +617,11 @@ VALUE Map_hash(VALUE _self) { Map* self = ruby_to_Map(_self); uint64_t hash = 0; - size_t iter = UPB_MAP_BEGIN; + size_t iter = kUpb_Map_Begin; TypeInfo key_info = {self->key_type}; - while (upb_mapiter_next(self->map, &iter)) { - upb_msgval key = upb_mapiter_key(self->map, iter); - upb_msgval val = upb_mapiter_value(self->map, iter); + while (upb_MapIterator_Next(self->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(self->map, iter); + upb_MessageValue val = upb_MapIterator_Value(self->map, iter); hash = Msgval_GetHash(key, key_info, hash); hash = Msgval_GetHash(val, self->value_type_info, hash); } @@ -680,7 +688,10 @@ void Map_register(VALUE module) { rb_define_method(klass, "delete", Map_delete, 1); rb_define_method(klass, "clear", Map_clear, 0); rb_define_method(klass, "length", Map_length, 0); + rb_define_method(klass, "size", Map_length, 0); rb_define_method(klass, "dup", Map_dup, 0); + // Also define #clone so that we don't inherit Object#clone. + rb_define_method(klass, "clone", Map_dup, 0); rb_define_method(klass, "==", Map_eq, 1); rb_define_method(klass, "freeze", Map_freeze, 0); rb_define_method(klass, "hash", Map_hash, 0); diff --git a/ruby/ext/google/protobuf_c/map.h b/ruby/ext/google/protobuf_c/map.h index 411362cab3b5f..7b4a1514cafac 100644 --- a/ruby/ext/google/protobuf_c/map.h +++ b/ruby/ext/google/protobuf_c/map.h @@ -38,22 +38,21 @@ // Returns a Ruby wrapper object for the given map, which will be created if // one does not exist already. -VALUE Map_GetRubyWrapper(upb_map *map, upb_fieldtype_t key_type, - TypeInfo value_type, VALUE arena); +VALUE Map_GetRubyWrapper(upb_Map *map, upb_CType key_type, TypeInfo value_type, + VALUE arena); -// Gets the underlying upb_map for this Ruby map object, which must have +// Gets the underlying upb_Map for this Ruby map object, which must have // key/value type that match |field|. If this is not a map or the type doesn't // match, raises an exception. -const upb_map *Map_GetUpbMap(VALUE val, const upb_fielddef *field, - upb_arena *arena); +const upb_Map *Map_GetUpbMap(VALUE val, const upb_FieldDef *field, + upb_Arena *arena); // Implements #inspect for this map by appending its contents to |b|. -void Map_Inspect(StringBuilder *b, const upb_map *map, upb_fieldtype_t key_type, +void Map_Inspect(StringBuilder *b, const upb_Map *map, upb_CType key_type, TypeInfo val_type); // Returns a new Hash object containing the contents of this Map. -VALUE Map_CreateHash(const upb_map* map, upb_fieldtype_t key_type, - TypeInfo val_info); +VALUE Map_CreateHash(const upb_Map *map, upb_CType key_type, TypeInfo val_info); // Returns a deep copy of this Map object. VALUE Map_deep_copy(VALUE obj); diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index 59602cf0899da..7feee75db87b5 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -40,7 +40,7 @@ static VALUE cParseError = Qnil; static ID descriptor_instancevar_interned; static VALUE initialize_rb_class_with_no_args(VALUE klass) { - return rb_funcall(klass, rb_intern("new"), 0); + return rb_funcall(klass, rb_intern("new"), 0); } VALUE MessageOrEnum_GetDescriptor(VALUE klass) { @@ -53,19 +53,20 @@ VALUE MessageOrEnum_GetDescriptor(VALUE klass) { typedef struct { VALUE arena; - const upb_msg* msg; // Can get as mutable when non-frozen. - const upb_msgdef* msgdef; // kept alive by self.class.descriptor reference. + const upb_Message* msg; // Can get as mutable when non-frozen. + const upb_MessageDef* + msgdef; // kept alive by self.class.descriptor reference. } Message; static void Message_mark(void* _self) { - Message* self = (Message *)_self; + Message* self = (Message*)_self; rb_gc_mark(self->arena); } static rb_data_type_t Message_type = { - "Message", - { Message_mark, RUBY_DEFAULT_FREE, NULL }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Message", + {Message_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static Message* ruby_to_Message(VALUE msg_rb) { @@ -89,18 +90,18 @@ static VALUE Message_alloc(VALUE klass) { return ret; } -const upb_msg *Message_Get(VALUE msg_rb, const upb_msgdef **m) { +const upb_Message* Message_Get(VALUE msg_rb, const upb_MessageDef** m) { Message* msg = ruby_to_Message(msg_rb); if (m) *m = msg->msgdef; return msg->msg; } -upb_msg *Message_GetMutable(VALUE msg_rb, const upb_msgdef **m) { +upb_Message* Message_GetMutable(VALUE msg_rb, const upb_MessageDef** m) { rb_check_frozen(msg_rb); - return (upb_msg*)Message_Get(msg_rb, m); + return (upb_Message*)Message_Get(msg_rb, m); } -void Message_InitPtr(VALUE self_, upb_msg *msg, VALUE arena) { +void Message_InitPtr(VALUE self_, upb_Message* msg, VALUE arena) { Message* self = ruby_to_Message(self_); self->msg = msg; self->arena = arena; @@ -119,7 +120,8 @@ void Message_CheckClass(VALUE klass) { } } -VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena) { +VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m, + VALUE arena) { if (msg == NULL) return Qnil; VALUE val = ObjectCache_Get(msg); @@ -133,17 +135,17 @@ VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena) { return val; } -void Message_PrintMessage(StringBuilder* b, const upb_msg* msg, - const upb_msgdef* m) { +void Message_PrintMessage(StringBuilder* b, const upb_Message* msg, + const upb_MessageDef* m) { bool first = true; - int n = upb_msgdef_fieldcount(m); + int n = upb_MessageDef_FieldCount(m); VALUE klass = Descriptor_DefToClass(m); StringBuilder_Printf(b, "<%s: ", rb_class2name(klass)); for (int i = 0; i < n; i++) { - const upb_fielddef* field = upb_msgdef_field(m, i); + const upb_FieldDef* field = upb_MessageDef_Field(m, i); - if (upb_fielddef_haspresence(field) && !upb_msg_has(msg, field)) { + if (upb_FieldDef_HasPresence(field) && !upb_Message_Has(msg, field)) { continue; } @@ -153,17 +155,19 @@ void Message_PrintMessage(StringBuilder* b, const upb_msg* msg, first = false; } - upb_msgval msgval = upb_msg_get(msg, field); + upb_MessageValue msgval = upb_Message_Get(msg, field); - StringBuilder_Printf(b, "%s: ", upb_fielddef_name(field)); + StringBuilder_Printf(b, "%s: ", upb_FieldDef_Name(field)); - if (upb_fielddef_ismap(field)) { - const upb_msgdef* entry_m = upb_fielddef_msgsubdef(field); - const upb_fielddef* key_f = upb_msgdef_itof(entry_m, 1); - const upb_fielddef* val_f = upb_msgdef_itof(entry_m, 2); + if (upb_FieldDef_IsMap(field)) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field); + const upb_FieldDef* key_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 1); + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 2); TypeInfo val_info = TypeInfo_get(val_f); - Map_Inspect(b, msgval.map_val, upb_fielddef_type(key_f), val_info); - } else if (upb_fielddef_isseq(field)) { + Map_Inspect(b, msgval.map_val, upb_FieldDef_CType(key_f), val_info); + } else if (upb_FieldDef_IsRepeated(field)) { RepeatedField_Inspect(b, msgval.array_val, TypeInfo_get(field)); } else { StringBuilder_PrintMsgval(b, msgval, TypeInfo_get(field)); @@ -187,14 +191,31 @@ enum { }; // Check if the field is a well known wrapper type -static bool IsWrapper(const upb_fielddef* f) { - return upb_fielddef_issubmsg(f) && - upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f)); +static bool IsWrapper(const upb_MessageDef* m) { + if (!m) return false; + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: + return true; + default: + return false; + } } -static bool Match(const upb_msgdef* m, const char* name, const upb_fielddef** f, - const upb_oneofdef** o, const char* prefix, - const char* suffix) { +static bool IsFieldWrapper(const upb_FieldDef* f) { + return IsWrapper(upb_FieldDef_MessageSubDef(f)); +} + +static bool Match(const upb_MessageDef* m, const char* name, + const upb_FieldDef** f, const upb_OneofDef** o, + const char* prefix, const char* suffix) { size_t sp = strlen(prefix); size_t ss = strlen(suffix); size_t sn = strlen(name); @@ -206,12 +227,12 @@ static bool Match(const upb_msgdef* m, const char* name, const upb_fielddef** f, return false; } - return upb_msgdef_lookupname(m, name + sp, sn - sp - ss, f, o); + return upb_MessageDef_FindByNameWithSize(m, name + sp, sn - sp - ss, f, o); } static int extract_method_call(VALUE method_name, Message* self, - const upb_fielddef** f, const upb_oneofdef** o) { - const upb_msgdef* m = self->msgdef; + const upb_FieldDef** f, const upb_OneofDef** o) { + const upb_MessageDef* m = self->msgdef; const char* name; Check_Type(method_name, T_SYMBOL); @@ -221,156 +242,159 @@ static int extract_method_call(VALUE method_name, Message* self, if (Match(m, name, f, o, "", "=")) return METHOD_SETTER; if (Match(m, name, f, o, "clear_", "")) return METHOD_CLEAR; if (Match(m, name, f, o, "has_", "?") && - (*o || (*f && upb_fielddef_haspresence(*f)))) { + (*o || (*f && upb_FieldDef_HasPresence(*f)))) { // Disallow oneof hazzers for proto3. // TODO(haberman): remove this test when we are enabling oneof hazzers for // proto3. - if (*f && !upb_fielddef_issubmsg(*f) && - upb_fielddef_realcontainingoneof(*f) && - upb_msgdef_syntax(upb_fielddef_containingtype(*f)) != - UPB_SYNTAX_PROTO2) { + if (*f && !upb_FieldDef_IsSubMessage(*f) && + upb_FieldDef_RealContainingOneof(*f) && + upb_MessageDef_Syntax(upb_FieldDef_ContainingType(*f)) != + kUpb_Syntax_Proto2) { return METHOD_UNKNOWN; } return METHOD_PRESENCE; } - if (Match(m, name, f, o, "", "_as_value") && *f && !upb_fielddef_isseq(*f) && - IsWrapper(*f)) { + if (Match(m, name, f, o, "", "_as_value") && *f && + !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) { return METHOD_WRAPPER_GETTER; } - if (Match(m, name, f, o, "", "_as_value=") && *f && !upb_fielddef_isseq(*f) && - IsWrapper(*f)) { + if (Match(m, name, f, o, "", "_as_value=") && *f && + !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) { return METHOD_WRAPPER_SETTER; } if (Match(m, name, f, o, "", "_const") && *f && - upb_fielddef_type(*f) == UPB_TYPE_ENUM) { + upb_FieldDef_CType(*f) == kUpb_CType_Enum) { return METHOD_ENUM_GETTER; } return METHOD_UNKNOWN; } -static VALUE Message_oneof_accessor(VALUE _self, const upb_oneofdef* o, +static VALUE Message_oneof_accessor(VALUE _self, const upb_OneofDef* o, int accessor_type) { Message* self = ruby_to_Message(_self); - const upb_fielddef* oneof_field = upb_msg_whichoneof(self->msg, o); + const upb_FieldDef* oneof_field = upb_Message_WhichOneof(self->msg, o); switch (accessor_type) { case METHOD_PRESENCE: return oneof_field == NULL ? Qfalse : Qtrue; case METHOD_CLEAR: if (oneof_field != NULL) { - upb_msg_clearfield(Message_GetMutable(_self, NULL), oneof_field); + upb_Message_ClearField(Message_GetMutable(_self, NULL), oneof_field); } return Qnil; case METHOD_GETTER: return oneof_field == NULL ? Qnil - : ID2SYM(rb_intern(upb_fielddef_name(oneof_field))); + : ID2SYM(rb_intern(upb_FieldDef_Name(oneof_field))); case METHOD_SETTER: rb_raise(rb_eRuntimeError, "Oneof accessors are read-only."); } rb_raise(rb_eRuntimeError, "Invalid access of oneof field."); } -static void Message_setfield(upb_msg* msg, const upb_fielddef* f, VALUE val, - upb_arena* arena) { - upb_msgval msgval; - if (upb_fielddef_ismap(f)) { +static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val, + upb_Arena* arena) { + upb_MessageValue msgval; + if (upb_FieldDef_IsMap(f)) { msgval.map_val = Map_GetUpbMap(val, f, arena); - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(f)) { msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); } else { if (val == Qnil && - (upb_fielddef_issubmsg(f) || upb_fielddef_realcontainingoneof(f))) { - upb_msg_clearfield(msg, f); + (upb_FieldDef_IsSubMessage(f) || upb_FieldDef_RealContainingOneof(f))) { + upb_Message_ClearField(msg, f); return; } msgval = - Convert_RubyToUpb(val, upb_fielddef_name(f), TypeInfo_get(f), arena); + Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); } - upb_msg_set(msg, f, msgval, arena); + upb_Message_Set(msg, f, msgval, arena); } -VALUE Message_getfield(VALUE _self, const upb_fielddef* f) { +VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) { Message* self = ruby_to_Message(_self); - // This is a special-case: upb_msg_mutable() for map & array are logically + // This is a special-case: upb_Message_Mutable() for map & array are logically // const (they will not change what is serialized) but physically // non-const, as they do allocate a repeated field or map. The logical // constness means it's ok to do even if the message is frozen. - upb_msg *msg = (upb_msg*)self->msg; - upb_arena *arena = Arena_get(self->arena); - if (upb_fielddef_ismap(f)) { - upb_map *map = upb_msg_mutable(msg, f, arena).map; - const upb_fielddef *key_f = map_field_key(f); - const upb_fielddef *val_f = map_field_value(f); - upb_fieldtype_t key_type = upb_fielddef_type(key_f); + upb_Message* msg = (upb_Message*)self->msg; + upb_Arena* arena = Arena_get(self->arena); + if (upb_FieldDef_IsMap(f)) { + upb_Map* map = upb_Message_Mutable(msg, f, arena).map; + const upb_FieldDef* key_f = map_field_key(f); + const upb_FieldDef* val_f = map_field_value(f); + upb_CType key_type = upb_FieldDef_CType(key_f); TypeInfo value_type_info = TypeInfo_get(val_f); return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena); - } else if (upb_fielddef_isseq(f)) { - upb_array *arr = upb_msg_mutable(msg, f, arena).array; + } else if (upb_FieldDef_IsRepeated(f)) { + upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena); - } else if (upb_fielddef_issubmsg(f)) { - if (!upb_msg_has(self->msg, f)) return Qnil; - upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg; - const upb_msgdef *m = upb_fielddef_msgsubdef(f); + } else if (upb_FieldDef_IsSubMessage(f)) { + if (!upb_Message_Has(self->msg, f)) return Qnil; + upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); return Message_GetRubyWrapper(submsg, m, self->arena); } else { - upb_msgval msgval = upb_msg_get(self->msg, f); + upb_MessageValue msgval = upb_Message_Get(self->msg, f); return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena); } } -static VALUE Message_field_accessor(VALUE _self, const upb_fielddef* f, +static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f, int accessor_type, int argc, VALUE* argv) { - upb_arena *arena = Arena_get(Message_GetArena(_self)); + upb_Arena* arena = Arena_get(Message_GetArena(_self)); switch (accessor_type) { case METHOD_SETTER: Message_setfield(Message_GetMutable(_self, NULL), f, argv[1], arena); return Qnil; case METHOD_CLEAR: - upb_msg_clearfield(Message_GetMutable(_self, NULL), f); + upb_Message_ClearField(Message_GetMutable(_self, NULL), f); return Qnil; case METHOD_PRESENCE: - if (!upb_fielddef_haspresence(f)) { + if (!upb_FieldDef_HasPresence(f)) { rb_raise(rb_eRuntimeError, "Field does not have presence."); } - return upb_msg_has(Message_Get(_self, NULL), f); + return upb_Message_Has(Message_Get(_self, NULL), f); case METHOD_WRAPPER_GETTER: { Message* self = ruby_to_Message(_self); - if (upb_msg_has(self->msg, f)) { - PBRUBY_ASSERT(upb_fielddef_issubmsg(f) && !upb_fielddef_isseq(f)); - upb_msgval wrapper = upb_msg_get(self->msg, f); - const upb_msgdef *wrapper_m = upb_fielddef_msgsubdef(f); - const upb_fielddef *value_f = upb_msgdef_itof(wrapper_m, 1); - upb_msgval value = upb_msg_get(wrapper.msg_val, value_f); + if (upb_Message_Has(self->msg, f)) { + PBRUBY_ASSERT(upb_FieldDef_IsSubMessage(f) && + !upb_FieldDef_IsRepeated(f)); + upb_MessageValue wrapper = upb_Message_Get(self->msg, f); + const upb_MessageDef* wrapper_m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* value_f = + upb_MessageDef_FindFieldByNumberWithSize(wrapper_m, 1); + upb_MessageValue value = upb_Message_Get(wrapper.msg_val, value_f); return Convert_UpbToRuby(value, TypeInfo_get(value_f), self->arena); } else { return Qnil; } } case METHOD_WRAPPER_SETTER: { - upb_msg *msg = Message_GetMutable(_self, NULL); + upb_Message* msg = Message_GetMutable(_self, NULL); if (argv[1] == Qnil) { - upb_msg_clearfield(msg, f); + upb_Message_ClearField(msg, f); } else { - const upb_fielddef *val_f = upb_msgdef_itof(upb_fielddef_msgsubdef(f), 1); - upb_msgval msgval = Convert_RubyToUpb(argv[1], upb_fielddef_name(f), - TypeInfo_get(val_f), arena); - upb_msg *wrapper = upb_msg_mutable(msg, f, arena).msg; - upb_msg_set(wrapper, val_f, msgval, arena); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumberWithSize( + upb_FieldDef_MessageSubDef(f), 1); + upb_MessageValue msgval = Convert_RubyToUpb( + argv[1], upb_FieldDef_Name(f), TypeInfo_get(val_f), arena); + upb_Message* wrapper = upb_Message_Mutable(msg, f, arena).msg; + upb_Message_Set(wrapper, val_f, msgval, arena); } return Qnil; } case METHOD_ENUM_GETTER: { - upb_msgval msgval = upb_msg_get(Message_Get(_self, NULL), f); + upb_MessageValue msgval = upb_Message_Get(Message_Get(_self, NULL), f); - if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) { + if (upb_FieldDef_Label(f) == kUpb_Label_Repeated) { // Map repeated fields to a new type with ints VALUE arr = rb_ary_new(); - size_t i, n = upb_array_size(msgval.array_val); + size_t i, n = upb_Array_Size(msgval.array_val); for (i = 0; i < n; i++) { - upb_msgval elem = upb_array_get(msgval.array_val, i); + upb_MessageValue elem = upb_Array_Get(msgval.array_val, i); rb_ary_push(arr, INT2NUM(elem.int32_val)); } return arr; @@ -415,8 +439,8 @@ static VALUE Message_field_accessor(VALUE _self, const upb_fielddef* f, */ static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { Message* self = ruby_to_Message(_self); - const upb_oneofdef* o; - const upb_fielddef* f; + const upb_OneofDef* o; + const upb_FieldDef* f; int accessor_type; if (argc < 1) { @@ -453,8 +477,8 @@ static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { static VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) { Message* self = ruby_to_Message(_self); - const upb_oneofdef* o; - const upb_fielddef* f; + const upb_OneofDef* o; + const upb_FieldDef* f; int accessor_type; if (argc < 1) { @@ -472,53 +496,56 @@ static VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) { } } -void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val, - upb_arena* arena); +void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val, + upb_Arena* arena); typedef struct { - upb_map *map; + upb_Map* map; TypeInfo key_type; TypeInfo val_type; - upb_arena *arena; + upb_Arena* arena; } MapInit; static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { - MapInit *map_init = (MapInit*)_self; - upb_msgval k, v; + MapInit* map_init = (MapInit*)_self; + upb_MessageValue k, v; k = Convert_RubyToUpb(key, "", map_init->key_type, NULL); - if (map_init->val_type.type == UPB_TYPE_MESSAGE && TYPE(val) == T_HASH) { - upb_msg *msg = upb_msg_new(map_init->val_type.def.msgdef, map_init->arena); + if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) { + upb_Message* msg = + upb_Message_New(map_init->val_type.def.msgdef, map_init->arena); Message_InitFromValue(msg, map_init->val_type.def.msgdef, val, map_init->arena); v.msg_val = msg; } else { v = Convert_RubyToUpb(val, "", map_init->val_type, map_init->arena); } - upb_map_set(map_init->map, k, v, map_init->arena); + upb_Map_Set(map_init->map, k, v, map_init->arena); return ST_CONTINUE; } -static void Map_InitFromValue(upb_map* map, const upb_fielddef* f, VALUE val, - upb_arena* arena) { - const upb_msgdef* entry_m = upb_fielddef_msgsubdef(f); - const upb_fielddef* key_f = upb_msgdef_itof(entry_m, 1); - const upb_fielddef* val_f = upb_msgdef_itof(entry_m, 2); +static void Map_InitFromValue(upb_Map* map, const upb_FieldDef* f, VALUE val, + upb_Arena* arena) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 1); + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 2); if (TYPE(val) != T_HASH) { rb_raise(rb_eArgError, "Expected Hash object as initializer value for map field '%s' " "(given %s).", - upb_fielddef_name(f), rb_class2name(CLASS_OF(val))); + upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val))); } MapInit map_init = {map, TypeInfo_get(key_f), TypeInfo_get(val_f), arena}; rb_hash_foreach(val, Map_initialize_kwarg, (VALUE)&map_init); } -static upb_msgval MessageValue_FromValue(VALUE val, TypeInfo info, - upb_arena* arena) { - if (info.type == UPB_TYPE_MESSAGE) { - upb_msgval msgval; - upb_msg* msg = upb_msg_new(info.def.msgdef, arena); +static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info, + upb_Arena* arena) { + if (info.type == kUpb_CType_Message) { + upb_MessageValue msgval; + upb_Message* msg = upb_Message_New(info.def.msgdef, arena); Message_InitFromValue(msg, info.def.msgdef, val, arena); msgval.msg_val = msg; return msgval; @@ -527,61 +554,62 @@ static upb_msgval MessageValue_FromValue(VALUE val, TypeInfo info, } } -static void RepeatedField_InitFromValue(upb_array* arr, const upb_fielddef* f, - VALUE val, upb_arena* arena) { +static void RepeatedField_InitFromValue(upb_Array* arr, const upb_FieldDef* f, + VALUE val, upb_Arena* arena) { TypeInfo type_info = TypeInfo_get(f); if (TYPE(val) != T_ARRAY) { rb_raise(rb_eArgError, - "Expected array as initializer value for repeated field '%s' (given %s).", - upb_fielddef_name(f), rb_class2name(CLASS_OF(val))); + "Expected array as initializer value for repeated field '%s' " + "(given %s).", + upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val))); } for (int i = 0; i < RARRAY_LEN(val); i++) { VALUE entry = rb_ary_entry(val, i); - upb_msgval msgval; - if (upb_fielddef_issubmsg(f) && TYPE(entry) == T_HASH) { + upb_MessageValue msgval; + if (upb_FieldDef_IsSubMessage(f) && TYPE(entry) == T_HASH) { msgval = MessageValue_FromValue(entry, type_info, arena); } else { - msgval = Convert_RubyToUpb(entry, upb_fielddef_name(f), type_info, arena); + msgval = Convert_RubyToUpb(entry, upb_FieldDef_Name(f), type_info, arena); } - upb_array_append(arr, msgval, arena); + upb_Array_Append(arr, msgval, arena); } } -static void Message_InitFieldFromValue(upb_msg* msg, const upb_fielddef* f, - VALUE val, upb_arena* arena) { +static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f, + VALUE val, upb_Arena* arena) { if (TYPE(val) == T_NIL) return; - if (upb_fielddef_ismap(f)) { - upb_map *map = upb_msg_mutable(msg, f, arena).map; + if (upb_FieldDef_IsMap(f)) { + upb_Map* map = upb_Message_Mutable(msg, f, arena).map; Map_InitFromValue(map, f, val, arena); - } else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) { - upb_array *arr = upb_msg_mutable(msg, f, arena).array; + } else if (upb_FieldDef_Label(f) == kUpb_Label_Repeated) { + upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; RepeatedField_InitFromValue(arr, f, val, arena); - } else if (upb_fielddef_issubmsg(f)) { + } else if (upb_FieldDef_IsSubMessage(f)) { if (TYPE(val) == T_HASH) { - upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg; - Message_InitFromValue(submsg, upb_fielddef_msgsubdef(f), val, arena); + upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + Message_InitFromValue(submsg, upb_FieldDef_MessageSubDef(f), val, arena); } else { Message_setfield(msg, f, val, arena); } } else { - upb_msgval msgval = - Convert_RubyToUpb(val, upb_fielddef_name(f), TypeInfo_get(f), arena); - upb_msg_set(msg, f, msgval, arena); + upb_MessageValue msgval = + Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + upb_Message_Set(msg, f, msgval, arena); } } typedef struct { - upb_msg *msg; - const upb_msgdef *msgdef; - upb_arena *arena; + upb_Message* msg; + const upb_MessageDef* msgdef; + upb_Arena* arena; } MsgInit; static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { - MsgInit *msg_init = (MsgInit*)_self; - const char *name; + MsgInit* msg_init = (MsgInit*)_self; + const char* name; if (TYPE(key) == T_STRING) { name = RSTRING_PTR(key); @@ -589,10 +617,12 @@ static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { name = RSTRING_PTR(rb_id2str(SYM2ID(key))); } else { rb_raise(rb_eArgError, - "Expected string or symbols as hash keys when initializing proto from hash."); + "Expected string or symbols as hash keys when initializing proto " + "from hash."); } - const upb_fielddef* f = upb_msgdef_ntofz(msg_init->msgdef, name); + const upb_FieldDef* f = + upb_MessageDef_FindFieldByName(msg_init->msgdef, name); if (f == NULL) { rb_raise(rb_eArgError, @@ -603,8 +633,8 @@ static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { return ST_CONTINUE; } -void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val, - upb_arena* arena) { +void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val, + upb_Arena* arena) { MsgInit msg_init = {msg, m, arena}; if (TYPE(val) == T_HASH) { rb_hash_foreach(val, Message_initialize_kwarg, (VALUE)&msg_init); @@ -629,8 +659,8 @@ void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val, static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) { Message* self = ruby_to_Message(_self); VALUE arena_rb = Arena_new(); - upb_arena *arena = Arena_get(arena_rb); - upb_msg *msg = upb_msg_new(self->msgdef, arena); + upb_Arena* arena = Arena_get(arena_rb); + upb_Message* msg = upb_Message_New(self->msgdef, arena); Message_InitPtr(_self, msg, arena_rb); @@ -640,7 +670,7 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) { if (argc != 1) { rb_raise(rb_eArgError, "Expected 0 or 1 arguments."); } - Message_InitFromValue((upb_msg*)self->msg, self->msgdef, argv[0], arena); + Message_InitFromValue((upb_Message*)self->msg, self->msgdef, argv[0], arena); return Qnil; } @@ -654,34 +684,35 @@ static VALUE Message_dup(VALUE _self) { Message* self = ruby_to_Message(_self); VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self)); Message* new_msg_self = ruby_to_Message(new_msg); - size_t size = upb_msgdef_layout(self->msgdef)->size; + size_t size = upb_MessageDef_MiniTable(self->msgdef)->size; // TODO(copy unknown fields?) // TODO(use official upb msg copy function) - memcpy((upb_msg*)new_msg_self->msg, self->msg, size); + memcpy((upb_Message*)new_msg_self->msg, self->msg, size); Arena_fuse(self->arena, Arena_get(new_msg_self->arena)); return new_msg; } // Support function for Message_eq, and also used by other #eq functions. -bool Message_Equal(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) { +bool Message_Equal(const upb_Message* m1, const upb_Message* m2, + const upb_MessageDef* m) { if (m1 == m2) return true; size_t size1, size2; - int encode_opts = UPB_ENCODE_SKIPUNKNOWN | UPB_ENCODE_DETERMINISTIC; - upb_arena *arena_tmp = upb_arena_new(); - const upb_msglayout *layout = upb_msgdef_layout(m); + int encode_opts = kUpb_Encode_SkipUnknown | kUpb_Encode_Deterministic; + upb_Arena* arena_tmp = upb_Arena_New(); + const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); // Compare deterministically serialized payloads with no unknown fields. - char *data1 = upb_encode_ex(m1, layout, encode_opts, arena_tmp, &size1); - char *data2 = upb_encode_ex(m2, layout, encode_opts, arena_tmp, &size2); + char* data1 = upb_Encode(m1, layout, encode_opts, arena_tmp, &size1); + char* data2 = upb_Encode(m2, layout, encode_opts, arena_tmp, &size2); if (data1 && data2) { bool ret = (size1 == size2) && (memcmp(data1, data2, size1) == 0); - upb_arena_free(arena_tmp); + upb_Arena_Free(arena_tmp); return ret; } else { - upb_arena_free(arena_tmp); + upb_Arena_Free(arena_tmp); rb_raise(cParseError, "Error comparing messages"); } } @@ -705,22 +736,23 @@ static VALUE Message_eq(VALUE _self, VALUE _other) { return Message_Equal(self->msg, other->msg, self->msgdef) ? Qtrue : Qfalse; } -uint64_t Message_Hash(const upb_msg* msg, const upb_msgdef* m, uint64_t seed) { - upb_arena *arena = upb_arena_new(); - const char *data; +uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed) { + upb_Arena* arena = upb_Arena_New(); + const char* data; size_t size; // Hash a deterministically serialized payloads with no unknown fields. - data = upb_encode_ex(msg, upb_msgdef_layout(m), - UPB_ENCODE_SKIPUNKNOWN | UPB_ENCODE_DETERMINISTIC, arena, - &size); + data = upb_Encode(msg, upb_MessageDef_MiniTable(m), + kUpb_Encode_SkipUnknown | kUpb_Encode_Deterministic, arena, + &size); if (data) { uint64_t ret = Wyhash(data, size, seed, kWyhashSalt); - upb_arena_free(arena); + upb_Arena_Free(arena); return ret; } else { - upb_arena_free(arena); + upb_Arena_Free(arena); rb_raise(cParseError, "Error calculating hash"); } } @@ -759,13 +791,13 @@ static VALUE Message_inspect(VALUE _self) { // Support functions for Message_to_h ////////////////////////////////////////// -static VALUE RepeatedField_CreateArray(const upb_array* arr, +static VALUE RepeatedField_CreateArray(const upb_Array* arr, TypeInfo type_info) { - int size = arr ? upb_array_size(arr) : 0; + int size = arr ? upb_Array_Size(arr) : 0; VALUE ary = rb_ary_new2(size); for (int i = 0; i < size; i++) { - upb_msgval msgval = upb_array_get(arr, i); + upb_MessageValue msgval = upb_Array_Get(arr, i); VALUE val = Scalar_CreateHash(msgval, type_info); rb_ary_push(ary, val); } @@ -773,54 +805,57 @@ static VALUE RepeatedField_CreateArray(const upb_array* arr, return ary; } -static VALUE Message_CreateHash(const upb_msg *msg, const upb_msgdef *m) { +static VALUE Message_CreateHash(const upb_Message* msg, + const upb_MessageDef* m) { if (!msg) return Qnil; VALUE hash = rb_hash_new(); - int n = upb_msgdef_fieldcount(m); + int n = upb_MessageDef_FieldCount(m); bool is_proto2; // 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(m) == UPB_SYNTAX_PROTO2; + is_proto2 = upb_MessageDef_Syntax(m) == kUpb_Syntax_Proto2; for (int i = 0; i < n; i++) { - const upb_fielddef* field = upb_msgdef_field(m, i); + const upb_FieldDef* field = upb_MessageDef_Field(m, i); TypeInfo type_info = TypeInfo_get(field); - upb_msgval msgval; + upb_MessageValue msgval; VALUE msg_value; VALUE msg_key; - if (!is_proto2 && upb_fielddef_issubmsg(field) && - !upb_fielddef_isseq(field) && !upb_msg_has(msg, field)) { + if (!is_proto2 && upb_FieldDef_IsSubMessage(field) && + !upb_FieldDef_IsRepeated(field) && !upb_Message_Has(msg, field)) { // TODO: Legacy behavior, remove when we fix the is_proto2 differences. - msg_key = ID2SYM(rb_intern(upb_fielddef_name(field))); + msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field))); rb_hash_aset(hash, msg_key, Qnil); continue; } // Do not include fields that are not present (oneof or optional fields). - if (is_proto2 && upb_fielddef_haspresence(field) && - !upb_msg_has(msg, field)) { + if (is_proto2 && upb_FieldDef_HasPresence(field) && + !upb_Message_Has(msg, field)) { continue; } - msg_key = ID2SYM(rb_intern(upb_fielddef_name(field))); - msgval = upb_msg_get(msg, field); + msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field))); + msgval = upb_Message_Get(msg, field); // Proto2 omits empty map/repeated filds also. - if (upb_fielddef_ismap(field)) { - const upb_msgdef *entry_m = upb_fielddef_msgsubdef(field); - const upb_fielddef *key_f = upb_msgdef_itof(entry_m, 1); - const upb_fielddef *val_f = upb_msgdef_itof(entry_m, 2); - upb_fieldtype_t key_type = upb_fielddef_type(key_f); + if (upb_FieldDef_IsMap(field)) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field); + const upb_FieldDef* key_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 1); + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 2); + upb_CType key_type = upb_FieldDef_CType(key_f); msg_value = Map_CreateHash(msgval.map_val, key_type, TypeInfo_get(val_f)); - } else if (upb_fielddef_isseq(field)) { + } else if (upb_FieldDef_IsRepeated(field)) { if (is_proto2 && - (!msgval.array_val || upb_array_size(msgval.array_val) == 0)) { + (!msgval.array_val || upb_Array_Size(msgval.array_val) == 0)) { continue; } msg_value = RepeatedField_CreateArray(msgval.array_val, type_info); @@ -834,8 +869,8 @@ static VALUE Message_CreateHash(const upb_msg *msg, const upb_msgdef *m) { return hash; } -VALUE Scalar_CreateHash(upb_msgval msgval, TypeInfo type_info) { - if (type_info.type == UPB_TYPE_MESSAGE) { +VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) { + if (type_info.type == kUpb_CType_Message) { return Message_CreateHash(msgval.msg_val, type_info.def.msgdef); } else { return Convert_UpbToRuby(msgval, type_info, Qnil); @@ -878,10 +913,10 @@ static VALUE Message_freeze(VALUE _self) { */ static VALUE Message_index(VALUE _self, VALUE field_name) { Message* self = ruby_to_Message(_self); - const upb_fielddef* field; + const upb_FieldDef* field; Check_Type(field_name, T_STRING); - field = upb_msgdef_ntofz(self->msgdef, RSTRING_PTR(field_name)); + field = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name)); if (field == NULL) { return Qnil; @@ -899,19 +934,19 @@ static VALUE Message_index(VALUE _self, VALUE field_name) { */ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) { Message* self = ruby_to_Message(_self); - const upb_fielddef* f; - upb_msgval val; - upb_arena *arena = Arena_get(self->arena); + const upb_FieldDef* f; + upb_MessageValue val; + upb_Arena* arena = Arena_get(self->arena); Check_Type(field_name, T_STRING); - f = upb_msgdef_ntofz(self->msgdef, RSTRING_PTR(field_name)); + f = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name)); if (f == NULL) { rb_raise(rb_eArgError, "Unknown field: %s", RSTRING_PTR(field_name)); } - val = Convert_RubyToUpb(value, upb_fielddef_name(f), TypeInfo_get(f), arena); - upb_msg_set(Message_GetMutable(_self, NULL), f, val, arena); + val = Convert_RubyToUpb(value, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + upb_Message_Set(Message_GetMutable(_self, NULL), f, val, arena); return Qnil; } @@ -932,9 +967,11 @@ static VALUE Message_decode(VALUE klass, VALUE data) { VALUE msg_rb = initialize_rb_class_with_no_args(klass); Message* msg = ruby_to_Message(msg_rb); - if (!upb_decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_msg*)msg->msg, - upb_msgdef_layout(msg->msgdef), - Arena_get(msg->arena))) { + upb_DecodeStatus status = upb_Decode( + RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg, + upb_MessageDef_MiniTable(msg->msgdef), NULL, 0, Arena_get(msg->arena)); + + if (status != kUpb_DecodeStatus_Ok) { rb_raise(cParseError, "Error occurred during parsing"); } @@ -956,10 +993,10 @@ static VALUE Message_decode(VALUE klass, VALUE data) { static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { VALUE data = argv[0]; int options = 0; - upb_status status; + upb_Status status; // TODO(haberman): use this message's pool instead. - const upb_symtab *symtab = DescriptorPool_GetSymtab(generated_pool); + const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool); if (argc < 1 || argc > 2) { rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); @@ -971,8 +1008,9 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { rb_raise(rb_eArgError, "Expected hash arguments."); } - if (RTEST(rb_hash_lookup2( hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse))) { - options |= UPB_JSONDEC_IGNOREUNKNOWN; + if (RTEST(rb_hash_lookup2( + hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse))) { + options |= upb_JsonDecode_IgnoreUnknown; } } @@ -988,16 +1026,16 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { Message* msg = ruby_to_Message(msg_rb); // We don't allow users to decode a wrapper type directly. - if (upb_msgdef_iswrapper(msg->msgdef)) { + if (IsWrapper(msg->msgdef)) { rb_raise(rb_eRuntimeError, "Cannot parse a wrapper directly."); } - upb_status_clear(&status); - if (!upb_json_decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_msg*)msg->msg, - msg->msgdef, symtab, options, - Arena_get(msg->arena), &status)) { + upb_Status_Clear(&status); + if (!upb_JsonDecode(RSTRING_PTR(data), RSTRING_LEN(data), + (upb_Message*)msg->msg, msg->msgdef, symtab, options, + Arena_get(msg->arena), &status)) { rb_raise(cParseError, "Error occurred during parsing: %s", - upb_status_errmsg(&status)); + upb_Status_ErrorMessage(&status)); } return msg_rb; @@ -1012,24 +1050,25 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { */ static VALUE Message_encode(VALUE klass, VALUE msg_rb) { Message* msg = ruby_to_Message(msg_rb); - upb_arena *arena = upb_arena_new(); - const char *data; + const char* data; size_t size; if (CLASS_OF(msg_rb) != klass) { rb_raise(rb_eArgError, "Message of wrong type."); } - data = upb_encode(msg->msg, upb_msgdef_layout(msg->msgdef), arena, + upb_Arena* arena = upb_Arena_New(); + + data = upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), 0, arena, &size); if (data) { VALUE ret = rb_str_new(data, size); rb_enc_associate(ret, rb_ascii8bit_encoding()); - upb_arena_free(arena); + upb_Arena_Free(arena); return ret; } else { - upb_arena_free(arena); + upb_Arena_Free(arena); rb_raise(rb_eRuntimeError, "Exceeded maximum depth (possibly cycle)"); } } @@ -1040,18 +1079,19 @@ static VALUE Message_encode(VALUE klass, VALUE msg_rb) { * * Encodes the given message object into its serialized JSON representation. * @param options [Hash] options for the decoder - * preserve_proto_fieldnames: set true to use original fieldnames (default is to camelCase) - * emit_defaults: set true to emit 0/false values (default is to omit them) + * preserve_proto_fieldnames: set true to use original fieldnames (default is + * to camelCase) emit_defaults: set true to emit 0/false values (default is to + * omit them) */ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) { Message* msg = ruby_to_Message(argv[0]); int options = 0; char buf[1024]; size_t size; - upb_status status; + upb_Status status; // TODO(haberman): use this message's pool instead. - const upb_symtab *symtab = DescriptorPool_GetSymtab(generated_pool); + const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool); if (argc < 1 || argc > 2) { rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); @@ -1066,29 +1106,29 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) { if (RTEST(rb_hash_lookup2(hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse))) { - options |= UPB_JSONENC_PROTONAMES; + options |= upb_JsonEncode_UseProtoNames; } if (RTEST(rb_hash_lookup2(hash_args, ID2SYM(rb_intern("emit_defaults")), Qfalse))) { - options |= UPB_JSONENC_EMITDEFAULTS; + options |= upb_JsonEncode_EmitDefaults; } } - upb_status_clear(&status); - size = upb_json_encode(msg->msg, msg->msgdef, symtab, options, buf, - sizeof(buf), &status); + upb_Status_Clear(&status); + size = upb_JsonEncode(msg->msg, msg->msgdef, symtab, options, buf, + sizeof(buf), &status); - if (!upb_ok(&status)) { + if (!upb_Status_IsOk(&status)) { rb_raise(cParseError, "Error occurred during encoding: %s", - upb_status_errmsg(&status)); + upb_Status_ErrorMessage(&status)); } VALUE ret; if (size >= sizeof(buf)) { char* buf2 = malloc(size + 1); - upb_json_encode(msg->msg, msg->msgdef, symtab, options, buf2, size + 1, - &status); + upb_JsonEncode(msg->msg, msg->msgdef, symtab, options, buf2, size + 1, + &status); ret = rb_str_new(buf2, size); free(buf2); } else { @@ -1111,10 +1151,10 @@ static VALUE Message_descriptor(VALUE klass) { } VALUE build_class_from_descriptor(VALUE descriptor) { - const char *name; + const char* name; VALUE klass; - name = upb_msgdef_fullname(Descriptor_GetMsgDef(descriptor)); + name = upb_MessageDef_FullName(Descriptor_GetMsgDef(descriptor)); if (name == NULL) { rb_raise(rb_eRuntimeError, "Descriptor does not have assigned name."); } @@ -1122,8 +1162,7 @@ VALUE build_class_from_descriptor(VALUE descriptor) { klass = rb_define_class_id( // Docs say this parameter is ignored. User will assign return value to // their own toplevel constant class name. - rb_intern("Message"), - rb_cObject); + rb_intern("Message"), rb_cObject); rb_ivar_set(klass, descriptor_instancevar_interned, descriptor); rb_define_alloc_func(klass, Message_alloc); rb_require("google/protobuf/message_exts"); @@ -1131,10 +1170,9 @@ VALUE build_class_from_descriptor(VALUE descriptor) { rb_extend_object( klass, rb_eval_string("::Google::Protobuf::MessageExts::ClassMethods")); - rb_define_method(klass, "method_missing", - Message_method_missing, -1); - rb_define_method(klass, "respond_to_missing?", - Message_respond_to_missing, -1); + rb_define_method(klass, "method_missing", Message_method_missing, -1); + rb_define_method(klass, "respond_to_missing?", Message_respond_to_missing, + -1); rb_define_method(klass, "initialize", Message_initialize, -1); rb_define_method(klass, "dup", Message_dup, 0); // Also define #clone so that we don't inherit Object#clone. @@ -1167,13 +1205,12 @@ VALUE build_class_from_descriptor(VALUE descriptor) { static VALUE enum_lookup(VALUE self, VALUE number) { int32_t num = NUM2INT(number); VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned); - const upb_enumdef *e = EnumDescriptor_GetEnumDef(desc); - - const char* name = upb_enumdef_iton(e, num); - if (name == NULL) { - return Qnil; + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e, num); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); } else { - return ID2SYM(rb_intern(name)); + return Qnil; } } @@ -1187,14 +1224,12 @@ static VALUE enum_lookup(VALUE self, VALUE number) { static VALUE enum_resolve(VALUE self, VALUE sym) { const char* name = rb_id2name(SYM2ID(sym)); VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned); - const upb_enumdef *e = EnumDescriptor_GetEnumDef(desc); - - int32_t num = 0; - bool found = upb_enumdef_ntoiz(e, name, &num); - if (!found) { - return Qnil; + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByName(e, name); + if (ev) { + return INT2NUM(upb_EnumValueDef_Number(ev)); } else { - return INT2NUM(num); + return Qnil; } } @@ -1210,19 +1245,19 @@ static VALUE enum_descriptor(VALUE self) { } VALUE build_module_from_enumdesc(VALUE _enumdesc) { - const upb_enumdef *e = EnumDescriptor_GetEnumDef(_enumdesc); - VALUE mod = rb_define_module_id(rb_intern(upb_enumdef_fullname(e))); - - upb_enum_iter it; - for (upb_enum_begin(&it, e); - !upb_enum_done(&it); - upb_enum_next(&it)) { - const char* name = upb_enum_iter_name(&it); - int32_t value = upb_enum_iter_number(&it); + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(_enumdesc); + VALUE mod = rb_define_module_id(rb_intern(upb_EnumDef_FullName(e))); + + int n = upb_EnumDef_ValueCount(e); + for (int i = 0; i < n; i++) { + const upb_EnumValueDef* ev = upb_EnumDef_Value(e, i); + const char* name = upb_EnumValueDef_Name(ev); + int32_t value = upb_EnumValueDef_Number(ev); if (name[0] < 'A' || name[0] > 'Z') { - rb_warn("Enum value '%s' does not start with an uppercase letter " - "as is required for Ruby constants.", - name); + rb_warn( + "Enum value '%s' does not start with an uppercase letter " + "as is required for Ruby constants.", + name); } rb_define_const(mod, name, INT2NUM(value)); } @@ -1236,80 +1271,84 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc) { } // Internal only; used by Google::Protobuf.deep_copy. -upb_msg* Message_deep_copy(const upb_msg* msg, const upb_msgdef* m, - upb_arena *arena) { +upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, + upb_Arena* arena) { // Serialize and parse. - upb_arena *tmp_arena = upb_arena_new(); - const upb_msglayout *layout = upb_msgdef_layout(m); + upb_Arena* tmp_arena = upb_Arena_New(); + const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); size_t size; - char* data = upb_encode_ex(msg, layout, 0, tmp_arena, &size); - upb_msg* new_msg = upb_msg_new(m, arena); + char* data = upb_Encode(msg, layout, 0, tmp_arena, &size); + upb_Message* new_msg = upb_Message_New(m, arena); - if (!data || !upb_decode(data, size, new_msg, layout, arena)) { - upb_arena_free(tmp_arena); + if (!data || upb_Decode(data, size, new_msg, layout, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + upb_Arena_Free(tmp_arena); rb_raise(cParseError, "Error occurred copying proto"); } - upb_arena_free(tmp_arena); + upb_Arena_Free(tmp_arena); return new_msg; } -const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m, - const char* name, upb_arena* arena) { +const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, + const char* name, upb_Arena* arena) { if (value == Qnil) { rb_raise(cTypeError, "nil message not allowed here."); } VALUE klass = CLASS_OF(value); VALUE desc_rb = rb_ivar_get(klass, descriptor_instancevar_interned); - const upb_msgdef* val_m = + const upb_MessageDef* val_m = desc_rb == Qnil ? NULL : Descriptor_GetMsgDef(desc_rb); if (val_m != m) { // Check for possible implicit conversions // TODO: hash conversion? - switch (upb_msgdef_wellknowntype(m)) { - case UPB_WELLKNOWN_TIMESTAMP: { + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Timestamp: { // Time -> Google::Protobuf::Timestamp - upb_msg *msg = upb_msg_new(m, arena); - upb_msgval sec, nsec; + upb_Message* msg = upb_Message_New(m, arena); + upb_MessageValue sec, nsec; struct timespec time; - const upb_fielddef *sec_f = upb_msgdef_itof(m, 1); - const upb_fielddef *nsec_f = upb_msgdef_itof(m, 2); + const upb_FieldDef* sec_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_FieldDef* nsec_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 2); if (!rb_obj_is_kind_of(value, rb_cTime)) goto badtype; time = rb_time_timespec(value); sec.int64_val = time.tv_sec; nsec.int32_val = time.tv_nsec; - upb_msg_set(msg, sec_f, sec, arena); - upb_msg_set(msg, nsec_f, nsec, arena); + upb_Message_Set(msg, sec_f, sec, arena); + upb_Message_Set(msg, nsec_f, nsec, arena); return msg; } - case UPB_WELLKNOWN_DURATION: { + case kUpb_WellKnown_Duration: { // Numeric -> Google::Protobuf::Duration - upb_msg *msg = upb_msg_new(m, arena); - upb_msgval sec, nsec; - const upb_fielddef *sec_f = upb_msgdef_itof(m, 1); - const upb_fielddef *nsec_f = upb_msgdef_itof(m, 2); + upb_Message* msg = upb_Message_New(m, arena); + upb_MessageValue sec, nsec; + const upb_FieldDef* sec_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_FieldDef* nsec_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 2); if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype; sec.int64_val = NUM2LL(value); nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000); - upb_msg_set(msg, sec_f, sec, arena); - upb_msg_set(msg, nsec_f, nsec, arena); + upb_Message_Set(msg, sec_f, sec, arena); + upb_Message_Set(msg, nsec_f, nsec, arena); return msg; } default: badtype: rb_raise(cTypeError, "Invalid type %s to assign to submessage field '%s'.", - rb_class2name(CLASS_OF(value)), name); + rb_class2name(CLASS_OF(value)), name); } - } Message* self = ruby_to_Message(value); diff --git a/ruby/ext/google/protobuf_c/message.h b/ruby/ext/google/protobuf_c/message.h index 2ec440c869cc7..b409650ef8c9f 100644 --- a/ruby/ext/google/protobuf_c/message.h +++ b/ruby/ext/google/protobuf_c/message.h @@ -36,55 +36,58 @@ #include "protobuf.h" #include "ruby-upb.h" -// Gets the underlying upb_msg* and upb_msgdef for the given Ruby message -// wrapper. Requires that |value| is indeed a message object. -const upb_msg *Message_Get(VALUE value, const upb_msgdef **m); +// Gets the underlying upb_Message* and upb_MessageDef for the given Ruby +// message wrapper. Requires that |value| is indeed a message object. +const upb_Message* Message_Get(VALUE value, const upb_MessageDef** m); // Like Message_Get(), but checks that the object is not frozen and returns a // mutable pointer. -upb_msg *Message_GetMutable(VALUE value, const upb_msgdef **m); +upb_Message* Message_GetMutable(VALUE value, const upb_MessageDef** m); // Returns the Arena object for this message. VALUE Message_GetArena(VALUE value); -// Converts |value| into a upb_msg value of the expected upb_msgdef type, -// raising an error if this is not possible. Used when assigning |value| to a -// field of another message, which means the message must be of a particular -// type. +// Converts |value| into a upb_Message value of the expected upb_MessageDef +// type, raising an error if this is not possible. Used when assigning |value| +// to a field of another message, which means the message must be of a +// particular type. // // This will perform automatic conversions in some cases (for example, Time -> // Google::Protobuf::Timestamp). If any new message is created, it will be // created on |arena|, and any existing message will have its arena fused with // |arena|. -const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m, - const char* name, upb_arena* arena); +const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, + const char* name, upb_Arena* arena); // Gets or constructs a Ruby wrapper object for the given message. The wrapper // object will reference |arena| and ensure that it outlives this object. -VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena); +VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m, + VALUE arena); // Gets the given field from this message. -VALUE Message_getfield(VALUE _self, const upb_fielddef* f); +VALUE Message_getfield(VALUE _self, const upb_FieldDef* f); // Implements #inspect for this message, printing the text to |b|. -void Message_PrintMessage(StringBuilder* b, const upb_msg* msg, - const upb_msgdef* m); +void Message_PrintMessage(StringBuilder* b, const upb_Message* msg, + const upb_MessageDef* m); // Returns a hash value for the given message. -uint64_t Message_Hash(const upb_msg *msg, const upb_msgdef *m, uint64_t seed); +uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed); // Returns a deep copy of the given message. -upb_msg* Message_deep_copy(const upb_msg* msg, const upb_msgdef* m, - upb_arena *arena); +upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, + upb_Arena* arena); // Returns true if these two messages are equal. -bool Message_Equal(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m); +bool Message_Equal(const upb_Message* m1, const upb_Message* m2, + const upb_MessageDef* m); // Checks that this Ruby object is a message, and raises an exception if not. void Message_CheckClass(VALUE klass); // Returns a new Hash object containing the contents of this message. -VALUE Scalar_CreateHash(upb_msgval val, TypeInfo type_info); +VALUE Scalar_CreateHash(upb_MessageValue val, TypeInfo type_info); // Creates a message class or enum module for this descriptor, respectively. VALUE build_class_from_descriptor(VALUE descriptor); diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c index a61328b442e6e..4d3e1a51448e9 100644 --- a/ruby/ext/google/protobuf_c/protobuf.c +++ b/ruby/ext/google/protobuf_c/protobuf.c @@ -40,14 +40,14 @@ VALUE cParseError; VALUE cTypeError; -const upb_fielddef* map_field_key(const upb_fielddef* field) { - const upb_msgdef *entry = upb_fielddef_msgsubdef(field); - return upb_msgdef_itof(entry, 1); +const upb_FieldDef *map_field_key(const upb_FieldDef *field) { + const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field); + return upb_MessageDef_FindFieldByNumberWithSize(entry, 1); } -const upb_fielddef* map_field_value(const upb_fielddef* field) { - const upb_msgdef *entry = upb_fielddef_msgsubdef(field); - return upb_msgdef_itof(entry, 2); +const upb_FieldDef *map_field_value(const upb_FieldDef *field) { + const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field); + return upb_MessageDef_FindFieldByNumberWithSize(entry, 2); } // ----------------------------------------------------------------------------- @@ -66,21 +66,21 @@ static size_t StringBuilder_SizeOf(size_t cap) { return sizeof(StringBuilder) + cap; } -StringBuilder* StringBuilder_New() { +StringBuilder *StringBuilder_New() { const size_t cap = 128; - StringBuilder* builder = malloc(sizeof(*builder)); + StringBuilder *builder = malloc(sizeof(*builder)); builder->size = 0; builder->cap = cap; builder->data = malloc(builder->cap); return builder; } -void StringBuilder_Free(StringBuilder* b) { +void StringBuilder_Free(StringBuilder *b) { free(b->data); free(b); } -void StringBuilder_Printf(StringBuilder* b, const char *fmt, ...) { +void StringBuilder_Printf(StringBuilder *b, const char *fmt, ...) { size_t have = b->cap - b->size; size_t n; va_list args; @@ -104,60 +104,62 @@ void StringBuilder_Printf(StringBuilder* b, const char *fmt, ...) { b->size += n; } -VALUE StringBuilder_ToRubyString(StringBuilder* b) { +VALUE StringBuilder_ToRubyString(StringBuilder *b) { VALUE ret = rb_str_new(b->data, b->size); rb_enc_associate(ret, rb_utf8_encoding()); return ret; } -static void StringBuilder_PrintEnum(StringBuilder* b, int32_t val, - const upb_enumdef* e) { - const char *name = upb_enumdef_iton(e, val); - if (name) { - StringBuilder_Printf(b, ":%s", name); +static void StringBuilder_PrintEnum(StringBuilder *b, int32_t val, + const upb_EnumDef *e) { + const upb_EnumValueDef *ev = upb_EnumDef_FindValueByNumber(e, val); + if (ev) { + StringBuilder_Printf(b, ":%s", upb_EnumValueDef_Name(ev)); } else { StringBuilder_Printf(b, "%" PRId32, val); } } -void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val, +void StringBuilder_PrintMsgval(StringBuilder *b, upb_MessageValue val, TypeInfo info) { switch (info.type) { - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: StringBuilder_Printf(b, "%s", val.bool_val ? "true" : "false"); break; - case UPB_TYPE_FLOAT: { + case kUpb_CType_Float: { VALUE str = rb_inspect(DBL2NUM(val.float_val)); StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); break; } - case UPB_TYPE_DOUBLE: { + case kUpb_CType_Double: { VALUE str = rb_inspect(DBL2NUM(val.double_val)); StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); break; } - case UPB_TYPE_INT32: + case kUpb_CType_Int32: StringBuilder_Printf(b, "%" PRId32, val.int32_val); break; - case UPB_TYPE_UINT32: + case kUpb_CType_UInt32: StringBuilder_Printf(b, "%" PRIu32, val.uint32_val); break; - case UPB_TYPE_INT64: + case kUpb_CType_Int64: StringBuilder_Printf(b, "%" PRId64, val.int64_val); break; - case UPB_TYPE_UINT64: + case kUpb_CType_UInt64: StringBuilder_Printf(b, "%" PRIu64, val.uint64_val); break; - case UPB_TYPE_STRING: - StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, val.str_val.data); + case kUpb_CType_String: + StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, + val.str_val.data); break; - case UPB_TYPE_BYTES: - StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, val.str_val.data); + case kUpb_CType_Bytes: + StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, + val.str_val.data); break; - case UPB_TYPE_ENUM: + case kUpb_CType_Enum: StringBuilder_PrintEnum(b, val.int32_val, info.def.enumdef); break; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: Message_PrintMessage(b, val.msg_val, info.def.msgdef); break; } @@ -168,7 +170,7 @@ void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val, // ----------------------------------------------------------------------------- typedef struct { - upb_arena *arena; + upb_Arena *arena; VALUE pinned_objs; } Arena; @@ -179,44 +181,42 @@ static void Arena_mark(void *data) { static void Arena_free(void *data) { Arena *arena = data; - upb_arena_free(arena->arena); + upb_Arena_Free(arena->arena); xfree(arena); } static VALUE cArena; const rb_data_type_t Arena_type = { - "Google::Protobuf::Internal::Arena", - { Arena_mark, Arena_free, NULL }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::Internal::Arena", + {Arena_mark, Arena_free, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static VALUE Arena_alloc(VALUE klass) { Arena *arena = ALLOC(Arena); - arena->arena = upb_arena_new(); + arena->arena = upb_Arena_New(); arena->pinned_objs = Qnil; return TypedData_Wrap_Struct(klass, &Arena_type, arena); } -upb_arena *Arena_get(VALUE _arena) { +upb_Arena *Arena_get(VALUE _arena) { Arena *arena; TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); return arena->arena; } -void Arena_fuse(VALUE _arena, upb_arena *other) { +void Arena_fuse(VALUE _arena, upb_Arena *other) { Arena *arena; TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); - if (!upb_arena_fuse(arena->arena, other)) { + if (!upb_Arena_Fuse(arena->arena, other)) { rb_raise(rb_eRuntimeError, "Unable to fuse arenas. This should never happen since Ruby does " "not use initial blocks"); } } -VALUE Arena_new() { - return Arena_alloc(cArena); -} +VALUE Arena_new() { return Arena_alloc(cArena); } void Arena_Pin(VALUE _arena, VALUE obj) { Arena *arena; @@ -333,8 +333,8 @@ static void SecondaryMap_MaybeGC() { // avoid O(N^2) CPU costs. size_t threshold = PBRUBY_MAX(secondary_len * 0.2, 2000); if (waste > threshold) { - rb_funcall(gc_secondary_map_lambda, rb_intern("call"), 2, - secondary_map, weak_obj_cache); + rb_funcall(gc_secondary_map_lambda, rb_intern("call"), 2, secondary_map, + weak_obj_cache); } } @@ -353,7 +353,7 @@ static VALUE SecondaryMap_Get(VALUE key, bool create) { #endif // Requires: secondary_map_mutex is held by this thread iff create == true. -static VALUE ObjectCache_GetKey(const void* key, bool create) { +static VALUE ObjectCache_GetKey(const void *key, bool create) { VALUE key_val = (VALUE)key; PBRUBY_ASSERT((key_val & 3) == 0); VALUE ret = LL2NUM(key_val >> 2); @@ -380,7 +380,7 @@ static void ObjectCache_Init() { #endif } -void ObjectCache_Add(const void* key, VALUE val) { +void ObjectCache_Add(const void *key, VALUE val) { PBRUBY_ASSERT(ObjectCache_Get(key) == Qnil); #if USE_SECONDARY_MAP rb_mutex_lock(secondary_map_mutex); @@ -394,7 +394,7 @@ void ObjectCache_Add(const void* key, VALUE val) { } // Returns the cached object for this key, if any. Otherwise returns Qnil. -VALUE ObjectCache_Get(const void* key) { +VALUE ObjectCache_Get(const void *key) { VALUE key_rb = ObjectCache_GetKey(key, false); return rb_funcall(weak_obj_cache, item_get, 1, key_rb); } @@ -407,9 +407,9 @@ VALUE ObjectCache_Get(const void* key) { * unknown fields in submessages. */ static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) { - const upb_msgdef *m; - upb_msg *msg = Message_GetMutable(msg_rb, &m); - if (!upb_msg_discardunknown(msg, m, 128)) { + const upb_MessageDef *m; + upb_Message *msg = Message_GetMutable(msg_rb, &m); + if (!upb_Message_DiscardUnknown(msg, m, 128)) { rb_raise(rb_eRuntimeError, "Messages nested too deeply."); } @@ -431,10 +431,10 @@ VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) { return Map_deep_copy(obj); } else { VALUE new_arena_rb = Arena_new(); - upb_arena *new_arena = Arena_get(new_arena_rb); - const upb_msgdef *m; - const upb_msg *msg = Message_Get(obj, &m); - upb_msg* new_msg = Message_deep_copy(msg, m, new_arena); + upb_Arena *new_arena = Arena_get(new_arena_rb); + const upb_MessageDef *m; + const upb_Message *msg = Message_Get(obj, &m); + upb_Message *new_msg = Message_deep_copy(msg, m, new_arena); return Message_GetRubyWrapper(new_msg, m, new_arena_rb); } } @@ -445,8 +445,7 @@ VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) { // This must be named "Init_protobuf_c" because the Ruby module is named // "protobuf_c" -- the VM looks for this symbol in our .so. -__attribute__ ((visibility ("default"))) -void Init_protobuf_c() { +__attribute__((visibility("default"))) void Init_protobuf_c() { ObjectCache_Init(); VALUE google = rb_define_module("Google"); @@ -465,6 +464,6 @@ void Init_protobuf_c() { rb_define_singleton_method(protobuf, "discard_unknown", Google_Protobuf_discard_unknown, 1); - rb_define_singleton_method(protobuf, "deep_copy", - Google_Protobuf_deep_copy, 1); + rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy, + 1); } diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index f7ac2049d7096..c6af98fa47277 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -31,33 +31,33 @@ #ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ #define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ +#include #include #include -#include -#include "ruby-upb.h" #include "defs.h" +#include "ruby-upb.h" // These operate on a map field (i.e., a repeated field of submessages whose // submessage type is a map-entry msgdef). -const upb_fielddef* map_field_key(const upb_fielddef* field); -const upb_fielddef* map_field_value(const upb_fielddef* field); +const upb_FieldDef* map_field_key(const upb_FieldDef* field); +const upb_FieldDef* map_field_value(const upb_FieldDef* field); // ----------------------------------------------------------------------------- // Arena // ----------------------------------------------------------------------------- -// A Ruby object that wraps an underlying upb_arena. Any objects that are +// A Ruby object that wraps an underlying upb_Arena. Any objects that are // allocated from this arena should reference the Arena in rb_gc_mark(), to // ensure that the object's underlying memory outlives any Ruby object that can // reach it. VALUE Arena_new(); -upb_arena *Arena_get(VALUE arena); +upb_Arena* Arena_get(VALUE arena); // Fuses this arena to another, throwing a Ruby exception if this is not // possible. -void Arena_fuse(VALUE arena, upb_arena *other); +void Arena_fuse(VALUE arena, upb_Arena* other); // Pins this Ruby object to the lifetime of this arena, so that as long as the // arena is alive this object will not be collected. @@ -93,10 +93,11 @@ typedef struct StringBuilder StringBuilder; StringBuilder* StringBuilder_New(); void StringBuilder_Free(StringBuilder* b); -void StringBuilder_Printf(StringBuilder* b, const char *fmt, ...); +void StringBuilder_Printf(StringBuilder* b, const char* fmt, ...); VALUE StringBuilder_ToRubyString(StringBuilder* b); -void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val, TypeInfo info); +void StringBuilder_PrintMsgval(StringBuilder* b, upb_MessageValue val, + TypeInfo info); // ----------------------------------------------------------------------------- // Utilities. @@ -105,7 +106,9 @@ void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val, TypeInfo info); extern VALUE cTypeError; #ifdef NDEBUG -#define PBRUBY_ASSERT(expr) do {} while (false && (expr)) +#define PBRUBY_ASSERT(expr) \ + do { \ + } while (false && (expr)) #else #define PBRUBY_ASSERT(expr) assert(expr) #endif diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c index 5ff3c769ac911..700ca16f38a65 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.c +++ b/ruby/ext/google/protobuf_c/repeated_field.c @@ -40,10 +40,10 @@ // ----------------------------------------------------------------------------- typedef struct { - const upb_array *array; // Can get as mutable when non-frozen. + const upb_Array* array; // Can get as mutable when non-frozen. TypeInfo type_info; VALUE type_class; // To GC-root the msgdef/enumdef in type_info. - VALUE arena; // To GC-root the upb_array. + VALUE arena; // To GC-root the upb_Array. } RepeatedField; VALUE cRepeatedField; @@ -55,9 +55,9 @@ static void RepeatedField_mark(void* _self) { } const rb_data_type_t RepeatedField_type = { - "Google::Protobuf::RepeatedField", - { RepeatedField_mark, RUBY_DEFAULT_FREE, NULL }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY, + "Google::Protobuf::RepeatedField", + {RepeatedField_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; static RepeatedField* ruby_to_RepeatedField(VALUE _self) { @@ -66,9 +66,9 @@ static RepeatedField* ruby_to_RepeatedField(VALUE _self) { return self; } -static upb_array *RepeatedField_GetMutable(VALUE _self) { +static upb_Array* RepeatedField_GetMutable(VALUE _self) { rb_check_frozen(_self); - return (upb_array*)ruby_to_RepeatedField(_self)->array; + return (upb_Array*)ruby_to_RepeatedField(_self)->array; } VALUE RepeatedField_alloc(VALUE klass) { @@ -79,7 +79,7 @@ VALUE RepeatedField_alloc(VALUE klass) { return TypedData_Wrap_Struct(klass, &RepeatedField_type, self); } -VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info, +VALUE RepeatedField_GetRubyWrapper(upb_Array* array, TypeInfo type_info, VALUE arena) { PBRUBY_ASSERT(array); VALUE val = ObjectCache_Get(array); @@ -92,7 +92,7 @@ VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info, self->array = array; self->arena = arena; self->type_info = type_info; - if (self->type_info.type == UPB_TYPE_MESSAGE) { + if (self->type_info.type == kUpb_CType_Message) { self->type_class = Descriptor_DefToClass(type_info.def.msgdef); } } @@ -105,24 +105,24 @@ VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info, static VALUE RepeatedField_new_this_type(RepeatedField* from) { VALUE arena_rb = Arena_new(); - upb_array *array = upb_array_new(Arena_get(arena_rb), from->type_info.type); + upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type); VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb); PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class); return ret; } -void RepeatedField_Inspect(StringBuilder* b, const upb_array* array, +void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array, TypeInfo info) { bool first = true; StringBuilder_Printf(b, "["); - size_t n = array ? upb_array_size(array) : 0; + size_t n = array ? upb_Array_Size(array) : 0; for (size_t i = 0; i < n; i++) { if (first) { first = false; } else { StringBuilder_Printf(b, ", "); } - StringBuilder_PrintMsgval(b, upb_array_get(array, i), info); + StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info); } StringBuilder_Printf(b, "]"); } @@ -132,24 +132,24 @@ VALUE RepeatedField_deep_copy(VALUE _self) { VALUE new_rptfield = RepeatedField_new_this_type(self); RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield); VALUE arena_rb = new_self->arena; - upb_array *new_array = RepeatedField_GetMutable(new_rptfield); - upb_arena *arena = Arena_get(arena_rb); - size_t elements = upb_array_size(self->array); + upb_Array* new_array = RepeatedField_GetMutable(new_rptfield); + upb_Arena* arena = Arena_get(arena_rb); + size_t elements = upb_Array_Size(self->array); - upb_array_resize(new_array, elements, arena); + upb_Array_Resize(new_array, elements, arena); - size_t size = upb_array_size(self->array); + size_t size = upb_Array_Size(self->array); for (size_t i = 0; i < size; i++) { - upb_msgval msgval = upb_array_get(self->array, i); - upb_msgval copy = Msgval_DeepCopy(msgval, self->type_info, arena); - upb_array_set(new_array, i, copy); + upb_MessageValue msgval = upb_Array_Get(self->array, i); + upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena); + upb_Array_Set(new_array, i, copy); } return new_rptfield; } -const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field, - upb_arena* arena) { +const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field, + upb_Arena* arena) { RepeatedField* self; TypeInfo type_info = TypeInfo_get(field); @@ -173,17 +173,17 @@ const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field, static int index_position(VALUE _index, RepeatedField* repeated_field) { int index = NUM2INT(_index); - if (index < 0) index += upb_array_size(repeated_field->array); + if (index < 0) index += upb_Array_Size(repeated_field->array); return index; } static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) { - size_t size = upb_array_size(self->array); + size_t size = upb_Array_Size(self->array); VALUE ary = rb_ary_new2(size); long i; for (i = beg; i < beg + len; i++) { - upb_msgval msgval = upb_array_get(self->array, i); + upb_MessageValue msgval = upb_Array_Get(self->array, i); VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena); rb_ary_push(ary, elem); } @@ -200,18 +200,17 @@ static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) { */ static VALUE RepeatedField_each(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - int size = upb_array_size(self->array); + int size = upb_Array_Size(self->array); int i; for (i = 0; i < size; i++) { - upb_msgval msgval = upb_array_get(self->array, i); + upb_MessageValue msgval = upb_Array_Get(self->array, i); VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); rb_yield(val); } return _self; } - /* * call-seq: * RepeatedField.[](index) => value @@ -220,20 +219,20 @@ static VALUE RepeatedField_each(VALUE _self) { */ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - long size = upb_array_size(self->array); + long size = upb_Array_Size(self->array); VALUE arg = argv[0]; long beg, len; - if (argc == 1){ + if (argc == 1) { if (FIXNUM_P(arg)) { /* standard case */ - upb_msgval msgval; + upb_MessageValue msgval; int index = index_position(argv[0], self); - if (index < 0 || (size_t)index >= upb_array_size(self->array)) { + if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) { return Qnil; } - msgval = upb_array_get(self->array, index); + msgval = upb_Array_Get(self->array, index); return Convert_UpbToRuby(msgval, self->type_info, self->arena); } else { /* check if idx is Range */ @@ -269,10 +268,10 @@ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) { */ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { RepeatedField* self = ruby_to_RepeatedField(_self); - int size = upb_array_size(self->array); - upb_array *array = RepeatedField_GetMutable(_self); - upb_arena *arena = Arena_get(self->arena); - upb_msgval msgval = Convert_RubyToUpb(val, "", self->type_info, arena); + int size = upb_Array_Size(self->array); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena); int index = index_position(_index, self); if (index < 0 || index >= (INT_MAX - 1)) { @@ -280,17 +279,17 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { } if (index >= size) { - upb_array_resize(array, index + 1, arena); - upb_msgval fill; + upb_Array_Resize(array, index + 1, arena); + upb_MessageValue fill; memset(&fill, 0, sizeof(fill)); for (int i = size; i < index; i++) { // Fill default values. // TODO(haberman): should this happen at the upb level? - upb_array_set(array, i, fill); + upb_Array_Set(array, i, fill); } } - upb_array_set(array, index, msgval); + upb_Array_Set(array, index, msgval); return Qnil; } @@ -302,13 +301,14 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { */ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - upb_arena *arena = Arena_get(self->arena); - upb_array *array = RepeatedField_GetMutable(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_Array* array = RepeatedField_GetMutable(_self); int i; for (i = 0; i < argc; i++) { - upb_msgval msgval = Convert_RubyToUpb(argv[i], "", self->type_info, arena); - upb_array_append(array, msgval, arena); + upb_MessageValue msgval = + Convert_RubyToUpb(argv[i], "", self->type_info, arena); + upb_Array_Append(array, msgval, arena); } return _self; @@ -322,11 +322,11 @@ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) { */ static VALUE RepeatedField_push(VALUE _self, VALUE val) { RepeatedField* self = ruby_to_RepeatedField(_self); - upb_arena *arena = Arena_get(self->arena); - upb_array *array = RepeatedField_GetMutable(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_Array* array = RepeatedField_GetMutable(_self); - upb_msgval msgval = Convert_RubyToUpb(val, "", self->type_info, arena); - upb_array_append(array, msgval, arena); + upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena); + upb_Array_Append(array, msgval, arena); return _self; } @@ -336,19 +336,19 @@ static VALUE RepeatedField_push(VALUE _self, VALUE val) { */ static VALUE RepeatedField_pop_one(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - size_t size = upb_array_size(self->array); - upb_array *array = RepeatedField_GetMutable(_self); - upb_msgval last; + size_t size = upb_Array_Size(self->array); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_MessageValue last; VALUE ret; if (size == 0) { return Qnil; } - last = upb_array_get(self->array, size - 1); + last = upb_Array_Get(self->array, size - 1); ret = Convert_UpbToRuby(last, self->type_info, self->arena); - upb_array_resize(array, size - 1, Arena_get(self->arena)); + upb_Array_Resize(array, size - 1, Arena_get(self->arena)); return ret; } @@ -360,11 +360,11 @@ static VALUE RepeatedField_pop_one(VALUE _self) { */ static VALUE RepeatedField_replace(VALUE _self, VALUE list) { RepeatedField* self = ruby_to_RepeatedField(_self); - upb_array *array = RepeatedField_GetMutable(_self); + upb_Array* array = RepeatedField_GetMutable(_self); int i; Check_Type(list, T_ARRAY); - upb_array_resize(array, 0, Arena_get(self->arena)); + upb_Array_Resize(array, 0, Arena_get(self->arena)); for (i = 0; i < RARRAY_LEN(list); i++) { RepeatedField_push(_self, rb_ary_entry(list, i)); @@ -381,8 +381,8 @@ static VALUE RepeatedField_replace(VALUE _self, VALUE list) { */ static VALUE RepeatedField_clear(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - upb_array *array = RepeatedField_GetMutable(_self); - upb_array_resize(array, 0, Arena_get(self->arena)); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_Array_Resize(array, 0, Arena_get(self->arena)); return _self; } @@ -394,7 +394,7 @@ static VALUE RepeatedField_clear(VALUE _self) { */ static VALUE RepeatedField_length(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - return INT2NUM(upb_array_size(self->array)); + return INT2NUM(upb_Array_Size(self->array)); } /* @@ -408,16 +408,16 @@ static VALUE RepeatedField_dup(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); VALUE new_rptfield = RepeatedField_new_this_type(self); RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield); - upb_array *new_array = RepeatedField_GetMutable(new_rptfield); - upb_arena* arena = Arena_get(new_rptfield_self->arena); - int size = upb_array_size(self->array); + upb_Array* new_array = RepeatedField_GetMutable(new_rptfield); + upb_Arena* arena = Arena_get(new_rptfield_self->arena); + int size = upb_Array_Size(self->array); int i; Arena_fuse(self->arena, arena); for (i = 0; i < size; i++) { - upb_msgval msgval = upb_array_get(self->array, i); - upb_array_append(new_array, msgval, arena); + upb_MessageValue msgval = upb_Array_Get(self->array, i); + upb_Array_Append(new_array, msgval, arena); } return new_rptfield; @@ -432,12 +432,12 @@ static VALUE RepeatedField_dup(VALUE _self) { */ VALUE RepeatedField_to_ary(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - int size = upb_array_size(self->array); + int size = upb_Array_Size(self->array); VALUE ary = rb_ary_new2(size); int i; for (i = 0; i < size; i++) { - upb_msgval msgval = upb_array_get(self->array, i); + upb_MessageValue msgval = upb_Array_Get(self->array, i); VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); rb_ary_push(ary, val); } @@ -473,17 +473,17 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) { self = ruby_to_RepeatedField(_self); other = ruby_to_RepeatedField(_other); - size_t n = upb_array_size(self->array); + size_t n = upb_Array_Size(self->array); if (self->type_info.type != other->type_info.type || self->type_class != other->type_class || - upb_array_size(other->array) != n) { + upb_Array_Size(other->array) != n) { return Qfalse; } for (size_t i = 0; i < n; i++) { - upb_msgval val1 = upb_array_get(self->array, i); - upb_msgval val2 = upb_array_get(other->array, i); + upb_MessageValue val1 = upb_Array_Get(self->array, i); + upb_MessageValue val2 = upb_Array_Get(other->array, i); if (!Msgval_IsEqual(val1, val2, self->type_info)) { return Qfalse; } @@ -517,10 +517,10 @@ static VALUE RepeatedField_freeze(VALUE _self) { VALUE RepeatedField_hash(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); uint64_t hash = 0; - size_t n = upb_array_size(self->array); + size_t n = upb_Array_Size(self->array); for (size_t i = 0; i < n; i++) { - upb_msgval val = upb_array_get(self->array, i); + upb_MessageValue val = upb_Array_Get(self->array, i); hash = Msgval_GetHash(val, self->type_info, hash); } @@ -549,10 +549,10 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) { RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* list_rptfield = ruby_to_RepeatedField(list); RepeatedField* dupped = ruby_to_RepeatedField(dupped_); - upb_array *dupped_array = RepeatedField_GetMutable(dupped_); - upb_arena* arena = Arena_get(dupped->arena); + upb_Array* dupped_array = RepeatedField_GetMutable(dupped_); + upb_Arena* arena = Arena_get(dupped->arena); Arena_fuse(list_rptfield->arena, arena); - int size = upb_array_size(list_rptfield->array); + int size = upb_Array_Size(list_rptfield->array); int i; if (self->type_info.type != list_rptfield->type_info.type || @@ -562,8 +562,8 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) { } for (i = 0; i < size; i++) { - upb_msgval msgval = upb_array_get(list_rptfield->array, i); - upb_array_append(dupped_array, msgval, arena); + upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i); + upb_Array_Append(dupped_array, msgval, arena); } } else { rb_raise(rb_eArgError, "Unknown type appending to RepeatedField"); @@ -601,7 +601,7 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) { */ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - upb_arena *arena; + upb_Arena* arena; VALUE ary = Qnil; self->arena = Arena_new(); @@ -612,7 +612,7 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) { } self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary); - self->array = upb_array_new(arena, self->type_info.type); + self->array = upb_Array_New(arena, self->type_info.type); ObjectCache_Add(self->array, _self); if (ary != Qnil) { @@ -627,14 +627,12 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) { } void RepeatedField_register(VALUE module) { - VALUE klass = rb_define_class_under( - module, "RepeatedField", rb_cObject); + VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject); rb_define_alloc_func(klass, RepeatedField_alloc); rb_gc_register_address(&cRepeatedField); cRepeatedField = klass; - rb_define_method(klass, "initialize", - RepeatedField_init, -1); + rb_define_method(klass, "initialize", RepeatedField_init, -1); rb_define_method(klass, "each", RepeatedField_each, 0); rb_define_method(klass, "[]", RepeatedField_index, -1); rb_define_method(klass, "at", RepeatedField_index, -1); diff --git a/ruby/ext/google/protobuf_c/repeated_field.h b/ruby/ext/google/protobuf_c/repeated_field.h index e4ef252924375..b0581635b85a1 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.h +++ b/ruby/ext/google/protobuf_c/repeated_field.h @@ -36,19 +36,19 @@ #include "protobuf.h" #include "ruby-upb.h" -// Returns a Ruby wrapper object for the given upb_array, which will be created +// Returns a Ruby wrapper object for the given upb_Array, which will be created // if one does not exist already. -VALUE RepeatedField_GetRubyWrapper(upb_array* msg, TypeInfo type_info, +VALUE RepeatedField_GetRubyWrapper(upb_Array* msg, TypeInfo type_info, VALUE arena); -// Gets the underlying upb_array for this Ruby RepeatedField object, which must +// Gets the underlying upb_Array for this Ruby RepeatedField object, which must // have a type that matches |f|. If this is not a repeated field or the type // doesn't match, raises an exception. -const upb_array* RepeatedField_GetUpbArray(VALUE value, const upb_fielddef* f, - upb_arena* arena); +const upb_Array* RepeatedField_GetUpbArray(VALUE value, const upb_FieldDef* f, + upb_Arena* arena); // Implements #inspect for this repeated field by appending its contents to |b|. -void RepeatedField_Inspect(StringBuilder* b, const upb_array* array, +void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array, TypeInfo info); // Returns a deep copy of this RepeatedField object. diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index d68caac0e2cce..15f2224643548 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -264,25 +264,25 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); /* 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 */ + -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. */ @@ -297,8 +297,8 @@ static const uint8_t desctype_to_mapsize[] = { 4, /* FIXED32 */ 1, /* BOOL */ UPB_MAPTYPE_STRING, /* STRING */ - sizeof(void *), /* GROUP */ - sizeof(void *), /* MESSAGE */ + sizeof(void*), /* GROUP */ + sizeof(void*), /* MESSAGE */ UPB_MAPTYPE_STRING, /* BYTES */ 4, /* UINT32 */ 4, /* ENUM */ @@ -308,66 +308,80 @@ static const uint8_t desctype_to_mapsize[] = { 8, /* SINT64 */ }; -static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) | - (1 << UPB_DTYPE_FIXED32) | - (1 << UPB_DTYPE_SFIXED32); +static const unsigned FIXED32_OK_MASK = (1 << kUpb_FieldType_Float) | + (1 << kUpb_FieldType_Fixed32) | + (1 << kUpb_FieldType_SFixed32); -static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) | - (1 << UPB_DTYPE_FIXED64) | - (1 << UPB_DTYPE_SFIXED64); +static const unsigned FIXED64_OK_MASK = (1 << kUpb_FieldType_Double) | + (1 << kUpb_FieldType_Fixed64) | + (1 << kUpb_FieldType_SFixed64); + +/* Three fake field types for MessageSet. */ +#define TYPE_MSGSET_ITEM 19 +#define TYPE_MSGSET_TYPE_ID 20 +#define TYPE_COUNT 20 /* 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_UNKNOWN -1 /* Unknown field. */ +#define OP_MSGSET_ITEM -2 +#define OP_MSGSET_TYPEID -3 +#define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */ +#define OP_ENUM 1 #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 */ +/* Scalar fields use only ops above. 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] */ +#define OP_PACKED_ENUM 13 + +static const int8_t varint_ops[] = { + OP_UNKNOWN, /* field not found */ + OP_UNKNOWN, /* DOUBLE */ + OP_UNKNOWN, /* FLOAT */ OP_SCALAR_LG2(3), /* INT64 */ OP_SCALAR_LG2(3), /* UINT64 */ OP_SCALAR_LG2(2), /* INT32 */ - -1, /* FIXED64 */ - -1, /* FIXED32 */ + OP_UNKNOWN, /* FIXED64 */ + OP_UNKNOWN, /* FIXED32 */ OP_SCALAR_LG2(0), /* BOOL */ - -1, /* STRING */ - -1, /* GROUP */ - -1, /* MESSAGE */ - -1, /* BYTES */ + OP_UNKNOWN, /* STRING */ + OP_UNKNOWN, /* GROUP */ + OP_UNKNOWN, /* MESSAGE */ + OP_UNKNOWN, /* BYTES */ OP_SCALAR_LG2(2), /* UINT32 */ - OP_SCALAR_LG2(2), /* ENUM */ - -1, /* SFIXED32 */ - -1, /* SFIXED64 */ + OP_ENUM, /* ENUM */ + OP_UNKNOWN, /* SFIXED32 */ + OP_UNKNOWN, /* SFIXED64 */ OP_SCALAR_LG2(2), /* SINT32 */ OP_SCALAR_LG2(3), /* SINT64 */ + OP_UNKNOWN, /* MSGSET_ITEM */ + OP_MSGSET_TYPEID, /* MSGSET TYPEID */ }; -static const int8_t delim_ops[37] = { +static const int8_t delim_ops[] = { /* 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 */ + OP_UNKNOWN, /* field not found */ + OP_UNKNOWN, /* DOUBLE */ + OP_UNKNOWN, /* FLOAT */ + OP_UNKNOWN, /* INT64 */ + OP_UNKNOWN, /* UINT64 */ + OP_UNKNOWN, /* INT32 */ + OP_UNKNOWN, /* FIXED64 */ + OP_UNKNOWN, /* FIXED32 */ + OP_UNKNOWN, /* BOOL */ + OP_STRING, /* STRING */ + OP_UNKNOWN, /* GROUP */ + OP_SUBMSG, /* MESSAGE */ + OP_BYTES, /* BYTES */ + OP_UNKNOWN, /* UINT32 */ + OP_UNKNOWN, /* ENUM */ + OP_UNKNOWN, /* SFIXED32 */ + OP_UNKNOWN, /* SFIXED64 */ + OP_UNKNOWN, /* SINT32 */ + OP_UNKNOWN, /* SINT64 */ + OP_UNKNOWN, /* MSGSET_ITEM */ + OP_UNKNOWN, /* MSGSET TYPEID */ /* For repeated field type. */ OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */ OP_FIXPCK_LG2(2), /* REPEATED FLOAT */ @@ -382,11 +396,12 @@ static const int8_t delim_ops[37] = { OP_SUBMSG, /* REPEATED MESSAGE */ OP_BYTES, /* REPEATED BYTES */ OP_VARPCK_LG2(2), /* REPEATED UINT32 */ - OP_VARPCK_LG2(2), /* REPEATED ENUM */ + OP_PACKED_ENUM, /* 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 */ + /* Omitting MSGSET_*, because we never emit a repeated msgset type */ }; typedef union { @@ -396,61 +411,39 @@ typedef union { 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) { UPB_LONGJMP(d->err, 1); } +static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable* layout); -// We don't want to mark this NORETURN, see comment in .h. -// Unfortunately this code to suppress the warning doesn't appear to be working. -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wsuggest-attribute" -#endif +UPB_NORETURN static void* decode_err(upb_Decoder* d, upb_DecodeStatus status) { + assert(status != kUpb_DecodeStatus_Ok); + UPB_LONGJMP(d->err, status); +} -const char *fastdecode_err(upb_decstate *d) { - longjmp(d->err, 1); +const char* fastdecode_err(upb_Decoder* d, int status) { + assert(status != kUpb_DecodeStatus_Ok); + UPB_LONGJMP(d->err, status); return NULL; } - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -const uint8_t upb_utf8_offsets[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 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, -}; - -static void decode_verifyutf8(upb_decstate *d, const char *buf, int len) { - if (!decode_verifyutf8_inl(buf, len)) decode_err(d); +static void decode_verifyutf8(upb_Decoder* d, const char* buf, int len) { + if (!decode_verifyutf8_inl(buf, len)) + decode_err(d, kUpb_DecodeStatus_BadUtf8); } -static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) { +static bool decode_reserve(upb_Decoder* 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); + decode_err(d, kUpb_DecodeStatus_OutOfMemory); } return need_realloc; } typedef struct { - const char *ptr; + const char* ptr; uint64_t val; } decode_vret; UPB_NOINLINE -static decode_vret decode_longvarint64(const char *ptr, uint64_t val) { +static decode_vret decode_longvarint64(const char* ptr, uint64_t val) { decode_vret ret = {NULL, 0}; uint64_t byte; int i; @@ -467,120 +460,92 @@ static decode_vret decode_longvarint64(const char *ptr, uint64_t val) { } UPB_FORCEINLINE -static const char *decode_varint64(upb_decstate *d, const char *ptr, - uint64_t *val) { +static const char* decode_varint64(upb_Decoder* 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); + if (!res.ptr) return decode_err(d, kUpb_DecodeStatus_Malformed); *val = res.val; return res.ptr; } } UPB_FORCEINLINE -static const char *decode_tag(upb_decstate *d, const char *ptr, - uint32_t *val) { +static const char* decode_tag(upb_Decoder* d, const char* ptr, uint32_t* val) { uint64_t byte = (uint8_t)*ptr; if (UPB_LIKELY((byte & 0x80) == 0)) { *val = byte; return ptr + 1; } else { - const char *start = ptr; + const char* start = ptr; decode_vret res = decode_longvarint64(ptr, byte); - ptr = res.ptr; + if (!res.ptr || res.ptr - start > 5 || res.val > UINT32_MAX) { + return decode_err(d, kUpb_DecodeStatus_Malformed); + } *val = res.val; - if (!ptr || *val > UINT32_MAX || ptr - start > 5) decode_err(d); - return ptr; + return res.ptr; } } -static void decode_munge(int type, wireval *val) { +static void decode_munge_int32(wireval* val) { + if (!_upb_IsLittleEndian()) { + /* The next stage will memcpy(dst, &val, 4) */ + val->uint32_val = val->uint64_val; + } +} + +static void decode_munge(int type, wireval* val) { switch (type) { - case UPB_DESCRIPTOR_TYPE_BOOL: + case kUpb_FieldType_Bool: val->bool_val = val->uint64_val != 0; break; - case UPB_DESCRIPTOR_TYPE_SINT32: { - uint32_t n = val->uint32_val; + case kUpb_FieldType_SInt32: { + uint32_t n = val->uint64_val; val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1); break; } - case UPB_DESCRIPTOR_TYPE_SINT64: { + case kUpb_FieldType_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; - } + case kUpb_FieldType_Int32: + case kUpb_FieldType_UInt32: + case kUpb_FieldType_Enum: + decode_munge_int32(val); break; } } -static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, - uint32_t field_number, - int *last_field_index) { - static upb_msglayout_field none = {0, 0, 0, 0, 0, 0}; - - if (l == NULL) return &none; - - size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX - if (idx < l->dense_below) { - goto found; - } - - /* Resume scanning from last_field_index since fields are usually in order. */ - int last = *last_field_index; - for (idx = last; idx < l->field_count; idx++) { - if (l->fields[idx].number == field_number) { - goto found; - } - } - - for (idx = 0; idx < last; idx++) { - if (l->fields[idx].number == field_number) { - goto found; - } - } - - return &none; /* Unknown field. */ - - found: - UPB_ASSERT(l->fields[idx].number == field_number); - *last_field_index = idx; - return &l->fields[idx]; -} - -static upb_msg *decode_newsubmsg(upb_decstate *d, - upb_msglayout const *const *submsgs, - const upb_msglayout_field *field) { - const upb_msglayout *subl = submsgs[field->submsg_index]; - return _upb_msg_new_inl(subl, &d->arena); +static upb_Message* decode_newsubmsg(upb_Decoder* d, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field) { + const upb_MiniTable* subl = subs[field->submsg_index].submsg; + return _upb_Message_New_inl(subl, &d->arena); } UPB_NOINLINE -const char *decode_isdonefallback(upb_decstate *d, const char *ptr, +const char* decode_isdonefallback(upb_Decoder* d, const char* ptr, int overrun) { - ptr = decode_isdonefallback_inl(d, ptr, overrun); + int status; + ptr = decode_isdonefallback_inl(d, ptr, overrun, &status); if (ptr == NULL) { - decode_err(d); + return decode_err(d, status); } return ptr; } -static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, - upb_strview *str) { - if (d->alias) { +static const char* decode_readstr(upb_Decoder* d, const char* ptr, int size, + upb_StringView* str) { + if (d->options & kUpb_DecodeOption_AliasString) { str->data = ptr; } else { - char *data = upb_arena_malloc(&d->arena, size); - if (!data) decode_err(d); + char* data = upb_Arena_Malloc(&d->arena, size); + if (!data) return decode_err(d, kUpb_DecodeStatus_OutOfMemory); memcpy(data, ptr, size); str->data = data; } @@ -589,61 +554,222 @@ static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, } UPB_FORCEINLINE -static const char *decode_tosubmsg(upb_decstate *d, const char *ptr, - upb_msg *submsg, - upb_msglayout const *const *submsgs, - const upb_msglayout_field *field, int size) { - const upb_msglayout *subl = submsgs[field->submsg_index]; +static const char* decode_tosubmsg2(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable* subl, int size) { int saved_delta = decode_pushlimit(d, ptr, size); - if (--d->depth < 0) decode_err(d); - if (!decode_isdone(d, &ptr)) { - ptr = decode_msg(d, ptr, submsg, subl); - } - if (d->end_group != DECODE_NOGROUP) decode_err(d); + if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); + ptr = decode_msg(d, ptr, submsg, subl); + if (d->end_group != DECODE_NOGROUP) + return decode_err(d, kUpb_DecodeStatus_Malformed); decode_poplimit(d, ptr, saved_delta); d->depth++; return ptr; } UPB_FORCEINLINE -static const char *decode_group(upb_decstate *d, const char *ptr, - upb_msg *submsg, const upb_msglayout *subl, +static const char* decode_tosubmsg(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, int size) { + return decode_tosubmsg2(d, ptr, submsg, subs[field->submsg_index].submsg, + size); +} + +UPB_FORCEINLINE +static const char* decode_group(upb_Decoder* d, const char* ptr, + upb_Message* submsg, const upb_MiniTable* subl, uint32_t number) { - if (--d->depth < 0) decode_err(d); + if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); if (decode_isdone(d, &ptr)) { - decode_err(d); + return decode_err(d, kUpb_DecodeStatus_Malformed); } ptr = decode_msg(d, ptr, submsg, subl); - if (d->end_group != number) decode_err(d); + if (d->end_group != number) return decode_err(d, kUpb_DecodeStatus_Malformed); d->end_group = DECODE_NOGROUP; d->depth++; return ptr; } UPB_FORCEINLINE -static const char *decode_togroup(upb_decstate *d, const char *ptr, - upb_msg *submsg, - upb_msglayout const *const *submsgs, - const upb_msglayout_field *field) { - const upb_msglayout *subl = submsgs[field->submsg_index]; +static const char* decode_togroup(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field) { + const upb_MiniTable* subl = subs[field->submsg_index].submsg; return decode_group(d, ptr, submsg, subl, field->number); } -static const char *decode_toarray(upb_decstate *d, const char *ptr, - upb_msg *msg, - upb_msglayout const *const *submsgs, - 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; +static char* encode_varint32(uint32_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +UPB_NOINLINE +static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable_Enum* e, + const upb_MiniTable_Field* field, + uint32_t v) { + // OPT: binary search long lists? + int n = e->value_count; + for (int i = 0; i < n; i++) { + if ((uint32_t)e->values[i] == v) return true; + } + + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, so we + // just re-encode the tag here. + char buf[20]; + char* end = buf; + uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; + end = encode_varint32(tag, end); + end = encode_varint32(v, end); + + if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) { + decode_err(d, kUpb_DecodeStatus_OutOfMemory); + } + + return false; +} + +UPB_FORCEINLINE +static bool decode_checkenum(upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable_Enum* e, + const upb_MiniTable_Field* field, wireval* val) { + uint32_t v = val->uint32_val; + + if (UPB_LIKELY(v < 64) && UPB_LIKELY(((1ULL << v) & e->mask))) return true; + + return decode_checkenum_slow(d, ptr, msg, e, field, v); +} + +UPB_NOINLINE +static const char* decode_enum_toarray(upb_Decoder* d, const char* ptr, + upb_Message* msg, upb_Array* arr, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, + wireval* val) { + const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum; + if (!decode_checkenum(d, ptr, msg, e, field, val)) return ptr; + void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void); + arr->len++; + memcpy(mem, val, 4); + return ptr; +} + +UPB_FORCEINLINE +static const char* decode_fixed_packed(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTable_Field* field, + int lg2) { + int mask = (1 << lg2) - 1; + size_t count = val->size >> lg2; + if ((val->size & mask) != 0) { + // Length isn't a round multiple of elem size. + return decode_err(d, kUpb_DecodeStatus_Malformed); + } + decode_reserve(d, arr, count); + void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + arr->len += count; + // Note: if/when the decoder supports multi-buffer input, we will need to + // handle buffer seams here. + if (_upb_IsLittleEndian()) { + memcpy(mem, ptr, val->size); + ptr += val->size; + } else { + const char* end = ptr + val->size; + char* dst = mem; + while (ptr < end) { + if (lg2 == 2) { + uint32_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap32(val); + memcpy(dst, &val, sizeof(val)); + } else { + UPB_ASSERT(lg2 == 3); + uint64_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap64(val); + memcpy(dst, &val, sizeof(val)); + } + ptr += 1 << lg2; + dst += 1 << lg2; + } + } + + return ptr; +} + +UPB_FORCEINLINE +static const char* decode_varint_packed(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTable_Field* field, + int lg2) { + 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, ptr, saved_limit); + return ptr; +} + +UPB_NOINLINE +static const char* decode_enum_packed(upb_Decoder* d, const char* ptr, + upb_Message* msg, upb_Array* arr, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, + wireval* val) { + const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum; + int saved_limit = decode_pushlimit(d, ptr, val->size); + char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void); + while (!decode_isdone(d, &ptr)) { + wireval elem; + ptr = decode_varint64(d, ptr, &elem.uint64_val); + decode_munge_int32(&elem); + if (!decode_checkenum(d, ptr, msg, e, field, &elem)) { + continue; + } + if (decode_reserve(d, arr, 1)) { + out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void); + } + arr->len++; + memcpy(out, &elem, 4); + out += 4; + } + decode_poplimit(d, ptr, saved_limit); + return ptr; +} + +static const char* decode_toarray(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_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); + arr = _upb_Array_New(&d->arena, 4, lg2); + if (!arr) return decode_err(d, kUpb_DecodeStatus_OutOfMemory); *arrp = arr; } @@ -661,111 +787,95 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, /* Fallthrough. */ case OP_BYTES: { /* Append bytes. */ - upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len; + upb_StringView* str = (upb_StringView*)_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, submsgs, field); - *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) = + upb_Message* submsg = decode_newsubmsg(d, subs, field); + *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void*), upb_Message*) = submsg; arr->len++; - if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) { - return decode_togroup(d, ptr, submsg, submsgs, field); + if (UPB_UNLIKELY(field->descriptortype == kUpb_FieldType_Group)) { + return decode_togroup(d, ptr, submsg, subs, field); } else { - return decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size); + return decode_tosubmsg(d, ptr, submsg, subs, 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_FIXPCK_LG2(3): + return decode_fixed_packed(d, ptr, arr, val, field, + op - OP_FIXPCK_LG2(0)); 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, ptr, saved_limit); - return ptr; - } + case OP_VARPCK_LG2(3): + return decode_varint_packed(d, ptr, arr, val, field, + op - OP_VARPCK_LG2(0)); + case OP_ENUM: + return decode_enum_toarray(d, ptr, msg, arr, subs, field, val); + case OP_PACKED_ENUM: + return decode_enum_packed(d, ptr, msg, arr, subs, field, val); default: UPB_UNREACHABLE(); } } -static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg, - upb_msglayout const *const *submsgs, - 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 = submsgs[field->submsg_index]; +static const char* decode_tomap(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, + wireval* val) { + upb_Map** map_p = UPB_PTR_AT(msg, field->offset, upb_Map*); + upb_Map* map = *map_p; + upb_MapEntry ent; + const upb_MiniTable* entry = subs[field->submsg_index].submsg; if (!map) { /* Lazily create map. */ - const upb_msglayout_field *key_field = &entry->fields[0]; - const upb_msglayout_field *val_field = &entry->fields[1]; + const upb_MiniTable_Field* key_field = &entry->fields[0]; + const upb_MiniTable_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); + UPB_ASSERT(val_field->offset == sizeof(upb_StringView)); + 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) { + if (entry->fields[1].descriptortype == kUpb_FieldType_Message || + entry->fields[1].descriptortype == kUpb_FieldType_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)); + ent.v.val = + upb_value_ptr(_upb_Message_New(entry->subs[0].submsg, &d->arena)); } - ptr = decode_tosubmsg(d, ptr, &ent.k, submsgs, field, val->size); - _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena); + ptr = decode_tosubmsg(d, ptr, &ent.k, subs, 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, - upb_msglayout const *const *submsgs, - const upb_msglayout_field *field, wireval *val, +static const char* decode_tomsg(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, wireval* val, int op) { - void *mem = UPB_PTR_AT(msg, field->offset, void); + void* mem = UPB_PTR_AT(msg, field->offset, void); int type = field->descriptortype; + if (UPB_UNLIKELY(op == OP_ENUM) && + !decode_checkenum(d, ptr, msg, subs[field->submsg_index].subenum, field, + val)) { + return ptr; + } + /* Set presence if necessary. */ if (field->presence > 0) { _upb_sethas_field(msg, field); } else if (field->presence < 0) { /* Oneof case */ - uint32_t *oneof_case = _upb_oneofcase_field(msg, field); + uint32_t* oneof_case = _upb_oneofcase_field(msg, field); if (op == OP_SUBMSG && *oneof_case != field->number) { memset(mem, 0, sizeof(void*)); } @@ -775,16 +885,16 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, /* Store into message. */ switch (op) { case OP_SUBMSG: { - upb_msg **submsgp = mem; - upb_msg *submsg = *submsgp; + upb_Message** submsgp = mem; + upb_Message* submsg = *submsgp; if (!submsg) { - submsg = decode_newsubmsg(d, submsgs, field); + submsg = decode_newsubmsg(d, subs, field); *submsgp = submsg; } - if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) { - ptr = decode_togroup(d, ptr, submsg, submsgs, field); + if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) { + ptr = decode_togroup(d, ptr, submsg, subs, field); } else { - ptr = decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size); + ptr = decode_tosubmsg(d, ptr, submsg, subs, field, val->size); } break; } @@ -796,6 +906,7 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, case OP_SCALAR_LG2(3): memcpy(mem, val, 8); break; + case OP_ENUM: case OP_SCALAR_LG2(2): memcpy(mem, val, 4); break; @@ -809,9 +920,27 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, return ptr; } +UPB_NOINLINE +const char* decode_checkrequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* l) { + assert(l->required_count); + if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) { + return ptr; + } + uint64_t msg_head; + memcpy(&msg_head, msg, 8); + msg_head = _upb_BigEndian_Swap64(msg_head); + if (upb_MiniTable_requiredmask(l) & ~msg_head) { + d->missing_required = true; + } + return ptr; +} + UPB_FORCEINLINE -static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr, - upb_msg *msg, const upb_msglayout *layout) { +static bool decode_tryfastdispatch(upb_Decoder* d, const char** ptr, + upb_Message* msg, + const upb_MiniTable* layout) { #if UPB_FASTTABLE if (layout && layout->table_mask != (unsigned char)-1) { uint16_t tag = fastdecode_loadtag(*ptr); @@ -823,176 +952,385 @@ static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr, return false; } +static const char* decode_msgset(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* layout) { + // We create a temporary upb_MiniTable here and abuse its fields as temporary + // storage, to avoid creating lots of MessageSet-specific parsing code-paths: + // 1. We store 'layout' in item_layout.subs. We will need this later as + // a key to look up extensions for this MessageSet. + // 2. We use item_layout.fields as temporary storage to store the extension + // we + // found when parsing the type id. + upb_MiniTable item_layout = { + .subs = (const upb_MiniTable_Sub[]){{.submsg = layout}}, + .fields = NULL, + .size = 0, + .field_count = 0, + .ext = upb_ExtMode_IsMessageSet_ITEM, + .dense_below = 0, + .table_mask = -1}; + return decode_group(d, ptr, msg, &item_layout, 1); +} + +static const upb_MiniTable_Field* decode_findfield(upb_Decoder* d, + const upb_MiniTable* l, + uint32_t field_number, + int* last_field_index) { + static upb_MiniTable_Field none = {0, 0, 0, 0, 0, 0}; + if (l == NULL) return &none; + + size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX + if (idx < l->dense_below) { + /* Fastest case: index into dense fields. */ + goto found; + } + + if (l->dense_below < l->field_count) { + /* Linear search non-dense fields. Resume scanning from last_field_index + * since fields are usually in order. */ + int last = *last_field_index; + for (idx = last; idx < l->field_count; idx++) { + if (l->fields[idx].number == field_number) { + goto found; + } + } + + for (idx = l->dense_below; idx < last; idx++) { + if (l->fields[idx].number == field_number) { + goto found; + } + } + } + + if (d->extreg) { + switch (l->ext) { + case upb_ExtMode_Extendable: { + const upb_MiniTable_Extension* ext = + _upb_extreg_get(d->extreg, l, field_number); + if (ext) return &ext->field; + break; + } + case upb_ExtMode_IsMessageSet: + if (field_number == _UPB_MSGSET_ITEM) { + static upb_MiniTable_Field item = {0, 0, 0, 0, TYPE_MSGSET_ITEM, 0}; + return &item; + } + break; + case upb_ExtMode_IsMessageSet_ITEM: + switch (field_number) { + case _UPB_MSGSET_TYPEID: { + static upb_MiniTable_Field type_id = { + 0, 0, 0, 0, TYPE_MSGSET_TYPE_ID, 0}; + return &type_id; + } + case _UPB_MSGSET_MESSAGE: + if (l->fields) { + // We saw type_id previously and succeeded in looking up msg. + return l->fields; + } else { + // TODO: out of order MessageSet. + // This is a very rare case: all serializers will emit in-order + // MessageSets. To hit this case there has to be some kind of + // re-ordering proxy. We should eventually handle this case, but + // not today. + } + break; + } + } + } + + return &none; /* Unknown field. */ + +found: + UPB_ASSERT(l->fields[idx].number == field_number); + *last_field_index = idx; + return &l->fields[idx]; +} + +UPB_FORCEINLINE +static const char* decode_wireval(upb_Decoder* d, const char* ptr, + const upb_MiniTable_Field* field, + int wire_type, wireval* val, int* op) { + switch (wire_type) { + case kUpb_WireType_Varint: + ptr = decode_varint64(d, ptr, &val->uint64_val); + *op = varint_ops[field->descriptortype]; + decode_munge(field->descriptortype, val); + return ptr; + case kUpb_WireType_32Bit: + memcpy(&val->uint32_val, ptr, 4); + val->uint32_val = _upb_BigEndian_Swap32(val->uint32_val); + *op = OP_SCALAR_LG2(2); + if (((1 << field->descriptortype) & FIXED32_OK_MASK) == 0) { + *op = OP_UNKNOWN; + } + return ptr + 4; + case kUpb_WireType_64Bit: + memcpy(&val->uint64_val, ptr, 8); + val->uint64_val = _upb_BigEndian_Swap64(val->uint64_val); + *op = OP_SCALAR_LG2(3); + if (((1 << field->descriptortype) & FIXED64_OK_MASK) == 0) { + *op = OP_UNKNOWN; + } + return ptr + 8; + case kUpb_WireType_Delimited: { + int ndx = field->descriptortype; + uint64_t size; + if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += TYPE_COUNT; + ptr = decode_varint64(d, ptr, &size); + if (size >= INT32_MAX || ptr - d->end + (int32_t)size > d->limit) { + break; /* Length overflow. */ + } + *op = delim_ops[ndx]; + val->size = size; + return ptr; + } + case kUpb_WireType_StartGroup: + val->uint32_val = field->number; + if (field->descriptortype == kUpb_FieldType_Group) { + *op = OP_SUBMSG; + } else if (field->descriptortype == TYPE_MSGSET_ITEM) { + *op = OP_MSGSET_ITEM; + } else { + *op = OP_UNKNOWN; + } + return ptr; + default: + break; + } + return decode_err(d, kUpb_DecodeStatus_Malformed); +} + +UPB_FORCEINLINE +static const char* decode_known(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable* layout, + const upb_MiniTable_Field* field, int op, + wireval* val) { + const upb_MiniTable_Sub* subs = layout->subs; + uint8_t mode = field->mode; + + if (UPB_UNLIKELY(mode & upb_LabelFlags_IsExtension)) { + const upb_MiniTable_Extension* ext_layout = + (const upb_MiniTable_Extension*)field; + upb_Message_Extension* ext = + _upb_Message_Getorcreateext(msg, ext_layout, &d->arena); + if (UPB_UNLIKELY(!ext)) return decode_err(d, kUpb_DecodeStatus_OutOfMemory); + msg = &ext->data; + subs = &ext->ext->sub; + } + + switch (mode & kUpb_FieldMode_Mask) { + case kUpb_FieldMode_Array: + return decode_toarray(d, ptr, msg, subs, field, val, op); + case kUpb_FieldMode_Map: + return decode_tomap(d, ptr, msg, subs, field, val); + case kUpb_FieldMode_Scalar: + return decode_tomsg(d, ptr, msg, subs, field, val, op); + default: + UPB_UNREACHABLE(); + } +} + +static const char* decode_reverse_skip_varint(const char* ptr, uint32_t val) { + uint32_t seen = 0; + do { + ptr--; + seen <<= 7; + seen |= *ptr & 0x7f; + } while (seen != val); + return ptr; +} + +static const char* decode_unknown(upb_Decoder* d, const char* ptr, + upb_Message* msg, int field_number, + int wire_type, wireval val) { + if (field_number == 0) return decode_err(d, kUpb_DecodeStatus_Malformed); + + // Since unknown fields are the uncommon case, we do a little extra work here + // to walk backwards through the buffer to find the field start. This frees + // up a register in the fast paths (when the field is known), which leads to + // significant speedups in benchmarks. + const char* start = ptr; + + if (wire_type == kUpb_WireType_Delimited) ptr += val.size; + if (msg) { + switch (wire_type) { + case kUpb_WireType_Varint: + case kUpb_WireType_Delimited: + start--; + while (start[-1] & 0x80) start--; + break; + case kUpb_WireType_32Bit: + start -= 4; + break; + case kUpb_WireType_64Bit: + start -= 8; + break; + default: + break; + } + + assert(start == d->debug_valstart); + uint32_t tag = ((uint32_t)field_number << 3) | wire_type; + start = decode_reverse_skip_varint(start, tag); + assert(start == d->debug_tagstart); + + if (wire_type == kUpb_WireType_StartGroup) { + d->unknown = start; + d->unknown_msg = msg; + ptr = decode_group(d, ptr, NULL, NULL, field_number); + start = d->unknown; + d->unknown_msg = NULL; + d->unknown = NULL; + } + if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) { + return decode_err(d, kUpb_DecodeStatus_OutOfMemory); + } + } else if (wire_type == kUpb_WireType_StartGroup) { + ptr = decode_group(d, ptr, NULL, NULL, field_number); + } + return ptr; +} + UPB_NOINLINE -static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, - const upb_msglayout *layout) { +static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable* layout) { int last_field_index = 0; - while (true) { + +#if UPB_FASTTABLE + // The first time we want to skip fast dispatch, because we may have just been + // invoked by the fast parser to handle a case that it bailed on. + if (!decode_isdone(d, &ptr)) goto nofast; +#endif + + while (!decode_isdone(d, &ptr)) { uint32_t tag; - const upb_msglayout_field *field; + const upb_MiniTable_Field* field; int field_number; int wire_type; - const char *field_start = ptr; wireval val; int op; + if (decode_tryfastdispatch(d, &ptr, msg, layout)) break; + +#if UPB_FASTTABLE + nofast: +#endif + +#ifndef NDEBUG + d->debug_tagstart = ptr; +#endif + UPB_ASSERT(ptr < d->limit_ptr); ptr = decode_tag(d, ptr, &tag); field_number = tag >> 3; wire_type = tag & 7; - field = upb_find_field(layout, field_number, &last_field_index); +#ifndef NDEBUG + d->debug_valstart = ptr; +#endif - 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; - uint64_t size; - if (_upb_getmode(field) == _UPB_MODE_ARRAY) ndx += 18; - ptr = decode_varint64(d, ptr, &size); - if (size >= INT32_MAX || - ptr - d->end + (int32_t)size > d->limit) { - decode_err(d); /* Length overflow. */ - } - op = delim_ops[ndx]; - val.size = size; - 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 (wire_type == kUpb_WireType_EndGroup) { + d->end_group = field_number; + return ptr; } + field = decode_findfield(d, layout, field_number, &last_field_index); + ptr = decode_wireval(d, ptr, field, wire_type, &val, &op); + if (op >= 0) { - /* Parse, using op for dispatch. */ - switch (_upb_getmode(field)) { - case _UPB_MODE_ARRAY: - ptr = decode_toarray(d, ptr, msg, layout->submsgs, field, &val, op); + ptr = decode_known(d, ptr, msg, layout, field, op, &val); + } else { + switch (op) { + case OP_UNKNOWN: + ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val); break; - case _UPB_MODE_MAP: - ptr = decode_tomap(d, ptr, msg, layout->submsgs, field, &val); + case OP_MSGSET_ITEM: + ptr = decode_msgset(d, ptr, msg, layout); break; - case _UPB_MODE_SCALAR: - ptr = decode_tomsg(d, ptr, msg, layout->submsgs, field, &val, op); + case OP_MSGSET_TYPEID: { + const upb_MiniTable_Extension* ext = _upb_extreg_get( + d->extreg, layout->subs[0].submsg, val.uint64_val); + if (ext) ((upb_MiniTable*)layout)->fields = &ext->field; break; - default: - UPB_UNREACHABLE(); - } - } else { - unknown: - /* Skip unknown field. */ - if (field_number == 0) decode_err(d); - if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size; - if (msg) { - if (wire_type == UPB_WIRE_TYPE_START_GROUP) { - d->unknown = field_start; - d->unknown_msg = msg; - ptr = decode_group(d, ptr, NULL, NULL, field_number); - d->unknown_msg = NULL; - field_start = d->unknown; } - if (!_upb_msg_addunknown(msg, field_start, ptr - field_start, - &d->arena)) { - decode_err(d); - } - } else if (wire_type == UPB_WIRE_TYPE_START_GROUP) { - ptr = decode_group(d, ptr, NULL, NULL, field_number); } } - - if (decode_isdone(d, &ptr)) return ptr; - if (decode_tryfastdispatch(d, &ptr, msg, layout)) return ptr; } + + return UPB_UNLIKELY(layout && layout->required_count) + ? decode_checkrequired(d, ptr, msg, layout) + : ptr; } -const char *fastdecode_generic(struct upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, uint64_t hasbits, - uint64_t data) { +const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data) { (void)data; *(uint32_t*)msg |= hasbits; return decode_msg(d, ptr, msg, decode_totablep(table)); } -static bool decode_top(struct upb_decstate *d, const char *buf, void *msg, - const upb_msglayout *l) { +static upb_DecodeStatus decode_top(struct upb_Decoder* d, const char* buf, + void* msg, const upb_MiniTable* l) { if (!decode_tryfastdispatch(d, &buf, msg, l)) { decode_msg(d, buf, msg, l); } - return d->end_group == DECODE_NOGROUP; + if (d->end_group != DECODE_NOGROUP) return kUpb_DecodeStatus_Malformed; + if (d->missing_required) return kUpb_DecodeStatus_MissingRequired; + return kUpb_DecodeStatus_Ok; } -bool _upb_decode(const char *buf, size_t size, void *msg, - const upb_msglayout *l, const upb_extreg *extreg, int options, - upb_arena *arena) { - bool ok; - upb_decstate state; +upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg, + const upb_MiniTable* l, + const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena) { + upb_Decoder state; unsigned depth = (unsigned)options >> 16; - if (size == 0) { - return true; - } else if (size <= 16) { + 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; + options &= ~kUpb_DecodeOption_AliasString; // Can't alias patch buf. } else { state.end = buf + size - 16; state.limit = 16; - state.alias = options & UPB_DECODE_ALIAS; } + state.extreg = extreg; state.limit_ptr = state.end; state.unknown_msg = NULL; state.depth = depth ? depth : 64; state.end_group = DECODE_NOGROUP; + state.options = (uint16_t)options; + state.missing_required = false; state.arena.head = arena->head; state.arena.last_size = arena->last_size; state.arena.cleanup_metadata = arena->cleanup_metadata; state.arena.parent = arena; - if (UPB_UNLIKELY(UPB_SETJMP(state.err))) { - ok = false; - } else { - ok = decode_top(&state, buf, msg, l); + upb_DecodeStatus status = UPB_SETJMP(state.err); + if (UPB_LIKELY(status == kUpb_DecodeStatus_Ok)) { + status = decode_top(&state, buf, msg, l); } arena->head.ptr = state.arena.head.ptr; arena->head.end = state.arena.head.end; arena->cleanup_metadata = state.arena.cleanup_metadata; - return ok; + return status; } +#undef OP_UNKNOWN +#undef OP_SKIP #undef OP_SCALAR_LG2 #undef OP_FIXPCK_LG2 #undef OP_VARPCK_LG2 #undef OP_STRING +#undef OP_BYTES #undef OP_SUBMSG /** upb/encode.c ************************************************************/ @@ -1008,7 +1346,7 @@ bool _upb_decode(const char *buf, size_t size, void *msg, #define UPB_PB_VARINT_MAX_LEN 10 UPB_NOINLINE -static size_t encode_varint64(uint64_t val, char *buf) { +static size_t encode_varint64(uint64_t val, char* buf) { size_t i = 0; do { uint8_t byte = val & 0x7fU; @@ -1019,12 +1357,16 @@ static size_t encode_varint64(uint64_t val, char *buf) { 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); } +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; + upb_alloc* alloc; char *buf, *ptr, *limit; int options; int depth; @@ -1039,15 +1381,13 @@ static size_t upb_roundup_pow2(size_t bytes) { return ret; } -UPB_NORETURN static void encode_err(upb_encstate *e) { - UPB_LONGJMP(e->err, 1); -} +UPB_NORETURN static void encode_err(upb_encstate* e) { UPB_LONGJMP(e->err, 1); } UPB_NOINLINE -static void encode_growbuffer(upb_encstate *e, size_t bytes) { +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); + char* new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size); if (!new_buf) encode_err(e); @@ -1066,7 +1406,7 @@ static void encode_growbuffer(upb_encstate *e, size_t 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) { +static void encode_reserve(upb_encstate* e, size_t bytes) { if ((size_t)(e->ptr - e->buf) < bytes) { encode_growbuffer(e, bytes); return; @@ -1076,26 +1416,26 @@ static void encode_reserve(upb_encstate *e, size_t 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 */ +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); +static void encode_fixed64(upb_encstate* e, uint64_t val) { + val = _upb_BigEndian_Swap64(val); encode_bytes(e, &val, sizeof(uint64_t)); } -static void encode_fixed32(upb_encstate *e, uint32_t val) { - val = _upb_be_swap32(val); +static void encode_fixed32(upb_encstate* e, uint32_t val) { + val = _upb_BigEndian_Swap32(val); encode_bytes(e, &val, sizeof(uint32_t)); } UPB_NOINLINE -static void encode_longvarint(upb_encstate *e, uint64_t val) { +static void encode_longvarint(upb_encstate* e, uint64_t val) { size_t len; - char *start; + char* start; encode_reserve(e, UPB_PB_VARINT_MAX_LEN); len = encode_varint64(val, e->ptr); @@ -1105,7 +1445,7 @@ static void encode_longvarint(upb_encstate *e, uint64_t val) { } UPB_FORCEINLINE -static void encode_varint(upb_encstate *e, uint64_t val) { +static void encode_varint(upb_encstate* e, uint64_t val) { if (val < 128 && e->ptr != e->buf) { --e->ptr; *e->ptr = val; @@ -1114,34 +1454,47 @@ static void encode_varint(upb_encstate *e, uint64_t val) { } } -static void encode_double(upb_encstate *e, double d) { +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) { +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, uint32_t field_number, +static void encode_tag(upb_encstate* e, uint32_t field_number, uint8_t 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) { +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) { + + if (tag || !_upb_IsLittleEndian()) { while (true) { - encode_bytes(e, ptr, elem_size); - encode_varint(e, tag); + if (elem_size == 4) { + uint32_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap32(val); + encode_bytes(e, &val, elem_size); + } else { + UPB_ASSERT(elem_size == 8); + uint64_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap64(val); + encode_bytes(e, &val, elem_size); + } + + if (tag) encode_varint(e, tag); if (ptr == data) break; ptr -= elem_size; } @@ -1150,87 +1503,81 @@ static void encode_fixedarray(upb_encstate *e, const upb_array *arr, } } -static void encode_message(upb_encstate *e, const upb_msg *msg, - const upb_msglayout *m, size_t *size); +static void encode_message(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* 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; +static void encode_scalar(upb_encstate* e, const void* _field_mem, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { + 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; \ - } \ + ctype val = *(ctype*)field_mem; \ 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; - } + case kUpb_FieldType_Double: + CASE(double, double, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Float: + CASE(float, float, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: + CASE(uint64_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_UInt32: + CASE(uint32_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: + CASE(int32_t, varint, kUpb_WireType_Varint, (int64_t)val); + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + CASE(uint64_t, fixed64, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + CASE(uint32_t, fixed32, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Bool: + CASE(bool, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_SInt32: + CASE(int32_t, varint, kUpb_WireType_Varint, encode_zz32(val)); + case kUpb_FieldType_SInt64: + CASE(int64_t, varint, kUpb_WireType_Varint, encode_zz64(val)); + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + upb_StringView view = *(upb_StringView*)field_mem; encode_bytes(e, view.data, view.size); encode_varint(e, view.size); - wire_type = UPB_WIRE_TYPE_DELIMITED; + wire_type = kUpb_WireType_Delimited; break; } - case UPB_DESCRIPTOR_TYPE_GROUP: { + case kUpb_FieldType_Group: { size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; + void* submsg = *(void**)field_mem; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (submsg == NULL) { return; } if (--e->depth == 0) encode_err(e); - encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_tag(e, f->number, kUpb_WireType_EndGroup); encode_message(e, submsg, subm, &size); - wire_type = UPB_WIRE_TYPE_START_GROUP; + wire_type = kUpb_WireType_StartGroup; e->depth++; break; } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { + case kUpb_FieldType_Message: { size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; + void* submsg = *(void**)field_mem; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (submsg == NULL) { return; } if (--e->depth == 0) encode_err(e); encode_message(e, submsg, subm, &size); encode_varint(e, size); - wire_type = UPB_WIRE_TYPE_DELIMITED; + wire_type = kUpb_WireType_Delimited; e->depth++; break; } @@ -1242,10 +1589,11 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem, encode_tag(e, f->number, wire_type); } -static void encode_array(upb_encstate *e, const upb_msg *msg, - const upb_msglayout *m, const upb_msglayout_field *f) { - const upb_array *arr = *UPB_PTR_AT(msg, f->offset, upb_array*); - bool packed = f->mode & _UPB_MODE_IS_PACKED; +static void encode_array(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { + const upb_Array* arr = *UPB_PTR_AT(msg, f->offset, upb_Array*); + bool packed = f->mode & upb_LabelFlags_IsPacked; size_t pre_len = e->limit - e->ptr; if (arr == NULL || arr->len == 0) { @@ -1254,9 +1602,9 @@ static void encode_array(upb_encstate *e, const upb_msg *msg, #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; \ + const ctype* start = _upb_array_constptr(arr); \ + const ctype* ptr = start + arr->len; \ + uint32_t tag = packed ? 0 : (f->number << 3) | kUpb_WireType_Varint; \ do { \ ptr--; \ encode_varint(e, encode); \ @@ -1268,72 +1616,72 @@ static void encode_array(upb_encstate *e, const upb_msg *msg, #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)); + case kUpb_FieldType_Double: + encode_fixedarray(e, arr, sizeof(double), TAG(kUpb_WireType_64Bit)); break; - case UPB_DESCRIPTOR_TYPE_FLOAT: - encode_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT)); + case kUpb_FieldType_Float: + encode_fixedarray(e, arr, sizeof(float), TAG(kUpb_WireType_32Bit)); break; - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - encode_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT)); + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + encode_fixedarray(e, arr, sizeof(uint64_t), TAG(kUpb_WireType_64Bit)); break; - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - encode_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT)); + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + encode_fixedarray(e, arr, sizeof(uint32_t), TAG(kUpb_WireType_32Bit)); break; - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: VARINT_CASE(uint64_t, *ptr); - case UPB_DESCRIPTOR_TYPE_UINT32: + case kUpb_FieldType_UInt32: VARINT_CASE(uint32_t, *ptr); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_ENUM: + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: VARINT_CASE(int32_t, (int64_t)*ptr); - case UPB_DESCRIPTOR_TYPE_BOOL: + case kUpb_FieldType_Bool: VARINT_CASE(bool, *ptr); - case UPB_DESCRIPTOR_TYPE_SINT32: + case kUpb_FieldType_SInt32: VARINT_CASE(int32_t, encode_zz32(*ptr)); - case UPB_DESCRIPTOR_TYPE_SINT64: + case kUpb_FieldType_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; + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + const upb_StringView* start = _upb_array_constptr(arr); + const upb_StringView* 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); + encode_tag(e, f->number, kUpb_WireType_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]; + case kUpb_FieldType_Group: { + const void* const* start = _upb_array_constptr(arr); + const void* const* ptr = start + arr->len; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (--e->depth == 0) encode_err(e); do { size_t size; ptr--; - encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_tag(e, f->number, kUpb_WireType_EndGroup); encode_message(e, *ptr, subm, &size); - encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); + encode_tag(e, f->number, kUpb_WireType_StartGroup); } while (ptr != start); e->depth++; 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]; + case kUpb_FieldType_Message: { + const void* const* start = _upb_array_constptr(arr); + const void* const* ptr = start + arr->len; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (--e->depth == 0) encode_err(e); do { size_t size; ptr--; encode_message(e, *ptr, subm, &size); encode_varint(e, size); - encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, f->number, kUpb_WireType_Delimited); } while (ptr != start); e->depth++; return; @@ -1343,37 +1691,38 @@ static void encode_array(upb_encstate *e, const upb_msg *msg, if (packed) { encode_varint(e, e->limit - e->ptr - pre_len); - encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, f->number, kUpb_WireType_Delimited); } } -static void encode_mapentry(upb_encstate *e, uint32_t number, - const upb_msglayout *layout, - const upb_map_entry *ent) { - const upb_msglayout_field *key_field = &layout->fields[0]; - const upb_msglayout_field *val_field = &layout->fields[1]; +static void encode_mapentry(upb_encstate* e, uint32_t number, + const upb_MiniTable* layout, + const upb_MapEntry* ent) { + const upb_MiniTable_Field* key_field = &layout->fields[0]; + const upb_MiniTable_Field* val_field = &layout->fields[1]; size_t pre_len = e->limit - e->ptr; size_t size; - encode_scalar(e, &ent->v, layout, val_field, false); - encode_scalar(e, &ent->k, layout, key_field, false); + encode_scalar(e, &ent->v, layout->subs, val_field); + encode_scalar(e, &ent->k, layout->subs, key_field); size = (e->limit - e->ptr) - pre_len; encode_varint(e, size); - encode_tag(e, number, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, number, kUpb_WireType_Delimited); } -static void encode_map(upb_encstate *e, const upb_msg *msg, - const upb_msglayout *m, const upb_msglayout_field *f) { - const upb_map *map = *UPB_PTR_AT(msg, f->offset, const upb_map*); - const upb_msglayout *layout = m->submsgs[f->submsg_index]; +static void encode_map(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { + const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*); + const upb_MiniTable* layout = subs[f->submsg_index].submsg; UPB_ASSERT(layout->field_count == 2); if (map == NULL) return; - if (e->options & UPB_ENCODE_DETERMINISTIC) { + if (e->options & kUpb_Encode_Deterministic) { _upb_sortedmap sorted; _upb_mapsorter_pushmap(&e->sorter, layout->fields[0].descriptortype, map, &sorted); - upb_map_entry ent; + upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { encode_mapentry(e, f->number, layout, &ent); } @@ -1381,10 +1730,10 @@ static void encode_map(upb_encstate *e, const upb_msg *msg, } else { upb_strtable_iter i; upb_strtable_begin(&i, &map->table); - for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { - upb_strview key = upb_strtable_iter_key(&i); + for (; !upb_strtable_done(&i); upb_strtable_next(&i)) { + upb_StringView key = upb_strtable_iter_key(&i); const upb_value val = upb_strtable_iter_value(&i); - upb_map_entry ent; + upb_MapEntry ent; _upb_map_fromkey(key, &ent.k, map->key_size); _upb_map_fromvalue(val, &ent.v, map->val_size); encode_mapentry(e, f->number, layout, &ent); @@ -1392,71 +1741,145 @@ static void encode_map(upb_encstate *e, const upb_msg *msg, } } -static void encode_scalarfield(upb_encstate *e, const char *msg, - const upb_msglayout *m, - const upb_msglayout_field *f) { - bool skip_empty = false; +static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { if (f->presence == 0) { - /* Proto3 presence. */ - skip_empty = true; + /* Proto3 presence or map/array. */ + const void* mem = UPB_PTR_AT(msg, f->offset, void); + switch (f->mode >> upb_FieldRep_Shift) { + case upb_FieldRep_1Byte: { + char ch; + memcpy(&ch, mem, 1); + return ch != 0; + } + case upb_FieldRep_4Byte: { + uint32_t u32; + memcpy(&u32, mem, 4); + return u32 != 0; + } + case upb_FieldRep_8Byte: { + uint64_t u64; + memcpy(&u64, mem, 8); + return u64 != 0; + } + case upb_FieldRep_StringView: { + const upb_StringView* str = (const upb_StringView*)mem; + return str->size != 0; + } + default: + UPB_UNREACHABLE(); + } } else if (f->presence > 0) { /* Proto2 presence: hasbit. */ - if (!_upb_hasbit_field(msg, f)) return; + return _upb_hasbit_field(msg, f); } else { /* Field is in a oneof. */ - if (_upb_getoneofcase_field(msg, f) != f->number) return; + return _upb_getoneofcase_field(msg, f) == f->number; + } +} + +static void encode_field(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field) { + switch (upb_FieldMode_Get(field)) { + case kUpb_FieldMode_Array: + encode_array(e, msg, subs, field); + break; + case kUpb_FieldMode_Map: + encode_map(e, msg, subs, field); + break; + case kUpb_FieldMode_Scalar: + encode_scalar(e, UPB_PTR_AT(msg, field->offset, void), subs, field); + break; + default: + UPB_UNREACHABLE(); } - encode_scalar(e, msg + f->offset, m, f, skip_empty); } -static void encode_message(upb_encstate *e, const upb_msg *msg, - const upb_msglayout *m, size_t *size) { +/* message MessageSet { + * repeated group Item = 1 { + * required int32 type_id = 2; + * required string message = 3; + * } + * } */ +static void encode_msgset_item(upb_encstate* e, + const upb_Message_Extension* ext) { + size_t size; + encode_tag(e, 1, kUpb_WireType_EndGroup); + encode_message(e, ext->data.ptr, ext->ext->sub.submsg, &size); + encode_varint(e, size); + encode_tag(e, 3, kUpb_WireType_Delimited); + encode_varint(e, ext->ext->field.number); + encode_tag(e, 2, kUpb_WireType_Varint); + encode_tag(e, 1, kUpb_WireType_StartGroup); +} + +static void encode_message(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size) { size_t pre_len = e->limit - e->ptr; - const upb_msglayout_field *f = &m->fields[m->field_count]; - const upb_msglayout_field *first = &m->fields[0]; - if ((e->options & UPB_ENCODE_SKIPUNKNOWN) == 0) { + if ((e->options & kUpb_Encode_CheckRequired) && m->required_count) { + uint64_t msg_head; + memcpy(&msg_head, msg, 8); + msg_head = _upb_BigEndian_Swap64(msg_head); + if (upb_MiniTable_requiredmask(m) & ~msg_head) { + encode_err(e); + } + } + + if ((e->options & kUpb_Encode_SkipUnknown) == 0) { size_t unknown_size; - const char *unknown = upb_msg_getunknown(msg, &unknown_size); + const char* unknown = upb_Message_GetUnknown(msg, &unknown_size); if (unknown) { encode_bytes(e, unknown, unknown_size); } } + if (m->ext != upb_ExtMode_NonExtendable) { + /* Encode all extensions together. Unlike C++, we do not attempt to keep + * these in field number order relative to normal fields or even to each + * other. */ + size_t ext_count; + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &ext_count); + const upb_Message_Extension* end = ext + ext_count; + if (ext_count) { + for (; ext != end; ext++) { + if (UPB_UNLIKELY(m->ext == upb_ExtMode_IsMessageSet)) { + encode_msgset_item(e, ext); + } else { + encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field); + } + } + } + } + + const upb_MiniTable_Field* f = &m->fields[m->field_count]; + const upb_MiniTable_Field* first = &m->fields[0]; while (f != first) { f--; - switch (_upb_getmode(f)) { - case _UPB_MODE_ARRAY: - encode_array(e, msg, m, f); - break; - case _UPB_MODE_MAP: - encode_map(e, msg, m, f); - break; - case _UPB_MODE_SCALAR: - encode_scalarfield(e, msg, m, f); - break; - default: - UPB_UNREACHABLE(); + if (encode_shouldencode(e, msg, m->subs, f)) { + encode_field(e, msg, m->subs, f); } } *size = (e->limit - e->ptr) - pre_len; } -char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options, - upb_arena *arena, size_t *size) { +char* upb_Encode(const void* msg, const upb_MiniTable* l, int options, + upb_Arena* arena, size_t* size) { upb_encstate e; unsigned depth = (unsigned)options >> 16; - e.alloc = upb_arena_alloc(arena); + e.alloc = upb_Arena_Alloc(arena); e.buf = NULL; e.limit = NULL; e.ptr = NULL; e.depth = depth ? depth : 64; e.options = options; _upb_mapsorter_init(&e.sorter); - char *ret = NULL; + char* ret = NULL; if (UPB_SETJMP(e.err)) { *size = 0; @@ -1480,30 +1903,32 @@ char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options, /** upb/msg.c ************************************************************/ -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ -static const size_t overhead = sizeof(upb_msg_internaldata); +static const size_t overhead = sizeof(upb_Message_InternalData); -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); +static const upb_Message_Internal* upb_Message_Getinternal_const( + const upb_Message* msg) { + ptrdiff_t size = sizeof(upb_Message_Internal); + return (upb_Message_Internal*)((char*)msg - size); } -upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) { - return _upb_msg_new_inl(l, a); +upb_Message* _upb_Message_New(const upb_MiniTable* l, upb_Arena* a) { + return _upb_Message_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); +void _upb_Message_Clear(upb_Message* msg, const upb_MiniTable* l) { + void* mem = UPB_PTR_AT(msg, -sizeof(upb_Message_Internal), char); memset(mem, 0, upb_msg_sizeof(l)); } -static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) { - upb_msg_internal *in = upb_msg_getinternal(msg); +static bool realloc_internal(upb_Message* msg, size_t need, upb_Arena* arena) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); if (!in->internal) { /* No internal data, allocate from scratch. */ - size_t size = UPB_MAX(128, _upb_lg2ceilsize(need + overhead)); - upb_msg_internaldata *internal = upb_arena_malloc(arena, size); + size_t size = UPB_MAX(128, _upb_Log2Ceilingsize(need + overhead)); + upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); if (!internal) return false; internal->size = size; internal->unknown_end = overhead; @@ -1511,15 +1936,15 @@ static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) { in->internal = internal; } else if (in->internal->ext_begin - in->internal->unknown_end < need) { /* Internal data is too small, reallocate. */ - size_t new_size = _upb_lg2ceilsize(in->internal->size + need); + size_t new_size = _upb_Log2Ceilingsize(in->internal->size + need); size_t ext_bytes = in->internal->size - in->internal->ext_begin; size_t new_ext_begin = new_size - ext_bytes; - upb_msg_internaldata *internal = - upb_arena_realloc(arena, in->internal, in->internal->size, new_size); + upb_Message_InternalData* internal = + upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); if (!internal) return false; if (ext_bytes) { /* Need to move extension data to the end. */ - char *ptr = (char*)internal; + char* ptr = (char*)internal; memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); } internal->ext_begin = new_ext_begin; @@ -1530,24 +1955,24 @@ static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) { return true; } -bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena) { +bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, + upb_Arena* arena) { if (!realloc_internal(msg, len, arena)) return false; - upb_msg_internal *in = upb_msg_getinternal(msg); + upb_Message_Internal* in = upb_Message_Getinternal(msg); memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len); in->internal->unknown_end += len; return true; } -void _upb_msg_discardunknown_shallow(upb_msg *msg) { - upb_msg_internal *in = upb_msg_getinternal(msg); +void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { in->internal->unknown_end = overhead; } } -const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { - const upb_msg_internal *in = upb_msg_getinternal_const(msg); +const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) { + const upb_Message_Internal* in = upb_Message_Getinternal_const(msg); if (in->internal) { *len = in->internal->unknown_end - overhead; return (char*)(in->internal + 1); @@ -1557,11 +1982,12 @@ const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { } } -const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count) { - const upb_msg_internal *in = upb_msg_getinternal_const(msg); +const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, + size_t* count) { + const upb_Message_Internal* in = upb_Message_Getinternal_const(msg); if (in->internal) { - *count = - (in->internal->size - in->internal->ext_begin) / sizeof(upb_msg_ext); + *count = (in->internal->size - in->internal->ext_begin) / + sizeof(upb_Message_Extension); return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); } else { *count = 0; @@ -1569,10 +1995,10 @@ const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count) { } } -const upb_msg_ext *_upb_msg_getext(const upb_msg *msg, - const upb_msglayout_ext *e) { +const upb_Message_Extension* _upb_Message_Getext( + const upb_Message* msg, const upb_MiniTable_Extension* e) { size_t n; - const upb_msg_ext *ext = _upb_msg_getexts(msg, &n); + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); /* For now we use linear search exclusively to find extensions. If this * becomes an issue due to messages with lots of extensions, we can introduce @@ -1586,22 +2012,43 @@ const upb_msg_ext *_upb_msg_getext(const upb_msg *msg, return NULL; } -upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *e, - upb_arena *arena) { - upb_msg_ext *ext = (upb_msg_ext*)_upb_msg_getext(msg, e); +void _upb_Message_Clearext(upb_Message* msg, + const upb_MiniTable_Extension* ext_l) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); + if (!in->internal) return; + const upb_Message_Extension* base = + UPB_PTR_AT(in->internal, in->internal->ext_begin, void); + upb_Message_Extension* ext = + (upb_Message_Extension*)_upb_Message_Getext(msg, ext_l); + if (ext) { + *ext = *base; + in->internal->ext_begin += sizeof(upb_Message_Extension); + } +} + +upb_Message_Extension* _upb_Message_Getorcreateext( + upb_Message* msg, const upb_MiniTable_Extension* e, upb_Arena* arena) { + upb_Message_Extension* ext = + (upb_Message_Extension*)_upb_Message_Getext(msg, e); if (ext) return ext; - if (!realloc_internal(msg, sizeof(upb_msg_ext), arena)) return NULL; - upb_msg_internal *in = upb_msg_getinternal(msg); - in->internal->ext_begin -= sizeof(upb_msg_ext); + if (!realloc_internal(msg, sizeof(upb_Message_Extension), arena)) return NULL; + upb_Message_Internal* in = upb_Message_Getinternal(msg); + in->internal->ext_begin -= sizeof(upb_Message_Extension); ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - memset(ext, 0, sizeof(upb_msg_ext)); + memset(ext, 0, sizeof(upb_Message_Extension)); ext->ext = e; return ext; } -/** upb_array *****************************************************************/ +size_t upb_Message_ExtensionCount(const upb_Message* msg) { + size_t count; + _upb_Message_Getexts(msg, &count); + return count; +} + +/** upb_Array *****************************************************************/ -bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { +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; @@ -1612,7 +2059,7 @@ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { 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); + ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes); if (!ptr) { return false; @@ -1623,44 +2070,44 @@ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { return true; } -static upb_array *getorcreate_array(upb_array **arr_ptr, int elem_size_lg2, - upb_arena *arena) { - upb_array *arr = *arr_ptr; +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); + 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) +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); +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)) { + if (!_upb_Array_Resize(arr, elems + 1, arena)) { return false; } - char *data = _upb_array_ptr(arr); + 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 *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { - upb_map *map = upb_arena_malloc(a, sizeof(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; @@ -1673,65 +2120,69 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { return map; } -static void _upb_mapsorter_getkeys(const void *_a, const void *_b, void *a_key, - void *b_key, size_t size) { - const upb_tabent *const*a = _a; - const upb_tabent *const*b = _b; - upb_strview a_tabkey = upb_tabstrview((*a)->key); - upb_strview b_tabkey = upb_tabstrview((*b)->key); +static void _upb_mapsorter_getkeys(const void* _a, const void* _b, void* a_key, + void* b_key, size_t size) { + const upb_tabent* const* a = _a; + const upb_tabent* const* b = _b; + upb_StringView a_tabkey = upb_tabstrview((*a)->key); + upb_StringView b_tabkey = upb_tabstrview((*b)->key); _upb_map_fromkey(a_tabkey, a_key, size); _upb_map_fromkey(b_tabkey, b_key, size); } -static int _upb_mapsorter_cmpi64(const void *_a, const void *_b) { +#define UPB_COMPARE_INTEGERS(a, b) ((a) < (b) ? -1 : ((a) == (b) ? 0 : 1)) + +static int _upb_mapsorter_cmpi64(const void* _a, const void* _b) { int64_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpu64(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpu64(const void* _a, const void* _b) { uint64_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpi32(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpi32(const void* _a, const void* _b) { int32_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpu32(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpu32(const void* _a, const void* _b) { uint32_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpbool(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpbool(const void* _a, const void* _b) { bool a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 1); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpstr(const void *_a, const void *_b) { - upb_strview a, b; +static int _upb_mapsorter_cmpstr(const void* _a, const void* _b) { + upb_StringView a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, UPB_MAPTYPE_STRING); size_t common_size = UPB_MIN(a.size, b.size); int cmp = memcmp(a.data, b.data, common_size); - if (cmp) return cmp; - return a.size - b.size; + if (cmp) return -cmp; + return UPB_COMPARE_INTEGERS(a.size, b.size); } -bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, - const upb_map *map, _upb_sortedmap *sorted) { - int map_size = _upb_map_size(map); +#undef UPB_COMPARE_INTEGERS + +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const upb_Map* map, _upb_sortedmap* sorted) { + int map_size = _upb_Map_Size(map); sorted->start = s->size; sorted->pos = sorted->start; sorted->end = sorted->start + map_size; /* Grow s->entries if necessary. */ if (sorted->end > s->cap) { - s->cap = _upb_lg2ceilsize(sorted->end); + s->cap = _upb_Log2Ceilingsize(sorted->end); s->entries = realloc(s->entries, s->cap * sizeof(*s->entries)); if (!s->entries) return false; } @@ -1739,9 +2190,9 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, s->size = sorted->end; /* Copy non-empty entries from the table to s->entries. */ - upb_tabent const**dst = &s->entries[sorted->start]; - const upb_tabent *src = map->table.t.entries; - const upb_tabent *end = src + upb_table_size(&map->table.t); + upb_tabent const** dst = &s->entries[sorted->start]; + const upb_tabent* src = map->table.t.entries; + const upb_tabent* end = src + upb_table_size(&map->table.t); for (; src < end; src++) { if (!upb_tabent_isempty(src)) { *dst = src; @@ -1752,32 +2203,33 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, /* Sort entries according to the key type. */ - int (*compar)(const void *, const void *); + int (*compar)(const void*, const void*); switch (key_type) { - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_SINT64: + case kUpb_FieldType_Int64: + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_SInt64: compar = _upb_mapsorter_cmpi64; break; - case UPB_DESCRIPTOR_TYPE_UINT64: - case UPB_DESCRIPTOR_TYPE_FIXED64: + case kUpb_FieldType_UInt64: + case kUpb_FieldType_Fixed64: compar = _upb_mapsorter_cmpu64; break; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_SINT32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - case UPB_DESCRIPTOR_TYPE_ENUM: + case kUpb_FieldType_Int32: + case kUpb_FieldType_SInt32: + case kUpb_FieldType_SFixed32: + case kUpb_FieldType_Enum: compar = _upb_mapsorter_cmpi32; break; - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_FIXED32: + case kUpb_FieldType_UInt32: + case kUpb_FieldType_Fixed32: compar = _upb_mapsorter_cmpu32; break; - case UPB_DESCRIPTOR_TYPE_BOOL: + case kUpb_FieldType_Bool: compar = _upb_mapsorter_cmpbool; break; - case UPB_DESCRIPTOR_TYPE_STRING: + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: compar = _upb_mapsorter_cmpstr; break; default: @@ -1788,36 +2240,39 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, return true; } -/** upb_extreg ****************************************************************/ +/** upb_ExtensionRegistry + * ****************************************************************/ -struct upb_extreg { - upb_arena *arena; - upb_strtable exts; /* Key is upb_msglayout* concatenated with fieldnum. */ +struct upb_ExtensionRegistry { + upb_Arena* arena; + upb_strtable exts; /* Key is upb_MiniTable* concatenated with fieldnum. */ }; -#define EXTREG_KEY_SIZE (sizeof(upb_msglayout*) + sizeof(uint32_t)) +#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t)) -static void extreg_key(char *buf, const upb_msglayout *l, uint32_t fieldnum) { +static void extreg_key(char* buf, const upb_MiniTable* l, uint32_t fieldnum) { memcpy(buf, &l, sizeof(l)); memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum)); } -upb_extreg *upb_extreg_new(upb_arena *arena) { - upb_extreg *r = upb_arena_malloc(arena, sizeof(*r)); +upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { + upb_ExtensionRegistry* r = upb_Arena_Malloc(arena, sizeof(*r)); if (!r) return NULL; r->arena = arena; if (!upb_strtable_init(&r->exts, 8, arena)) return NULL; return r; } -bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count) { +bool _upb_extreg_add(upb_ExtensionRegistry* r, + const upb_MiniTable_Extension** e, size_t count) { char buf[EXTREG_KEY_SIZE]; - const upb_msglayout_ext *start = e; - const upb_msglayout_ext *end = e + count; + const upb_MiniTable_Extension** start = e; + const upb_MiniTable_Extension** end = UPB_PTRADD(e, count); for (; e < end; e++) { - extreg_key(buf, e->extendee, e->field.number); + const upb_MiniTable_Extension* ext = *e; + extreg_key(buf, ext->extendee, ext->field.number); if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, - upb_value_constptr(e), r->arena)) { + upb_value_constptr(ext), r->arena)) { goto failure; } } @@ -1826,15 +2281,16 @@ bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count) { failure: /* Back out the entries previously added. */ for (end = e, e = start; e < end; e++) { - extreg_key(buf, e->extendee, e->field.number); - upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL); + const upb_MiniTable_Extension* ext = *e; + extreg_key(buf, ext->extendee, ext->field.number); + upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL); } return false; } -const upb_msglayout_field *_upb_extreg_get(const upb_extreg *r, - const upb_msglayout *l, - uint32_t num) { +const upb_MiniTable_Extension* _upb_extreg_get(const upb_ExtensionRegistry* r, + const upb_MiniTable* l, + uint32_t num) { char buf[EXTREG_KEY_SIZE]; upb_value v; extreg_key(buf, l, num); @@ -1857,11 +2313,11 @@ const upb_msglayout_field *_upb_extreg_get(const upb_extreg *r, /* Must be last. */ -#define UPB_MAXARRSIZE 16 /* 64k. */ +#define UPB_MAXARRSIZE 16 /* 64k. */ /* From Chromium. */ #define ARRAY_SIZE(x) \ - ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x]))))) static const double MAX_LOAD = 0.85; @@ -1882,20 +2338,20 @@ static int log2ceil(uint64_t v) { int ret = 0; bool pow2 = is_pow2(v); while (v >>= 1) ret++; - ret = pow2 ? ret : ret + 1; /* Ceiling. */ + ret = pow2 ? ret : ret + 1; /* Ceiling. */ return UPB_MIN(UPB_MAXARRSIZE, ret); } -char *upb_strdup2(const char *s, size_t len, upb_arena *a) { +char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { size_t n; - char *p; + 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_arena_malloc(a, n); + p = upb_Arena_Malloc(a, n); if (p) { memcpy(p, s, len); p[len] = 0; @@ -1907,12 +2363,12 @@ char *upb_strdup2(const char *s, size_t len, upb_arena *a) { typedef union { uintptr_t num; struct { - const char *str; + const char* str; size_t len; } str; } lookupkey_t; -static lookupkey_t strkey2(const char *str, size_t len) { +static lookupkey_t strkey2(const char* str, size_t len) { lookupkey_t k; k.str.str = str; k.str.len = len; @@ -1930,24 +2386,17 @@ typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2); /* Base table (shared code) ***************************************************/ -static uint32_t upb_inthash(uintptr_t key) { - return (uint32_t)key; -} +static uint32_t upb_inthash(uintptr_t key) { return (uint32_t)key; } -static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) { +static const upb_tabent* upb_getentry(const upb_table* t, uint32_t hash) { return t->entries + (hash & t->mask); } -static bool upb_arrhas(upb_tabval key) { - return key.val != (uint64_t)-1; -} - +static bool upb_arrhas(upb_tabval key) { return key.val != (uint64_t)-1; } -static bool isfull(upb_table *t) { - return t->count == t->max_count; -} +static bool isfull(upb_table* t) { return t->count == t->max_count; } -static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) { +static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) { size_t bytes; t->count = 0; @@ -1956,7 +2405,7 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) { t->max_count = upb_table_size(t) * MAX_LOAD; bytes = upb_table_size(t) * sizeof(upb_tabent); if (bytes > 0) { - t->entries = upb_arena_malloc(a, bytes); + t->entries = upb_Arena_Malloc(a, bytes); if (!t->entries) return false; memset(t->entries, 0, bytes); } else { @@ -1965,9 +2414,9 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) { return true; } -static upb_tabent *emptyent(upb_table *t, upb_tabent *e) { - upb_tabent *begin = t->entries; - upb_tabent *end = begin + upb_table_size(t); +static upb_tabent* emptyent(upb_table* t, upb_tabent* e) { + upb_tabent* begin = t->entries; + upb_tabent* end = begin + upb_table_size(t); for (e = e + 1; e < end; e++) { if (upb_tabent_isempty(e)) return e; } @@ -1978,13 +2427,13 @@ static upb_tabent *emptyent(upb_table *t, upb_tabent *e) { return NULL; } -static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) { +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; +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); @@ -1995,14 +2444,14 @@ static const upb_tabent *findentry(const upb_table *t, lookupkey_t key, } } -static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key, - uint32_t hash, eqlfunc_t *eql) { +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); +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); @@ -2014,11 +2463,11 @@ static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, } /* 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; +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); @@ -2031,12 +2480,13 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, our_e->next = NULL; } else { /* Collision. */ - upb_tabent *new_e = emptyent(t, mainpos_e); + upb_tabent* new_e = emptyent(t, mainpos_e); /* Head of collider's chain. */ - upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key)); + upb_tabent* chain = getentry_mutable(t, hashfunc(mainpos_e->key)); if (chain == mainpos_e) { /* Existing ent is in its main position (it has the same hash as us, and - * is the head of our chain). Insert to new ent and append to this chain. */ + * 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; @@ -2044,7 +2494,7 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, /* 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. */ + *new_e = *mainpos_e; /* copies next. */ while (chain->next != mainpos_e) { chain = (upb_tabent*)chain->next; UPB_ASSERT(chain); @@ -2059,9 +2509,9 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, 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); +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. */ @@ -2069,11 +2519,11 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, if (val) _upb_value_setval(val, chain->val.val); if (removed) *removed = chain->key; if (chain->next) { - upb_tabent *move = (upb_tabent*)chain->next; + upb_tabent* move = (upb_tabent*)chain->next; *chain = *move; - move->key = 0; /* Make the slot empty. */ + move->key = 0; /* Make the slot empty. */ } else { - chain->key = 0; /* Make the slot empty. */ + chain->key = 0; /* Make the slot empty. */ } return true; } else { @@ -2084,11 +2534,11 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, } if (chain->next) { /* Found element to remove. */ - upb_tabent *rm = (upb_tabent*)chain->next; + 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. */ + rm->key = 0; /* Make the slot empty. */ chain->next = rm->next; return true; } else { @@ -2098,27 +2548,24 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, } } -static size_t next(const upb_table *t, size_t i) { +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])); + 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); -} - +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. */ +/* A simple "subclass" of upb_table that only adds a hash function for strings. + */ -static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) { - uint32_t len = (uint32_t) k2.str.len; - char *str = upb_arena_malloc(a, k2.str.len + sizeof(uint32_t) + 1); +static upb_tabkey strcopy(lookupkey_t k2, upb_Arena* a) { + uint32_t len = (uint32_t)k2.str.len; + char* str = upb_Arena_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); @@ -2128,13 +2575,13 @@ static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) { /* Adapted from ABSL's wyhash. */ -static uint64_t UnalignedLoad64(const void *p) { +static uint64_t UnalignedLoad64(const void* p) { uint64_t val; memcpy(&val, p, 8); return val; } -static uint32_t UnalignedLoad32(const void *p) { +static uint32_t UnalignedLoad32(const void* p) { uint32_t val; memcpy(&val, p, 4); return val; @@ -2177,8 +2624,8 @@ static uint64_t WyhashMix(uint64_t v0, uint64_t v1) { return low ^ high; } -uint64_t Wyhash(const void *data, size_t len, uint64_t seed, - const uint64_t salt[]) { +uint64_t Wyhash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[]) { const uint8_t* ptr = (const uint8_t*)data; uint64_t starting_length = (uint64_t)len; uint64_t current_state = seed ^ salt[0]; @@ -2261,45 +2708,45 @@ const uint64_t kWyhashSalt[5] = { 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL, }; -static uint32_t table_hash(const char *p, size_t n) { +static uint32_t table_hash(const char* p, size_t n) { return Wyhash(p, n, 0, kWyhashSalt); } static uint32_t strhash(upb_tabkey key) { uint32_t len; - char *str = upb_tabstr(key, &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); + char* str = upb_tabstr(k1, &len); return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0); } -bool upb_strtable_init(upb_strtable *t, size_t expected_size, upb_arena *a) { - // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator. +bool upb_strtable_init(upb_strtable* t, size_t expected_size, upb_Arena* a) { + // 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); + int size_lg2 = _upb_Log2Ceiling(need_entries); return init(&t->t, size_lg2, a); } -void upb_strtable_clear(upb_strtable *t) { +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); } -bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a) { +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a) { upb_strtable new_table; upb_strtable_iter i; - if (!init(&new_table.t, size_lg2, a)) - return false; + 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); + for (; !upb_strtable_done(&i); upb_strtable_next(&i)) { + upb_StringView key = upb_strtable_iter_key(&i); upb_strtable_insert(&new_table, key.data, key.size, upb_strtable_iter_value(&i), a); } @@ -2307,8 +2754,8 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a) { return true; } -bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len, - upb_value v, upb_arena *a) { +bool upb_strtable_insert(upb_strtable* t, const char* k, size_t len, + upb_value v, upb_Arena* a) { lookupkey_t key; upb_tabkey tabkey; uint32_t hash; @@ -2329,14 +2776,14 @@ bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len, return true; } -bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, - upb_value *v) { +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_remove(upb_strtable *t, const char *key, size_t len, - upb_value *val) { +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val) { uint32_t hash = table_hash(key, len); upb_tabkey tabkey; return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql); @@ -2344,23 +2791,23 @@ bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len, /* Iteration */ -void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) { +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) { +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) { +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; +upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i) { + upb_StringView key; uint32_t len; UPB_ASSERT(!upb_strtable_done(i)); key.data = upb_tabstr(str_tabent(i)->key, &len); @@ -2368,24 +2815,22 @@ upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) { return key; } -upb_value upb_strtable_iter_value(const upb_strtable_iter *i) { +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) { +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; +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 @@ -2393,34 +2838,32 @@ bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, 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 bool inteql(upb_tabkey k1, lookupkey_t k2) { return k1 == k2.num; } -static upb_tabval *mutable_array(upb_inttable *t) { +static upb_tabval* mutable_array(upb_inttable* t) { return (upb_tabval*)t->array; } -static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) { +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 = + 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, +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) { +size_t upb_inttable_count(const upb_inttable* t) { return t->t.count + t->array_count; } -static void check(upb_inttable *t) { +static void check(upb_inttable* t) { UPB_UNUSED(t); #if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG) { @@ -2428,7 +2871,7 @@ static void check(upb_inttable *t) { size_t count = 0; upb_inttable_iter i; upb_inttable_begin(&i, t); - for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) { + 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)); @@ -2436,8 +2879,8 @@ static void check(upb_inttable *t) { #endif } -bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, - upb_arena *a) { +bool upb_inttable_sizedinit(upb_inttable* t, size_t asize, int hsize_lg2, + upb_Arena* a) { size_t array_bytes; if (!init(&t->t, hsize_lg2, a)) return false; @@ -2446,7 +2889,7 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, t->array_size = UPB_MAX(1, asize); t->array_count = 0; array_bytes = t->array_size * sizeof(upb_value); - t->array = upb_arena_malloc(a, array_bytes); + t->array = upb_Arena_Malloc(a, array_bytes); if (!t->array) { return false; } @@ -2455,15 +2898,16 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, return true; } -bool upb_inttable_init(upb_inttable *t, upb_arena *a) { +bool upb_inttable_init(upb_inttable* t, upb_Arena* a) { return upb_inttable_sizedinit(t, 0, 4, a); } -bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, - upb_arena *a) { +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a) { upb_tabval tabval; tabval.val = val.val; - UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */ + 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])); @@ -2480,7 +2924,7 @@ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, } for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { - const upb_tabent *e = &t->t.entries[i]; + const upb_tabent* e = &t->t.entries[i]; uint32_t hash; upb_value v; @@ -2499,21 +2943,21 @@ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, 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); +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); +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 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])) { @@ -2534,7 +2978,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { return success; } -void upb_inttable_compact(upb_inttable *t, upb_arena *a) { +void upb_inttable_compact(upb_inttable* t, upb_Arena* a) { /* A power-of-two histogram of the table keys. */ size_t counts[UPB_MAXARRSIZE + 1] = {0}; @@ -2573,7 +3017,7 @@ void upb_inttable_compact(upb_inttable *t, upb_arena *a) { { /* Insert all elements into new, perfectly-sized table. */ - size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */ + 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); @@ -2592,25 +3036,25 @@ void upb_inttable_compact(upb_inttable *t, upb_arena *a) { /* Iteration. */ -static const upb_tabent *int_tabent(const upb_inttable_iter *i) { +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) { +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) { +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; +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))) { @@ -2624,45 +3068,137 @@ void upb_inttable_next(upb_inttable_iter *iter) { } } -bool upb_inttable_done(const upb_inttable_iter *i) { +bool upb_inttable_next2(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter) { + intptr_t i = *iter; + if (i < t->array_size) { + while (++i < t->array_size) { + upb_tabval ent = t->array[i]; + if (upb_arrhas(ent)) { + *key = i; + *val = _upb_value_val(ent.val); + *iter = i; + return true; + } + } + } + + size_t tab_idx = next(&t->t, i == -1 ? -1 : i - t->array_size); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + *key = ent->key; + *val = _upb_value_val(ent->val.val); + *iter = tab_idx + t->array_size; + return true; + } + + return false; +} + +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter) { + intptr_t i = *iter; + if (i < t->array_size) { + t->array_count--; + mutable_array(t)[i].val = -1; + } else { + upb_tabent* ent = &t->t.entries[i - t->array_size]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = 0; + ent->next = NULL; + } +} + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter) { + size_t tab_idx = next(&t->t, *iter); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + uint32_t len; + key->data = upb_tabstr(ent->key, &len); + key->size = len; + *val = _upb_value_val(ent->val.val); + *iter = tab_idx; + return true; + } + + return false; +} + +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter) { + intptr_t i = *iter; + upb_tabent* ent = &t->t.entries[i]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = 0; + ent->next = NULL; +} + +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)); + 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) { +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_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); + 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) { +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; +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; } /** upb/upb.c ************************************************************/ - #include +#include #include #include #include @@ -2671,51 +3207,57 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, #include -/* upb_status *****************************************************************/ +// Must be last. + +/* upb_Status *****************************************************************/ -void upb_status_clear(upb_status *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; } +bool upb_Status_IsOk(const upb_Status* status) { return status->ok; } -const char *upb_status_errmsg(const upb_status *status) { return status->msg; } +const char* upb_Status_ErrorMessage(const upb_Status* status) { + return status->msg; +} -void upb_status_seterrmsg(upb_status *status, const char *msg) { +void upb_Status_SetErrorMessage(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'; + strncpy(status->msg, msg, _kUpb_Status_MaxMessage - 1); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; } -void upb_status_seterrf(upb_status *status, const char *fmt, ...) { +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) { va_list args; va_start(args, fmt); - upb_status_vseterrf(status, fmt, args); + upb_Status_VSetErrorFormat(status, fmt, args); va_end(args); } -void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { +void upb_Status_VSetErrorFormat(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'; + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; } -void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) { +void upb_Status_VAppendErrorFormat(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'; + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; } /* upb_alloc ******************************************************************/ -static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, +static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size) { UPB_UNUSED(alloc); UPB_UNUSED(oldsize); @@ -2727,53 +3269,53 @@ static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, } } -static uint32_t *upb_cleanup_pointer(uintptr_t cleanup_metadata) { - return (uint32_t *)(cleanup_metadata & ~0x1); +static uint32_t* upb_cleanup_pointer(uintptr_t cleanup_metadata) { + return (uint32_t*)(cleanup_metadata & ~0x1); } static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata) { return cleanup_metadata & 0x1; } -static uintptr_t upb_cleanup_metadata(uint32_t *cleanup, +static uintptr_t upb_cleanup_metadata(uint32_t* cleanup, bool has_initial_block) { return (uintptr_t)cleanup | has_initial_block; } upb_alloc upb_alloc_global = {&upb_global_allocfunc}; -/* upb_arena ******************************************************************/ +/* upb_Arena ******************************************************************/ /* Be conservative and choose 16 in case anyone is using SSE. */ struct mem_block { - struct mem_block *next; + struct mem_block* next; uint32_t size; uint32_t cleanups; /* Data follows. */ }; typedef struct cleanup_ent { - upb_cleanup_func *cleanup; - void *ud; + upb_CleanupFunc* 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) { +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; + 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, +static void upb_Arena_addblock(upb_Arena* a, upb_Arena* root, void* ptr, size_t size) { - mem_block *block = ptr; + mem_block* block = ptr; /* The block is for arena |a|, but should appear in the freelist of |root|. */ block->next = root->freelist; @@ -2791,33 +3333,33 @@ static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr, 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); +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); + mem_block* block = upb_malloc(root->block_alloc, block_size); if (!block) return false; - upb_arena_addblock(a, root, block, block_size); + 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); +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, +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); + 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; +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; @@ -2825,10 +3367,10 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { return NULL; } - a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena); n -= sizeof(*a); - a->head.alloc.func = &upb_arena_doalloc; + a->head.alloc.func = &upb_Arena_doalloc; a->block_alloc = alloc; a->parent = a; a->refcount = 1; @@ -2836,25 +3378,33 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { a->freelist_tail = NULL; a->cleanup_metadata = upb_cleanup_metadata(NULL, false); - upb_arena_addblock(a, a, mem, n); + 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; +upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) { + upb_Arena* a; + + if (n) { + /* Align initial pointer up so that we return properly-aligned pointers. */ + void* aligned = (void*)UPB_ALIGN_UP((uintptr_t)mem, 16); + size_t delta = (uintptr_t)aligned - (uintptr_t)mem; + n = delta <= n ? n - delta : 0; + mem = aligned; + } /* 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)); + n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_Arena)); - if (UPB_UNLIKELY(n < sizeof(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); + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena); - a->head.alloc.func = &upb_arena_doalloc; + a->head.alloc.func = &upb_Arena_doalloc; a->block_alloc = alloc; a->parent = a; a->refcount = 1; @@ -2867,18 +3417,18 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { return a; } -static void arena_dofree(upb_arena *a) { - mem_block *block = a->freelist; +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; + 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; + cleanup_ent* end = UPB_PTR_AT(block, block->size, void); + cleanup_ent* ptr = end - block->cleanups; for (; ptr < end; ptr++) { ptr->cleanup(ptr->ud); @@ -2890,18 +3440,18 @@ static void arena_dofree(upb_arena *a) { } } -void upb_arena_free(upb_arena *a) { +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; +bool upb_Arena_AddCleanup(upb_Arena* a, void* ud, upb_CleanupFunc* func) { + cleanup_ent* ent; uint32_t* cleanups = upb_cleanup_pointer(a->cleanup_metadata); - if (!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)); + if (!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)); cleanups = upb_cleanup_pointer(a->cleanup_metadata); } @@ -2916,11 +3466,11 @@ bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { return true; } -bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) { - upb_arena *r1 = arena_findroot(a1); - upb_arena *r2 = arena_findroot(a2); +bool 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 true; /* Already fused. */ + if (r1 == r2) return true; /* Already fused. */ /* Do not fuse initial blocks since we cannot lifetime extend them. */ if (upb_cleanup_has_initial_block(r1->cleanup_metadata)) return false; @@ -2932,7 +3482,7 @@ bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) { /* 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; + upb_Arena* tmp = r1; r1 = r2; r2 = tmp; } @@ -2948,6 +3498,40 @@ bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) { return true; } +/* Miscellaneous utilities ****************************************************/ + +static void upb_FixLocale(char* p) { + /* printf() is dependent on locales; sadly there is no easy and portable way + * to avoid this. This little post-processing step will translate 1,2 -> 1.2 + * since JSON needs the latter. Arguably a hack, but it is simple and the + * alternatives are far more complicated, platform-dependent, and/or larger + * in code size. */ + for (; *p; p++) { + if (*p == ',') *p = '.'; + } +} + + +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + snprintf(buf, size, "%.*g", DBL_DIG, val); + if (strtod(buf, NULL) != val) { + snprintf(buf, size, "%.*g", DBL_DIG + 2, val); + assert(strtod(buf, NULL) == val); + } + upb_FixLocale(buf); +} + +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + snprintf(buf, size, "%.*g", FLT_DIG, val); + if (strtof(buf, NULL) != val) { + snprintf(buf, size, "%.*g", FLT_DIG + 3, val); + assert(strtof(buf, NULL) == val); + } + upb_FixLocale(buf); +} + /** upb/decode_fast.c ************************************************************/ // Fast decoder: ~3x the speed of decode.c, but requires x86-64/ARM64. // Also the table size grows by 2x. @@ -2967,44 +3551,48 @@ bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) { // The standard set of arguments passed to each parsing function. // Thanks to x86-64 calling conventions, these will stay in registers. -#define UPB_PARSE_PARAMS \ - upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \ +#define UPB_PARSE_PARAMS \ + upb_Decoder *d, const char *ptr, upb_Message *msg, intptr_t table, \ uint64_t hasbits, uint64_t data #define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data -#define RETURN_GENERIC(m) \ - /* Uncomment either of these for debugging purposes. */ \ - /* fprintf(stderr, m); */ \ - /*__builtin_trap(); */ \ +#define RETURN_GENERIC(m) \ + /* Uncomment either of these for debugging purposes. */ \ + /* fprintf(stderr, m); */ \ + /*__builtin_trap(); */ \ return fastdecode_generic(d, ptr, msg, table, hasbits, 0); typedef enum { - CARD_s = 0, /* Singular (optional, non-repeated) */ - CARD_o = 1, /* Oneof */ - CARD_r = 2, /* Repeated */ - CARD_p = 3 /* Packed Repeated */ + CARD_s = 0, /* Singular (optional, non-repeated) */ + CARD_o = 1, /* Oneof */ + CARD_r = 2, /* Repeated */ + CARD_p = 3 /* Packed Repeated */ } upb_card; UPB_NOINLINE -static const char *fastdecode_isdonefallback(UPB_PARSE_PARAMS) { +static const char* fastdecode_isdonefallback(UPB_PARSE_PARAMS) { int overrun = data; - ptr = decode_isdonefallback_inl(d, ptr, overrun); + int status; + ptr = decode_isdonefallback_inl(d, ptr, overrun, &status); if (ptr == NULL) { - return fastdecode_err(d); + return fastdecode_err(d, status); } data = fastdecode_loadtag(ptr); UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); } UPB_FORCEINLINE -static const char *fastdecode_dispatch(UPB_PARSE_PARAMS) { +static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) { if (UPB_UNLIKELY(ptr >= d->limit_ptr)) { int overrun = ptr - d->end; if (UPB_LIKELY(overrun == d->limit)) { // Parse is finished. *(uint32_t*)msg |= hasbits; // Sync hasbits. - return ptr; + const upb_MiniTable* l = decode_totablep(table); + return UPB_UNLIKELY(l->required_count) + ? decode_checkrequired(d, ptr, msg, l) + : ptr; } else { data = overrun; UPB_MUSTTAIL return fastdecode_isdonefallback(UPB_PARSE_ARGS); @@ -3026,7 +3614,7 @@ static bool fastdecode_checktag(uint16_t data, int tagbytes) { } UPB_FORCEINLINE -static const char *fastdecode_longsize(const char *ptr, int *size) { +static const char* fastdecode_longsize(const char* ptr, int* size) { int i; UPB_ASSERT(*size & 0x80); *size &= 0xff; @@ -3046,8 +3634,8 @@ static const char *fastdecode_longsize(const char *ptr, int *size) { } UPB_FORCEINLINE -static bool fastdecode_boundscheck(const char *ptr, size_t len, - const char *end) { +static bool fastdecode_boundscheck(const char* ptr, size_t len, + const char* end) { uintptr_t uptr = (uintptr_t)ptr; uintptr_t uend = (uintptr_t)end + 16; uintptr_t res = uptr + len; @@ -3055,8 +3643,8 @@ static bool fastdecode_boundscheck(const char *ptr, size_t len, } UPB_FORCEINLINE -static bool fastdecode_boundscheck2(const char *ptr, size_t len, - const char *end) { +static bool fastdecode_boundscheck2(const char* ptr, size_t len, + const char* end) { // This is one extra branch compared to the more normal: // return (size_t)(end - ptr) < size; // However it is one less computation if we are just about to use "ptr + len": @@ -3068,12 +3656,12 @@ static bool fastdecode_boundscheck2(const char *ptr, size_t len, return res < uptr || res > uend; } -typedef const char *fastdecode_delimfunc(upb_decstate *d, const char *ptr, - void *ctx); +typedef const char* fastdecode_delimfunc(upb_Decoder* d, const char* ptr, + void* ctx); UPB_FORCEINLINE -static const char *fastdecode_delimited(upb_decstate *d, const char *ptr, - fastdecode_delimfunc *func, void *ctx) { +static const char* fastdecode_delimited(upb_Decoder* d, const char* ptr, + fastdecode_delimfunc* func, void* ctx) { ptr++; int len = (int8_t)ptr[-1]; if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) { @@ -3098,7 +3686,7 @@ static const char *fastdecode_delimited(upb_decstate *d, const char *ptr, } else { // Fast case: Sub-message is <128 bytes and fits in the current buffer. // This means we can preserve limit/limit_ptr verbatim. - const char *saved_limit_ptr = d->limit_ptr; + const char* saved_limit_ptr = d->limit_ptr; int saved_limit = d->limit; d->limit_ptr = ptr + len; d->limit = d->limit_ptr - d->end; @@ -3114,8 +3702,8 @@ static const char *fastdecode_delimited(upb_decstate *d, const char *ptr, /* singular, oneof, repeated field handling ***********************************/ typedef struct { - upb_array *arr; - void *end; + upb_Array* arr; + void* end; } fastdecode_arr; typedef enum { @@ -3125,21 +3713,21 @@ typedef enum { } fastdecode_next; typedef struct { - void *dst; + void* dst; fastdecode_next next; uint32_t tag; } fastdecode_nextret; UPB_FORCEINLINE -static void *fastdecode_resizearr(upb_decstate *d, void *dst, - fastdecode_arr *farr, int valbytes) { +static void* fastdecode_resizearr(upb_Decoder* d, void* dst, + fastdecode_arr* farr, int valbytes) { if (UPB_UNLIKELY(dst == farr->end)) { size_t old_size = farr->arr->size; size_t old_bytes = old_size * valbytes; size_t new_size = old_size * 2; size_t new_bytes = new_size * valbytes; - char *old_ptr = _upb_array_ptr(farr->arr); - char *new_ptr = upb_arena_realloc(&d->arena, old_ptr, old_bytes, new_bytes); + char* old_ptr = _upb_array_ptr(farr->arr); + char* new_ptr = upb_Arena_Realloc(&d->arena, old_ptr, old_bytes, new_bytes); uint8_t elem_size_lg2 = __builtin_ctz(valbytes); farr->arr->size = new_size; farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2); @@ -3159,20 +3747,20 @@ static bool fastdecode_tagmatch(uint32_t tag, uint64_t data, int tagbytes) { } UPB_FORCEINLINE -static void fastdecode_commitarr(void *dst, fastdecode_arr *farr, +static void fastdecode_commitarr(void* dst, fastdecode_arr* farr, int valbytes) { farr->arr->len = - (size_t)((char *)dst - (char *)_upb_array_ptr(farr->arr)) / valbytes; + (size_t)((char*)dst - (char*)_upb_array_ptr(farr->arr)) / valbytes; } UPB_FORCEINLINE -static fastdecode_nextret fastdecode_nextrepeated(upb_decstate *d, void *dst, - const char **ptr, - fastdecode_arr *farr, +static fastdecode_nextret fastdecode_nextrepeated(upb_Decoder* d, void* dst, + const char** ptr, + fastdecode_arr* farr, uint64_t data, int tagbytes, int valbytes) { fastdecode_nextret ret; - dst = (char *)dst + valbytes; + dst = (char*)dst + valbytes; if (UPB_LIKELY(!decode_isdone(d, ptr))) { ret.tag = fastdecode_loadtag(*ptr); @@ -3192,16 +3780,16 @@ static fastdecode_nextret fastdecode_nextrepeated(upb_decstate *d, void *dst, } UPB_FORCEINLINE -static void *fastdecode_fieldmem(upb_msg *msg, uint64_t data) { +static void* fastdecode_fieldmem(upb_Message* msg, uint64_t data) { size_t ofs = data >> 48; - return (char *)msg + ofs; + return (char*)msg + ofs; } UPB_FORCEINLINE -static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg, - uint64_t *data, uint64_t *hasbits, - fastdecode_arr *farr, int valbytes, - upb_card card) { +static void* fastdecode_getfield(upb_Decoder* d, const char* ptr, + upb_Message* msg, uint64_t* data, + uint64_t* hasbits, fastdecode_arr* farr, + int valbytes, upb_card card) { switch (card) { case CARD_s: { uint8_t hasbit_index = *data >> 24; @@ -3211,20 +3799,20 @@ static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg, } case CARD_o: { uint16_t case_ofs = *data >> 32; - uint32_t *oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t); + uint32_t* oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t); uint8_t field_number = *data >> 24; *oneof_case = field_number; return fastdecode_fieldmem(msg, *data); } case CARD_r: { - // Get pointer to upb_array and allocate/expand if necessary. + // Get pointer to upb_Array and allocate/expand if necessary. uint8_t elem_size_lg2 = __builtin_ctz(valbytes); - upb_array **arr_p = fastdecode_fieldmem(msg, *data); - char *begin; + upb_Array** arr_p = fastdecode_fieldmem(msg, *data); + char* begin; *(uint32_t*)msg |= *hasbits; *hasbits = 0; if (UPB_LIKELY(!*arr_p)) { - farr->arr = _upb_array_new(&d->arena, 8, elem_size_lg2); + farr->arr = _upb_Array_New(&d->arena, 8, elem_size_lg2); *arr_p = farr->arr; } else { farr->arr = *arr_p; @@ -3240,17 +3828,17 @@ static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg, } UPB_FORCEINLINE -static bool fastdecode_flippacked(uint64_t *data, int tagbytes) { +static bool fastdecode_flippacked(uint64_t* data, int tagbytes) { *data ^= (0x2 ^ 0x0); // Patch data to match packed wiretype. return fastdecode_checktag(*data, tagbytes); } -#define FASTDECODE_CHECKPACKED(tagbytes, card, func) \ - if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \ - if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \ - UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \ - } \ - RETURN_GENERIC("packed check tag mismatch\n"); \ +#define FASTDECODE_CHECKPACKED(tagbytes, card, func) \ + if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \ + if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \ + UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \ + } \ + RETURN_GENERIC("packed check tag mismatch\n"); \ } /* varint fields **************************************************************/ @@ -3272,7 +3860,7 @@ static uint64_t fastdecode_munge(uint64_t val, int valbytes, bool zigzag) { } UPB_FORCEINLINE -static const char *fastdecode_varint64(const char *ptr, uint64_t *val) { +static const char* fastdecode_varint64(const char* ptr, uint64_t* val) { ptr++; *val = (uint8_t)ptr[-1]; if (UPB_UNLIKELY(*val & 0x80)) { @@ -3298,7 +3886,7 @@ static const char *fastdecode_varint64(const char *ptr, uint64_t *val) { #define FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ valbytes, card, zigzag, packed) \ uint64_t val; \ - void *dst; \ + void* dst; \ fastdecode_arr farr; \ \ FASTDECODE_CHECKPACKED(tagbytes, card, packed); \ @@ -3318,8 +3906,7 @@ static const char *fastdecode_varint64(const char *ptr, uint64_t *val) { \ ptr += tagbytes; \ ptr = fastdecode_varint64(ptr, &val); \ - if (ptr == NULL) \ - return fastdecode_err(d); \ + if (ptr == NULL) return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ val = fastdecode_munge(val, valbytes, zigzag); \ memcpy(dst, &val, valbytes); \ \ @@ -3327,14 +3914,14 @@ static const char *fastdecode_varint64(const char *ptr, uint64_t *val) { fastdecode_nextret ret = fastdecode_nextrepeated( \ d, dst, &ptr, &farr, data, tagbytes, valbytes); \ switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ } \ } \ \ @@ -3343,15 +3930,15 @@ static const char *fastdecode_varint64(const char *ptr, uint64_t *val) { typedef struct { uint8_t valbytes; bool zigzag; - void *dst; + void* dst; fastdecode_arr farr; } fastdecode_varintdata; UPB_FORCEINLINE -static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr, - void *ctx) { - fastdecode_varintdata *data = ctx; - void *dst = data->dst; +static const char* fastdecode_topackedvarint(upb_Decoder* d, const char* ptr, + void* ctx) { + fastdecode_varintdata* data = ctx; + void* dst = data->dst; uint64_t val; while (!decode_isdone(d, &ptr)) { @@ -3360,32 +3947,32 @@ static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr, if (ptr == NULL) return NULL; val = fastdecode_munge(val, data->valbytes, data->zigzag); memcpy(dst, &val, data->valbytes); - dst = (char *)dst + data->valbytes; + dst = (char*)dst + data->valbytes; } fastdecode_commitarr(dst, &data->farr, data->valbytes); return ptr; } -#define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ - valbytes, zigzag, unpacked) \ - fastdecode_varintdata ctx = {valbytes, zigzag}; \ - \ - FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \ - \ - ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \ - valbytes, CARD_r); \ - if (UPB_UNLIKELY(!ctx.dst)) { \ - RETURN_GENERIC("need array resize\n"); \ - } \ - \ - ptr += tagbytes; \ - ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \ - \ - if (UPB_UNLIKELY(ptr == NULL)) { \ - return fastdecode_err(d); \ - } \ - \ +#define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ + valbytes, zigzag, unpacked) \ + fastdecode_varintdata ctx = {valbytes, zigzag}; \ + \ + FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \ + \ + ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \ + valbytes, CARD_r); \ + if (UPB_UNLIKELY(!ctx.dst)) { \ + RETURN_GENERIC("need array resize\n"); \ + } \ + \ + ptr += tagbytes; \ + ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \ + \ + if (UPB_UNLIKELY(ptr == NULL)) { \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ + } \ + \ UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0); #define FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ @@ -3407,7 +3994,7 @@ static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr, #define F(card, type, valbytes, tagbytes) \ UPB_NOINLINE \ - const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \ CARD_##card, type##_ZZ, \ upb_pr##type##valbytes##_##tagbytes##bt, \ @@ -3443,48 +4030,47 @@ TAGBYTES(p) #undef FASTDECODE_PACKEDVARINT #undef FASTDECODE_VARINT - /* fixed fields ***************************************************************/ -#define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \ - valbytes, card, packed) \ - void *dst; \ - fastdecode_arr farr; \ - \ - FASTDECODE_CHECKPACKED(tagbytes, card, packed) \ - \ - dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \ - card); \ - if (card == CARD_r) { \ - if (UPB_UNLIKELY(!dst)) { \ - RETURN_GENERIC("couldn't allocate array in arena\n"); \ - } \ - } \ - \ - again: \ - if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, valbytes); \ - } \ - \ - ptr += tagbytes; \ - memcpy(dst, ptr, valbytes); \ - ptr += valbytes; \ - \ - if (card == CARD_r) { \ - fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, valbytes); \ - switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ - } \ - } \ - \ +#define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \ + valbytes, card, packed) \ + void* dst; \ + fastdecode_arr farr; \ + \ + FASTDECODE_CHECKPACKED(tagbytes, card, packed) \ + \ + dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \ + card); \ + if (card == CARD_r) { \ + if (UPB_UNLIKELY(!dst)) { \ + RETURN_GENERIC("couldn't allocate array in arena\n"); \ + } \ + } \ + \ + again: \ + if (card == CARD_r) { \ + dst = fastdecode_resizearr(d, dst, &farr, valbytes); \ + } \ + \ + ptr += tagbytes; \ + memcpy(dst, ptr, valbytes); \ + ptr += valbytes; \ + \ + if (card == CARD_r) { \ + fastdecode_nextret ret = fastdecode_nextrepeated( \ + d, dst, &ptr, &farr, data, tagbytes, valbytes); \ + switch (ret.next) { \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ + } \ + } \ + \ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); #define FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \ @@ -3500,24 +4086,24 @@ TAGBYTES(p) \ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \ (size % valbytes) != 0)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ \ - upb_array **arr_p = fastdecode_fieldmem(msg, data); \ - upb_array *arr = *arr_p; \ + upb_Array** arr_p = fastdecode_fieldmem(msg, data); \ + upb_Array* arr = *arr_p; \ uint8_t elem_size_lg2 = __builtin_ctz(valbytes); \ int elems = size / valbytes; \ \ if (UPB_LIKELY(!arr)) { \ - *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2); \ + *arr_p = arr = _upb_Array_New(&d->arena, elems, elem_size_lg2); \ if (!arr) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ } else { \ - _upb_array_resize(arr, elems, &d->arena); \ + _upb_Array_Resize(arr, elems, &d->arena); \ } \ \ - char *dst = _upb_array_ptr(arr); \ + char* dst = _upb_array_ptr(arr); \ memcpy(dst, ptr, size); \ arr->len = elems; \ \ @@ -3539,7 +4125,7 @@ TAGBYTES(p) #define F(card, valbytes, tagbytes) \ UPB_NOINLINE \ - const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \ CARD_##card, upb_ppf##valbytes##_##tagbytes##bt, \ upb_prf##valbytes##_##tagbytes##bt); \ @@ -3566,18 +4152,19 @@ TAGBYTES(p) /* string fields **************************************************************/ -typedef const char *fastdecode_copystr_func(struct upb_decstate *d, - const char *ptr, upb_msg *msg, - const upb_msglayout *table, - uint64_t hasbits, upb_strview *dst); +typedef const char* fastdecode_copystr_func(struct upb_Decoder* d, + const char* ptr, upb_Message* msg, + const upb_MiniTable* table, + uint64_t hasbits, + upb_StringView* dst); UPB_NOINLINE -static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, +static const char* fastdecode_verifyutf8(upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, uint64_t hasbits, uint64_t data) { - upb_strview *dst = (upb_strview*)data; + upb_StringView* dst = (upb_StringView*)data; if (!decode_verifyutf8_inl(dst->data, dst->size)) { - return fastdecode_err(d); + return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); } UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); } @@ -3591,16 +4178,16 @@ static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, \ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \ dst->size = 0; \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ \ - if (d->alias) { \ + if (d->options & kUpb_DecodeOption_AliasString) { \ dst->data = ptr; \ dst->size = size; \ } else { \ - char *data = upb_arena_malloc(&d->arena, size); \ + char* data = upb_Arena_Malloc(&d->arena, size); \ if (!data) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_OutOfMemory); \ } \ memcpy(data, ptr, size); \ dst->data = data; \ @@ -3616,27 +4203,25 @@ static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, } UPB_NOINLINE -static const char *fastdecode_longstring_utf8(struct upb_decstate *d, - const char *ptr, upb_msg *msg, +static const char* fastdecode_longstring_utf8(struct upb_Decoder* d, + const char* ptr, upb_Message* msg, intptr_t table, uint64_t hasbits, uint64_t data) { - upb_strview *dst = (upb_strview*)data; + upb_StringView* dst = (upb_StringView*)data; FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, true); } UPB_NOINLINE -static const char *fastdecode_longstring_noutf8(struct upb_decstate *d, - const char *ptr, upb_msg *msg, - intptr_t table, - uint64_t hasbits, - uint64_t data) { - upb_strview *dst = (upb_strview*)data; +static const char* fastdecode_longstring_noutf8( + struct upb_Decoder* d, const char* ptr, upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data) { + upb_StringView* dst = (upb_StringView*)data; FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, false); } UPB_FORCEINLINE -static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, - int copy, char *data, upb_strview *dst) { +static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size, + int copy, char* data, upb_StringView* dst) { d->arena.head.ptr += copy; dst->data = data; UPB_UNPOISON_MEMORY_REGION(data, copy); @@ -3644,96 +4229,95 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, UPB_POISON_MEMORY_REGION(data + size, copy - size); } -#define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ - card, validate_utf8) \ - upb_strview *dst; \ - fastdecode_arr farr; \ - int64_t size; \ - size_t arena_has; \ - size_t common_has; \ - char *buf; \ - \ - UPB_ASSERT(!d->alias); \ - UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \ - \ - dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ - sizeof(upb_strview), card); \ - \ - again: \ - if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \ - } \ - \ - size = (uint8_t)ptr[tagbytes]; \ - ptr += tagbytes + 1; \ - dst->size = size; \ - \ - buf = d->arena.head.ptr; \ - arena_has = _upb_arenahas(&d->arena); \ - common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \ - \ - if (UPB_LIKELY(size <= 15 - tagbytes)) { \ - if (arena_has < 16) \ - goto longstr; \ - d->arena.head.ptr += 16; \ - memcpy(buf, ptr - tagbytes - 1, 16); \ - dst->data = buf + tagbytes + 1; \ - } else if (UPB_LIKELY(size <= 32)) { \ - if (UPB_UNLIKELY(common_has < 32)) \ - goto longstr; \ - fastdecode_docopy(d, ptr, size, 32, buf, dst); \ - } else if (UPB_LIKELY(size <= 64)) { \ - if (UPB_UNLIKELY(common_has < 64)) \ - goto longstr; \ - fastdecode_docopy(d, ptr, size, 64, buf, dst); \ - } else if (UPB_LIKELY(size < 128)) { \ - if (UPB_UNLIKELY(common_has < 128)) \ - goto longstr; \ - fastdecode_docopy(d, ptr, size, 128, buf, dst); \ - } else { \ - goto longstr; \ - } \ - \ - ptr += size; \ - \ - if (card == CARD_r) { \ - if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ - return fastdecode_err(d); \ - } \ - fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \ - switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ - } \ - } \ - \ - if (card != CARD_r && validate_utf8) { \ - data = (uint64_t)dst; \ - UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \ - } \ - \ - UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \ - \ - longstr: \ - ptr--; \ - if (validate_utf8) { \ - UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \ - hasbits, (uint64_t)dst); \ - } else { \ - UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \ - hasbits, (uint64_t)dst); \ +#define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ + card, validate_utf8) \ + upb_StringView* dst; \ + fastdecode_arr farr; \ + int64_t size; \ + size_t arena_has; \ + size_t common_has; \ + char* buf; \ + \ + UPB_ASSERT((d->options & kUpb_DecodeOption_AliasString) == 0); \ + UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \ + \ + dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ + sizeof(upb_StringView), card); \ + \ + again: \ + if (card == CARD_r) { \ + dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \ + } \ + \ + size = (uint8_t)ptr[tagbytes]; \ + ptr += tagbytes + 1; \ + dst->size = size; \ + \ + buf = d->arena.head.ptr; \ + arena_has = _upb_ArenaHas(&d->arena); \ + common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \ + \ + if (UPB_LIKELY(size <= 15 - tagbytes)) { \ + if (arena_has < 16) goto longstr; \ + d->arena.head.ptr += 16; \ + memcpy(buf, ptr - tagbytes - 1, 16); \ + dst->data = buf + tagbytes + 1; \ + } else if (UPB_LIKELY(size <= 32)) { \ + if (UPB_UNLIKELY(common_has < 32)) goto longstr; \ + fastdecode_docopy(d, ptr, size, 32, buf, dst); \ + } else if (UPB_LIKELY(size <= 64)) { \ + if (UPB_UNLIKELY(common_has < 64)) goto longstr; \ + fastdecode_docopy(d, ptr, size, 64, buf, dst); \ + } else if (UPB_LIKELY(size < 128)) { \ + if (UPB_UNLIKELY(common_has < 128)) goto longstr; \ + fastdecode_docopy(d, ptr, size, 128, buf, dst); \ + } else { \ + goto longstr; \ + } \ + \ + ptr += size; \ + \ + if (card == CARD_r) { \ + if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ + return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \ + } \ + fastdecode_nextret ret = fastdecode_nextrepeated( \ + d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \ + switch (ret.next) { \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ + } \ + } \ + \ + if (card != CARD_r && validate_utf8) { \ + data = (uint64_t)dst; \ + UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \ + } \ + \ + UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \ + \ + longstr: \ + if (card == CARD_r) { \ + fastdecode_commitarr(dst + 1, &farr, sizeof(upb_StringView)); \ + } \ + ptr--; \ + if (validate_utf8) { \ + UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \ + hasbits, (uint64_t)dst); \ + } else { \ + UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \ + hasbits, (uint64_t)dst); \ } #define FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, card, \ copyfunc, validate_utf8) \ - upb_strview *dst; \ + upb_StringView* dst; \ fastdecode_arr farr; \ int64_t size; \ \ @@ -3741,16 +4325,16 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, RETURN_GENERIC("string field tag mismatch\n"); \ } \ \ - if (UPB_UNLIKELY(!d->alias)) { \ + if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \ UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \ } \ \ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ - sizeof(upb_strview), card); \ + sizeof(upb_StringView), card); \ \ again: \ if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \ + dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \ } \ \ size = (int8_t)ptr[tagbytes]; \ @@ -3773,27 +4357,27 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, \ if (card == CARD_r) { \ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \ } \ fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \ + d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \ switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - if (UPB_UNLIKELY(!d->alias)) { \ - /* Buffer flipped and we can't alias any more. Bounce to */ \ - /* copyfunc(), but via dispatch since we need to reload table */ \ - /* data also. */ \ - fastdecode_commitarr(dst, &farr, sizeof(upb_strview)); \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \ + /* Buffer flipped and we can't alias any more. Bounce to */ \ + /* copyfunc(), but via dispatch since we need to reload table */ \ + /* data also. */ \ + fastdecode_commitarr(dst, &farr, sizeof(upb_StringView)); \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + } \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ data = ret.tag; \ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - } \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ } \ } \ \ @@ -3812,11 +4396,11 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, #define F(card, tagbytes, type) \ UPB_NOINLINE \ - const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ CARD_##card, type##_VALIDATE); \ } \ - const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, \ CARD_##card, upb_c##card##type##_##tagbytes##bt, \ type##_VALIDATE); \ @@ -3845,12 +4429,12 @@ TAGBYTES(r) /* message fields *************************************************************/ UPB_INLINE -upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l, - int msg_ceil_bytes) { - size_t size = l->size + sizeof(upb_msg_internal); - char *msg_data; +upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* l, + int msg_ceil_bytes) { + size_t size = l->size + sizeof(upb_Message_Internal); + char* msg_data; if (UPB_LIKELY(msg_ceil_bytes > 0 && - _upb_arenahas(&d->arena) >= msg_ceil_bytes)) { + _upb_ArenaHas(&d->arena) >= msg_ceil_bytes)) { UPB_ASSERT(size <= (size_t)msg_ceil_bytes); msg_data = d->arena.head.ptr; d->arena.head.ptr += size; @@ -3858,21 +4442,21 @@ upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l, memset(msg_data, 0, msg_ceil_bytes); UPB_POISON_MEMORY_REGION(msg_data + size, msg_ceil_bytes - size); } else { - msg_data = (char*)upb_arena_malloc(&d->arena, size); + msg_data = (char*)upb_Arena_Malloc(&d->arena, size); memset(msg_data, 0, size); } - return msg_data + sizeof(upb_msg_internal); + return msg_data + sizeof(upb_Message_Internal); } typedef struct { intptr_t table; - upb_msg *msg; + upb_Message* msg; } fastdecode_submsgdata; UPB_FORCEINLINE -static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, - void *ctx) { - fastdecode_submsgdata *submsg = ctx; +static const char* fastdecode_tosubmsg(upb_Decoder* d, const char* ptr, + void* ctx) { + fastdecode_submsgdata* submsg = ctx; ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0, 0); UPB_ASSUME(ptr != NULL); return ptr; @@ -3885,12 +4469,14 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, RETURN_GENERIC("submessage field tag mismatch\n"); \ } \ \ - if (--d->depth == 0) return fastdecode_err(d); \ + if (--d->depth == 0) { \ + return fastdecode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); \ + } \ \ - upb_msg **dst; \ + upb_Message** dst; \ uint32_t submsg_idx = (data >> 16) & 0xff; \ - const upb_msglayout *tablep = decode_totablep(table); \ - const upb_msglayout *subtablep = tablep->submsgs[submsg_idx]; \ + const upb_MiniTable* tablep = decode_totablep(table); \ + const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \ fastdecode_arr farr; \ \ @@ -3899,16 +4485,16 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, } \ \ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ - sizeof(upb_msg *), card); \ + sizeof(upb_Message*), card); \ \ if (card == CARD_s) { \ - *(uint32_t *)msg |= hasbits; \ + *(uint32_t*)msg |= hasbits; \ hasbits = 0; \ } \ \ again: \ if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg *)); \ + dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_Message*)); \ } \ \ submsg.msg = *dst; \ @@ -3921,12 +4507,12 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \ \ if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ \ if (card == CARD_r) { \ fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *)); \ + d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_Message*)); \ switch (ret.next) { \ case FD_NEXT_SAMEFIELD: \ dst = ret.dst; \ @@ -3945,21 +4531,21 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); #define F(card, tagbytes, size_ceil, ceil_arg) \ - const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \ + const char* upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \ UPB_PARSE_PARAMS) { \ FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, ceil_arg, \ CARD_##card); \ } #define SIZES(card, tagbytes) \ - F(card, tagbytes, 64, 64) \ + F(card, tagbytes, 64, 64) \ F(card, tagbytes, 128, 128) \ F(card, tagbytes, 192, 192) \ F(card, tagbytes, 256, 256) \ F(card, tagbytes, max, -1) #define TAGBYTES(card) \ - SIZES(card, 1) \ + SIZES(card, 1) \ SIZES(card, 2) TAGBYTES(s) @@ -3971,7 +4557,7 @@ TAGBYTES(r) #undef F #undef FASTDECODE_SUBMSG -#endif /* UPB_FASTTABLE */ +#endif /* UPB_FASTTABLE */ /** bazel-out/k8-fastbuild/bin/external/com_google_protobuf/google/protobuf/descriptor.upb.c ************************************************************//* This file was generated by upbc (the upb compiler) from the input * file: @@ -3984,474 +4570,564 @@ TAGBYTES(r) #include -static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = { - &google_protobuf_FileDescriptorProto_msginit, +static const upb_MiniTable_Sub google_protobuf_FileDescriptorSet_submsgs[1] = { + {.submsg = &google_protobuf_FileDescriptorProto_msginit}, }; -static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_FileDescriptorSet__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_FileDescriptorSet_msginit = { +const upb_MiniTable google_protobuf_FileDescriptorSet_msginit = { &google_protobuf_FileDescriptorSet_submsgs[0], &google_protobuf_FileDescriptorSet__fields[0], - UPB_SIZE(8, 8), 1, false, 1, 255, + UPB_SIZE(8, 8), 1, upb_ExtMode_NonExtendable, 1, 255, 0, }; -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_MiniTable_Sub google_protobuf_FileDescriptorProto_submsgs[6] = { + {.submsg = &google_protobuf_DescriptorProto_msginit}, + {.submsg = &google_protobuf_EnumDescriptorProto_msginit}, + {.submsg = &google_protobuf_FieldDescriptorProto_msginit}, + {.submsg = &google_protobuf_FileOptions_msginit}, + {.submsg = &google_protobuf_ServiceDescriptorProto_msginit}, + {.submsg = &google_protobuf_SourceCodeInfo_msginit}, }; -static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = { - {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(36, 72), 0, 0, 12, _UPB_MODE_ARRAY}, - {4, UPB_SIZE(40, 80), 0, 0, 11, _UPB_MODE_ARRAY}, - {5, UPB_SIZE(44, 88), 0, 1, 11, _UPB_MODE_ARRAY}, - {6, UPB_SIZE(48, 96), 0, 4, 11, _UPB_MODE_ARRAY}, - {7, UPB_SIZE(52, 104), 0, 2, 11, _UPB_MODE_ARRAY}, - {8, UPB_SIZE(28, 56), 3, 3, 11, _UPB_MODE_SCALAR}, - {9, UPB_SIZE(32, 64), 4, 5, 11, _UPB_MODE_SCALAR}, - {10, UPB_SIZE(56, 112), 0, 0, 5, _UPB_MODE_ARRAY}, - {11, UPB_SIZE(60, 120), 0, 0, 5, _UPB_MODE_ARRAY}, - {12, UPB_SIZE(20, 40), 5, 0, 12, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_FileDescriptorProto__fields[12] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 24), 2, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {3, UPB_SIZE(36, 72), 0, 0, 12, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {4, UPB_SIZE(40, 80), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {5, UPB_SIZE(44, 88), 0, 1, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {6, UPB_SIZE(48, 96), 0, 4, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {7, UPB_SIZE(52, 104), 0, 2, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {8, UPB_SIZE(28, 56), 3, 3, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {9, UPB_SIZE(32, 64), 4, 5, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {10, UPB_SIZE(56, 112), 0, 0, 5, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {11, UPB_SIZE(60, 120), 0, 0, 5, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {12, UPB_SIZE(20, 40), 5, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { +const upb_MiniTable google_protobuf_FileDescriptorProto_msginit = { &google_protobuf_FileDescriptorProto_submsgs[0], &google_protobuf_FileDescriptorProto__fields[0], - UPB_SIZE(64, 128), 12, false, 12, 255, + UPB_SIZE(64, 128), 12, upb_ExtMode_NonExtendable, 12, 255, 0, }; -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_MiniTable_Sub google_protobuf_DescriptorProto_submsgs[7] = { + {.submsg = &google_protobuf_DescriptorProto_msginit}, + {.submsg = &google_protobuf_DescriptorProto_ExtensionRange_msginit}, + {.submsg = &google_protobuf_DescriptorProto_ReservedRange_msginit}, + {.submsg = &google_protobuf_EnumDescriptorProto_msginit}, + {.submsg = &google_protobuf_FieldDescriptorProto_msginit}, + {.submsg = &google_protobuf_MessageOptions_msginit}, + {.submsg = &google_protobuf_OneofDescriptorProto_msginit}, }; -static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { - {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(16, 32), 0, 4, 11, _UPB_MODE_ARRAY}, - {3, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY}, - {4, UPB_SIZE(24, 48), 0, 3, 11, _UPB_MODE_ARRAY}, - {5, UPB_SIZE(28, 56), 0, 1, 11, _UPB_MODE_ARRAY}, - {6, UPB_SIZE(32, 64), 0, 4, 11, _UPB_MODE_ARRAY}, - {7, UPB_SIZE(12, 24), 2, 5, 11, _UPB_MODE_SCALAR}, - {8, UPB_SIZE(36, 72), 0, 6, 11, _UPB_MODE_ARRAY}, - {9, UPB_SIZE(40, 80), 0, 2, 11, _UPB_MODE_ARRAY}, - {10, UPB_SIZE(44, 88), 0, 0, 12, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_DescriptorProto__fields[10] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 32), 0, 4, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {3, UPB_SIZE(20, 40), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {4, UPB_SIZE(24, 48), 0, 3, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {5, UPB_SIZE(28, 56), 0, 1, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {6, UPB_SIZE(32, 64), 0, 4, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {7, UPB_SIZE(12, 24), 2, 5, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {8, UPB_SIZE(36, 72), 0, 6, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {9, UPB_SIZE(40, 80), 0, 2, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {10, UPB_SIZE(44, 88), 0, 0, 12, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_DescriptorProto_msginit = { +const upb_MiniTable google_protobuf_DescriptorProto_msginit = { &google_protobuf_DescriptorProto_submsgs[0], &google_protobuf_DescriptorProto__fields[0], - UPB_SIZE(48, 96), 10, false, 10, 255, + UPB_SIZE(48, 96), 10, upb_ExtMode_NonExtendable, 10, 255, 0, }; -static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { - &google_protobuf_ExtensionRangeOptions_msginit, +static const upb_MiniTable_Sub google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { + {.submsg = &google_protobuf_ExtensionRangeOptions_msginit}, }; -static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { - {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(12, 16), 3, 0, 11, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 8), 2, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 16), 3, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = { +const upb_MiniTable google_protobuf_DescriptorProto_ExtensionRange_msginit = { &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0], &google_protobuf_DescriptorProto_ExtensionRange__fields[0], - UPB_SIZE(16, 24), 3, false, 3, 255, + UPB_SIZE(16, 24), 3, upb_ExtMode_NonExtendable, 3, 255, 0, }; -static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = { - {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_DescriptorProto_ReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 8), 2, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = { +const upb_MiniTable google_protobuf_DescriptorProto_ReservedRange_msginit = { NULL, &google_protobuf_DescriptorProto_ReservedRange__fields[0], - UPB_SIZE(16, 16), 2, false, 2, 255, + UPB_SIZE(16, 16), 2, upb_ExtMode_NonExtendable, 2, 255, 0, }; -static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_ExtensionRangeOptions_submsgs[1] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, }; -static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = { - {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_ExtensionRangeOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = { +const upb_MiniTable google_protobuf_ExtensionRangeOptions_msginit = { &google_protobuf_ExtensionRangeOptions_submsgs[0], &google_protobuf_ExtensionRangeOptions__fields[0], - UPB_SIZE(8, 8), 1, false, 0, 255, + UPB_SIZE(8, 8), 1, upb_ExtMode_Extendable, 0, 255, 0, }; -static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = { - &google_protobuf_FieldOptions_msginit, +static const upb_MiniTable_Sub google_protobuf_FieldDescriptorProto_submsgs[3] = { + {.submsg = &google_protobuf_FieldOptions_msginit}, + {.subenum = &google_protobuf_FieldDescriptorProto_Label_enuminit}, + {.subenum = &google_protobuf_FieldDescriptorProto_Type_enuminit}, }; -static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = { - {1, UPB_SIZE(24, 24), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(32, 40), 2, 0, 12, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(12, 12), 3, 0, 5, _UPB_MODE_SCALAR}, - {4, UPB_SIZE(4, 4), 4, 0, 14, _UPB_MODE_SCALAR}, - {5, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR}, - {6, UPB_SIZE(40, 56), 6, 0, 12, _UPB_MODE_SCALAR}, - {7, UPB_SIZE(48, 72), 7, 0, 12, _UPB_MODE_SCALAR}, - {8, UPB_SIZE(64, 104), 8, 0, 11, _UPB_MODE_SCALAR}, - {9, UPB_SIZE(16, 16), 9, 0, 5, _UPB_MODE_SCALAR}, - {10, UPB_SIZE(56, 88), 10, 0, 12, _UPB_MODE_SCALAR}, - {17, UPB_SIZE(20, 20), 11, 0, 8, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_FieldDescriptorProto__fields[11] = { + {1, UPB_SIZE(24, 24), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(32, 40), 2, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 12), 3, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {4, UPB_SIZE(4, 4), 4, 1, 14, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {5, UPB_SIZE(8, 8), 5, 2, 14, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {6, UPB_SIZE(40, 56), 6, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {7, UPB_SIZE(48, 72), 7, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {8, UPB_SIZE(64, 104), 8, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {9, UPB_SIZE(16, 16), 9, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {10, UPB_SIZE(56, 88), 10, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {17, UPB_SIZE(20, 20), 11, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { +const upb_MiniTable google_protobuf_FieldDescriptorProto_msginit = { &google_protobuf_FieldDescriptorProto_submsgs[0], &google_protobuf_FieldDescriptorProto__fields[0], - UPB_SIZE(72, 112), 11, false, 10, 255, + UPB_SIZE(72, 112), 11, upb_ExtMode_NonExtendable, 10, 255, 0, }; -static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { - &google_protobuf_OneofOptions_msginit, +static const upb_MiniTable_Sub google_protobuf_OneofDescriptorProto_submsgs[1] = { + {.submsg = &google_protobuf_OneofOptions_msginit}, }; -static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = { - {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(12, 24), 2, 0, 11, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_OneofDescriptorProto__fields[2] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 24), 2, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { +const upb_MiniTable google_protobuf_OneofDescriptorProto_msginit = { &google_protobuf_OneofDescriptorProto_submsgs[0], &google_protobuf_OneofDescriptorProto__fields[0], - UPB_SIZE(16, 32), 2, false, 2, 255, + UPB_SIZE(16, 32), 2, upb_ExtMode_NonExtendable, 2, 255, 0, }; -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_MiniTable_Sub google_protobuf_EnumDescriptorProto_submsgs[3] = { + {.submsg = &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit}, + {.submsg = &google_protobuf_EnumOptions_msginit}, + {.submsg = &google_protobuf_EnumValueDescriptorProto_msginit}, }; -static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = { - {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(16, 32), 0, 2, 11, _UPB_MODE_ARRAY}, - {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR}, - {4, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY}, - {5, UPB_SIZE(24, 48), 0, 0, 12, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_EnumDescriptorProto__fields[5] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 32), 0, 2, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 24), 2, 1, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 40), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 48), 0, 0, 12, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { +const upb_MiniTable google_protobuf_EnumDescriptorProto_msginit = { &google_protobuf_EnumDescriptorProto_submsgs[0], &google_protobuf_EnumDescriptorProto__fields[0], - UPB_SIZE(32, 64), 5, false, 5, 255, + UPB_SIZE(32, 64), 5, upb_ExtMode_NonExtendable, 5, 255, 0, }; -static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { - {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 8), 2, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { +const upb_MiniTable google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { NULL, &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0], - UPB_SIZE(16, 16), 2, false, 2, 255, + UPB_SIZE(16, 16), 2, upb_ExtMode_NonExtendable, 2, 255, 0, }; -static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = { - &google_protobuf_EnumValueOptions_msginit, +static const upb_MiniTable_Sub google_protobuf_EnumValueDescriptorProto_submsgs[1] = { + {.submsg = &google_protobuf_EnumValueOptions_msginit}, }; -static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = { - {1, UPB_SIZE(8, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(16, 24), 3, 0, 11, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_EnumValueDescriptorProto__fields[3] = { + {1, UPB_SIZE(8, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(4, 4), 2, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 24), 3, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { +const upb_MiniTable google_protobuf_EnumValueDescriptorProto_msginit = { &google_protobuf_EnumValueDescriptorProto_submsgs[0], &google_protobuf_EnumValueDescriptorProto__fields[0], - UPB_SIZE(24, 32), 3, false, 3, 255, + UPB_SIZE(24, 32), 3, upb_ExtMode_NonExtendable, 3, 255, 0, }; -static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = { - &google_protobuf_MethodDescriptorProto_msginit, - &google_protobuf_ServiceOptions_msginit, +static const upb_MiniTable_Sub google_protobuf_ServiceDescriptorProto_submsgs[2] = { + {.submsg = &google_protobuf_MethodDescriptorProto_msginit}, + {.submsg = &google_protobuf_ServiceOptions_msginit}, }; -static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = { - {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(16, 32), 0, 0, 11, _UPB_MODE_ARRAY}, - {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_ServiceDescriptorProto__fields[3] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 32), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 24), 2, 1, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = { +const upb_MiniTable google_protobuf_ServiceDescriptorProto_msginit = { &google_protobuf_ServiceDescriptorProto_submsgs[0], &google_protobuf_ServiceDescriptorProto__fields[0], - UPB_SIZE(24, 48), 3, false, 3, 255, + UPB_SIZE(24, 48), 3, upb_ExtMode_NonExtendable, 3, 255, 0, }; -static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = { - &google_protobuf_MethodOptions_msginit, +static const upb_MiniTable_Sub google_protobuf_MethodDescriptorProto_submsgs[1] = { + {.submsg = &google_protobuf_MethodOptions_msginit}, }; -static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = { - {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(20, 40), 3, 0, 12, _UPB_MODE_SCALAR}, - {4, UPB_SIZE(28, 56), 4, 0, 11, _UPB_MODE_SCALAR}, - {5, UPB_SIZE(1, 1), 5, 0, 8, _UPB_MODE_SCALAR}, - {6, UPB_SIZE(2, 2), 6, 0, 8, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_MethodDescriptorProto__fields[6] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 24), 2, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {3, UPB_SIZE(20, 40), 3, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {4, UPB_SIZE(28, 56), 4, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {5, UPB_SIZE(1, 1), 5, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {6, UPB_SIZE(2, 2), 6, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = { +const upb_MiniTable google_protobuf_MethodDescriptorProto_msginit = { &google_protobuf_MethodDescriptorProto_submsgs[0], &google_protobuf_MethodDescriptorProto__fields[0], - UPB_SIZE(32, 64), 6, false, 6, 255, + UPB_SIZE(32, 64), 6, upb_ExtMode_NonExtendable, 6, 255, 0, }; -static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_FileOptions_submsgs[2] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, + {.subenum = &google_protobuf_FileOptions_OptimizeMode_enuminit}, }; -static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { - {1, UPB_SIZE(20, 24), 1, 0, 12, _UPB_MODE_SCALAR}, - {8, UPB_SIZE(28, 40), 2, 0, 12, _UPB_MODE_SCALAR}, - {9, UPB_SIZE(4, 4), 3, 0, 14, _UPB_MODE_SCALAR}, - {10, UPB_SIZE(8, 8), 4, 0, 8, _UPB_MODE_SCALAR}, - {11, UPB_SIZE(36, 56), 5, 0, 12, _UPB_MODE_SCALAR}, - {16, UPB_SIZE(9, 9), 6, 0, 8, _UPB_MODE_SCALAR}, - {17, UPB_SIZE(10, 10), 7, 0, 8, _UPB_MODE_SCALAR}, - {18, UPB_SIZE(11, 11), 8, 0, 8, _UPB_MODE_SCALAR}, - {20, UPB_SIZE(12, 12), 9, 0, 8, _UPB_MODE_SCALAR}, - {23, UPB_SIZE(13, 13), 10, 0, 8, _UPB_MODE_SCALAR}, - {27, UPB_SIZE(14, 14), 11, 0, 8, _UPB_MODE_SCALAR}, - {31, UPB_SIZE(15, 15), 12, 0, 8, _UPB_MODE_SCALAR}, - {36, UPB_SIZE(44, 72), 13, 0, 12, _UPB_MODE_SCALAR}, - {37, UPB_SIZE(52, 88), 14, 0, 12, _UPB_MODE_SCALAR}, - {39, UPB_SIZE(60, 104), 15, 0, 12, _UPB_MODE_SCALAR}, - {40, UPB_SIZE(68, 120), 16, 0, 12, _UPB_MODE_SCALAR}, - {41, UPB_SIZE(76, 136), 17, 0, 12, _UPB_MODE_SCALAR}, - {42, UPB_SIZE(16, 16), 18, 0, 8, _UPB_MODE_SCALAR}, - {44, UPB_SIZE(84, 152), 19, 0, 12, _UPB_MODE_SCALAR}, - {45, UPB_SIZE(92, 168), 20, 0, 12, _UPB_MODE_SCALAR}, - {999, UPB_SIZE(100, 184), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_FileOptions__fields[21] = { + {1, UPB_SIZE(20, 24), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {8, UPB_SIZE(28, 40), 2, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {9, UPB_SIZE(4, 4), 3, 1, 14, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {10, UPB_SIZE(8, 8), 4, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {11, UPB_SIZE(36, 56), 5, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {16, UPB_SIZE(9, 9), 6, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {17, UPB_SIZE(10, 10), 7, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {18, UPB_SIZE(11, 11), 8, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {20, UPB_SIZE(12, 12), 9, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {23, UPB_SIZE(13, 13), 10, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {27, UPB_SIZE(14, 14), 11, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {31, UPB_SIZE(15, 15), 12, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {36, UPB_SIZE(44, 72), 13, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {37, UPB_SIZE(52, 88), 14, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {39, UPB_SIZE(60, 104), 15, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {40, UPB_SIZE(68, 120), 16, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {41, UPB_SIZE(76, 136), 17, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {42, UPB_SIZE(16, 16), 18, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {44, UPB_SIZE(84, 152), 19, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {45, UPB_SIZE(92, 168), 20, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {999, UPB_SIZE(100, 184), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_FileOptions_msginit = { +const upb_MiniTable google_protobuf_FileOptions_msginit = { &google_protobuf_FileOptions_submsgs[0], &google_protobuf_FileOptions__fields[0], - UPB_SIZE(104, 192), 21, false, 1, 255, + UPB_SIZE(104, 192), 21, upb_ExtMode_Extendable, 1, 255, 0, }; -static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_MessageOptions_submsgs[1] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, }; -static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = { - {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(3, 3), 3, 0, 8, _UPB_MODE_SCALAR}, - {7, UPB_SIZE(4, 4), 4, 0, 8, _UPB_MODE_SCALAR}, - {999, UPB_SIZE(8, 8), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_MessageOptions__fields[5] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {2, UPB_SIZE(2, 2), 2, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {3, UPB_SIZE(3, 3), 3, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {7, UPB_SIZE(4, 4), 4, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {999, UPB_SIZE(8, 8), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_MessageOptions_msginit = { +const upb_MiniTable google_protobuf_MessageOptions_msginit = { &google_protobuf_MessageOptions_submsgs[0], &google_protobuf_MessageOptions__fields[0], - UPB_SIZE(16, 16), 5, false, 3, 255, + UPB_SIZE(16, 16), 5, upb_ExtMode_Extendable, 3, 255, 0, }; -static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_FieldOptions_submsgs[3] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, + {.subenum = &google_protobuf_FieldOptions_CType_enuminit}, + {.subenum = &google_protobuf_FieldOptions_JSType_enuminit}, }; -static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { - {1, UPB_SIZE(4, 4), 1, 0, 14, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(12, 12), 2, 0, 8, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(13, 13), 3, 0, 8, _UPB_MODE_SCALAR}, - {5, UPB_SIZE(14, 14), 4, 0, 8, _UPB_MODE_SCALAR}, - {6, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR}, - {10, UPB_SIZE(15, 15), 6, 0, 8, _UPB_MODE_SCALAR}, - {999, UPB_SIZE(16, 16), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_FieldOptions__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 1, 14, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 12), 2, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {3, UPB_SIZE(13, 13), 3, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {5, UPB_SIZE(14, 14), 4, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {6, UPB_SIZE(8, 8), 5, 2, 14, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {10, UPB_SIZE(15, 15), 6, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {999, UPB_SIZE(16, 16), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_FieldOptions_msginit = { +const upb_MiniTable google_protobuf_FieldOptions_msginit = { &google_protobuf_FieldOptions_submsgs[0], &google_protobuf_FieldOptions__fields[0], - UPB_SIZE(24, 24), 7, false, 3, 255, + UPB_SIZE(24, 24), 7, upb_ExtMode_Extendable, 3, 255, 0, }; -static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_OneofOptions_submsgs[1] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, }; -static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = { - {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_OneofOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_OneofOptions_msginit = { +const upb_MiniTable google_protobuf_OneofOptions_msginit = { &google_protobuf_OneofOptions_submsgs[0], &google_protobuf_OneofOptions__fields[0], - UPB_SIZE(8, 8), 1, false, 0, 255, + UPB_SIZE(8, 8), 1, upb_ExtMode_Extendable, 0, 255, 0, }; -static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_EnumOptions_submsgs[1] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, }; -static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = { - {2, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR}, - {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_EnumOptions__fields[3] = { + {2, UPB_SIZE(1, 1), 1, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {3, UPB_SIZE(2, 2), 2, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {999, UPB_SIZE(4, 8), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_EnumOptions_msginit = { +const upb_MiniTable google_protobuf_EnumOptions_msginit = { &google_protobuf_EnumOptions_submsgs[0], &google_protobuf_EnumOptions__fields[0], - UPB_SIZE(8, 16), 3, false, 0, 255, + UPB_SIZE(8, 16), 3, upb_ExtMode_Extendable, 0, 255, 0, }; -static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_EnumValueOptions_submsgs[1] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, }; -static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = { - {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR}, - {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_EnumValueOptions__fields[2] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {999, UPB_SIZE(4, 8), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_EnumValueOptions_msginit = { +const upb_MiniTable google_protobuf_EnumValueOptions_msginit = { &google_protobuf_EnumValueOptions_submsgs[0], &google_protobuf_EnumValueOptions__fields[0], - UPB_SIZE(8, 16), 2, false, 1, 255, + UPB_SIZE(8, 16), 2, upb_ExtMode_Extendable, 1, 255, 0, }; -static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_ServiceOptions_submsgs[1] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, }; -static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = { - {33, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR}, - {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_ServiceOptions__fields[2] = { + {33, UPB_SIZE(1, 1), 1, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {999, UPB_SIZE(4, 8), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_ServiceOptions_msginit = { +const upb_MiniTable google_protobuf_ServiceOptions_msginit = { &google_protobuf_ServiceOptions_submsgs[0], &google_protobuf_ServiceOptions__fields[0], - UPB_SIZE(8, 16), 2, false, 0, 255, + UPB_SIZE(8, 16), 2, upb_ExtMode_Extendable, 0, 255, 0, }; -static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, +static const upb_MiniTable_Sub google_protobuf_MethodOptions_submsgs[2] = { + {.submsg = &google_protobuf_UninterpretedOption_msginit}, + {.subenum = &google_protobuf_MethodOptions_IdempotencyLevel_enuminit}, }; -static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { - {33, UPB_SIZE(8, 8), 1, 0, 8, _UPB_MODE_SCALAR}, - {34, UPB_SIZE(4, 4), 2, 0, 14, _UPB_MODE_SCALAR}, - {999, UPB_SIZE(12, 16), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_MethodOptions__fields[3] = { + {33, UPB_SIZE(8, 8), 1, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {34, UPB_SIZE(4, 4), 2, 1, 14, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {999, UPB_SIZE(12, 16), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_MethodOptions_msginit = { +const upb_MiniTable google_protobuf_MethodOptions_msginit = { &google_protobuf_MethodOptions_submsgs[0], &google_protobuf_MethodOptions__fields[0], - UPB_SIZE(16, 24), 3, false, 0, 255, + UPB_SIZE(16, 24), 3, upb_ExtMode_Extendable, 0, 255, 0, }; -static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = { - &google_protobuf_UninterpretedOption_NamePart_msginit, +static const upb_MiniTable_Sub google_protobuf_UninterpretedOption_submsgs[1] = { + {.submsg = &google_protobuf_UninterpretedOption_NamePart_msginit}, }; -static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = { - {2, UPB_SIZE(56, 80), 0, 0, 11, _UPB_MODE_ARRAY}, - {3, UPB_SIZE(32, 32), 1, 0, 12, _UPB_MODE_SCALAR}, - {4, UPB_SIZE(8, 8), 2, 0, 4, _UPB_MODE_SCALAR}, - {5, UPB_SIZE(16, 16), 3, 0, 3, _UPB_MODE_SCALAR}, - {6, UPB_SIZE(24, 24), 4, 0, 1, _UPB_MODE_SCALAR}, - {7, UPB_SIZE(40, 48), 5, 0, 12, _UPB_MODE_SCALAR}, - {8, UPB_SIZE(48, 64), 6, 0, 12, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_UninterpretedOption__fields[7] = { + {2, UPB_SIZE(56, 80), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {3, UPB_SIZE(32, 32), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {4, UPB_SIZE(8, 8), 2, 0, 4, kUpb_FieldMode_Scalar | (upb_FieldRep_8Byte << upb_FieldRep_Shift)}, + {5, UPB_SIZE(16, 16), 3, 0, 3, kUpb_FieldMode_Scalar | (upb_FieldRep_8Byte << upb_FieldRep_Shift)}, + {6, UPB_SIZE(24, 24), 4, 0, 1, kUpb_FieldMode_Scalar | (upb_FieldRep_8Byte << upb_FieldRep_Shift)}, + {7, UPB_SIZE(40, 48), 5, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {8, UPB_SIZE(48, 64), 6, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_UninterpretedOption_msginit = { +const upb_MiniTable google_protobuf_UninterpretedOption_msginit = { &google_protobuf_UninterpretedOption_submsgs[0], &google_protobuf_UninterpretedOption__fields[0], - UPB_SIZE(64, 96), 7, false, 0, 255, + UPB_SIZE(64, 96), 7, upb_ExtMode_NonExtendable, 0, 255, 0, }; -static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = { - {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {2, UPB_SIZE(1, 1), 2, 0, 8, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_UninterpretedOption_NamePart__fields[2] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {2, UPB_SIZE(1, 1), 2, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = { +const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msginit = { NULL, &google_protobuf_UninterpretedOption_NamePart__fields[0], - UPB_SIZE(16, 32), 2, false, 2, 255, + UPB_SIZE(16, 32), 2, upb_ExtMode_NonExtendable, 2, 255, 2, }; -static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = { - &google_protobuf_SourceCodeInfo_Location_msginit, +static const upb_MiniTable_Sub google_protobuf_SourceCodeInfo_submsgs[1] = { + {.submsg = &google_protobuf_SourceCodeInfo_Location_msginit}, }; -static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_SourceCodeInfo__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { +const upb_MiniTable google_protobuf_SourceCodeInfo_msginit = { &google_protobuf_SourceCodeInfo_submsgs[0], &google_protobuf_SourceCodeInfo__fields[0], - UPB_SIZE(8, 8), 1, false, 1, 255, + UPB_SIZE(8, 8), 1, upb_ExtMode_NonExtendable, 1, 255, 0, }; -static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = { - {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED}, - {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED}, - {3, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR}, - {4, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR}, - {6, UPB_SIZE(28, 56), 0, 0, 12, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_SourceCodeInfo_Location__fields[5] = { + {1, UPB_SIZE(20, 40), 0, 0, 5, kUpb_FieldMode_Array | upb_LabelFlags_IsPacked | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {2, UPB_SIZE(24, 48), 0, 0, 5, kUpb_FieldMode_Array | upb_LabelFlags_IsPacked | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {3, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {4, UPB_SIZE(12, 24), 2, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {6, UPB_SIZE(28, 56), 0, 0, 12, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { +const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msginit = { NULL, &google_protobuf_SourceCodeInfo_Location__fields[0], - UPB_SIZE(32, 64), 5, false, 4, 255, + UPB_SIZE(32, 64), 5, upb_ExtMode_NonExtendable, 4, 255, 0, }; -static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = { - &google_protobuf_GeneratedCodeInfo_Annotation_msginit, +static const upb_MiniTable_Sub google_protobuf_GeneratedCodeInfo_submsgs[1] = { + {.submsg = &google_protobuf_GeneratedCodeInfo_Annotation_msginit}, }; -static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY}, +static const upb_MiniTable_Field google_protobuf_GeneratedCodeInfo__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { +const upb_MiniTable google_protobuf_GeneratedCodeInfo_msginit = { &google_protobuf_GeneratedCodeInfo_submsgs[0], &google_protobuf_GeneratedCodeInfo__fields[0], - UPB_SIZE(8, 8), 1, false, 1, 255, + UPB_SIZE(8, 8), 1, upb_ExtMode_NonExtendable, 1, 255, 0, }; -static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { - {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED}, - {2, UPB_SIZE(12, 16), 1, 0, 12, _UPB_MODE_SCALAR}, - {3, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR}, - {4, UPB_SIZE(8, 8), 3, 0, 5, _UPB_MODE_SCALAR}, +static const upb_MiniTable_Field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { + {1, UPB_SIZE(20, 32), 0, 0, 5, kUpb_FieldMode_Array | upb_LabelFlags_IsPacked | (upb_FieldRep_Pointer << upb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 1, 0, 12, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)}, + {3, UPB_SIZE(4, 4), 2, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, + {4, UPB_SIZE(8, 8), 3, 0, 5, kUpb_FieldMode_Scalar | (upb_FieldRep_4Byte << upb_FieldRep_Shift)}, }; -const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { +const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msginit = { NULL, &google_protobuf_GeneratedCodeInfo_Annotation__fields[0], - UPB_SIZE(24, 48), 4, false, 4, 255, + UPB_SIZE(24, 48), 4, upb_ExtMode_NonExtendable, 4, 255, 0, +}; + +static const upb_MiniTable *messages_layout[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, +}; + +const upb_MiniTable_Enum google_protobuf_FieldDescriptorProto_Type_enuminit = { + NULL, + 0x7fffeULL, + 0, +}; + +const upb_MiniTable_Enum google_protobuf_FieldDescriptorProto_Label_enuminit = { + NULL, + 0xeULL, + 0, +}; + +const upb_MiniTable_Enum google_protobuf_FileOptions_OptimizeMode_enuminit = { + NULL, + 0xeULL, + 0, +}; + +const upb_MiniTable_Enum google_protobuf_FieldOptions_CType_enuminit = { + NULL, + 0x7ULL, + 0, +}; + +const upb_MiniTable_Enum google_protobuf_FieldOptions_JSType_enuminit = { + NULL, + 0x7ULL, + 0, +}; + +const upb_MiniTable_Enum google_protobuf_MethodOptions_IdempotencyLevel_enuminit = { + NULL, + 0x7ULL, + 0, +}; + +static const upb_MiniTable_Enum *enums_layout[6] = { + &google_protobuf_FieldDescriptorProto_Type_enuminit, + &google_protobuf_FieldDescriptorProto_Label_enuminit, + &google_protobuf_FileOptions_OptimizeMode_enuminit, + &google_protobuf_FieldOptions_CType_enuminit, + &google_protobuf_FieldOptions_JSType_enuminit, + &google_protobuf_MethodOptions_IdempotencyLevel_enuminit, +}; + +const upb_MiniTable_File google_protobuf_descriptor_proto_upb_file_layout = { + messages_layout, + enums_layout, + NULL, + 27, + 6, + 0, }; @@ -4469,143 +5145,240 @@ const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { typedef struct { size_t len; - char str[1]; /* Null-terminated string data follows. */ + 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; +/* The upb core does not generally have a concept of default instances. However + * for descriptor options we make an exception since the max size is known and + * modest (<200 bytes). All types can share a default instance since it is + * initialized to zeroes. + * + * We have to allocate an extra pointer for upb's internal metadata. */ +static const char opt_default_buf[_UPB_MAXOPT_SIZE + sizeof(void*)] = {0}; +static const char* opt_default = &opt_default_buf[sizeof(void*)]; + +struct upb_FieldDef { + const google_protobuf_FieldOptions* opts; + const upb_FileDef* file; + const upb_MessageDef* 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; + str_t* str; } defaultval; - const upb_oneofdef *oneof; union { - const upb_msgdef *msgdef; - const upb_enumdef *enumdef; - const google_protobuf_FieldDescriptorProto *unresolved; + const upb_OneofDef* oneof; + const upb_MessageDef* extension_scope; + } scope; + union { + const upb_MessageDef* msgdef; + const upb_EnumDef* enumdef; + const google_protobuf_FieldDescriptorProto* unresolved; } sub; uint32_t number_; uint16_t index_; - uint16_t layout_index; + uint16_t layout_index; /* Index into msgdef->layout->fields or file->exts */ + bool has_default; bool is_extension_; - bool lazy_; bool packed_; bool proto3_optional_; - upb_descriptortype_t type_; - upb_label_t label_; + bool has_json_name_; + upb_FieldType type_; + upb_Label label_; +}; + +struct upb_ExtensionRange { + const google_protobuf_ExtensionRangeOptions* opts; + int32_t start; + int32_t end; }; -struct upb_msgdef { - const upb_msglayout *layout; - const upb_filedef *file; - const char *full_name; +struct upb_MessageDef { + const google_protobuf_MessageOptions* opts; + const upb_MiniTable* layout; + const upb_FileDef* file; + const upb_MessageDef* containing_type; + const char* full_name; /* Tables for looking up fields by number and name. */ upb_inttable itof; upb_strtable ntof; - const upb_fielddef *fields; - const upb_oneofdef *oneofs; + /* All nested defs. + * MEM: We could save some space here by putting nested defs in a contiguous + * region and calculating counts from offsets or vice-versa. */ + const upb_FieldDef* fields; + const upb_OneofDef* oneofs; + const upb_ExtensionRange* ext_ranges; + const upb_MessageDef* nested_msgs; + const upb_EnumDef* nested_enums; + const upb_FieldDef* nested_exts; 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). */ + int oneof_count; + int ext_range_count; + int nested_msg_count; + int nested_enum_count; + int nested_ext_count; + bool in_message_set; + upb_WellKnown well_known_type; }; -struct upb_enumdef { - const upb_filedef *file; - const char *full_name; +struct upb_EnumDef { + const google_protobuf_EnumOptions* opts; + const upb_MiniTable_Enum* layout; // Only for proto2. + const upb_FileDef* file; + const upb_MessageDef* containing_type; // Could be merged with "file". + const char* full_name; upb_strtable ntoi; upb_inttable iton; + const upb_EnumValueDef* values; + int value_count; int32_t defaultval; }; -struct upb_oneofdef { - const upb_msgdef *parent; - const char *full_name; +struct upb_EnumValueDef { + const google_protobuf_EnumValueOptions* opts; + const upb_EnumDef* parent; + const char* full_name; + int32_t number; +}; + +struct upb_OneofDef { + const google_protobuf_OneofOptions* opts; + const upb_MessageDef* parent; + const char* full_name; int field_count; bool synthetic; - const upb_fielddef **fields; + 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; - - const upb_filedef **deps; - const upb_msgdef *msgs; - const upb_enumdef *enums; - const upb_fielddef *exts; - const upb_symtab *symtab; +struct upb_FileDef { + const google_protobuf_FileOptions* opts; + const char* name; + const char* package; + + const upb_FileDef** deps; + const int32_t* public_deps; + const int32_t* weak_deps; + const upb_MessageDef* top_lvl_msgs; + const upb_EnumDef* top_lvl_enums; + const upb_FieldDef* top_lvl_exts; + const upb_ServiceDef* services; + const upb_MiniTable_Extension** ext_layouts; + const upb_DefPool* symtab; int dep_count; - int msg_count; - int enum_count; - int ext_count; - upb_syntax_t syntax; + int public_dep_count; + int weak_dep_count; + int top_lvl_msg_count; + int top_lvl_enum_count; + int top_lvl_ext_count; + int service_count; + int ext_count; /* All exts in the file. */ + upb_Syntax syntax; +}; + +struct upb_MethodDef { + const google_protobuf_MethodOptions* opts; + upb_ServiceDef* service; + const char* full_name; + const upb_MessageDef* input_type; + const upb_MessageDef* output_type; + bool client_streaming; + bool server_streaming; +}; + +struct upb_ServiceDef { + const google_protobuf_ServiceOptions* opts; + const upb_FileDef* file; + const char* full_name; + upb_MethodDef* methods; + int method_count; + int index; }; -struct upb_symtab { - upb_arena *arena; +struct upb_DefPool { + upb_Arena* arena; upb_strtable syms; /* full_name -> packed def ptr */ - upb_strtable files; /* file_name -> upb_filedef* */ + upb_strtable files; /* file_name -> upb_FileDef* */ + upb_inttable exts; /* upb_MiniTable_Extension* -> upb_FieldDef* */ + upb_ExtensionRegistry* extreg; size_t bytes_loaded; }; /* Inside a symtab we store tagged pointers to specific def types. */ typedef enum { - UPB_DEFTYPE_FIELD = 0, + UPB_DEFTYPE_MASK = 7, /* Only inside symtab table. */ + UPB_DEFTYPE_EXT = 0, UPB_DEFTYPE_MSG = 1, UPB_DEFTYPE_ENUM = 2, + UPB_DEFTYPE_ENUMVAL = 3, + UPB_DEFTYPE_SERVICE = 4, /* Only inside message table. */ + UPB_DEFTYPE_FIELD = 0, UPB_DEFTYPE_ONEOF = 1, - UPB_DEFTYPE_FIELD_JSONNAME = 2 + UPB_DEFTYPE_FIELD_JSONNAME = 2, + + /* Only inside file table. */ + UPB_DEFTYPE_FILE = 0, + UPB_DEFTYPE_LAYOUT = 1 } upb_deftype_t; -static const void *unpack_def(upb_value v, upb_deftype_t type) { +#define FIELD_TYPE_UNSPECIFIED 0 + +static upb_deftype_t deftype(upb_value v) { uintptr_t num = (uintptr_t)upb_value_getconstptr(v); - return (num & 3) == type ? (const void*)(num & ~3) : NULL; + return num & UPB_DEFTYPE_MASK; } -static upb_value pack_def(const void *ptr, upb_deftype_t type) { - uintptr_t num = (uintptr_t)ptr | type; +static const void* unpack_def(upb_value v, upb_deftype_t type) { + uintptr_t num = (uintptr_t)upb_value_getconstptr(v); + return (num & UPB_DEFTYPE_MASK) == type + ? (const void*)(num & ~UPB_DEFTYPE_MASK) + : NULL; +} + +static upb_value pack_def(const void* ptr, upb_deftype_t type) { + uintptr_t num = (uintptr_t)ptr; + UPB_ASSERT((num & UPB_DEFTYPE_MASK) == 0); + num |= 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) { +static bool upb_isbetween(uint8_t c, uint8_t low, uint8_t high) { return c >= low && c <= high; } +static char upb_ascii_lower(char ch) { + // Per ASCII this will lower-case a letter. If the result is a letter, the + // input was definitely a letter. If the output is not a letter, this may + // have transformed the character unpredictably. + return ch | 0x20; +} + static bool upb_isletter(char c) { - return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_'; + char lower = upb_ascii_lower(c); + return upb_isbetween(lower, '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; +static const char* shortdefname(const char* fullname) { + const char* p; if (fullname == NULL) { return NULL; @@ -4620,371 +5393,417 @@ static const char *shortdefname(const char *fullname) { /* 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); +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; + if (!upb_FieldDef_IsSubMessage(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; +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); } -static void upb_status_setoom(upb_status *status) { - upb_status_seterrmsg(status, "out of memory"); +static void upb_Status_setoom(upb_Status* status) { + upb_Status_SetErrorMessage(status, "out of memory"); } -static void assign_msg_wellknowntype(upb_msgdef *m) { - const char *name = upb_msgdef_fullname(m); +static void assign_msg_wellknowntype(upb_MessageDef* m) { + const char* name = upb_MessageDef_FullName(m); if (name == NULL) { - m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + m->well_known_type = kUpb_WellKnown_Unspecified; return; } if (!strcmp(name, "google.protobuf.Any")) { - m->well_known_type = UPB_WELLKNOWN_ANY; + m->well_known_type = kUpb_WellKnown_Any; } else if (!strcmp(name, "google.protobuf.FieldMask")) { - m->well_known_type = UPB_WELLKNOWN_FIELDMASK; + m->well_known_type = kUpb_WellKnown_FieldMask; } else if (!strcmp(name, "google.protobuf.Duration")) { - m->well_known_type = UPB_WELLKNOWN_DURATION; + m->well_known_type = kUpb_WellKnown_Duration; } else if (!strcmp(name, "google.protobuf.Timestamp")) { - m->well_known_type = UPB_WELLKNOWN_TIMESTAMP; + m->well_known_type = kUpb_WellKnown_Timestamp; } else if (!strcmp(name, "google.protobuf.DoubleValue")) { - m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE; + m->well_known_type = kUpb_WellKnown_DoubleValue; } else if (!strcmp(name, "google.protobuf.FloatValue")) { - m->well_known_type = UPB_WELLKNOWN_FLOATVALUE; + m->well_known_type = kUpb_WellKnown_FloatValue; } else if (!strcmp(name, "google.protobuf.Int64Value")) { - m->well_known_type = UPB_WELLKNOWN_INT64VALUE; + m->well_known_type = kUpb_WellKnown_Int64Value; } else if (!strcmp(name, "google.protobuf.UInt64Value")) { - m->well_known_type = UPB_WELLKNOWN_UINT64VALUE; + m->well_known_type = kUpb_WellKnown_UInt64Value; } else if (!strcmp(name, "google.protobuf.Int32Value")) { - m->well_known_type = UPB_WELLKNOWN_INT32VALUE; + m->well_known_type = kUpb_WellKnown_Int32Value; } else if (!strcmp(name, "google.protobuf.UInt32Value")) { - m->well_known_type = UPB_WELLKNOWN_UINT32VALUE; + m->well_known_type = kUpb_WellKnown_UInt32Value; } else if (!strcmp(name, "google.protobuf.BoolValue")) { - m->well_known_type = UPB_WELLKNOWN_BOOLVALUE; + m->well_known_type = kUpb_WellKnown_BoolValue; } else if (!strcmp(name, "google.protobuf.StringValue")) { - m->well_known_type = UPB_WELLKNOWN_STRINGVALUE; + m->well_known_type = kUpb_WellKnown_StringValue; } else if (!strcmp(name, "google.protobuf.BytesValue")) { - m->well_known_type = UPB_WELLKNOWN_BYTESVALUE; + m->well_known_type = kUpb_WellKnown_BytesValue; } else if (!strcmp(name, "google.protobuf.Value")) { - m->well_known_type = UPB_WELLKNOWN_VALUE; + m->well_known_type = kUpb_WellKnown_Value; } else if (!strcmp(name, "google.protobuf.ListValue")) { - m->well_known_type = UPB_WELLKNOWN_LISTVALUE; + m->well_known_type = kUpb_WellKnown_ListValue; } else if (!strcmp(name, "google.protobuf.Struct")) { - m->well_known_type = UPB_WELLKNOWN_STRUCT; + m->well_known_type = kUpb_WellKnown_Struct; } else { - m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + m->well_known_type = kUpb_WellKnown_Unspecified; } } +/* upb_EnumDef ****************************************************************/ -/* upb_enumdef ****************************************************************/ - -const char *upb_enumdef_fullname(const upb_enumdef *e) { - return e->full_name; +const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { + return e->opts; } -const char *upb_enumdef_name(const upb_enumdef *e) { - return shortdefname(e->full_name); +bool upb_EnumDef_HasOptions(const upb_EnumDef* e) { + return e->opts != (void*)opt_default; } -const upb_filedef *upb_enumdef_file(const upb_enumdef *e) { - return e->file; -} +const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; } -int32_t upb_enumdef_default(const upb_enumdef *e) { - UPB_ASSERT(upb_enumdef_iton(e, e->defaultval)); - return e->defaultval; +const char* upb_EnumDef_Name(const upb_EnumDef* e) { + return shortdefname(e->full_name); } -int upb_enumdef_numvals(const upb_enumdef *e) { - return (int)upb_strtable_count(&e->ntoi); +const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e) { return e->file; } + +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e) { + return e->containing_type; } -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); +int32_t upb_EnumDef_Default(const upb_EnumDef* e) { + UPB_ASSERT(upb_EnumDef_FindValueByNumber(e, e->defaultval)); + return e->defaultval; } -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); } +int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; } -bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name, - size_t len, int32_t *num) { +const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* def, const char* name, size_t len) { upb_value v; - if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) { - return false; - } - if (num) *num = upb_value_getint32(v); - return true; + return upb_strtable_lookup2(&def->ntoi, name, len, &v) + ? upb_value_getconstptr(v) + : NULL; } -const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) { +const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* def, + int32_t num) { upb_value v; - return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getcstr(v) : NULL; + return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getconstptr(v) + : NULL; } -const char *upb_enum_iter_name(upb_enum_iter *iter) { - return upb_strtable_iter_key(iter).data; +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num) { + // We could use upb_EnumDef_FindValueByNumber(e, num) != NULL, but we expect + // this to be faster (especially for small numbers). + return upb_MiniTable_Enum_CheckValue(e->layout, num); } -int32_t upb_enum_iter_number(upb_enum_iter *iter) { - return upb_value_getint32(upb_strtable_iter_value(iter)); +const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { + UPB_ASSERT(0 <= i && i < e->value_count); + return &e->values[i]; } +/* upb_EnumValueDef ***********************************************************/ -/* upb_fielddef ***************************************************************/ - -const char *upb_fielddef_fullname(const upb_fielddef *f) { - return f->full_name; +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* e) { + return e->opts; } -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(); +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* e) { + return e->opts != (void*)opt_default; } -upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) { - return f->type_; +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* ev) { + return ev->parent; } -uint32_t upb_fielddef_index(const upb_fielddef *f) { - return f->index_; +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* ev) { + return ev->full_name; } -upb_label_t upb_fielddef_label(const upb_fielddef *f) { - return f->label_; +const char* upb_EnumValueDef_Name(const upb_EnumValueDef* ev) { + return shortdefname(ev->full_name); } -uint32_t upb_fielddef_number(const upb_fielddef *f) { - return f->number_; +int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* ev) { + return ev->number; } -bool upb_fielddef_isextension(const upb_fielddef *f) { - return f->is_extension_; +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* ev) { + // Compute index in our parent's array. + return ev - ev->parent->values; } -bool upb_fielddef_lazy(const upb_fielddef *f) { - return f->lazy_; -} +/* upb_ExtensionRange + * ***************************************************************/ -bool upb_fielddef_packed(const upb_fielddef *f) { - return f->packed_; +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r) { + return r->opts; } -const char *upb_fielddef_name(const upb_fielddef *f) { - return shortdefname(f->full_name); +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r) { + return r->opts != (void*)opt_default; } -const char *upb_fielddef_jsonname(const upb_fielddef *f) { - return f->json_name; +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* e) { + return e->start; } -const upb_filedef *upb_fielddef_file(const upb_fielddef *f) { - return f->file; -} +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* e) { return e->end; } -const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { - return f->msgdef; +/* upb_FieldDef ***************************************************************/ + +const google_protobuf_FieldOptions* upb_FieldDef_Options( + const upb_FieldDef* f) { + return f->opts; } -const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) { - return f->oneof; +bool upb_FieldDef_HasOptions(const upb_FieldDef* f) { + return f->opts != (void*)opt_default; } -const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) { - if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL; - return f->oneof; +const char* upb_FieldDef_FullName(const upb_FieldDef* f) { + return f->full_name; } -upb_msgval upb_fielddef_default(const upb_fielddef *f) { - UPB_ASSERT(!upb_fielddef_issubmsg(f)); - upb_msgval ret; - if (upb_fielddef_isstring(f)) { - str_t *str = f->defaultval.str; - if (str) { - ret.str_val.data = str->str; - ret.str_val.size = str->len; - } else { - ret.str_val.size = 0; - } - } else { - memcpy(&ret, &f->defaultval, 8); +upb_CType upb_FieldDef_CType(const upb_FieldDef* f) { + switch (f->type_) { + case kUpb_FieldType_Double: + return kUpb_CType_Double; + case kUpb_FieldType_Float: + return kUpb_CType_Float; + case kUpb_FieldType_Int64: + case kUpb_FieldType_SInt64: + case kUpb_FieldType_SFixed64: + return kUpb_CType_Int64; + case kUpb_FieldType_Int32: + case kUpb_FieldType_SFixed32: + case kUpb_FieldType_SInt32: + return kUpb_CType_Int32; + case kUpb_FieldType_UInt64: + case kUpb_FieldType_Fixed64: + return kUpb_CType_UInt64; + case kUpb_FieldType_UInt32: + case kUpb_FieldType_Fixed32: + return kUpb_CType_UInt32; + case kUpb_FieldType_Enum: + return kUpb_CType_Enum; + case kUpb_FieldType_Bool: + return kUpb_CType_Bool; + case kUpb_FieldType_String: + return kUpb_CType_String; + case kUpb_FieldType_Bytes: + return kUpb_CType_Bytes; + case kUpb_FieldType_Group: + case kUpb_FieldType_Message: + return kUpb_CType_Message; } - return ret; + UPB_UNREACHABLE(); } -static void chkdefaulttype(const upb_fielddef *f, int ctype) { - UPB_UNUSED(f); - UPB_UNUSED(ctype); -} +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; } -int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_INT64); - return f->defaultval.sint; -} +uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; } -int32_t upb_fielddef_defaultint32(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_INT32); - return (int32_t)f->defaultval.sint; -} +upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; } -uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT64); - return f->defaultval.uint; +uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } + +bool upb_FieldDef_IsExtension(const upb_FieldDef* f) { + return f->is_extension_; } -uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT32); - return (uint32_t)f->defaultval.uint; +bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { return f->packed_; } + +const char* upb_FieldDef_Name(const upb_FieldDef* f) { + return shortdefname(f->full_name); } -bool upb_fielddef_defaultbool(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_BOOL); - return f->defaultval.boolean; +const char* upb_FieldDef_JsonName(const upb_FieldDef* f) { + return f->json_name; } -float upb_fielddef_defaultfloat(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_FLOAT); - return f->defaultval.flt; +bool upb_FieldDef_HasJsonName(const upb_FieldDef* f) { + return f->has_json_name_; } -double upb_fielddef_defaultdouble(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_DOUBLE); - return f->defaultval.dbl; +const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f) { return f->file; } + +const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f) { + return f->msgdef; } -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_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f) { + return f->is_extension_ ? f->scope.extension_scope : NULL; +} + +const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f) { + return f->is_extension_ ? NULL : f->scope.oneof; +} + +const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f) { + const upb_OneofDef* oneof = upb_FieldDef_ContainingOneof(f); + if (!oneof || upb_OneofDef_IsSynthetic(oneof)) return NULL; + return oneof; +} + +upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f) { + UPB_ASSERT(!upb_FieldDef_IsSubMessage(f)); + upb_MessageValue ret; + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return (upb_MessageValue){.bool_val = f->defaultval.boolean}; + case kUpb_CType_Int64: + return (upb_MessageValue){.int64_val = f->defaultval.sint}; + case kUpb_CType_UInt64: + return (upb_MessageValue){.uint64_val = f->defaultval.uint}; + case kUpb_CType_Enum: + case kUpb_CType_Int32: + return (upb_MessageValue){.int32_val = (int32_t)f->defaultval.sint}; + case kUpb_CType_UInt32: + return (upb_MessageValue){.uint32_val = (uint32_t)f->defaultval.uint}; + case kUpb_CType_Float: + return (upb_MessageValue){.float_val = f->defaultval.flt}; + case kUpb_CType_Double: + return (upb_MessageValue){.double_val = f->defaultval.dbl}; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + str_t* str = f->defaultval.str; + if (str) { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = str->str, .size = str->len}}; + } else { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = NULL, .size = 0}}; + } + } + default: + UPB_UNREACHABLE(); } + + return ret; } -const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_MESSAGE ? f->sub.msgdef : NULL; +const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_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_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Enum ? f->sub.enumdef : NULL; } -const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) { +const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f) { + UPB_ASSERT(!upb_FieldDef_IsExtension(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; +const upb_MiniTable_Extension* _upb_FieldDef_ExtensionMiniTable( + const upb_FieldDef* f) { + UPB_ASSERT(upb_FieldDef_IsExtension(f)); + return f->file->ext_layouts[f->layout_index]; } -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_IsProto3Optional(const upb_FieldDef* f) { + return f->proto3_optional_; } -bool upb_fielddef_isseq(const upb_fielddef *f) { - return upb_fielddef_label(f) == UPB_LABEL_REPEATED; +bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Message; } -bool upb_fielddef_isprimitive(const upb_fielddef *f) { - return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f); +bool upb_FieldDef_IsString(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_String || + upb_FieldDef_CType(f) == kUpb_CType_Bytes; } -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_IsRepeated(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Repeated; } -bool upb_fielddef_hassubdef(const upb_fielddef *f) { - return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM; +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f) { + return !upb_FieldDef_IsString(f) && !upb_FieldDef_IsSubMessage(f); +} + +bool upb_FieldDef_IsMap(const upb_FieldDef* f) { + return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsSubMessage(f) && + upb_MessageDef_IsMapEntry(upb_FieldDef_MessageSubDef(f)); +} + +bool upb_FieldDef_HasDefault(const upb_FieldDef* f) { return f->has_default; } + +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsSubMessage(f) || + upb_FieldDef_CType(f) == kUpb_CType_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; +bool upb_FieldDef_HasPresence(const upb_FieldDef* f) { + if (upb_FieldDef_IsRepeated(f)) return false; + return upb_FieldDef_IsSubMessage(f) || upb_FieldDef_ContainingOneof(f) || + f->file->syntax == kUpb_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_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) { +bool upb_FieldDef_checkdescriptortype(int32_t type) { return between(type, 1, 18); } -/* upb_msgdef *****************************************************************/ +/* upb_MessageDef + * *****************************************************************/ -const char *upb_msgdef_fullname(const upb_msgdef *m) { +const google_protobuf_MessageOptions* upb_MessageDef_Options( + const upb_MessageDef* m) { + return m->opts; +} + +bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { + return m->opts != (void*)opt_default; +} + +const char* upb_MessageDef_FullName(const upb_MessageDef* m) { return m->full_name; } -const upb_filedef *upb_msgdef_file(const upb_msgdef *m) { +const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) { return m->file; } -const char *upb_msgdef_name(const upb_msgdef *m) { +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) { + return m->containing_type; +} + +const char* upb_MessageDef_Name(const upb_MessageDef* m) { return shortdefname(m->full_name); } -upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) { +upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m) { return m->file->syntax; } -const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) { +const upb_FieldDef* upb_MessageDef_FindFieldByNumberWithSize( + const upb_MessageDef* m, uint32_t i) { upb_value val; return upb_inttable_lookup(&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) { +const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len) { upb_value val; if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { @@ -4994,8 +5813,8 @@ const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, return unpack_def(val, UPB_DEFTYPE_FIELD); } -const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, - size_t len) { +const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len) { upb_value val; if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { @@ -5005,23 +5824,27 @@ const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, 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) { +bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, + const char* name, size_t len, + const upb_FieldDef** out_f, + const upb_OneofDef** out_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* f = unpack_def(val, UPB_DEFTYPE_FIELD); + const upb_OneofDef* o = unpack_def(val, UPB_DEFTYPE_ONEOF); + if (out_f) *out_f = f; + if (out_o) *out_o = o; + return f || o; /* False if this was a JSON name. */ } -const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, - const char *name, size_t len) { +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t len) { upb_value val; - const upb_fielddef* f; + const upb_FieldDef* f; if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { return NULL; @@ -5033,293 +5856,463 @@ const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, return f; } -int upb_msgdef_numfields(const upb_msgdef *m) { +int upb_MessageDef_numfields(const upb_MessageDef* m) { return m->field_count; } + +int upb_MessageDef_numoneofs(const upb_MessageDef* m) { return m->oneof_count; } + +int upb_MessageDef_numrealoneofs(const upb_MessageDef* m) { + return m->real_oneof_count; +} + +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) { + return m->ext_range_count; +} + +int upb_MessageDef_FieldCount(const upb_MessageDef* m) { return m->field_count; } -int upb_msgdef_numoneofs(const upb_msgdef *m) { +int upb_MessageDef_OneofCount(const upb_MessageDef* m) { return m->oneof_count; } -int upb_msgdef_numrealoneofs(const upb_msgdef *m) { - return m->real_oneof_count; +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) { + return m->nested_msg_count; } -int upb_msgdef_fieldcount(const upb_msgdef *m) { - return m->field_count; +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) { + return m->nested_enum_count; } -int upb_msgdef_oneofcount(const upb_msgdef *m) { - return m->oneof_count; +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) { + return m->nested_ext_count; } -int upb_msgdef_realoneofcount(const upb_msgdef *m) { +int upb_MessageDef_realoneofcount(const upb_MessageDef* m) { return m->real_oneof_count; } -const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) { +const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) { return m->layout; } -const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i) { - UPB_ASSERT(i >= 0 && i < m->field_count); +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->ext_range_count); + return &m->ext_ranges[i]; +} + +const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && 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); +const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->oneof_count); return &m->oneofs[i]; } -bool upb_msgdef_mapentry(const upb_msgdef *m) { - return m->map_entry; +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_msg_count); + return &m->nested_msgs[i]; } -upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) { - return m->well_known_type; +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->nested_enum_count); + return &m->nested_enums[i]; +} + +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_ext_count); + return &m->nested_exts[i]; } -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; +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { + return m->well_known_type; } -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; +/* upb_OneofDef ***************************************************************/ + +const google_protobuf_OneofOptions* upb_OneofDef_Options( + const upb_OneofDef* o) { + return o->opts; } -void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) { - upb_inttable_begin(iter, &m->itof); +bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { + return o->opts != (void*)opt_default; } -void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); } +const char* upb_OneofDef_Name(const upb_OneofDef* o) { + return shortdefname(o->full_name); +} -bool upb_msg_field_done(const upb_msg_field_iter *iter) { - return upb_inttable_done(iter); +const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) { + return o->parent; } -upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +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]; } -void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { - upb_inttable_iter_setdone(iter); +int upb_OneofDef_numfields(const upb_OneofDef* o) { return o->field_count; } + +uint32_t upb_OneofDef_Index(const upb_OneofDef* o) { + // Compute index in our parent's array. + return o - o->parent->oneofs; } -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); +bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o) { return o->synthetic; } + +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(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; } -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); - } +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num) { + upb_value val; + return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val) + : NULL; } -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)); +/* upb_FileDef ****************************************************************/ + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) { + return f->opts; } -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { - return upb_strtable_done(iter); +bool upb_FileDef_HasOptions(const upb_FileDef* f) { + return f->opts != (void*)opt_default; } -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); +const char* upb_FileDef_Name(const upb_FileDef* f) { return f->name; } + +const char* upb_FileDef_Package(const upb_FileDef* f) { return f->package; } + +upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f) { return f->syntax; } + +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f) { + return f->top_lvl_msg_count; } -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { - upb_strtable_iter_setdone(iter); +int upb_FileDef_DependencyCount(const upb_FileDef* f) { return f->dep_count; } + +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) { + return f->public_dep_count; } -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); +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { + return f->weak_dep_count; } -/* upb_oneofdef ***************************************************************/ +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { + return f->public_deps; +} -const char *upb_oneofdef_name(const upb_oneofdef *o) { - return shortdefname(o->full_name); +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) { + return f->weak_deps; } -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { - return o->parent; +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) { + return f->top_lvl_enum_count; } -int upb_oneofdef_fieldcount(const upb_oneofdef *o) { - return o->field_count; +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f) { + return f->top_lvl_ext_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_FileDef_ServiceCount(const upb_FileDef* f) { return f->service_count; } + +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->dep_count); + return f->deps[i]; } -int upb_oneofdef_numfields(const upb_oneofdef *o) { - return o->field_count; +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->public_deps[i]]; } -uint32_t upb_oneofdef_index(const upb_oneofdef *o) { - return o - o->parent->oneofs; +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->weak_deps[i]]; } -bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { - return o->synthetic; +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_msg_count); + return &f->top_lvl_msgs[i]; } -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_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_enum_count); + return &f->top_lvl_enums[i]; } -const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) { - upb_value val; - return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val) - : NULL; +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_ext_count); + return &f->top_lvl_exts[i]; } -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { - upb_inttable_begin(iter, &o->itof); +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->service_count); + return &f->services[i]; } -void upb_oneof_next(upb_oneof_iter *iter) { - upb_inttable_next(iter); +const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f) { return f->symtab; } + +/* upb_MethodDef **************************************************************/ + +const google_protobuf_MethodOptions* upb_MethodDef_Options( + const upb_MethodDef* m) { + return m->opts; } -bool upb_oneof_done(upb_oneof_iter *iter) { - return upb_inttable_done(iter); +bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { + return m->opts != (void*)opt_default; } -upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +const char* upb_MethodDef_FullName(const upb_MethodDef* m) { + return m->full_name; } -void upb_oneof_iter_setdone(upb_oneof_iter *iter) { - upb_inttable_iter_setdone(iter); +const char* upb_MethodDef_Name(const upb_MethodDef* m) { + return shortdefname(m->full_name); } -/* upb_filedef ****************************************************************/ +const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) { + return m->service; +} -const char *upb_filedef_name(const upb_filedef *f) { - return f->name; +const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) { + return m->input_type; } -const char *upb_filedef_package(const upb_filedef *f) { - return f->package; +const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) { + return m->output_type; } -const char *upb_filedef_phpprefix(const upb_filedef *f) { - return f->phpprefix; +bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) { + return m->client_streaming; } -const char *upb_filedef_phpnamespace(const upb_filedef *f) { - return f->phpnamespace; +bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { + return m->server_streaming; } -upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { - return f->syntax; +/* upb_ServiceDef *************************************************************/ + +const google_protobuf_ServiceOptions* upb_ServiceDef_Options( + const upb_ServiceDef* s) { + return s->opts; } -int upb_filedef_msgcount(const upb_filedef *f) { - return f->msg_count; +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { + return s->opts != (void*)opt_default; } -int upb_filedef_depcount(const upb_filedef *f) { - return f->dep_count; +const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { + return s->full_name; } -int upb_filedef_enumcount(const upb_filedef *f) { - return f->enum_count; +const char* upb_ServiceDef_Name(const upb_ServiceDef* s) { + return shortdefname(s->full_name); } -const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { - return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; +int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; } + +const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) { + return s->file; } -const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { - return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; +int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) { + return s->method_count; } -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { - return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; +const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) { + return i < 0 || i >= s->method_count ? NULL : &s->methods[i]; } -const upb_symtab *upb_filedef_symtab(const upb_filedef *f) { - return f->symtab; +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name) { + for (int i = 0; i < s->method_count; i++) { + if (strcmp(name, upb_MethodDef_Name(&s->methods[i])) == 0) { + return &s->methods[i]; + } + } + return NULL; } -void upb_symtab_free(upb_symtab *s) { - upb_arena_free(s->arena); +/* upb_DefPool ****************************************************************/ + +void upb_DefPool_Free(upb_DefPool* s) { + upb_Arena_Free(s->arena); upb_gfree(s); } -upb_symtab *upb_symtab_new(void) { - upb_symtab *s = upb_gmalloc(sizeof(*s)); +upb_DefPool* upb_DefPool_New(void) { + upb_DefPool* s = upb_gmalloc(sizeof(*s)); if (!s) { return NULL; } - s->arena = upb_arena_new(); + s->arena = upb_Arena_New(); s->bytes_loaded = 0; if (!upb_strtable_init(&s->syms, 32, s->arena) || - !upb_strtable_init(&s->files, 4, s->arena)) { - upb_arena_free(s->arena); - upb_gfree(s); - s = NULL; + !upb_strtable_init(&s->files, 4, s->arena) || + !upb_inttable_init(&s->exts, s->arena)) { + goto err; } + + s->extreg = upb_ExtensionRegistry_New(s->arena); + if (!s->extreg) goto err; return s; + +err: + upb_Arena_Free(s->arena); + upb_gfree(s); + return NULL; } -const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { +static const void* symtab_lookup(const upb_DefPool* s, const char* sym, + upb_deftype_t type) { upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_MSG) : NULL; + return upb_strtable_lookup(&s->syms, sym, &v) ? unpack_def(v, type) : NULL; } -const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, - size_t len) { +static const void* symtab_lookup2(const upb_DefPool* s, const char* sym, + size_t size, upb_deftype_t type) { upb_value v; - return upb_strtable_lookup2(&s->syms, sym, len, &v) ? - unpack_def(v, UPB_DEFTYPE_MSG) : NULL; + return upb_strtable_lookup2(&s->syms, sym, size, &v) ? unpack_def(v, type) + : NULL; +} + +const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, + const char* sym) { + return symtab_lookup(s, sym, UPB_DEFTYPE_MSG); } -const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len) { + return symtab_lookup2(s, sym, len, UPB_DEFTYPE_MSG); +} + +const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym) { + return symtab_lookup(s, sym, UPB_DEFTYPE_ENUM); +} + +const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s, + const char* sym) { + return symtab_lookup(s, sym, UPB_DEFTYPE_ENUMVAL); +} + +const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name) { upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; + return upb_strtable_lookup(&s->files, name, &v) + ? unpack_def(v, UPB_DEFTYPE_FILE) + : NULL; } -const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) { +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len) { upb_value v; - return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) - : NULL; + return upb_strtable_lookup2(&s->files, name, len, &v) + ? unpack_def(v, UPB_DEFTYPE_FILE) + : NULL; } -const upb_filedef *upb_symtab_lookupfile2( - const upb_symtab *s, const char *name, size_t len) { +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { upb_value v; - return upb_strtable_lookup2(&s->files, name, len, &v) ? - upb_value_getconstptr(v) : NULL; + if (!upb_strtable_lookup2(&s->syms, name, size, &v)) return NULL; + + switch (deftype(v)) { + case UPB_DEFTYPE_FIELD: + return unpack_def(v, UPB_DEFTYPE_FIELD); + case UPB_DEFTYPE_MSG: { + const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG); + return m->in_message_set ? &m->nested_exts[0] : NULL; + } + default: + break; + } + + return NULL; +} + +const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindExtensionByNameWithSize(s, sym, strlen(sym)); +} + +const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, + const char* name) { + return symtab_lookup(s, name, UPB_DEFTYPE_SERVICE); +} + +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { + return symtab_lookup2(s, name, size, UPB_DEFTYPE_SERVICE); } -int upb_symtab_filecount(const upb_symtab *s) { - return (int)upb_strtable_count(&s->files); +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name) { + upb_value v; + // TODO(haberman): non-extension fields and oneofs. + if (upb_strtable_lookup(&s->syms, name, &v)) { + switch (deftype(v)) { + case UPB_DEFTYPE_EXT: { + const upb_FieldDef* f = unpack_def(v, UPB_DEFTYPE_EXT); + return upb_FieldDef_File(f); + } + case UPB_DEFTYPE_MSG: { + const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG); + return upb_MessageDef_File(m); + } + case UPB_DEFTYPE_ENUM: { + const upb_EnumDef* e = unpack_def(v, UPB_DEFTYPE_ENUM); + return upb_EnumDef_File(e); + } + case UPB_DEFTYPE_ENUMVAL: { + const upb_EnumValueDef* ev = unpack_def(v, UPB_DEFTYPE_ENUMVAL); + return upb_EnumDef_File(upb_EnumValueDef_Enum(ev)); + } + case UPB_DEFTYPE_SERVICE: { + const upb_ServiceDef* service = unpack_def(v, UPB_DEFTYPE_SERVICE); + return upb_ServiceDef_File(service); + } + default: + UPB_UNREACHABLE(); + } + } + + const char* last_dot = strrchr(name, '.'); + if (last_dot) { + const upb_MessageDef* parent = + upb_DefPool_FindMessageByNameWithSize(s, name, last_dot - name); + if (parent) { + const char* shortname = last_dot + 1; + if (upb_MessageDef_FindByNameWithSize(parent, shortname, + strlen(shortname), NULL, NULL)) { + return upb_MessageDef_File(parent); + } + } + } + + return NULL; } /* Code to build defs from descriptor protos. *********************************/ @@ -5329,40 +6322,61 @@ int upb_symtab_filecount(const upb_symtab *s) { * 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); } +#define CHK_OOM(x) \ + if (!(x)) { \ + symtab_oomerr(ctx); \ + } typedef struct { - upb_symtab *symtab; - upb_filedef *file; /* File we are building. */ - upb_arena *arena; /* Allocate defs here. */ - const upb_msglayout **layouts; /* NULL if we should build layouts. */ - upb_status *status; /* Record errors here. */ - jmp_buf err; /* longjmp() on error. */ + upb_DefPool* symtab; + upb_FileDef* file; /* File we are building. */ + upb_Arena* arena; /* Allocate defs here. */ + upb_Arena* tmp_arena; /* For temporary allocations. */ + const upb_MiniTable_File* layout; /* NULL if we should build layouts. */ + int enum_count; /* Count of enums built so far. */ + int msg_count; /* Count of messages built so far. */ + int ext_count; /* Count of extensions built so far. */ + upb_Status* status; /* Record errors here. */ + jmp_buf err; /* longjmp() on error. */ } symtab_addctx; -UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3) -static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) { +UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3) static void symtab_errf( + symtab_addctx* ctx, const char* fmt, ...) { va_list argp; va_start(argp, fmt); - upb_status_vseterrf(ctx->status, fmt, argp); + upb_Status_VSetErrorFormat(ctx->status, fmt, argp); va_end(argp); UPB_LONGJMP(ctx->err, 1); } -UPB_NORETURN UPB_NOINLINE -static void symtab_oomerr(symtab_addctx *ctx) { - upb_status_setoom(ctx->status); +UPB_NORETURN UPB_NOINLINE static void symtab_oomerr(symtab_addctx* ctx) { + upb_Status_setoom(ctx->status); UPB_LONGJMP(ctx->err, 1); } -void *symtab_alloc(symtab_addctx *ctx, size_t bytes) { - void *ret = upb_arena_malloc(ctx->arena, bytes); +void* symtab_alloc(symtab_addctx* ctx, size_t bytes) { + if (bytes == 0) return NULL; + void* ret = upb_Arena_Malloc(ctx->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; +// We want to copy the options verbatim into the destination options proto. +// We use serialize+parse as our deep copy. +#define SET_OPTIONS(target, desc_type, options_type, proto) \ + if (google_protobuf_##desc_type##_has_options(proto)) { \ + size_t size; \ + char* pb = google_protobuf_##options_type##_serialize( \ + google_protobuf_##desc_type##_options(proto), ctx->tmp_arena, &size); \ + CHK_OOM(pb); \ + target = google_protobuf_##options_type##_parse(pb, size, ctx->arena); \ + CHK_OOM(target); \ + } else { \ + target = (const google_protobuf_##options_type*)opt_default; \ + } + +static void check_ident(symtab_addctx* ctx, upb_StringView name, bool full) { + const char* str = name.data; size_t len = name.size; bool start = true; size_t i; @@ -5393,158 +6407,223 @@ static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) { } } -static size_t div_round_up(size_t n, size_t d) { - return (n + d - 1) / d; -} +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) { +static size_t upb_MessageValue_sizeof(upb_CType type) { switch (type) { - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: return 8; - case UPB_TYPE_ENUM: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_FLOAT: + case kUpb_CType_Enum: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Float: return 4; - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return 1; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: return sizeof(void*); - case UPB_TYPE_BYTES: - case UPB_TYPE_STRING: - return sizeof(upb_strview); + case kUpb_CType_Bytes: + case kUpb_CType_String: + return sizeof(upb_StringView); } UPB_UNREACHABLE(); } -static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { - if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) { - upb_map_entry ent; +static uint8_t upb_msg_fielddefsize(const upb_FieldDef* f) { + if (upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f))) { + upb_MapEntry ent; UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v)); return sizeof(ent.k); - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(f)) { return sizeof(void*); } else { - return upb_msgval_sizeof(upb_fielddef_type(f)); + return upb_MessageValue_sizeof(upb_FieldDef_CType(f)); } } -static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) { - uint32_t ret; +static uint32_t upb_MiniTable_place(symtab_addctx* ctx, upb_MiniTable* l, + size_t size, const upb_MessageDef* m) { + size_t ofs = UPB_ALIGN_UP(l->size, size); + size_t next = ofs + size; - l->size = UPB_ALIGN_UP(l->size, size); - ret = l->size; - l->size += size; - return ret; + if (next > UINT16_MAX) { + symtab_errf(ctx, "size of message %s exceeded max size of %zu bytes", + upb_MessageDef_FullName(m), (size_t)UINT16_MAX); + } + + l->size = next; + return ofs; } -static int field_number_cmp(const void *p1, const void *p2) { - const upb_msglayout_field *f1 = p1; - const upb_msglayout_field *f2 = p2; +static int field_number_cmp(const void* p1, const void* p2) { + const upb_MiniTable_Field* f1 = p1; + const upb_MiniTable_Field* f2 = p2; return f1->number - f2->number; } -static void assign_layout_indices(const upb_msgdef *m, upb_msglayout *l, - upb_msglayout_field *fields) { +static void assign_layout_indices(const upb_MessageDef* m, upb_MiniTable* l, + upb_MiniTable_Field* fields) { int i; - int n = upb_msgdef_numfields(m); + int n = upb_MessageDef_numfields(m); int dense_below = 0; for (i = 0; i < n; i++) { - upb_fielddef *f = (upb_fielddef*)upb_msgdef_itof(m, fields[i].number); + upb_FieldDef* f = (upb_FieldDef*)upb_MessageDef_FindFieldByNumberWithSize( + m, fields[i].number); UPB_ASSERT(f); f->layout_index = i; if (i < UINT8_MAX && fields[i].number == i + 1 && - (i == 0 || fields[i-1].number == i)) { + (i == 0 || fields[i - 1].number == i)) { dense_below = i + 1; } } l->dense_below = dense_below; } -static void fill_fieldlayout(upb_msglayout_field *field, const upb_fielddef *f) { - field->number = upb_fielddef_number(f); - field->descriptortype = upb_fielddef_descriptortype(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; +static uint8_t map_descriptortype(const upb_FieldDef* f) { + uint8_t type = upb_FieldDef_Type(f); + /* See TableDescriptorType() in upbc/generator.cc for details and + * rationale of these exceptions. */ + if (type == kUpb_FieldType_String && f->file->syntax == kUpb_Syntax_Proto2) { + return kUpb_FieldType_Bytes; + } else if (type == kUpb_FieldType_Enum && + f->sub.enumdef->file->syntax == kUpb_Syntax_Proto3) { + return kUpb_FieldType_Int32; } + return type; +} - if (upb_fielddef_ismap(f)) { - field->mode = _UPB_MODE_MAP; - } else if (upb_fielddef_isseq(f)) { - field->mode = _UPB_MODE_ARRAY; - } else { - field->mode = _UPB_MODE_SCALAR; - } +static bool IsProto2Enum(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Enum && + f->sub.enumdef->file->syntax == kUpb_Syntax_Proto2; +} + +static void fill_fieldlayout(upb_MiniTable_Field* field, + const upb_FieldDef* f) { + field->number = upb_FieldDef_Number(f); + field->descriptortype = map_descriptortype(f); - if (upb_fielddef_packed(f)) { - field->mode |= _UPB_MODE_IS_PACKED; + if (upb_FieldDef_IsMap(f)) { + field->mode = + kUpb_FieldMode_Map | (upb_FieldRep_Pointer << upb_FieldRep_Shift); + } else if (upb_FieldDef_IsRepeated(f)) { + field->mode = + kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift); + } else { + /* Maps descriptor type -> elem_size_lg2. */ + static const uint8_t sizes[] = { + -1, /* invalid descriptor type */ + upb_FieldRep_8Byte, /* DOUBLE */ + upb_FieldRep_4Byte, /* FLOAT */ + upb_FieldRep_8Byte, /* INT64 */ + upb_FieldRep_8Byte, /* UINT64 */ + upb_FieldRep_4Byte, /* INT32 */ + upb_FieldRep_8Byte, /* FIXED64 */ + upb_FieldRep_4Byte, /* FIXED32 */ + upb_FieldRep_1Byte, /* BOOL */ + upb_FieldRep_StringView, /* STRING */ + upb_FieldRep_Pointer, /* GROUP */ + upb_FieldRep_Pointer, /* MESSAGE */ + upb_FieldRep_StringView, /* BYTES */ + upb_FieldRep_4Byte, /* UINT32 */ + upb_FieldRep_4Byte, /* ENUM */ + upb_FieldRep_4Byte, /* SFIXED32 */ + upb_FieldRep_8Byte, /* SFIXED64 */ + upb_FieldRep_4Byte, /* SINT32 */ + upb_FieldRep_8Byte, /* SINT64 */ + }; + field->mode = kUpb_FieldMode_Scalar | + (sizes[field->descriptortype] << upb_FieldRep_Shift); + } + + if (upb_FieldDef_IsPacked(f)) { + field->mode |= upb_LabelFlags_IsPacked; + } + + if (upb_FieldDef_IsExtension(f)) { + field->mode |= upb_LabelFlags_IsExtension; } } /* 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 field_count = upb_msgdef_numfields(m); - size_t submsg_count = 0; - const upb_msglayout **submsgs; - upb_msglayout_field *fields; - - memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry)); +static void make_layout(symtab_addctx* ctx, const upb_MessageDef* m) { + upb_MiniTable* l = (upb_MiniTable*)m->layout; + size_t field_count = upb_MessageDef_numfields(m); + size_t sublayout_count = 0; + upb_MiniTable_Sub* subs; + upb_MiniTable_Field* fields; + + memset(l, 0, sizeof(*l) + sizeof(_upb_FastTable_Entry)); /* Count sub-messages. */ for (size_t i = 0; i < field_count; i++) { - if (upb_fielddef_issubmsg(&m->fields[i])) { - submsg_count++; + const upb_FieldDef* f = &m->fields[i]; + if (upb_FieldDef_IsSubMessage(f)) { + sublayout_count++; + } else if (IsProto2Enum(f)) { + sublayout_count++; } } fields = symtab_alloc(ctx, field_count * sizeof(*fields)); - submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs)); + subs = symtab_alloc(ctx, sublayout_count * sizeof(*subs)); - l->field_count = upb_msgdef_numfields(m); + l->field_count = upb_MessageDef_numfields(m); l->fields = fields; - l->submsgs = submsgs; + l->subs = subs; l->table_mask = 0; + l->required_count = 0; + + if (upb_MessageDef_ExtensionRangeCount(m) > 0) { + if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) { + l->ext = upb_ExtMode_IsMessageSet; + } else { + l->ext = upb_ExtMode_Extendable; + } + } else { + l->ext = upb_ExtMode_NonExtendable; + } /* TODO(haberman): initialize fast tables so that reflection-based parsing * can get the same speeds as linked-in types. */ l->fasttable[0].field_parser = &fastdecode_generic; l->fasttable[0].field_data = 0; - if (upb_msgdef_mapentry(m)) { + if (upb_MessageDef_IsMapEntry(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); + const upb_FieldDef* key = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_FieldDef* val = upb_MessageDef_FindFieldByNumberWithSize(m, 2); fields[0].number = 1; fields[1].number = 2; - fields[0].mode = _UPB_MODE_SCALAR; - fields[1].mode = _UPB_MODE_SCALAR; + fields[0].mode = kUpb_FieldMode_Scalar; + fields[1].mode = kUpb_FieldMode_Scalar; fields[0].presence = 0; fields[1].presence = 0; - fields[0].descriptortype = upb_fielddef_descriptortype(key); - fields[1].descriptortype = upb_fielddef_descriptortype(val); + fields[0].descriptortype = map_descriptortype(key); + fields[1].descriptortype = map_descriptortype(val); fields[0].offset = 0; - fields[1].offset = sizeof(upb_strview); + fields[1].offset = sizeof(upb_StringView); fields[1].submsg_index = 0; - if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) { - submsgs[0] = upb_fielddef_msgsubdef(val)->layout; + if (upb_FieldDef_CType(val) == kUpb_CType_Message) { + subs[0].submsg = upb_FieldDef_MessageSubDef(val)->layout; + } else if (IsProto2Enum(val)) { + subs[0].subenum = upb_FieldDef_EnumSubDef(val)->layout; } + upb_FieldDef* fielddefs = (upb_FieldDef*)&m->fields[0]; + UPB_ASSERT(fielddefs[0].number_ == 1); + UPB_ASSERT(fielddefs[1].number_ == 2); + fielddefs[0].layout_index = 0; + fielddefs[1].layout_index = 1; + l->field_count = 2; - l->size = 2 * sizeof(upb_strview); + l->size = 2 * sizeof(upb_StringView); l->size = UPB_ALIGN_UP(l->size, 8); + l->dense_below = 2; return; } @@ -5557,23 +6636,44 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { * OPT: There is a lot of room for optimization here to minimize the size. */ + /* Assign hasbits for required fields first. */ + size_t hasbit = 0; + + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = &m->fields[i]; + upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)]; + if (upb_FieldDef_Label(f) == kUpb_Label_Required) { + field->presence = ++hasbit; + if (hasbit >= 63) { + symtab_errf(ctx, "Message with >=63 required fields: %s", + upb_MessageDef_FullName(m)); + } + l->required_count++; + } + } + /* 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)]; + sublayout_count = 0; + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = &m->fields[i]; + upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)]; fill_fieldlayout(field, f); - 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_IsSubMessage(f)) { + field->submsg_index = sublayout_count++; + subs[field->submsg_index].submsg = upb_FieldDef_MessageSubDef(f)->layout; + } else if (upb_FieldDef_CType(f) == kUpb_CType_Enum && + f->file->syntax == kUpb_Syntax_Proto2) { + field->submsg_index = sublayout_count++; + subs[field->submsg_index].subenum = upb_FieldDef_EnumSubDef(f)->layout; + UPB_ASSERT(subs[field->submsg_index].subenum); } - if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) { + if (upb_FieldDef_Label(f) == kUpb_Label_Required) { + /* Hasbit was already assigned. */ + } else 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; @@ -5583,55 +6683,47 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { } /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit, 8); + l->size = div_round_up(hasbit + 1, 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); + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = &m->fields[i]; size_t field_size = upb_msg_fielddefsize(f); - size_t index = upb_fielddef_index(f); + size_t index = upb_FieldDef_Index(f); - if (upb_fielddef_realcontainingoneof(f)) { + if (upb_FieldDef_RealContainingOneof(f)) { /* Oneofs are handled separately below. */ continue; } - fields[index].offset = upb_msglayout_place(l, field_size); + fields[index].offset = upb_MiniTable_place(ctx, l, field_size, m); } /* 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. */ + for (int i = 0; i < m->oneof_count; i++) { + const upb_OneofDef* o = &m->oneofs[i]; + 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; + 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); + for (int j = 0; j < o->field_count; j++) { + const upb_FieldDef* f = o->fields[j]; 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); + case_offset = upb_MiniTable_place(ctx, l, case_size, m); + data_offset = upb_MiniTable_place(ctx, l, field_size, m); - 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; + for (int i = 0; i < o->field_count; i++) { + const upb_FieldDef* f = o->fields[i]; + fields[upb_FieldDef_Index(f)].offset = data_offset; + fields[upb_FieldDef_Index(f)].presence = ~case_offset; } } @@ -5640,28 +6732,30 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { l->size = UPB_ALIGN_UP(l->size, 8); /* Sort fields by number. */ - qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp); + qsort(fields, upb_MessageDef_numfields(m), sizeof(*fields), field_number_cmp); assign_layout_indices(m, l, fields); } -static char *strviewdup(symtab_addctx *ctx, upb_strview view) { - return upb_strdup2(view.data, view.size, ctx->arena); +static char* strviewdup(symtab_addctx* ctx, upb_StringView view) { + char* ret = upb_strdup2(view.data, view.size, ctx->arena); + CHK_OOM(ret); + return ret; } -static bool streql2(const char *a, size_t n, const char *b) { +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) { +static bool streql_view(upb_StringView view, const char* b) { return streql2(view.data, view.size, b); } -static const char *makefullname(symtab_addctx *ctx, const char *prefix, - upb_strview name) { +static const char* makefullname(symtab_addctx* ctx, const char* prefix, + upb_StringView name) { if (prefix) { /* ret = prefix + '.' + name; */ size_t n = strlen(prefix); - char *ret = symtab_alloc(ctx, n + name.size + 2); + char* ret = symtab_alloc(ctx, n + name.size + 2); strcpy(ret, prefix); ret[n] = '.'; memcpy(&ret[n + 1], name.data, name.size); @@ -5672,33 +6766,33 @@ static const char *makefullname(symtab_addctx *ctx, const char *prefix, } } -static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) { +static void finalize_oneofs(symtab_addctx* ctx, upb_MessageDef* m) { int i; int synthetic_count = 0; - upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs; + upb_OneofDef* mutable_oneofs = (upb_OneofDef*)m->oneofs; for (i = 0; i < m->oneof_count; i++) { - upb_oneofdef *o = &mutable_oneofs[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)); + 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)); + upb_OneofDef_Name(o)); } - o->fields = symtab_alloc(ctx, sizeof(upb_fielddef *) * o->field_count); + 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; + const upb_FieldDef* f = &m->fields[i]; + upb_OneofDef* o = (upb_OneofDef*)upb_FieldDef_ContainingOneof(f); if (o) { o->fields[o->field_count++] = f; } @@ -5707,14 +6801,16 @@ static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) { m->real_oneof_count = m->oneof_count - synthetic_count; } -size_t getjsonname(const char *name, char *buf, size_t len) { +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' +#define WRITE(byte) \ + ++dst; \ + if (dst < len) \ + buf[dst - 1] = byte; \ + else if (dst == len) \ + buf[dst - 1] = '\0' if (!name) { WRITE('\0'); @@ -5745,14 +6841,19 @@ size_t getjsonname(const char *name, char *buf, size_t len) { #undef WRITE } -static char* makejsonname(symtab_addctx *ctx, const char* name) { +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) { +/* Adds a symbol |v| to the symtab, which must be a def pointer previously + * packed with pack_def(). The def's pointer to upb_FileDef* must be set before + * adding, so we know which entries to remove if building this file fails. */ +static void symtab_add(symtab_addctx* ctx, const char* name, upb_value v) { + // TODO: table should support an operation "tryinsert" to avoid the double + // lookup. if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) { symtab_errf(ctx, "duplicate symbol '%s'", name); } @@ -5761,83 +6862,264 @@ static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) { ctx->symtab->arena)); } +static bool remove_component(char* base, size_t* len) { + if (*len == 0) return false; + + for (size_t i = *len - 1; i > 0; i--) { + if (base[i] == '.') { + *len = i; + return true; + } + } + + *len = 0; + return true; +} + /* 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] == '.') { +static const void* symtab_resolveany(symtab_addctx* ctx, + const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t* type) { + const upb_strtable* t = &ctx->symtab->syms; + if (sym.size == 0) goto notfound; + upb_value v; + 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; + /* Remove components from base until we find an entry or run out. */ + size_t baselen = strlen(base); + char* tmp = malloc(sym.size + strlen(base) + 1); + while (1) { + char* p = tmp; + if (baselen) { + memcpy(p, base, baselen); + p[baselen] = '.'; + p += baselen + 1; + } + memcpy(p, sym.data, sym.size); + p += sym.size; + if (upb_strtable_lookup2(t, tmp, p - tmp, &v)) { + break; + } + if (!remove_component(tmp, &baselen)) { + free(tmp); + goto notfound; + } + } + free(tmp); } + *type = deftype(v); + return unpack_def(v, *type); + notfound: - symtab_errf(ctx, "couldn't resolve name '" UPB_STRVIEW_FORMAT "'", - UPB_STRVIEW_ARGS(sym)); + symtab_errf(ctx, "couldn't resolve name '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(sym)); +} + +static const void* symtab_resolve(symtab_addctx* ctx, const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t type) { + upb_deftype_t found_type; + const void* ret = + symtab_resolveany(ctx, from_name_dbg, base, sym, &found_type); + if (ret && found_type != type) { + symtab_errf( + ctx, + "type mismatch when resolving %s: couldn't find name %s with type=%d", + from_name_dbg, sym.data, (int)type); + } + return ret; } 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); + symtab_addctx* ctx, upb_MessageDef* m, + const google_protobuf_OneofDescriptorProto* oneof_proto, + const upb_OneofDef* _o) { + upb_OneofDef* o = (upb_OneofDef*)_o; + upb_StringView 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; + SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); + v = pack_def(o, UPB_DEFTYPE_ONEOF); - symtab_add(ctx, o->full_name, v); CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena)); CHK_OOM(upb_inttable_init(&o->itof, ctx->arena)); CHK_OOM(upb_strtable_init(&o->ntof, 4, ctx->arena)); } -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; +static str_t* newstr(symtab_addctx* ctx, const char* data, size_t len) { + str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len); + CHK_OOM(ret); 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; +static bool upb_DefPool_TryGetChar(const char** src, const char* end, + char* ch) { + if (*src == end) return false; + *ch = **src; + *src += 1; + return true; +} + +static char upb_DefPool_TryGetHexDigit(symtab_addctx* ctx, + const upb_FieldDef* f, const char** src, + const char* end) { + char ch; + if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '9') { + return ch - '0'; + } + ch = upb_ascii_lower(ch); + if ('a' <= ch && ch <= 'f') { + return ch - 'a' + 0xa; + } + *src -= 1; // Char wasn't actually a hex digit. + return -1; +} + +static char upb_DefPool_ParseHexEscape(symtab_addctx* ctx, + const upb_FieldDef* f, const char** src, + const char* end) { + char hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end); + if (hex_digit < 0) { + symtab_errf(ctx, + "\\x cannot be followed by non-hex digit in field '%s' default", + upb_FieldDef_FullName(f)); + return 0; + } + unsigned int ret = hex_digit; + while ((hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end)) >= 0) { + ret = (ret << 4) | hex_digit; + } + if (ret > 0xff) { + symtab_errf(ctx, "Value of hex escape in field %s exceeds 8 bits", + upb_FieldDef_FullName(f)); + return 0; + } + return ret; +} + +char upb_DefPool_TryGetOctalDigit(const char** src, const char* end) { + char ch; + if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '7') { + return ch - '0'; + } + *src -= 1; // Char wasn't actually an octal digit. + return -1; +} + +static char upb_DefPool_ParseOctalEscape(symtab_addctx* ctx, + const upb_FieldDef* f, + const char** src, const char* end) { + char ch = 0; + for (int i = 0; i < 3; i++) { + char digit; + if ((digit = upb_DefPool_TryGetOctalDigit(src, end)) >= 0) { + ch = (ch << 3) | digit; + } + } + return ch; +} + +static char upb_DefPool_ParseEscape(symtab_addctx* ctx, const upb_FieldDef* f, + const char** src, const char* end) { + char ch; + if (!upb_DefPool_TryGetChar(src, end, &ch)) { + symtab_errf(ctx, "unterminated escape sequence in field %s", + upb_FieldDef_FullName(f)); + return 0; + } + switch (ch) { + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '\"': + return '\"'; + case '?': + return '\?'; + case 'x': + case 'X': + return upb_DefPool_ParseHexEscape(ctx, f, src, end); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + *src -= 1; + return upb_DefPool_ParseOctalEscape(ctx, f, src, end); + } + symtab_errf(ctx, "Unknown escape sequence: \\%c", ch); +} + +static str_t* unescape(symtab_addctx* ctx, const upb_FieldDef* f, + const char* data, size_t len) { + // Size here is an upper bound; escape sequences could ultimately shrink it. + str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len); + char* dst = &ret->str[0]; + const char* src = data; + const char* end = data + len; + + while (src < end) { + if (*src == '\\') { + src++; + *dst++ = upb_DefPool_ParseEscape(ctx, f, &src, end); + } else { + *dst++ = *src++; + } + } + + ret->len = dst - &ret->str[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: + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + case kUpb_CType_Double: + case kUpb_CType_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); @@ -5850,8 +7132,8 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, break; } - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: { long val = strtol(str, &end, 0); if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) { goto invalid; @@ -5859,16 +7141,17 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, 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)) { + case kUpb_CType_Enum: { + const upb_EnumDef* e = f->sub.enumdef; + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNameWithSize(e, str, len); + if (!ev) { goto invalid; } - f->defaultval.sint = val; + f->defaultval.sint = ev->number; break; } - case UPB_TYPE_INT64: { + case kUpb_CType_Int64: { long long val = strtoll(str, &end, 0); if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) { goto invalid; @@ -5876,7 +7159,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.sint = val; break; } - case UPB_TYPE_UINT32: { + case kUpb_CType_UInt32: { unsigned long val = strtoul(str, &end, 0); if (val > UINT32_MAX || errno == ERANGE || *end) { goto invalid; @@ -5884,7 +7167,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.uint = val; break; } - case UPB_TYPE_UINT64: { + case kUpb_CType_UInt64: { unsigned long long val = strtoull(str, &end, 0); if (val > UINT64_MAX || errno == ERANGE || *end) { goto invalid; @@ -5892,7 +7175,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.uint = val; break; } - case UPB_TYPE_DOUBLE: { + case kUpb_CType_Double: { double val = strtod(str, &end); if (errno == ERANGE || *end) { goto invalid; @@ -5900,7 +7183,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.dbl = val; break; } - case UPB_TYPE_FLOAT: { + case kUpb_CType_Float: { float val = strtof(str, &end); if (errno == ERANGE || *end) { goto invalid; @@ -5908,75 +7191,78 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.flt = val; break; } - case UPB_TYPE_BOOL: { + case kUpb_CType_Bool: { if (streql2(str, len, "false")) { f->defaultval.boolean = false; } else if (streql2(str, len, "true")) { f->defaultval.boolean = true; } else { + goto invalid; } break; } - case UPB_TYPE_STRING: + case kUpb_CType_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); + case kUpb_CType_Bytes: + f->defaultval.str = unescape(ctx, f, str, len); break; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: /* Should not have a default value. */ symtab_errf(ctx, "Message should not have a default (%s)", - upb_fielddef_fullname(f)); + upb_FieldDef_FullName(f)); } return; invalid: - symtab_errf(ctx, "Invalid default '%.*s' for field %s", (int)len, str, - upb_fielddef_fullname(f)); + symtab_errf(ctx, "Invalid default '%.*s' for field %s of type %d", (int)len, + str, upb_FieldDef_FullName(f), (int)upb_FieldDef_Type(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: +static void set_default_default(symtab_addctx* ctx, upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: f->defaultval.sint = 0; break; - case UPB_TYPE_UINT64: - case UPB_TYPE_UINT32: + case kUpb_CType_UInt64: + case kUpb_CType_UInt32: f->defaultval.uint = 0; break; - case UPB_TYPE_DOUBLE: - case UPB_TYPE_FLOAT: + case kUpb_CType_Double: + case kUpb_CType_Float: f->defaultval.dbl = 0; break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_String: + case kUpb_CType_Bytes: f->defaultval.str = newstr(ctx, NULL, 0); break; - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: f->defaultval.boolean = false; break; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Enum: + f->defaultval.sint = f->sub.enumdef->values[0].number; + case kUpb_CType_Message: break; } } static void create_fielddef( - symtab_addctx *ctx, const char *prefix, upb_msgdef *m, - const google_protobuf_FieldDescriptorProto *field_proto) { - 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; + symtab_addctx* ctx, const char* prefix, upb_MessageDef* m, + const google_protobuf_FieldDescriptorProto* field_proto, + const upb_FieldDef* _f, bool is_extension) { + upb_FieldDef* f = (upb_FieldDef*)_f; + upb_StringView name; + const char* full_name; + const char* json_name; + const char* shortname; + int32_t field_number; + + f->file = ctx->file; /* Must happen prior to symtab_add(). */ if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { - symtab_errf(ctx, "field has no name (%s)", upb_msgdef_fullname(m)); + symtab_errf(ctx, "field has no name (%s)", upb_MessageDef_FullName(m)); } name = google_protobuf_FieldDescriptorProto_name(field_proto); @@ -5987,57 +7273,94 @@ static void create_fielddef( if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) { json_name = strviewdup( ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto)); + f->has_json_name_ = true; } else { json_name = makejsonname(ctx, shortname); + f->has_json_name_ = false; } 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); - } + f->full_name = full_name; + f->json_name = json_name; + f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); + f->number_ = field_number; + f->scope.oneof = NULL; + f->proto3_optional_ = + google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); - if (m) { - /* direct message field. */ - upb_value v, field_v, json_v; - size_t json_size; + bool has_type = google_protobuf_FieldDescriptorProto_has_type(field_proto); + bool has_type_name = + google_protobuf_FieldDescriptorProto_has_type_name(field_proto); - f = (upb_fielddef*)&m->fields[m->field_count]; - f->index_ = m->field_count++; - f->msgdef = m; - f->is_extension_ = false; + f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); - if (upb_strtable_lookup(&m->ntof, shortname, NULL)) { - symtab_errf(ctx, "duplicate field name (%s)", shortname); + if (has_type) { + switch (f->type_) { + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + case kUpb_FieldType_Enum: + if (!has_type_name) { + symtab_errf(ctx, "field of type %d requires type name (%s)", + (int)f->type_, full_name); + } + break; + default: + if (has_type_name) { + symtab_errf(ctx, "invalid type for field with type_name set (%s, %d)", + full_name, (int)f->type_); + } } + } else if (has_type_name) { + f->type_ = + FIELD_TYPE_UNSPECIFIED; // We'll fill this in in resolve_fielddef(). + } - if (upb_strtable_lookup(&m->ntof, json_name, NULL)) { - symtab_errf(ctx, "duplicate json_name (%s)", json_name); - } + if (!is_extension) { + /* direct message field. */ + upb_value v, field_v, json_v, existing_v; + size_t json_size; - if (upb_inttable_lookup(&m->itof, field_number, NULL)) { - symtab_errf(ctx, "duplicate field number (%u)", field_number); + if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) { + symtab_errf(ctx, "invalid field number (%u)", field_number); } + f->index_ = f - m->fields; + f->msgdef = m; + f->is_extension_ = 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); + if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) { + symtab_errf(ctx, "duplicate field name (%s)", shortname); + } + CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, field_v, ctx->arena)); - CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena)); if (strcmp(shortname, json_name) != 0) { - upb_strtable_insert(&m->ntof, json_name, json_size, json_v, ctx->arena); + if (upb_strtable_lookup(&m->ntof, json_name, &v)) { + symtab_errf(ctx, "duplicate json_name (%s)", json_name); + } else { + CHK_OOM(upb_strtable_insert(&m->ntof, json_name, json_size, json_v, + ctx->arena)); + } } - if (ctx->layouts) { - const upb_msglayout_field *fields = m->layout->fields; + if (upb_inttable_lookup(&m->itof, field_number, NULL)) { + symtab_errf(ctx, "duplicate field number (%u)", field_number); + } + + CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena)); + + if (ctx->layout) { + const upb_MiniTable_Field* fields = m->layout->fields; int count = m->layout->field_count; bool found = false; - int i; - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { if (fields[i].number == field_number) { f->layout_index = i; found = true; @@ -6048,37 +7371,42 @@ static void create_fielddef( } } 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->scope.extension_scope = m; + symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_EXT)); + f->layout_index = ctx->ext_count++; + if (ctx->layout) { + UPB_ASSERT(ctx->file->ext_layouts[f->layout_index]->field.number == + field_number); + } + } + + if (f->type_ < kUpb_FieldType_Double || f->type_ > kUpb_FieldType_SInt64) { + symtab_errf(ctx, "invalid type for field %s (%d)", f->full_name, f->type_); + } + + if (f->label_ < kUpb_Label_Optional || f->label_ > kUpb_Label_Repeated) { + symtab_errf(ctx, "invalid label for field %s (%d)", f->full_name, + f->label_); } - 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) { + if (f->label_ == kUpb_Label_Required && + f->file->syntax == kUpb_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_OneofDef* oneof; upb_value v = upb_value_constptr(f); - if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { + if (upb_FieldDef_Label(f) != kUpb_Label_Optional) { symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)", f->full_name); } @@ -6092,8 +7420,8 @@ static void create_fielddef( symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name); } - oneof = (upb_oneofdef *)&m->oneofs[oneof_index]; - f->oneof = oneof; + oneof = (upb_OneofDef*)&m->oneofs[oneof_index]; + f->scope.oneof = oneof; oneof->field_count++; if (f->proto3_optional_) { @@ -6103,43 +7431,166 @@ static void create_fielddef( CHK_OOM( upb_strtable_insert(&oneof->ntof, name.data, name.size, v, ctx->arena)); } 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; + SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); - if (options && google_protobuf_FieldOptions_has_packed(options)) { - f->packed_ = google_protobuf_FieldOptions_packed(options); + if (google_protobuf_FieldOptions_has_packed(f->opts)) { + f->packed_ = google_protobuf_FieldOptions_packed(f->opts); } 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; + f->packed_ = upb_FieldDef_IsPrimitive(f) && + f->label_ == kUpb_Label_Repeated && + f->file->syntax == kUpb_Syntax_Proto3; } +} - if (options) { - f->lazy_ = google_protobuf_FieldOptions_lazy(options); - } else { - f->lazy_ = false; +static void create_service( + symtab_addctx* ctx, const google_protobuf_ServiceDescriptorProto* svc_proto, + const upb_ServiceDef* _s) { + upb_ServiceDef* s = (upb_ServiceDef*)_s; + upb_StringView name; + const google_protobuf_MethodDescriptorProto* const* methods; + size_t i, n; + + s->file = ctx->file; /* Must happen prior to symtab_add. */ + + name = google_protobuf_ServiceDescriptorProto_name(svc_proto); + check_ident(ctx, name, false); + s->full_name = makefullname(ctx, ctx->file->package, name); + symtab_add(ctx, s->full_name, pack_def(s, UPB_DEFTYPE_SERVICE)); + + methods = google_protobuf_ServiceDescriptorProto_method(svc_proto, &n); + + s->method_count = n; + s->methods = symtab_alloc(ctx, sizeof(*s->methods) * n); + + SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, svc_proto); + + for (i = 0; i < n; i++) { + const google_protobuf_MethodDescriptorProto* method_proto = methods[i]; + upb_MethodDef* m = (upb_MethodDef*)&s->methods[i]; + upb_StringView name = + google_protobuf_MethodDescriptorProto_name(method_proto); + + m->service = s; + m->full_name = makefullname(ctx, s->full_name, name); + m->client_streaming = + google_protobuf_MethodDescriptorProto_client_streaming(method_proto); + m->server_streaming = + google_protobuf_MethodDescriptorProto_server_streaming(method_proto); + m->input_type = symtab_resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_input_type(method_proto), + UPB_DEFTYPE_MSG); + m->output_type = symtab_resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_output_type(method_proto), + UPB_DEFTYPE_MSG); + + SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, method_proto); + } +} + +static int count_bits_debug(uint64_t x) { + // For assertions only, speed does not matter. + int n = 0; + while (x) { + if (x & 1) n++; + x >>= 1; + } + return n; +} + +upb_MiniTable_Enum* create_enumlayout(symtab_addctx* ctx, + const upb_EnumDef* e) { + int n = 0; + uint64_t mask = 0; + + for (int i = 0; i < e->value_count; i++) { + uint32_t val = (uint32_t)e->values[i].number; + if (val < 64) { + mask |= 1 << val; + } else { + n++; + } + } + + int32_t* values = symtab_alloc(ctx, sizeof(*values) * n); + + if (n) { + int32_t* p = values; + + // Add values outside the bitmask range to the list, as described in the + // comments for upb_MiniTable_Enum. + for (int i = 0; i < e->value_count; i++) { + int32_t val = e->values[i].number; + if ((uint32_t)val >= 64) { + *p++ = val; + } + } + UPB_ASSERT(p == values + n); + } + + UPB_ASSERT(upb_inttable_count(&e->iton) == n + count_bits_debug(mask)); + + upb_MiniTable_Enum* layout = symtab_alloc(ctx, sizeof(*layout)); + layout->value_count = n; + layout->mask = mask; + layout->values = values; + + return layout; +} + +static void create_enumvaldef( + symtab_addctx* ctx, const char* prefix, + const google_protobuf_EnumValueDescriptorProto* val_proto, upb_EnumDef* e, + int i) { + upb_EnumValueDef* val = (upb_EnumValueDef*)&e->values[i]; + upb_StringView name = + google_protobuf_EnumValueDescriptorProto_name(val_proto); + upb_value v = upb_value_constptr(val); + + val->parent = e; /* Must happen prior to symtab_add(). */ + val->full_name = makefullname(ctx, prefix, name); + val->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); + symtab_add(ctx, val->full_name, pack_def(val, UPB_DEFTYPE_ENUMVAL)); + + SET_OPTIONS(val->opts, EnumValueDescriptorProto, EnumValueOptions, val_proto); + + if (i == 0 && e->file->syntax == kUpb_Syntax_Proto3 && val->number != 0) { + symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)", + e->full_name); + } + + CHK_OOM(upb_strtable_insert(&e->ntoi, name.data, name.size, v, ctx->arena)); + + // Multiple enumerators can have the same number, first one wins. + if (!upb_inttable_lookup(&e->iton, val->number, NULL)) { + CHK_OOM(upb_inttable_insert(&e->iton, val->number, v, ctx->arena)); } } 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; + symtab_addctx* ctx, const char* prefix, + const google_protobuf_EnumDescriptorProto* enum_proto, + const upb_MessageDef* containing_type, const upb_EnumDef* _e) { + upb_EnumDef* e = (upb_EnumDef*)_e; + ; + const google_protobuf_EnumValueDescriptorProto* const* values; + upb_StringView name; size_t i, n; + e->file = ctx->file; /* Must happen prior to symtab_add() */ + e->containing_type = containing_type; + 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)); @@ -6147,225 +7598,374 @@ static void create_enumdef( CHK_OOM(upb_strtable_init(&e->ntoi, n, ctx->arena)); CHK_OOM(upb_inttable_init(&e->iton, ctx->arena)); - e->file = ctx->file; e->defaultval = 0; + e->value_count = n; + e->values = symtab_alloc(ctx, sizeof(*e->values) * n); 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); - } + SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); - if (upb_strtable_lookup(&e->ntoi, name2, NULL)) { - symtab_errf(ctx, "duplicate enum label '%s'", name2); - } + for (i = 0; i < n; i++) { + create_enumvaldef(ctx, prefix, values[i], e, i); + } - CHK_OOM(name2) - CHK_OOM(upb_strtable_insert(&e->ntoi, name2, strlen(name2), v, ctx->arena)); + upb_inttable_compact(&e->iton, ctx->arena); - if (!upb_inttable_lookup(&e->iton, num, NULL)) { - upb_value v = upb_value_cstr(name2); - CHK_OOM(upb_inttable_insert(&e->iton, num, v, ctx->arena)); + if (e->file->syntax == kUpb_Syntax_Proto2) { + if (ctx->layout) { + UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count); + e->layout = ctx->layout->enums[ctx->enum_count++]; + UPB_ASSERT(n == + e->layout->value_count + count_bits_debug(e->layout->mask)); + } else { + e->layout = create_enumlayout(ctx, e); } + } else { + e->layout = NULL; } - - upb_inttable_compact(&e->iton, ctx->arena); } -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; +static void msgdef_create_nested( + symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto, + upb_MessageDef* m); + +static void create_msgdef(symtab_addctx* ctx, const char* prefix, + const google_protobuf_DescriptorProto* msg_proto, + const upb_MessageDef* containing_type, + const upb_MessageDef* _m) { + upb_MessageDef* m = (upb_MessageDef*)_m; + const google_protobuf_OneofDescriptorProto* const* oneofs; + const google_protobuf_FieldDescriptorProto* const* fields; + const google_protobuf_DescriptorProto_ExtensionRange* const* ext_ranges; + size_t i, n_oneof, n_field, n_ext_range; + upb_StringView name; + + m->file = ctx->file; /* Must happen prior to symtab_add(). */ + m->containing_type = containing_type; 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); + ext_ranges = + google_protobuf_DescriptorProto_extension_range(msg_proto, &n_ext_range); CHK_OOM(upb_inttable_init(&m->itof, ctx->arena)); CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena)); - 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++; + if (ctx->layout) { + /* create_fielddef() below depends on this being set. */ + UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count); + m->layout = ctx->layout->msgs[ctx->msg_count++]; + UPB_ASSERT(n_field == m->layout->field_count); } else { /* Allocate now (to allow cross-linking), populate later. */ - m->layout = symtab_alloc( - ctx, sizeof(*m->layout) + sizeof(_upb_fasttable_entry)); + m->layout = + symtab_alloc(ctx, sizeof(*m->layout) + sizeof(_upb_FastTable_Entry)); } - m->oneof_count = 0; + SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); + + m->oneof_count = n_oneof; m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof); for (i = 0; i < n_oneof; i++) { - create_oneofdef(ctx, m, oneofs[i]); + create_oneofdef(ctx, m, oneofs[i], &m->oneofs[i]); } - m->field_count = 0; + m->field_count = n_field; 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]); + create_fielddef(ctx, m->full_name, m, fields[i], &m->fields[i], + /* is_extension= */ false); } - finalize_oneofs(ctx, m); - assign_msg_wellknowntype(m); - upb_inttable_compact(&m->itof, ctx->arena); + m->ext_range_count = n_ext_range; + m->ext_ranges = symtab_alloc(ctx, sizeof(*m->ext_ranges) * n_ext_range); + for (i = 0; i < n_ext_range; i++) { + const google_protobuf_DescriptorProto_ExtensionRange* r = ext_ranges[i]; + upb_ExtensionRange* r_def = (upb_ExtensionRange*)&m->ext_ranges[i]; + int32_t start = google_protobuf_DescriptorProto_ExtensionRange_start(r); + int32_t end = google_protobuf_DescriptorProto_ExtensionRange_end(r); + int32_t max = + google_protobuf_MessageOptions_message_set_wire_format(m->opts) + ? INT32_MAX + : kUpb_MaxFieldNumber + 1; - /* This message is built. Now build nested messages and enums. */ + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + if (start < 1 || end <= start || end > max) { + symtab_errf(ctx, "Extension range (%d, %d) is invalid, message=%s\n", + (int)start, (int)end, m->full_name); + } - enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n); - for (i = 0; i < n; i++) { - create_enumdef(ctx, m->full_name, enums[i]); + r_def->start = start; + r_def->end = end; + SET_OPTIONS(r_def->opts, DescriptorProto_ExtensionRange, + ExtensionRangeOptions, r); } - msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); - for (i = 0; i < n; i++) { - create_msgdef(ctx, m->full_name, msgs[i]); - } + finalize_oneofs(ctx, m); + assign_msg_wellknowntype(m); + upb_inttable_compact(&m->itof, ctx->arena); + msgdef_create_nested(ctx, msg_proto, m); } -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++; +static void msgdef_create_nested( + symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto, + upb_MessageDef* m) { + size_t n; - msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); - for (i = 0; i < n; i++) { - count_types_in_msg(msgs[i], file); + const google_protobuf_EnumDescriptorProto* const* enums = + google_protobuf_DescriptorProto_enum_type(msg_proto, &n); + m->nested_enum_count = n; + m->nested_enums = symtab_alloc(ctx, sizeof(*m->nested_enums) * n); + for (size_t i = 0; i < n; i++) { + m->nested_enum_count = i + 1; + create_enumdef(ctx, m->full_name, enums[i], m, &m->nested_enums[i]); } - google_protobuf_DescriptorProto_enum_type(msg_proto, &n); - file->enum_count += n; + const google_protobuf_FieldDescriptorProto* const* exts = + google_protobuf_DescriptorProto_extension(msg_proto, &n); + m->nested_ext_count = n; + m->nested_exts = symtab_alloc(ctx, sizeof(*m->nested_exts) * n); + for (size_t i = 0; i < n; i++) { + create_fielddef(ctx, m->full_name, m, exts[i], &m->nested_exts[i], + /* is_extension= */ true); + ((upb_FieldDef*)&m->nested_exts[i])->index_ = i; + } - google_protobuf_DescriptorProto_extension(msg_proto, &n); - file->ext_count += n; + const google_protobuf_DescriptorProto* const* msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + m->nested_msg_count = n; + m->nested_msgs = symtab_alloc(ctx, sizeof(*m->nested_msgs) * n); + for (size_t i = 0; i < n; i++) { + create_msgdef(ctx, m->full_name, msgs[i], m, &m->nested_msgs[i]); + } +} + +static void resolve_subdef(symtab_addctx* ctx, const char* prefix, + upb_FieldDef* f) { + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + upb_StringView name = + google_protobuf_FieldDescriptorProto_type_name(field_proto); + bool has_name = + google_protobuf_FieldDescriptorProto_has_type_name(field_proto); + switch ((int)f->type_) { + case FIELD_TYPE_UNSPECIFIED: { + // Type was not specified and must be inferred. + UPB_ASSERT(has_name); + upb_deftype_t type; + const void* def = + symtab_resolveany(ctx, f->full_name, prefix, name, &type); + switch (type) { + case UPB_DEFTYPE_ENUM: + f->sub.enumdef = def; + f->type_ = kUpb_FieldType_Enum; + break; + case UPB_DEFTYPE_MSG: + f->sub.msgdef = def; + f->type_ = kUpb_FieldType_Message; // It appears there is no way of + // this being a group. + break; + default: + symtab_errf(ctx, "Couldn't resolve type name for field %s", + f->full_name); + } + } + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + UPB_ASSERT(has_name); + f->sub.msgdef = + symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG); + break; + case kUpb_FieldType_Enum: + UPB_ASSERT(has_name); + f->sub.enumdef = + symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_ENUM); + break; + default: + // No resolution necessary. + break; + } } -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); +static void resolve_extension( + symtab_addctx* ctx, const char* prefix, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* field_proto) { + if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { + symtab_errf(ctx, "extension for field '%s' had no extendee", f->full_name); } - google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); - file->enum_count += n; + upb_StringView name = + google_protobuf_FieldDescriptorProto_extendee(field_proto); + const upb_MessageDef* m = + symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG); + f->msgdef = m; - google_protobuf_FileDescriptorProto_extension(file_proto, &n); - file->ext_count += n; -} + bool found = false; -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); + for (int i = 0, n = m->ext_range_count; i < n; i++) { + const upb_ExtensionRange* r = &m->ext_ranges[i]; + if (r->start <= f->number_ && f->number_ < r->end) { + found = true; + break; } - - 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); + if (!found) { + symtab_errf(ctx, + "field number %u in extension %s has no extension range in " + "message %s", + (unsigned)f->number_, f->full_name, f->msgdef->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); + const upb_MiniTable_Extension* ext = ctx->file->ext_layouts[f->layout_index]; + if (ctx->layout) { + UPB_ASSERT(upb_FieldDef_Number(f) == ext->field.number); + } else { + upb_MiniTable_Extension* mut_ext = (upb_MiniTable_Extension*)ext; + fill_fieldlayout(&mut_ext->field, f); + mut_ext->field.presence = 0; + mut_ext->field.offset = 0; + mut_ext->field.submsg_index = 0; + mut_ext->extendee = f->msgdef->layout; + mut_ext->sub.submsg = f->sub.msgdef->layout; } - /* Have to delay resolving of the default value until now because of the enum - * case, since enum defaults are specified with a label. */ + CHK_OOM(upb_inttable_insert(&ctx->symtab->exts, (uintptr_t)ext, + upb_value_constptr(f), ctx->arena)); +} + +static void resolve_default( + symtab_addctx* ctx, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* field_proto) { + // 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 = + upb_StringView defaultval = google_protobuf_FieldDescriptorProto_default_value(field_proto); - if (f->file->syntax == UPB_SYNTAX_PROTO3) { + if (f->file->syntax == kUpb_Syntax_Proto3) { symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)", f->full_name); } - if (upb_fielddef_issubmsg(f)) { + if (upb_FieldDef_IsSubMessage(f)) { symtab_errf(ctx, "message fields cannot have explicit defaults (%s)", f->full_name); } parse_default(ctx, defaultval.data, defaultval.size, f); + f->has_default = true; } else { set_default_default(ctx, f); + f->has_default = false; + } +} + +static void resolve_fielddef(symtab_addctx* ctx, const char* prefix, + upb_FieldDef* f) { + // We have to stash this away since resolve_subdef() may overwrite it. + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + + resolve_subdef(ctx, prefix, f); + resolve_default(ctx, f, field_proto); + + if (f->is_extension_) { + resolve_extension(ctx, prefix, f, field_proto); + } +} + +static void resolve_msgdef(symtab_addctx* ctx, upb_MessageDef* m) { + for (int i = 0; i < m->field_count; i++) { + resolve_fielddef(ctx, m->full_name, (upb_FieldDef*)&m->fields[i]); + } + + for (int i = 0; i < m->nested_ext_count; i++) { + resolve_fielddef(ctx, m->full_name, (upb_FieldDef*)&m->nested_exts[i]); + } + + if (!ctx->layout) make_layout(ctx, m); + + m->in_message_set = false; + if (m->nested_ext_count == 1) { + const upb_FieldDef* ext = &m->nested_exts[0]; + if (ext->type_ == kUpb_FieldType_Message && + ext->label_ == kUpb_Label_Optional && ext->sub.msgdef == m && + google_protobuf_MessageOptions_message_set_wire_format( + ext->msgdef->opts)) { + m->in_message_set = true; + } + } + + for (int i = 0; i < m->nested_msg_count; i++) { + resolve_msgdef(ctx, (upb_MessageDef*)&m->nested_msgs[i]); + } +} + +static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) { + size_t n; + google_protobuf_DescriptorProto_extension(msg_proto, &n); + int ext_count = n; + + const google_protobuf_DescriptorProto* const* nested_msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (size_t i = 0; i < n; i++) { + ext_count += count_exts_in_msg(nested_msgs[i]); } + + return ext_count; } 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; + symtab_addctx* ctx, upb_FileDef* file, + const google_protobuf_FileDescriptorProto* file_proto) { + const google_protobuf_DescriptorProto* const* msgs; + const google_protobuf_EnumDescriptorProto* const* enums; + const google_protobuf_FieldDescriptorProto* const* exts; + const google_protobuf_ServiceDescriptorProto* const* services; + const upb_StringView* strs; + const int32_t* public_deps; + const int32_t* weak_deps; size_t i, n; file->symtab = ctx->symtab; - /* One pass to count and allocate. */ - file->msg_count = 0; - file->enum_count = 0; - file->ext_count = 0; - 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); + /* Count all extensions in the file, to build a flat array of layouts. */ + google_protobuf_FileDescriptorProto_extension(file_proto, &n); + int ext_count = n; + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (int i = 0; i < n; i++) { + ext_count += count_exts_in_msg(msgs[i]); + } + file->ext_count = ext_count; - /* In the second pass we increment these as defs are added. */ - file->msg_count = 0; - file->enum_count = 0; - file->ext_count = 0; + if (ctx->layout) { + /* We are using the ext layouts that were passed in. */ + file->ext_layouts = ctx->layout->exts; + if (ctx->layout->ext_count != file->ext_count) { + symtab_errf(ctx, "Extension count did not match layout (%d vs %d)", + ctx->layout->ext_count, file->ext_count); + } + } else { + /* We are building ext layouts from scratch. */ + file->ext_layouts = + symtab_alloc(ctx, sizeof(*file->ext_layouts) * file->ext_count); + upb_MiniTable_Extension* ext = + symtab_alloc(ctx, sizeof(*ext) * file->ext_count); + for (int i = 0; i < file->ext_count; i++) { + file->ext_layouts[i] = &ext[i]; + } + } if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) { symtab_errf(ctx, "File has no name"); @@ -6373,11 +7973,9 @@ static void build_filedef( 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 = + upb_StringView package = google_protobuf_FileDescriptorProto_package(file_proto); check_ident(ctx, package, true); file->package = strviewdup(ctx, package); @@ -6386,133 +7984,189 @@ static void build_filedef( } if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { - upb_strview syntax = + upb_StringView syntax = google_protobuf_FileDescriptorProto_syntax(file_proto); if (streql_view(syntax, "proto2")) { - file->syntax = UPB_SYNTAX_PROTO2; + file->syntax = kUpb_Syntax_Proto2; } else if (streql_view(syntax, "proto3")) { - file->syntax = UPB_SYNTAX_PROTO3; + file->syntax = kUpb_Syntax_Proto3; } else { - symtab_errf(ctx, "Invalid syntax '" UPB_STRVIEW_FORMAT "'", - UPB_STRVIEW_ARGS(syntax)); + symtab_errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(syntax)); } } else { - file->syntax = UPB_SYNTAX_PROTO2; + file->syntax = kUpb_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)); - } - } + SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto); /* Verify dependencies. */ strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); + file->dep_count = 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)) { + upb_StringView str = strs[i]; + file->deps[i] = + upb_DefPool_FindFileByNameWithSize(ctx->symtab, str.data, str.size); + if (!file->deps[i]) { symtab_errf(ctx, - "Depends on file '" UPB_STRVIEW_FORMAT + "Depends on file '" UPB_STRINGVIEW_FORMAT "', but it has not been loaded", - UPB_STRVIEW_ARGS(dep_name)); + UPB_STRINGVIEW_ARGS(str)); } - file->deps[i] = upb_value_getconstptr(v); } - /* Create messages. */ - msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + public_deps = + google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n); + file->public_dep_count = n; + file->public_deps = symtab_alloc(ctx, sizeof(*file->public_deps) * n); + int32_t* mutable_public_deps = (int32_t*)file->public_deps; for (i = 0; i < n; i++) { - create_msgdef(ctx, file->package, msgs[i]); + if (public_deps[i] >= file->dep_count) { + symtab_errf(ctx, "public_dep %d is out of range", (int)public_deps[i]); + } + mutable_public_deps[i] = public_deps[i]; + } + + weak_deps = + google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n); + file->weak_dep_count = n; + file->weak_deps = symtab_alloc(ctx, sizeof(*file->weak_deps) * n); + int32_t* mutable_weak_deps = (int32_t*)file->weak_deps; + for (i = 0; i < n; i++) { + if (weak_deps[i] >= file->dep_count) { + symtab_errf(ctx, "public_dep %d is out of range", (int)public_deps[i]); + } + mutable_weak_deps[i] = weak_deps[i]; } /* Create enums. */ enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + file->top_lvl_enum_count = n; + file->top_lvl_enums = symtab_alloc(ctx, sizeof(*file->top_lvl_enums) * n); for (i = 0; i < n; i++) { - create_enumdef(ctx, file->package, enums[i]); + create_enumdef(ctx, file->package, enums[i], NULL, &file->top_lvl_enums[i]); } /* Create extensions. */ exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); - file->exts = symtab_alloc(ctx, sizeof(*file->exts) * n); + file->top_lvl_ext_count = n; + file->top_lvl_exts = symtab_alloc(ctx, sizeof(*file->top_lvl_exts) * n); for (i = 0; i < n; i++) { - create_fielddef(ctx, file->package, NULL, exts[i]); + create_fielddef(ctx, file->package, NULL, exts[i], &file->top_lvl_exts[i], + /* is_extension= */ true); + ((upb_FieldDef*)&file->top_lvl_exts[i])->index_ = 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]); + /* Create messages. */ + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + file->top_lvl_msg_count = n; + file->top_lvl_msgs = symtab_alloc(ctx, sizeof(*file->top_lvl_msgs) * n); + for (i = 0; i < n; i++) { + create_msgdef(ctx, file->package, msgs[i], NULL, &file->top_lvl_msgs[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]); - } + /* Create services. */ + services = google_protobuf_FileDescriptorProto_service(file_proto, &n); + file->service_count = n; + file->services = symtab_alloc(ctx, sizeof(*file->services) * n); + for (i = 0; i < n; i++) { + create_service(ctx, services[i], &file->services[i]); + ((upb_ServiceDef*)&file->services[i])->index = i; } - if (!ctx->layouts) { - for (i = 0; i < (size_t)file->msg_count; i++) { - const upb_msgdef *m = &file->msgs[i]; - make_layout(ctx, m); - } + /* Now that all names are in the table, build layouts and resolve refs. */ + for (i = 0; i < (size_t)file->top_lvl_ext_count; i++) { + resolve_fielddef(ctx, file->package, (upb_FieldDef*)&file->top_lvl_exts[i]); } -} -static void remove_filedef(upb_symtab *s, upb_filedef *file) { - int i; - for (i = 0; i < file->msg_count; i++) { - const char *name = file->msgs[i].full_name; - upb_strtable_remove(&s->syms, name, strlen(name), NULL); + for (i = 0; i < (size_t)file->top_lvl_msg_count; i++) { + resolve_msgdef(ctx, (upb_MessageDef*)&file->top_lvl_msgs[i]); } - for (i = 0; i < file->enum_count; i++) { - const char *name = file->enums[i].full_name; - upb_strtable_remove(&s->syms, name, strlen(name), NULL); + + if (file->ext_count) { + CHK_OOM(_upb_extreg_add(ctx->symtab->extreg, file->ext_layouts, + file->ext_count)); } - for (i = 0; i < file->ext_count; i++) { - const char *name = file->exts[i].full_name; - upb_strtable_remove(&s->syms, name, strlen(name), NULL); +} + +static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { + intptr_t iter = UPB_INTTABLE_BEGIN; + upb_StringView key; + upb_value val; + while (upb_strtable_next2(&s->syms, &key, &val, &iter)) { + const upb_FileDef* f; + switch (deftype(val)) { + case UPB_DEFTYPE_EXT: + f = upb_FieldDef_File(unpack_def(val, UPB_DEFTYPE_EXT)); + break; + case UPB_DEFTYPE_MSG: + f = upb_MessageDef_File(unpack_def(val, UPB_DEFTYPE_MSG)); + break; + case UPB_DEFTYPE_ENUM: + f = upb_EnumDef_File(unpack_def(val, UPB_DEFTYPE_ENUM)); + break; + case UPB_DEFTYPE_ENUMVAL: + f = upb_EnumDef_File( + upb_EnumValueDef_Enum(unpack_def(val, UPB_DEFTYPE_ENUMVAL))); + break; + case UPB_DEFTYPE_SERVICE: + f = upb_ServiceDef_File(unpack_def(val, UPB_DEFTYPE_SERVICE)); + break; + default: + UPB_UNREACHABLE(); + } + + if (f == file) upb_strtable_removeiter(&s->syms, &iter); } } -static const upb_filedef *_upb_symtab_addfile( - upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, - const upb_msglayout **layouts, upb_status *status) { +static const upb_FileDef* _upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + const upb_MiniTable_File* layout, upb_Status* status) { symtab_addctx ctx; - upb_strview name = google_protobuf_FileDescriptorProto_name(file_proto); + upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto); + upb_value v; - if (upb_strtable_lookup2(&s->files, name.data, name.size, NULL)) { - upb_status_seterrf(status, "duplicate file name (%.*s)", - UPB_STRVIEW_ARGS(name)); - return NULL; + if (upb_strtable_lookup2(&s->files, name.data, name.size, &v)) { + if (unpack_def(v, UPB_DEFTYPE_FILE)) { + upb_Status_SetErrorFormat(status, "duplicate file name (%.*s)", + UPB_STRINGVIEW_ARGS(name)); + return NULL; + } + const upb_MiniTable_File* registered = unpack_def(v, UPB_DEFTYPE_LAYOUT); + UPB_ASSERT(registered); + if (layout && layout != registered) { + upb_Status_SetErrorFormat( + status, "tried to build with a different layout (filename=%.*s)", + UPB_STRINGVIEW_ARGS(name)); + return NULL; + } + layout = registered; } ctx.symtab = s; - ctx.layouts = layouts; + ctx.layout = layout; + ctx.msg_count = 0; + ctx.enum_count = 0; + ctx.ext_count = 0; ctx.status = status; ctx.file = NULL; - ctx.arena = upb_arena_new(); + ctx.arena = upb_Arena_New(); + ctx.tmp_arena = upb_Arena_New(); - if (!ctx.arena) { - upb_status_setoom(status); + if (!ctx.arena || !ctx.tmp_arena) { + if (ctx.arena) upb_Arena_Free(ctx.arena); + if (ctx.tmp_arena) upb_Arena_Free(ctx.tmp_arena); + upb_Status_setoom(status); return NULL; } if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) { - UPB_ASSERT(!upb_ok(status)); + UPB_ASSERT(!upb_Status_IsOk(status)); if (ctx.file) { remove_filedef(s, ctx.file); ctx.file = NULL; @@ -6521,51 +8175,52 @@ static const upb_filedef *_upb_symtab_addfile( ctx.file = symtab_alloc(&ctx, sizeof(*ctx.file)); build_filedef(&ctx, ctx.file, file_proto); upb_strtable_insert(&s->files, name.data, name.size, - upb_value_constptr(ctx.file), ctx.arena); - UPB_ASSERT(upb_ok(status)); - upb_arena_fuse(s->arena, ctx.arena); + pack_def(ctx.file, UPB_DEFTYPE_FILE), ctx.arena); + UPB_ASSERT(upb_Status_IsOk(status)); + upb_Arena_Fuse(s->arena, ctx.arena); } - upb_arena_free(ctx.arena); + upb_Arena_Free(ctx.arena); + upb_Arena_Free(ctx.tmp_arena); return ctx.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); +const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + upb_Status* status) { + return _upb_DefPool_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) { +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_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_DefPool_Init** deps = init->deps; + google_protobuf_FileDescriptorProto* file; + upb_Arena* arena; + upb_Status status; - upb_status_clear(&status); + upb_Status_Clear(&status); - if (upb_strtable_lookup(&s->files, init->filename, NULL)) { + if (upb_DefPool_FindFileByName(s, init->filename)) { return true; } - arena = upb_arena_new(); + arena = upb_Arena_New(); for (; *deps; deps++) { - if (!_upb_symtab_loaddefinit(s, *deps)) goto err; + if (!_upb_DefPool_LoadDefInit(s, *deps)) goto err; } file = google_protobuf_FileDescriptorProto_parse_ex( - init->descriptor.data, init->descriptor.size, NULL, UPB_DECODE_ALIAS, - arena); + init->descriptor.data, init->descriptor.size, NULL, + kUpb_DecodeOption_AliasString, arena); s->bytes_loaded += init->descriptor.size; if (!file) { - upb_status_seterrf( + upb_Status_SetErrorFormat( &status, "Failed to parse compiled-in descriptor for file '%s'. This should " "never happen.", @@ -6573,24 +8228,80 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { goto err; } - if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err; + if (!_upb_DefPool_AddFile(s, file, init->layout, &status)) { + goto err; + } - upb_arena_free(arena); + upb_Arena_Free(arena); return true; err: - fprintf(stderr, "Error loading compiled-in descriptor: %s\n", - upb_status_errmsg(&status)); - upb_arena_free(arena); + fprintf(stderr, + "Error loading compiled-in descriptor for file '%s' (this should " + "never happen): %s\n", + init->filename, upb_Status_ErrorMessage(&status)); + upb_Arena_Free(arena); return false; } -size_t _upb_symtab_bytesloaded(const upb_symtab *s) { +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s) { return s->bytes_loaded; } -upb_arena *_upb_symtab_arena(const upb_symtab *s) { - return s->arena; +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s) { return s->arena; } + +const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTable_Extension* ext) { + upb_value v; + bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v); + UPB_ASSERT(ok); + return upb_value_getconstptr(v); +} + +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum) { + const upb_MiniTable* l = upb_MessageDef_MiniTable(m); + const upb_MiniTable_Extension* ext = _upb_extreg_get(s->extreg, l, fieldnum); + return ext ? _upb_DefPool_FindExtensionByMiniTable(s, ext) : NULL; +} + +bool _upb_DefPool_registerlayout(upb_DefPool* s, const char* filename, + const upb_MiniTable_File* file) { + if (upb_DefPool_FindFileByName(s, filename)) return false; + upb_value v = pack_def(file, UPB_DEFTYPE_LAYOUT); + return upb_strtable_insert(&s->files, filename, strlen(filename), v, + s->arena); +} + +const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s) { + return s->extreg; +} + +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count) { + size_t n = 0; + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + // This is O(all exts) instead of O(exts for m). If we need this to be + // efficient we may need to make extreg into a two-level table, or have a + // second per-message index. + while (upb_inttable_next2(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) n++; + } + const upb_FieldDef** exts = malloc(n * sizeof(*exts)); + iter = UPB_INTTABLE_BEGIN; + size_t i = 0; + while (upb_inttable_next2(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) exts[i++] = f; + } + *count = n; + return exts; } #undef CHK_OOM @@ -6600,199 +8311,234 @@ upb_arena *_upb_symtab_arena(const upb_symtab *s) { #include -static size_t get_field_size(const upb_msglayout_field *f) { +static size_t get_field_size(const upb_MiniTable_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 */ + 0, /* 0 */ + 8, /* kUpb_FieldType_Double */ + 4, /* kUpb_FieldType_Float */ + 8, /* kUpb_FieldType_Int64 */ + 8, /* kUpb_FieldType_UInt64 */ + 4, /* kUpb_FieldType_Int32 */ + 8, /* kUpb_FieldType_Fixed64 */ + 4, /* kUpb_FieldType_Fixed32 */ + 1, /* kUpb_FieldType_Bool */ + sizeof(upb_StringView), /* kUpb_FieldType_String */ + sizeof(void*), /* kUpb_FieldType_Group */ + sizeof(void*), /* kUpb_FieldType_Message */ + sizeof(upb_StringView), /* kUpb_FieldType_Bytes */ + 4, /* kUpb_FieldType_UInt32 */ + 4, /* kUpb_FieldType_Enum */ + 4, /* kUpb_FieldType_SFixed32 */ + 8, /* kUpb_FieldType_SFixed64 */ + 4, /* kUpb_FieldType_SInt32 */ + 8, /* kUpb_FieldType_SInt64 */ }; - return _upb_repeated_or_map(f) ? sizeof(void *) : sizes[f->descriptortype]; + return upb_IsRepeatedOrMap(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 char _upb_CTypeo_mapsize[12] = { + 0, + 1, /* kUpb_CType_Bool */ + 4, /* kUpb_CType_Float */ + 4, /* kUpb_CType_Int32 */ + 4, /* kUpb_CType_UInt32 */ + 4, /* kUpb_CType_Enum */ + sizeof(void*), /* kUpb_CType_Message */ + 8, /* kUpb_CType_Double */ + 8, /* kUpb_CType_Int64 */ + 8, /* kUpb_CType_UInt64 */ + 0, /* kUpb_CType_String */ + 0, /* kUpb_CType_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 */ +static const char _upb_CTypeo_sizelg2[12] = { + 0, + 0, /* kUpb_CType_Bool */ + 2, /* kUpb_CType_Float */ + 2, /* kUpb_CType_Int32 */ + 2, /* kUpb_CType_UInt32 */ + 2, /* kUpb_CType_Enum */ + UPB_SIZE(2, 3), /* kUpb_CType_Message */ + 3, /* kUpb_CType_Double */ + 3, /* kUpb_CType_Int64 */ + 3, /* kUpb_CType_UInt64 */ + UPB_SIZE(3, 4), /* kUpb_CType_String */ + UPB_SIZE(3, 4), /* kUpb_CType_Bytes */ }; -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ -upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) { - return _upb_msg_new(upb_msgdef_layout(m), a); +upb_Message* upb_Message_New(const upb_MessageDef* m, upb_Arena* a) { + return _upb_Message_New(upb_MessageDef_MiniTable(m), a); } -static bool in_oneof(const upb_msglayout_field *field) { +static bool in_oneof(const upb_MiniTable_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}; +static upb_MessageValue _upb_Message_Getraw(const upb_Message* msg, + const upb_FieldDef* f) { + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); + const char* mem = UPB_PTR_AT(msg, field->offset, char); + upb_MessageValue 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); +bool upb_Message_Has(const upb_Message* msg, const upb_FieldDef* f) { + assert(upb_FieldDef_HasPresence(f)); + if (upb_FieldDef_IsExtension(f)) { + const upb_MiniTable_Extension* ext = _upb_FieldDef_ExtensionMiniTable(f); + return _upb_Message_Getext(msg, ext) != NULL; } 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_MiniTable_Field* field = upb_FieldDef_MiniTable(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 == kUpb_FieldType_Message || + field->descriptortype == kUpb_FieldType_Group); + return _upb_Message_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; +const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* 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_Message_Has(msg, f) ? f : NULL; } else { - const upb_msglayout_field *field = upb_fielddef_layout(f); + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); uint32_t oneof_case = _upb_getoneofcase_field(msg, field); - f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL; + f = oneof_case ? upb_OneofDef_LookupNumber(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); +upb_MessageValue upb_Message_Get(const upb_Message* msg, + const upb_FieldDef* f) { + if (upb_FieldDef_IsExtension(f)) { + const upb_Message_Extension* ext = + _upb_Message_Getext(msg, _upb_FieldDef_ExtensionMiniTable(f)); + if (ext) { + upb_MessageValue val; + memcpy(&val, &ext->data, sizeof(val)); + return val; + } else if (upb_FieldDef_IsRepeated(f)) { + return (upb_MessageValue){.array_val = NULL}; + } + } else if (!upb_FieldDef_HasPresence(f) || upb_Message_Has(msg, f)) { + return _upb_Message_Getraw(msg, f); + } + return upb_FieldDef_Default(f); +} + +upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, + const upb_FieldDef* f, + upb_Arena* a) { + UPB_ASSERT(upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsRepeated(f)); + if (upb_FieldDef_HasPresence(f) && !upb_Message_Has(msg, f)) { + // We need to skip the upb_Message_Get() call in this case. + goto make; + } + + upb_MessageValue val = upb_Message_Get(msg, f); + if (val.array_val) { + return (upb_MutableMessageValue){.array = (upb_Array*)val.array_val}; + } + + upb_MutableMessageValue ret; +make: + if (!a) return (upb_MutableMessageValue){.array = NULL}; + if (upb_FieldDef_IsMap(f)) { + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key = upb_MessageDef_FindFieldByNumberWithSize( + entry, kUpb_MapEntry_KeyFieldNumber); + const upb_FieldDef* value = upb_MessageDef_FindFieldByNumberWithSize( + entry, kUpb_MapEntry_ValueFieldNumber); + ret.map = + upb_Map_New(a, upb_FieldDef_CType(key), upb_FieldDef_CType(value)); + } else if (upb_FieldDef_IsRepeated(f)) { + ret.array = upb_Array_New(a, upb_FieldDef_CType(f)); } else { - return upb_fielddef_default(f); + UPB_ASSERT(upb_FieldDef_IsSubMessage(f)); + ret.msg = upb_Message_New(upb_FieldDef_MessageSubDef(f), a); } -} -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; + val.array_val = ret.array; + upb_Message_Set(msg, f, val, a); - 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*)); + return ret; +} - if (wrong_oneof) { - *_upb_oneofcase_field(msg, field) = field->number; - } else if (field->presence > 0) { +bool upb_Message_Set(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue val, upb_Arena* a) { + if (upb_FieldDef_IsExtension(f)) { + upb_Message_Extension* ext = _upb_Message_Getorcreateext( + msg, _upb_FieldDef_ExtensionMiniTable(f), a); + if (!ext) return false; + memcpy(&ext->data, &val, sizeof(val)); + } else { + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); + char* mem = UPB_PTR_AT(msg, field->offset, char); + 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; } } - return ret; + return true; } -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_Message_ClearField(upb_Message* msg, const upb_FieldDef* f) { + if (upb_FieldDef_IsExtension(f)) { + _upb_Message_Clearext(msg, _upb_FieldDef_ExtensionMiniTable(f)); + } else { + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); + char* mem = UPB_PTR_AT(msg, field->offset, char); -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; + } - 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)); } - - 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)); +void upb_Message_Clear(upb_Message* msg, const upb_MessageDef* m) { + _upb_Message_Clear(msg, upb_MessageDef_MiniTable(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}; +bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, const upb_FieldDef** out_f, + upb_MessageValue* out_val, size_t* iter) { + size_t i = *iter; + size_t n = upb_MessageDef_FieldCount(m); + const upb_MessageValue zero = {0}; UPB_UNUSED(ext_pool); + + /* Iterate over normal fields, returning the first one that is set. */ while (++i < n) { - const upb_fielddef *f = upb_msgdef_field(m, i); - upb_msgval val = _upb_msg_getraw(msg, f); + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + upb_MessageValue val = _upb_Message_Getraw(msg, f); /* Skip field if unset or empty. */ - if (upb_fielddef_haspresence(f)) { - if (!upb_msg_has(msg, f)) continue; + if (upb_FieldDef_HasPresence(f)) { + if (!upb_Message_Has(msg, f)) continue; } else { - upb_msgval test = val; - if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) { + upb_MessageValue test = val; + if (upb_FieldDef_IsString(f) && !upb_FieldDef_IsRepeated(f)) { /* Clear string pointer, only size matters (ptr could be non-NULL). */ test.str_val.data = NULL; } @@ -6800,10 +8546,10 @@ bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, 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; + if (upb_FieldDef_IsMap(f)) { + if (upb_Map_Size(test.map_val) == 0) continue; + } else if (upb_FieldDef_IsRepeated(f)) { + if (upb_Array_Size(test.array_val) == 0) continue; } } @@ -6812,48 +8558,67 @@ bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, *iter = i; return true; } + + if (ext_pool) { + /* Return any extensions that are set. */ + size_t count; + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &count); + if (i - n < count) { + ext += count - 1 - (i - n); + memcpy(out_val, &ext->data, sizeof(*out_val)); + *out_f = _upb_DefPool_FindExtensionByMiniTable(ext_pool, ext->ext); + *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 _upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + int depth) { + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; bool ret = true; if (--depth == 0) return false; - _upb_msg_discardunknown_shallow(msg); + _upb_Message_DiscardUnknown_shallow(msg); - while (upb_msg_next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) { - const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + while (upb_Message_Next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) { + const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(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 (upb_FieldDef_IsMap(f)) { + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumberWithSize(subm, 2); + const upb_MessageDef* val_m = upb_FieldDef_MessageSubDef(val_f); + upb_Map* map = (upb_Map*)val.map_val; + size_t iter = kUpb_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)) { + while (upb_MapIterator_Next(map, &iter)) { + upb_MessageValue map_val = upb_MapIterator_Value(map, iter); + if (!_upb_Message_DiscardUnknown((upb_Message*)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); + } else if (upb_FieldDef_IsRepeated(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)) { + upb_MessageValue elem = upb_Array_Get(arr, i); + if (!_upb_Message_DiscardUnknown((upb_Message*)elem.msg_val, subm, + depth)) { ret = false; } } } else { - if (!_upb_msg_discardunknown((upb_msg*)val.msg_val, subm, depth)) { + if (!_upb_Message_DiscardUnknown((upb_Message*)val.msg_val, subm, + depth)) { ret = false; } } @@ -6862,22 +8627,21 @@ bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth) { return ret; } -bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) { - return _upb_msg_discardunknown(msg, m, maxdepth); +bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + int maxdepth) { + return _upb_Message_DiscardUnknown(msg, m, maxdepth); } -/** upb_array *****************************************************************/ +/** 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]); +upb_Array* upb_Array_New(upb_Arena* a, upb_CType type) { + return _upb_Array_New(a, 4, _upb_CTypeo_sizelg2[type]); } -size_t upb_array_size(const upb_array *arr) { - return arr->len; -} +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; +upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { + upb_MessageValue ret; const char* data = _upb_array_constptr(arr); int lg2 = arr->data & 7; UPB_ASSERT(i < arr->len); @@ -6885,86 +8649,114 @@ upb_msgval upb_array_get(const upb_array *arr, size_t i) { return ret; } -void upb_array_set(upb_array *arr, size_t i, upb_msgval val) { +void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue 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_resize(arr, arr->len + 1, arena)) { +bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { + if (!upb_Array_Resize(arr, arr->len + 1, arena)) { return false; } - upb_array_set(arr, arr->len - 1, val); + 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); +void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx, + size_t count) { + char* data = _upb_array_ptr(arr); + int lg2 = arr->data & 7; + memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2); } -/** upb_map *******************************************************************/ +bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, + upb_Arena* arena) { + UPB_ASSERT(i <= arr->len); + UPB_ASSERT(count + arr->len >= count); + size_t oldsize = arr->len; + if (!upb_Array_Resize(arr, arr->len + count, arena)) { + return false; + } + upb_Array_Move(arr, i + count, i, oldsize - i); + return true; +} -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]); +/* + * i end arr->len + * |------------|XXXXXXXX|--------| + */ +void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) { + size_t end = i + count; + UPB_ASSERT(i <= end); + UPB_ASSERT(end <= arr->len); + upb_Array_Move(arr, i, end, arr->len - end); + arr->len -= count; } -size_t upb_map_size(const upb_map *map) { - return _upb_map_size(map); +bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) { + return _upb_Array_Resize(arr, size, arena); } -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); +/** upb_Map *******************************************************************/ + +upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, upb_CType value_type) { + return _upb_Map_New(a, _upb_CTypeo_mapsize[key_type], + _upb_CTypeo_mapsize[value_type]); } -void upb_map_clear(upb_map *map) { - _upb_map_clear(map); +size_t upb_Map_Size(const upb_Map* map) { return _upb_Map_Size(map); } + +bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* 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); +void upb_Map_Clear(upb_Map* map) { _upb_Map_Clear(map); } + +bool upb_Map_Set(upb_Map* map, upb_MessageValue key, upb_MessageValue 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_Map_Delete(upb_Map* map, upb_MessageValue key) { + return _upb_Map_Delete(map, &key, map->key_size); } -bool upb_mapiter_next(const upb_map *map, size_t *iter) { +bool upb_MapIterator_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) { +bool upb_MapIterator_Done(const upb_Map* map, size_t iter) { upb_strtable_iter i; - UPB_ASSERT(iter != UPB_MAP_BEGIN); + UPB_ASSERT(iter != kUpb_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_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) { upb_strtable_iter i; - upb_msgval ret; + upb_MessageValue 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_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter) { upb_strtable_iter i; - upb_msgval ret; + upb_MessageValue 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); */ +/* void upb_MapIterator_SetValue(upb_Map *map, size_t iter, upb_MessageValue + * value); */ /** upb/json_decode.c ************************************************************/ @@ -6982,62 +8774,64 @@ upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) { typedef struct { const char *ptr, *end; - upb_arena *arena; /* TODO: should we have a tmp arena for tmp data? */ - const upb_symtab *any_pool; + upb_Arena* arena; /* TODO: should we have a tmp arena for tmp data? */ + const upb_DefPool* symtab; int depth; - upb_status *status; + upb_Status* status; jmp_buf err; int line; - const char *line_begin; + const char* line_begin; bool is_first; int options; - const upb_fielddef *debug_field; + 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) { +static void jsondec_wellknown(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); +static upb_MessageValue jsondec_value(jsondec* d, const upb_FieldDef* f); +static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); +static void jsondec_object(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); + +static bool jsondec_streql(upb_StringView 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)), +static bool jsondec_isnullvalue(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_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) || +static bool jsondec_isvalue(const upb_FieldDef* f) { + return (upb_FieldDef_CType(f) == kUpb_CType_Message && + upb_MessageDef_WellKnownType(upb_FieldDef_MessageSubDef(f)) == + kUpb_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); +UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) { + upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: %s", d->line, + (int)(d->ptr - d->line_begin), msg); UPB_LONGJMP(d->err, 1); } UPB_PRINTF(2, 3) -UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) { +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)); + upb_Status_SetErrorFormat(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); + upb_Status_VAppendErrorFormat(d->status, fmt, argp); va_end(argp); UPB_LONGJMP(d->err, 1); } -static void jsondec_skipws(jsondec *d) { +static void jsondec_skipws(jsondec* d) { while (d->ptr != d->end) { switch (*d->ptr) { case '\n': @@ -7056,13 +8850,13 @@ static void jsondec_skipws(jsondec *d) { jsondec_err(d, "Unexpected EOF"); } -static bool jsondec_tryparsech(jsondec *d, char ch) { +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) { +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) { @@ -7071,23 +8865,23 @@ static void jsondec_parselit(jsondec *d, const char *lit) { d->ptr += len; } -static void jsondec_wsch(jsondec *d, char ch) { +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_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) { +static void jsondec_entrysep(jsondec* d) { jsondec_skipws(d); jsondec_parselit(d, ":"); } -static int jsondec_rawpeek(jsondec *d) { +static int jsondec_rawpeek(jsondec* d) { switch (*d->ptr) { case '{': return JD_OBJECT; @@ -7128,19 +8922,19 @@ static int jsondec_rawpeek(jsondec *d) { * } * jsondec_objend(d) */ -static int jsondec_peek(jsondec *d) { +static int jsondec_peek(jsondec* d) { jsondec_skipws(d); return jsondec_rawpeek(d); } -static void jsondec_push(jsondec *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) { +static bool jsondec_seqnext(jsondec* d, char end_ch) { bool is_first = d->is_first; d->is_first = false; jsondec_skipws(d); @@ -7149,31 +8943,29 @@ static bool jsondec_seqnext(jsondec *d, char end_ch) { return true; } -static void jsondec_arrstart(jsondec *d) { +static void jsondec_arrstart(jsondec* d) { jsondec_push(d); jsondec_wsch(d, '['); } -static void jsondec_arrend(jsondec *d) { +static void jsondec_arrend(jsondec* d) { d->depth++; jsondec_wsch(d, ']'); } -static bool jsondec_arrnext(jsondec *d) { - return jsondec_seqnext(d, ']'); -} +static bool jsondec_arrnext(jsondec* d) { return jsondec_seqnext(d, ']'); } -static void jsondec_objstart(jsondec *d) { +static void jsondec_objstart(jsondec* d) { jsondec_push(d); jsondec_wsch(d, '{'); } -static void jsondec_objend(jsondec *d) { +static void jsondec_objend(jsondec* d) { d->depth++; jsondec_wsch(d, '}'); } -static bool jsondec_objnext(jsondec *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"); @@ -7183,8 +8975,8 @@ static bool jsondec_objnext(jsondec *d) { /* JSON number ****************************************************************/ -static bool jsondec_tryskipdigits(jsondec *d) { - const char *start = d->ptr; +static bool jsondec_tryskipdigits(jsondec* d) { + const char* start = d->ptr; while (d->ptr < d->end) { if (*d->ptr < '0' || *d->ptr > '9') { @@ -7196,14 +8988,14 @@ static bool jsondec_tryskipdigits(jsondec *d) { return d->ptr != start; } -static void jsondec_skipdigits(jsondec *d) { +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; +static double jsondec_number(jsondec* d) { + const char* start = d->ptr; assert(jsondec_rawpeek(d) == JD_NUMBER); @@ -7263,7 +9055,7 @@ static double jsondec_number(jsondec *d) { /* JSON string ****************************************************************/ -static char jsondec_escape(jsondec *d) { +static char jsondec_escape(jsondec* d) { switch (*d->ptr++) { case '"': return '\"'; @@ -7286,9 +9078,9 @@ static char jsondec_escape(jsondec *d) { } } -static uint32_t jsondec_codepoint(jsondec *d) { +static uint32_t jsondec_codepoint(jsondec* d) { uint32_t cp = 0; - const char *end; + const char* end; if (d->end - d->ptr < 4) { jsondec_err(d, "EOF inside string"); @@ -7313,7 +9105,7 @@ static uint32_t jsondec_codepoint(jsondec *d) { } /* Parses a \uXXXX unicode escape (possibly a surrogate pair). */ -static size_t jsondec_unicode(jsondec *d, char* out) { +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. */ @@ -7355,22 +9147,22 @@ static size_t jsondec_unicode(jsondec *d, char* out) { } } -static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) { +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); + *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; +static upb_StringView jsondec_string(jsondec* d) { + char* buf = NULL; + char* end = NULL; + char* buf_end = NULL; jsondec_skipws(d); @@ -7387,10 +9179,10 @@ static upb_strview jsondec_string(jsondec *d) { switch (ch) { case '"': { - upb_strview ret; + upb_StringView ret; ret.data = buf; ret.size = end - buf; - *end = '\0'; /* Needed for possible strtod(). */ + *end = '\0'; /* Needed for possible strtod(). */ return ret; } case '\\': @@ -7419,7 +9211,7 @@ static upb_strview jsondec_string(jsondec *d) { jsondec_err(d, "EOF inside string"); } -static void jsondec_skipval(jsondec *d) { +static void jsondec_skipval(jsondec* d) { switch (jsondec_peek(d)) { case JD_OBJECT: jsondec_objstart(d); @@ -7502,8 +9294,8 @@ static unsigned int jsondec_base64_tablelookup(const char ch) { return table[(unsigned)ch]; } -static char *jsondec_partialbase64(jsondec *d, const char *ptr, const char *end, - char *out) { +static char* jsondec_partialbase64(jsondec* d, const char* ptr, const char* end, + char* out) { int32_t val = -1; switch (end - ptr) { @@ -7530,13 +9322,13 @@ static char *jsondec_partialbase64(jsondec *d, const char *ptr, const char *end, return out; } -static size_t jsondec_base64(jsondec *d, upb_strview str) { +static size_t jsondec_base64(jsondec* d, upb_StringView 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. */ + 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 | @@ -7574,8 +9366,8 @@ static size_t jsondec_base64(jsondec *d, upb_strview str) { /* 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) { +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'; @@ -7592,8 +9384,8 @@ static const char *jsondec_buftouint64(jsondec *d, const char *ptr, return ptr; } -static const char *jsondec_buftoint64(jsondec *d, const char *ptr, - const char *end, int64_t *val) { +static const char* jsondec_buftoint64(jsondec* d, const char* ptr, + const char* end, int64_t* val) { bool neg = false; uint64_t u64; @@ -7611,8 +9403,8 @@ static const char *jsondec_buftoint64(jsondec *d, const char *ptr, return ptr; } -static uint64_t jsondec_strtouint64(jsondec *d, upb_strview str) { - const char *end = str.data + str.size; +static uint64_t jsondec_strtouint64(jsondec* d, upb_StringView 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"); @@ -7620,8 +9412,8 @@ static uint64_t jsondec_strtouint64(jsondec *d, upb_strview str) { return ret; } -static int64_t jsondec_strtoint64(jsondec *d, upb_strview str) { - const char *end = str.data + str.size; +static int64_t jsondec_strtoint64(jsondec* d, upb_StringView 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"); @@ -7632,8 +9424,8 @@ static int64_t jsondec_strtoint64(jsondec *d, upb_strview str) { /* Primitive value types ******************************************************/ /* Parse INT32 or INT64 value. */ -static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) { - upb_msgval val; +static upb_MessageValue jsondec_int(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; switch (jsondec_peek(d)) { case JD_NUMBER: { @@ -7641,7 +9433,7 @@ static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) { 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 */ + val.int64_val = dbl; /* must be guarded, overflow here is UB */ if (val.int64_val != dbl) { jsondec_errf(d, "JSON number was not integral (%f != %" PRId64 ")", dbl, val.int64_val); @@ -7649,7 +9441,7 @@ static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) { break; } case JD_STRING: { - upb_strview str = jsondec_string(d); + upb_StringView str = jsondec_string(d); val.int64_val = jsondec_strtoint64(d, str); break; } @@ -7657,7 +9449,8 @@ static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) { jsondec_err(d, "Expected number or string"); } - if (upb_fielddef_type(f) == UPB_TYPE_INT32) { + if (upb_FieldDef_CType(f) == kUpb_CType_Int32 || + upb_FieldDef_CType(f) == kUpb_CType_Enum) { if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) { jsondec_err(d, "Integer out of range."); } @@ -7668,8 +9461,8 @@ static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) { } /* Parse UINT32 or UINT64 value. */ -static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) { - upb_msgval val = {0}; +static upb_MessageValue jsondec_uint(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val = {0}; switch (jsondec_peek(d)) { case JD_NUMBER: { @@ -7677,7 +9470,7 @@ static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) { 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 */ + val.uint64_val = dbl; /* must be guarded, overflow here is UB */ if (val.uint64_val != dbl) { jsondec_errf(d, "JSON number was not integral (%f != %" PRIu64 ")", dbl, val.uint64_val); @@ -7685,7 +9478,7 @@ static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) { break; } case JD_STRING: { - upb_strview str = jsondec_string(d); + upb_StringView str = jsondec_string(d); val.uint64_val = jsondec_strtouint64(d, str); break; } @@ -7693,7 +9486,7 @@ static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) { jsondec_err(d, "Expected number or string"); } - if (upb_fielddef_type(f) == UPB_TYPE_UINT32) { + if (upb_FieldDef_CType(f) == kUpb_CType_UInt32) { if (val.uint64_val > UINT32_MAX) { jsondec_err(d, "Integer out of range."); } @@ -7704,9 +9497,9 @@ static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) { } /* Parse DOUBLE or FLOAT value. */ -static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) { - upb_strview str; - upb_msgval val = {0}; +static upb_MessageValue jsondec_double(jsondec* d, const upb_FieldDef* f) { + upb_StringView str; + upb_MessageValue val = {0}; switch (jsondec_peek(d)) { case JD_NUMBER: @@ -7728,7 +9521,7 @@ static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) { jsondec_err(d, "Expected number or string"); } - if (upb_fielddef_type(f) == UPB_TYPE_FLOAT) { + if (upb_FieldDef_CType(f) == kUpb_CType_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"); @@ -7740,34 +9533,38 @@ static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) { } /* Parse STRING or BYTES value. */ -static upb_msgval jsondec_strfield(jsondec *d, const upb_fielddef *f) { - upb_msgval val; +static upb_MessageValue jsondec_strfield(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; val.str_val = jsondec_string(d); - if (upb_fielddef_type(f) == UPB_TYPE_BYTES) { + if (upb_FieldDef_CType(f) == kUpb_CType_Bytes) { val.str_val.size = jsondec_base64(d, val.str_val); } return val; } -static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *f) { +static upb_MessageValue 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) { + upb_StringView str = jsondec_string(d); + const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size); + upb_MessageValue val; + if (ev) { + val.int32_val = upb_EnumValueDef_Number(ev); + } else { + if (d->options & upb_JsonDecode_IgnoreUnknown) { val.int32_val = 0; } else { - jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'", - UPB_STRVIEW_ARGS(str)); + jsondec_errf(d, "Unknown enumerator: '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(str)); } } return val; } case JD_NULL: { if (jsondec_isnullvalue(f)) { - upb_msgval val; + upb_MessageValue val; jsondec_null(d); val.int32_val = 0; return val; @@ -7779,13 +9576,13 @@ static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *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; +static upb_MessageValue jsondec_bool(jsondec* d, const upb_FieldDef* f) { + bool is_map_key = upb_FieldDef_Number(f) == 1 && + upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f)); + upb_MessageValue val; if (is_map_key) { - upb_strview str = jsondec_string(d); + upb_StringView str = jsondec_string(d); if (jsondec_streql(str, "true")) { val.bool_val = true; } else if (jsondec_streql(str, "false")) { @@ -7813,65 +9610,83 @@ static upb_msgval jsondec_bool(jsondec *d, const upb_fielddef *f) { /* 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; +static void jsondec_array(jsondec* d, upb_Message* msg, const upb_FieldDef* f) { + upb_Array* arr = upb_Message_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); + upb_MessageValue 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); +static void jsondec_map(jsondec* d, upb_Message* msg, const upb_FieldDef* f) { + upb_Map* map = upb_Message_Mutable(msg, f, d->arena).map; + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = + upb_MessageDef_FindFieldByNumberWithSize(entry, 1); + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumberWithSize(entry, 2); jsondec_objstart(d); while (jsondec_objnext(d)) { - upb_msgval key, val; + upb_MessageValue 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); + 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) { +static void jsondec_tomsg(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + if (upb_MessageDef_WellKnownType(m) == kUpb_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; +static upb_MessageValue jsondec_msg(jsondec* d, const upb_FieldDef* f) { + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + upb_Message* msg = upb_Message_New(m, d->arena); + upb_MessageValue 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; +static void jsondec_field(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + upb_StringView 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 (name.size >= 2 && name.data[0] == '[' && + name.data[name.size - 1] == ']') { + f = upb_DefPool_FindExtensionByNameWithSize(d->symtab, name.data + 1, + name.size - 2); + if (f && upb_FieldDef_ContainingType(f) != m) { + jsondec_errf( + d, "Extension %s extends message %s, but was seen in message %s", + upb_FieldDef_FullName(f), + upb_MessageDef_FullName(upb_FieldDef_ContainingType(f)), + upb_MessageDef_FullName(m)); + } + } else { + f = upb_MessageDef_FindByJsonNameWithSize(m, name.data, name.size); + } if (!f) { - if ((d->options & UPB_JSONDEC_IGNOREUNKNOWN) == 0) { - jsondec_errf(d, "No such field: " UPB_STRVIEW_FORMAT, - UPB_STRVIEW_ARGS(name)); + if ((d->options & upb_JsonDecode_IgnoreUnknown) == 0) { + jsondec_errf(d, "No such field: " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(name)); } jsondec_skipval(d); return; @@ -7883,31 +9698,32 @@ static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) { return; } - if (upb_fielddef_realcontainingoneof(f) && - upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) { + if (upb_FieldDef_RealContainingOneof(f) && + upb_Message_WhichOneof(msg, upb_FieldDef_ContainingOneof(f))) { jsondec_err(d, "More than one field for this oneof."); } preserved = d->debug_field; d->debug_field = f; - if (upb_fielddef_ismap(f)) { + if (upb_FieldDef_IsMap(f)) { jsondec_map(d, msg, f); - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(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); + } else if (upb_FieldDef_IsSubMessage(f)) { + upb_Message* submsg = upb_Message_Mutable(msg, f, d->arena).msg; + const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f); jsondec_tomsg(d, submsg, subm); } else { - upb_msgval val = jsondec_value(d, f); - upb_msg_set(msg, f, val, d->arena); + upb_MessageValue val = jsondec_value(d, f); + upb_Message_Set(msg, f, val, d->arena); } d->debug_field = preserved; } -static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m) { +static void jsondec_object(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { jsondec_objstart(d); while (jsondec_objnext(d)) { jsondec_field(d, msg, m); @@ -7915,25 +9731,25 @@ static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m) { jsondec_objend(d); } -static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f) { - switch (upb_fielddef_type(f)) { - case UPB_TYPE_BOOL: +static upb_MessageValue jsondec_value(jsondec* d, const upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: return jsondec_bool(d, f); - case UPB_TYPE_FLOAT: - case UPB_TYPE_DOUBLE: + case kUpb_CType_Float: + case kUpb_CType_Double: return jsondec_double(d, f); - case UPB_TYPE_UINT32: - case UPB_TYPE_UINT64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: return jsondec_uint(d, f); - case UPB_TYPE_INT32: - case UPB_TYPE_INT64: + case kUpb_CType_Int32: + case kUpb_CType_Int64: return jsondec_int(d, f); - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_String: + case kUpb_CType_Bytes: return jsondec_strfield(d, f); - case UPB_TYPE_ENUM: + case kUpb_CType_Enum: return jsondec_enum(d, f); - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: return jsondec_msg(d, f); default: UPB_UNREACHABLE(); @@ -7942,14 +9758,14 @@ static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f) { /* Well-known types ***********************************************************/ -static int jsondec_tsdigits(jsondec *d, const char **ptr, size_t digits, - const char *after) { +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; + 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. */ + UPB_ASSERT(digits <= 9); /* int can't overflow. */ if (jsondec_buftouint64(d, p, end, &val) != end || (after_len && memcmp(end, after, after_len) != 0)) { @@ -7962,12 +9778,12 @@ static int jsondec_tsdigits(jsondec *d, const char **ptr, size_t digits, return (int)val; } -static int jsondec_nanos(jsondec *d, const char **ptr, const char *end) { +static int jsondec_nanos(jsondec* d, const char** ptr, const char* end) { uint64_t nanos = 0; - const char *p = *ptr; + const char* p = *ptr; if (p != end && *p == '.') { - const char *nano_end = jsondec_buftouint64(d, p + 1, end, &nanos); + 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) { @@ -7984,8 +9800,8 @@ static int jsondec_nanos(jsondec *d, const char **ptr, const char *end) { /* 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 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; @@ -7998,12 +9814,13 @@ 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; +static void jsondec_timestamp(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + upb_MessageValue seconds; + upb_MessageValue nanos; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; if (str.size < 20) goto malformed; @@ -8052,20 +9869,23 @@ static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m) { 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); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumberWithSize(m, 1), seconds, + d->arena); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumberWithSize(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; +static void jsondec_duration(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + upb_MessageValue seconds; + upb_MessageValue nanos; + upb_StringView 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. */ @@ -8081,110 +9901,116 @@ static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) { } if (seconds.int64_val < 0) { - nanos.int32_val = - nanos.int32_val; + 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); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumberWithSize(m, 1), seconds, + d->arena); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumberWithSize(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; +static void jsondec_listvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(values_f); + upb_Array* values = upb_Message_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; + upb_Message* value_msg = upb_Message_New(value_m, d->arena); + upb_MessageValue value; value.msg_val = value_msg; - upb_array_append(values, value, d->arena); + 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; +static void jsondec_struct(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 2); + const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(value_f); + upb_Map* fields = upb_Message_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); + upb_MessageValue key, value; + upb_Message* value_msg = upb_Message_New(value_m, d->arena); key.str_val = jsondec_string(d); value.msg_val = value_msg; - upb_map_set(fields, key, value, d->arena); + 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; +static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + upb_MessageValue val; + const upb_FieldDef* f; + upb_Message* submsg; switch (jsondec_peek(d)) { case JD_NUMBER: /* double number_value = 2; */ - f = upb_msgdef_itof(m, 2); + f = upb_MessageDef_FindFieldByNumberWithSize(m, 2); val.double_val = jsondec_number(d); break; case JD_STRING: /* string string_value = 3; */ - f = upb_msgdef_itof(m, 3); + f = upb_MessageDef_FindFieldByNumberWithSize(m, 3); val.str_val = jsondec_string(d); break; case JD_FALSE: /* bool bool_value = 4; */ - f = upb_msgdef_itof(m, 4); + f = upb_MessageDef_FindFieldByNumberWithSize(m, 4); val.bool_val = false; jsondec_false(d); break; case JD_TRUE: /* bool bool_value = 4; */ - f = upb_msgdef_itof(m, 4); + f = upb_MessageDef_FindFieldByNumberWithSize(m, 4); val.bool_val = true; jsondec_true(d); break; case JD_NULL: /* NullValue null_value = 1; */ - f = upb_msgdef_itof(m, 1); + f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); val.int32_val = 0; jsondec_null(d); break; - /* Note: these cases return, because upb_msg_mutable() is enough. */ + /* Note: these cases return, because upb_Message_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)); + f = upb_MessageDef_FindFieldByNumberWithSize(m, 5); + submsg = upb_Message_Mutable(msg, f, d->arena).msg; + jsondec_struct(d, submsg, upb_FieldDef_MessageSubDef(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)); + f = upb_MessageDef_FindFieldByNumberWithSize(m, 6); + submsg = upb_Message_Mutable(msg, f, d->arena).msg; + jsondec_listvalue(d, submsg, upb_FieldDef_MessageSubDef(f)); return; default: UPB_UNREACHABLE(); } - upb_msg_set(msg, f, val, d->arena); + upb_Message_Set(msg, f, val, d->arena); } -static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end) { +static upb_StringView 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; + const char* ptr = buf; + upb_StringView ret; + char* out; ret.size = end - ptr; while (ptr < end) { @@ -8192,7 +10018,7 @@ static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end) { ptr++; } - out = upb_arena_malloc(d->arena, ret.size); + out = upb_Arena_Malloc(d->arena, ret.size); ptr = buf; ret.data = out; @@ -8211,17 +10037,18 @@ static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end) { return ret; } -static void jsondec_fieldmask(jsondec *d, upb_msg *msg, const upb_msgdef *m) { +static void jsondec_fieldmask(jsondec* d, upb_Message* msg, + const upb_MessageDef* 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; + const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + upb_Array* arr = upb_Message_Mutable(msg, paths_f, d->arena).array; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; + upb_MessageValue val; while (ptr < end) { - const char *elem_end = memchr(ptr, ',', end - ptr); + const char* elem_end = memchr(ptr, ',', end - ptr); if (elem_end) { val.str_val = jsondec_mask(d, ptr, elem_end); ptr = elem_end + 1; @@ -8229,19 +10056,20 @@ static void jsondec_fieldmask(jsondec *d, upb_msg *msg, const upb_msgdef *m) { val.str_val = jsondec_mask(d, ptr, end); ptr = end; } - upb_array_append(arr, val, d->arena); + 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) { +static void jsondec_anyfield(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + if (upb_MessageDef_WellKnownType(m) == kUpb_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); + upb_StringView str = jsondec_string(d); jsondec_entrysep(d); if (!jsondec_streql(str, "value")) { jsondec_err(d, "Key for well-known type must be 'value'"); @@ -8250,27 +10078,29 @@ static void jsondec_anyfield(jsondec *d, upb_msg *msg, const upb_msgdef *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; +static const upb_MessageDef* jsondec_typeurl(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* type_url_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_MessageDef* type_m; + upb_StringView type_url = jsondec_string(d); + const char* end = type_url.data + type_url.size; + const char* ptr = end; + upb_MessageValue val; val.str_val = type_url; - upb_msg_set(msg, type_url_f, val, d->arena); + upb_Message_Set(msg, type_url_f, val, d->arena); /* Find message name after the last '/' */ - while (ptr > type_url.data && *--ptr != '/') {} + 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); + type_m = upb_DefPool_FindMessageByNameWithSize(d->symtab, ptr, end - ptr); if (!type_m) { jsondec_err(d, "Type was not found"); @@ -8279,22 +10109,22 @@ static const upb_msgdef *jsondec_typeurl(jsondec *d, upb_msg *msg, return type_m; } -static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *m) { +static void jsondec_any(jsondec* d, upb_Message* msg, const upb_MessageDef* 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; + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumberWithSize(m, 2); + upb_Message* any_msg; + const upb_MessageDef* any_m = NULL; + const char* pre_type_data = NULL; + const char* pre_type_end = NULL; + upb_MessageValue 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); + const char* start = d->ptr; + upb_StringView name = jsondec_string(d); jsondec_entrysep(d); if (jsondec_streql(name, "@type")) { any_m = jsondec_typeurl(d, msg, m); @@ -8312,13 +10142,13 @@ static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *m) { jsondec_err(d, "Any object didn't contain a '@type' field"); } - any_msg = upb_msg_new(any_m, d->arena); + any_msg = upb_Message_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; + 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; @@ -8337,49 +10167,51 @@ static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *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); + encoded.str_val.data = upb_Encode(any_msg, upb_MessageDef_MiniTable(any_m), 0, + d->arena, &encoded.str_val.size); + upb_Message_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_wrapper(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + upb_MessageValue val = jsondec_value(d, value_f); + upb_Message_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: +static void jsondec_wellknown(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Any: jsondec_any(d, msg, m); break; - case UPB_WELLKNOWN_FIELDMASK: + case kUpb_WellKnown_FieldMask: jsondec_fieldmask(d, msg, m); break; - case UPB_WELLKNOWN_DURATION: + case kUpb_WellKnown_Duration: jsondec_duration(d, msg, m); break; - case UPB_WELLKNOWN_TIMESTAMP: + case kUpb_WellKnown_Timestamp: jsondec_timestamp(d, msg, m); break; - case UPB_WELLKNOWN_VALUE: + case kUpb_WellKnown_Value: jsondec_wellknownvalue(d, msg, m); break; - case UPB_WELLKNOWN_LISTVALUE: + case kUpb_WellKnown_ListValue: jsondec_listvalue(d, msg, m); break; - case UPB_WELLKNOWN_STRUCT: + case kUpb_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: + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: jsondec_wrapper(d, msg, m); break; default: @@ -8387,9 +10219,9 @@ static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m) { } } -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) { +bool upb_JsonDecode(const char* buf, size_t size, upb_Message* msg, + const upb_MessageDef* m, const upb_DefPool* symtab, + int options, upb_Arena* arena, upb_Status* status) { jsondec d; if (size == 0) return true; @@ -8397,7 +10229,7 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg, d.ptr = buf; d.end = buf + size; d.arena = arena; - d.any_pool = any_pool; + d.symtab = symtab; d.status = status; d.options = options; d.depth = 64; @@ -8431,43 +10263,46 @@ typedef struct { size_t overflow; int indent_depth; int options; - const upb_symtab *ext_pool; + const upb_DefPool* ext_pool; jmp_buf err; - upb_status *status; - upb_arena *arena; + 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, bool first); -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); +static void jsonenc_msg(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); +static void jsonenc_scalar(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f); +static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); +static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m, bool first); +static void jsonenc_value(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); + +UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) { + upb_Status_SetErrorMessage(e->status, msg); longjmp(e->err, 1); } UPB_PRINTF(2, 3) -UPB_NORETURN static void jsonenc_errf(jsonenc *e, const char *fmt, ...) { +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); + upb_Status_VSetErrorFormat(e->status, fmt, argp); va_end(argp); longjmp(e->err, 1); } -static upb_arena *jsonenc_arena(jsonenc *e) { +static upb_Arena* jsonenc_arena(jsonenc* e) { /* Create lazily, since it's only needed for Any */ if (!e->arena) { - e->arena = upb_arena_new(); + e->arena = upb_Arena_New(); } return e->arena; } -static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) { +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); @@ -8481,12 +10316,12 @@ static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) { } } -static void jsonenc_putstr(jsonenc *e, const char *str) { +static void jsonenc_putstr(jsonenc* e, const char* str) { jsonenc_putbytes(e, str, strlen(str)); } UPB_PRINTF(2, 3) -static void jsonenc_printf(jsonenc *e, const char *fmt, ...) { +static void jsonenc_printf(jsonenc* e, const char* fmt, ...) { size_t n; size_t have = e->end - e->ptr; va_list args; @@ -8503,7 +10338,7 @@ static void jsonenc_printf(jsonenc *e, const char *fmt, ...) { } } -static void jsonenc_nanos(jsonenc *e, int32_t nanos) { +static void jsonenc_nanos(jsonenc* e, int32_t nanos) { int digits = 9; if (nanos == 0) return; @@ -8519,12 +10354,13 @@ static void jsonenc_nanos(jsonenc *e, int32_t nanos) { jsonenc_printf(e, ".%.*" 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; +static void jsonenc_timestamp(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* seconds_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumberWithSize(m, 2); + int64_t seconds = upb_Message_Get(msg, seconds_f).int64_val; + int32_t nanos = upb_Message_Get(msg, nanos_f).int32_val; int L, N, I, J, K, hour, min, sec; if (seconds < -62135596800) { @@ -8561,11 +10397,13 @@ static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg, 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; +static void jsonenc_duration(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* seconds_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumberWithSize(m, 2); + int64_t seconds = upb_Message_Get(msg, seconds_f).int64_val; + int32_t nanos = upb_Message_Get(msg, nanos_f).int32_val; if (seconds > 315576000000 || seconds < -315576000000 || (seconds < 0) != (nanos < 0)) { @@ -8581,28 +10419,28 @@ static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m 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); +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) { + 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); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e_def, val); - if (name) { - jsonenc_printf(e, "\"%s\"", name); + if (ev) { + jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev)); } else { jsonenc_printf(e, "%" PRId32, val); } } } -static void jsonenc_bytes(jsonenc *e, upb_strview str) { +static void jsonenc_bytes(jsonenc* e, upb_StringView 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 = UPB_PTRADD(ptr, str.size); + const unsigned char* ptr = (unsigned char*)str.data; + const unsigned char* end = UPB_PTRADD(ptr, str.size); char buf[4]; jsonenc_putstr(e, "\""); @@ -8636,9 +10474,9 @@ static void jsonenc_bytes(jsonenc *e, upb_strview str) { jsonenc_putstr(e, "\""); } -static void jsonenc_stringbody(jsonenc *e, upb_strview str) { - const char *ptr = str.data; - const char *end = UPB_PTRADD(ptr, str.size); +static void jsonenc_stringbody(jsonenc* e, upb_StringView str) { + const char* ptr = str.data; + const char* end = UPB_PTRADD(ptr, str.size); while (ptr < end) { switch (*ptr) { @@ -8677,13 +10515,13 @@ static void jsonenc_stringbody(jsonenc *e, upb_strview str) { } } -static void jsonenc_string(jsonenc *e, upb_strview str) { +static void jsonenc_string(jsonenc* e, upb_StringView str) { jsonenc_putstr(e, "\""); jsonenc_stringbody(e, str); jsonenc_putstr(e, "\""); } -static void jsonenc_double(jsonenc *e, const char *fmt, double val) { +static bool upb_JsonEncode_HandleSpecialDoubles(jsonenc* e, double val) { if (val == INFINITY) { jsonenc_putstr(e, "\"Infinity\""); } else if (val == -INFINITY) { @@ -8691,32 +10529,38 @@ static void jsonenc_double(jsonenc *e, const char *fmt, double val) { } else if (val != val) { jsonenc_putstr(e, "\"NaN\""); } else { - char *p = e->ptr; - jsonenc_printf(e, fmt, val); - - /* printf() is dependent on locales; sadly there is no easy and portable way - * to avoid this. This little post-processing step will translate 1,2 -> 1.2 - * since JSON needs the latter. Arguably a hack, but it is simple and the - * alternatives are far more complicated, platform-dependent, and/or larger - * in code size. */ - for (char *end = e->ptr; p < end; p++) { - if (*p == ',') *p = '.'; - } + return false; } + return true; +} + +static void upb_JsonEncode_Double(jsonenc* e, double val) { + if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return; + char buf[32]; + _upb_EncodeRoundTripDouble(val, buf, sizeof(buf)); + jsonenc_putstr(e, buf); +} + +static void upb_JsonEncode_Float(jsonenc* e, float val) { + if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return; + char buf[32]; + _upb_EncodeRoundTripFloat(val, buf, sizeof(buf)); + jsonenc_putstr(e, buf); } -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); +static void jsonenc_wrapper(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + upb_MessageValue val = upb_Message_Get(msg, val_f); jsonenc_scalar(e, val, val_f); } -static const upb_msgdef *jsonenc_getanymsg(jsonenc *e, upb_strview type_url) { +static const upb_MessageDef* jsonenc_getanymsg(jsonenc* e, + upb_StringView type_url) { /* Find last '/', if any. */ - const char *end = type_url.data + type_url.size; - const char *ptr = end; - const upb_msgdef *ret; + const char* end = type_url.data + type_url.size; + const char* ptr = end; + const upb_MessageDef* ret; if (!e->ext_pool) { jsonenc_err(e, "Tried to encode Any, but no symtab was provided"); @@ -8735,7 +10579,7 @@ static const upb_msgdef *jsonenc_getanymsg(jsonenc *e, upb_strview type_url) { } } - ret = upb_symtab_lookupmsg2(e->ext_pool, ptr, end - ptr); + ret = upb_DefPool_FindMessageByNameWithSize(e->ext_pool, ptr, end - ptr); if (!ret) { jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr); @@ -8744,28 +10588,31 @@ static const upb_msgdef *jsonenc_getanymsg(jsonenc *e, upb_strview type_url) { 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_errf(e, "Bad type URL: " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(type_url)); +} + +static void jsonenc_any(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* type_url_f = + upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumberWithSize(m, 2); + upb_StringView type_url = upb_Message_Get(msg, type_url_f).str_val; + upb_StringView value = upb_Message_Get(msg, value_f).str_val; + const upb_MessageDef* any_m = jsonenc_getanymsg(e, type_url); + const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m); + upb_Arena* arena = jsonenc_arena(e); + upb_Message* any = upb_Message_New(any_m, arena); + + if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { jsonenc_err(e, "Error decoding message in Any"); } jsonenc_putstr(e, "{\"@type\":"); jsonenc_string(e, type_url); - if (upb_msgdef_wellknowntype(any_m) == UPB_WELLKNOWN_UNSPECIFIED) { + if (upb_MessageDef_WellKnownType(any_m) == kUpb_WellKnown_Unspecified) { /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */ jsonenc_msgfields(e, any, any_m, false); } else { @@ -8777,7 +10624,7 @@ static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { jsonenc_putstr(e, "}"); } -static void jsonenc_putsep(jsonenc *e, const char *str, bool *first) { +static void jsonenc_putsep(jsonenc* e, const char* str, bool* first) { if (*first) { *first = false; } else { @@ -8785,9 +10632,9 @@ static void jsonenc_putsep(jsonenc *e, const char *str, bool *first) { } } -static void jsonenc_fieldpath(jsonenc *e, upb_strview path) { - const char *ptr = path.data; - const char *end = ptr + path.size; +static void jsonenc_fieldpath(jsonenc* e, upb_StringView path) { + const char* ptr = path.data; + const char* end = ptr + path.size; while (ptr < end) { char ch = *ptr; @@ -8806,65 +10653,66 @@ static void jsonenc_fieldpath(jsonenc *e, upb_strview path) { } } -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; +static void jsonenc_fieldmask(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_Array* paths = upb_Message_Get(msg, paths_f).array_val; bool first = true; size_t i, n = 0; - if (paths) n = upb_array_size(paths); + 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_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; +static void jsonenc_struct(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_Map* fields = upb_Message_Get(msg, fields_f).map_val; + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = + upb_MessageDef_FindFieldByNumberWithSize(entry_m, 2); + size_t iter = kUpb_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); + while (upb_MapIterator_Next(fields, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(fields, iter); + upb_MessageValue val = upb_MapIterator_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_value(e, val.msg_val, upb_FieldDef_MessageSubDef(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; +static void jsonenc_listvalue(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumberWithSize(m, 1); + const upb_MessageDef* values_m = upb_FieldDef_MessageSubDef(values_f); + const upb_Array* values = upb_Message_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); + const size_t size = upb_Array_Size(values); for (i = 0; i < size; i++) { - upb_msgval elem = upb_array_get(values, i); + upb_MessageValue elem = upb_Array_Get(values, i); jsonenc_putsep(e, ",", &first); jsonenc_value(e, elem.msg_val, values_m); @@ -8874,22 +10722,23 @@ static void jsonenc_listvalue(jsonenc *e, const upb_msg *msg, jsonenc_putstr(e, "]"); } -static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { +static void jsonenc_value(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* 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; + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; - if (!upb_msg_next(msg, m, NULL, &f, &val, &iter)) { + if (!upb_Message_Next(msg, m, NULL, &f, &val, &iter)) { jsonenc_err(e, "No value set in Value proto"); } - switch (upb_fielddef_number(f)) { + switch (upb_FieldDef_Number(f)) { case 1: jsonenc_putstr(e, "null"); break; case 2: - jsonenc_double(e, "%.17g", val.double_val); + upb_JsonEncode_Double(e, val.double_val); break; case 3: jsonenc_string(e, val.str_val); @@ -8898,113 +10747,115 @@ static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { jsonenc_putstr(e, val.bool_val ? "true" : "false"); break; case 5: - jsonenc_struct(e, val.msg_val, upb_fielddef_msgsubdef(f)); + jsonenc_struct(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); break; case 6: - jsonenc_listvalue(e, val.msg_val, upb_fielddef_msgsubdef(f)); + jsonenc_listvalue(e, val.msg_val, upb_FieldDef_MessageSubDef(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: +static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Unspecified: jsonenc_msg(e, msg, m); break; - case UPB_WELLKNOWN_ANY: + case kUpb_WellKnown_Any: jsonenc_any(e, msg, m); break; - case UPB_WELLKNOWN_FIELDMASK: + case kUpb_WellKnown_FieldMask: jsonenc_fieldmask(e, msg, m); break; - case UPB_WELLKNOWN_DURATION: + case kUpb_WellKnown_Duration: jsonenc_duration(e, msg, m); break; - case UPB_WELLKNOWN_TIMESTAMP: + case kUpb_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: + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: jsonenc_wrapper(e, msg, m); break; - case UPB_WELLKNOWN_VALUE: + case kUpb_WellKnown_Value: jsonenc_value(e, msg, m); break; - case UPB_WELLKNOWN_LISTVALUE: + case kUpb_WellKnown_ListValue: jsonenc_listvalue(e, msg, m); break; - case UPB_WELLKNOWN_STRUCT: + case kUpb_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: +static void jsonenc_scalar(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: jsonenc_putstr(e, val.bool_val ? "true" : "false"); break; - case UPB_TYPE_FLOAT: - jsonenc_double(e, "%.9g", val.float_val); + case kUpb_CType_Float: + upb_JsonEncode_Float(e, val.float_val); break; - case UPB_TYPE_DOUBLE: - jsonenc_double(e, "%.17g", val.double_val); + case kUpb_CType_Double: + upb_JsonEncode_Double(e, val.double_val); break; - case UPB_TYPE_INT32: + case kUpb_CType_Int32: jsonenc_printf(e, "%" PRId32, val.int32_val); break; - case UPB_TYPE_UINT32: + case kUpb_CType_UInt32: jsonenc_printf(e, "%" PRIu32, val.uint32_val); break; - case UPB_TYPE_INT64: + case kUpb_CType_Int64: jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val); break; - case UPB_TYPE_UINT64: + case kUpb_CType_UInt64: jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val); break; - case UPB_TYPE_STRING: + case kUpb_CType_String: jsonenc_string(e, val.str_val); break; - case UPB_TYPE_BYTES: + case kUpb_CType_Bytes: jsonenc_bytes(e, val.str_val); break; - case UPB_TYPE_ENUM: + case kUpb_CType_Enum: jsonenc_enum(val.int32_val, f, e); break; - case UPB_TYPE_MESSAGE: - jsonenc_msgfield(e, val.msg_val, upb_fielddef_msgsubdef(f)); + case kUpb_CType_Message: + jsonenc_msgfield(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); break; } } -static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f) { +static void jsonenc_mapkey(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f) { jsonenc_putstr(e, "\""); - switch (upb_fielddef_type(f)) { - case UPB_TYPE_BOOL: + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: jsonenc_putstr(e, val.bool_val ? "true" : "false"); break; - case UPB_TYPE_INT32: + case kUpb_CType_Int32: jsonenc_printf(e, "%" PRId32, val.int32_val); break; - case UPB_TYPE_UINT32: + case kUpb_CType_UInt32: jsonenc_printf(e, "%" PRIu32, val.uint32_val); break; - case UPB_TYPE_INT64: + case kUpb_CType_Int64: jsonenc_printf(e, "%" PRId64, val.int64_val); break; - case UPB_TYPE_UINT64: + case kUpb_CType_UInt64: jsonenc_printf(e, "%" PRIu64, val.uint64_val); break; - case UPB_TYPE_STRING: + case kUpb_CType_String: jsonenc_stringbody(e, val.str_val); break; default: @@ -9014,95 +10865,105 @@ static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f) { jsonenc_putstr(e, "\":"); } -static void jsonenc_array(jsonenc *e, const upb_array *arr, - const upb_fielddef *f) { +static void jsonenc_array(jsonenc* e, const upb_Array* arr, + const upb_FieldDef* f) { size_t i; - size_t size = arr ? upb_array_size(arr) : 0; + size_t size = arr ? upb_Array_Size(arr) : 0; 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_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; +static void jsonenc_map(jsonenc* e, const upb_Map* map, const upb_FieldDef* f) { + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = + upb_MessageDef_FindFieldByNumberWithSize(entry, 1); + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumberWithSize(entry, 2); + size_t iter = kUpb_Map_Begin; bool first = true; jsonenc_putstr(e, "{"); if (map) { - while (upb_mapiter_next(map, &iter)) { + while (upb_MapIterator_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_mapkey(e, upb_MapIterator_Key(map, iter), key_f); + jsonenc_scalar(e, upb_MapIterator_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; +static void jsonenc_fieldval(jsonenc* e, const upb_FieldDef* f, + upb_MessageValue val, bool* first) { + const char* name; + + jsonenc_putsep(e, ",", first); - if (e->options & UPB_JSONENC_PROTONAMES) { - name = upb_fielddef_name(f); + if (upb_FieldDef_IsExtension(f)) { + // TODO: For MessageSet, I would have expected this to print the message + // name here, but Python doesn't appear to do this. We should do more + // research here about what various implementations do. + jsonenc_printf(e, "\"[%s]\":", upb_FieldDef_FullName(f)); } else { - name = upb_fielddef_jsonname(f); + if (e->options & upb_JsonEncode_UseProtoNames) { + name = upb_FieldDef_Name(f); + } else { + name = upb_FieldDef_JsonName(f); + } + jsonenc_printf(e, "\"%s\":", name); } - jsonenc_putsep(e, ",", first); - jsonenc_printf(e, "\"%s\":", name); - - if (upb_fielddef_ismap(f)) { + if (upb_FieldDef_IsMap(f)) { jsonenc_map(e, val.map_val, f); - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(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, bool first) { - upb_msgval val; - const upb_fielddef *f; +static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m, bool first) { + upb_MessageValue val; + const upb_FieldDef* f; - if (e->options & UPB_JSONENC_EMITDEFAULTS) { + if (e->options & upb_JsonEncode_EmitDefaults) { /* Iterate over all fields. */ int i = 0; - int n = upb_msgdef_fieldcount(m); + int n = upb_MessageDef_FieldCount(m); for (i = 0; i < n; i++) { - f = upb_msgdef_field(m, i); - if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) { - jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first); + f = upb_MessageDef_Field(m, i); + if (!upb_FieldDef_HasPresence(f) || upb_Message_Has(msg, f)) { + jsonenc_fieldval(e, f, upb_Message_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)) { + size_t iter = kUpb_Message_Begin; + while (upb_Message_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) { +static void jsonenc_msg(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { jsonenc_putstr(e, "{"); jsonenc_msgfields(e, msg, m, true); jsonenc_putstr(e, "}"); } -static size_t jsonenc_nullz(jsonenc *e, size_t size) { +static size_t jsonenc_nullz(jsonenc* e, size_t size) { size_t ret = e->ptr - e->buf + e->overflow; if (size > 0) { @@ -9113,9 +10974,9 @@ static size_t jsonenc_nullz(jsonenc *e, size_t size) { 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) { +size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, char* buf, + size_t size, upb_Status* status) { jsonenc e; e.buf = buf; @@ -9130,7 +10991,7 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, if (setjmp(e.err)) return -1; jsonenc_msgfield(&e, msg, m); - if (e.arena) upb_arena_free(e.arena); + if (e.arena) upb_Arena_Free(e.arena); return jsonenc_nullz(&e, size); } diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 40072772b2fa5..369861c508549 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -255,7 +255,7 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); /** upb/decode.h ************************************************************/ /* - * upb_decode: parsing into a upb_msg using a upb_msglayout. + * upb_decode: parsing into a upb_Message using a upb_MiniTable. */ #ifndef UPB_DECODE_H_ @@ -297,54 +297,56 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); extern "C" { #endif -/* upb_status *****************************************************************/ +/* upb_Status *****************************************************************/ -#define UPB_STATUS_MAX_MESSAGE 127 +#define _kUpb_Status_MaxMessage 127 typedef struct { bool ok; - char msg[UPB_STATUS_MAX_MESSAGE]; /* Error message; NULL-terminated. */ -} upb_status; + char msg[_kUpb_Status_MaxMessage]; /* Error message; NULL-terminated. */ +} upb_Status; -const char *upb_status_errmsg(const upb_status *status); -bool upb_ok(const upb_status *status); +const char* upb_Status_ErrorMessage(const upb_Status* status); +bool upb_Status_IsOk(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_Clear(upb_Status* status); +void upb_Status_SetErrorMessage(upb_Status* status, const char* msg); +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) UPB_PRINTF(2, 3); -void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) - UPB_PRINTF(2, 0); -void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) - UPB_PRINTF(2, 0); +void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); +void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); -/** upb_strview ************************************************************/ +/** upb_StringView ************************************************************/ typedef struct { - const char *data; + const char* data; size_t size; -} upb_strview; +} upb_StringView; -UPB_INLINE upb_strview upb_strview_make(const char *data, size_t size) { - upb_strview ret; +UPB_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView 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 upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); } -UPB_INLINE bool upb_strview_eql(upb_strview a, upb_strview b) { +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; } -#define UPB_STRVIEW_INIT(ptr, len) {ptr, len} +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } -#define UPB_STRVIEW_FORMAT "%.*s" -#define UPB_STRVIEW_ARGS(view) (int)(view).size, (view).data +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data /** upb_alloc *****************************************************************/ @@ -360,25 +362,25 @@ 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, +typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size); struct upb_alloc { - upb_alloc_func *func; + upb_alloc_func* func; }; -UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) { +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, +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) { +UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) { assert(alloc); alloc->func(alloc, ptr, 0, 0); } @@ -392,69 +394,67 @@ extern upb_alloc upb_alloc_global; * 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) { +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) { +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_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } -/* upb_arena ******************************************************************/ +/* upb_Arena ******************************************************************/ -/* upb_arena is a specific allocator implementation that uses arena allocation. +/* 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. + * 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); +typedef void upb_CleanupFunc(void* ud); -struct upb_arena; -typedef struct upb_arena upb_arena; +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! + * 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; +} _upb_ArenaHead; /* 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); -bool upb_arena_fuse(upb_arena *a, upb_arena *b); -void *_upb_arena_slowmalloc(upb_arena *a, size_t size); +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_CleanupFunc* func); +bool 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 upb_alloc* upb_Arena_Alloc(upb_Arena* a) { return (upb_alloc*)a; } -UPB_INLINE size_t _upb_arenahas(upb_arena *a) { - _upb_arena_head *h = (_upb_arena_head*)a; +UPB_INLINE size_t _upb_ArenaHas(upb_Arena* a) { + _upb_ArenaHead* h = (_upb_ArenaHead*)a; return (size_t)(h->end - h->ptr); } -UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { - _upb_arena_head *h = (_upb_arena_head*)a; +UPB_INLINE void* upb_Arena_Malloc(upb_Arena* a, size_t size) { + _upb_ArenaHead* h = (_upb_ArenaHead*)a; void* ret; size = UPB_ALIGN_MALLOC(size); - if (UPB_UNLIKELY(_upb_arenahas(a) < size)) { - return _upb_arena_slowmalloc(a, size); + if (UPB_UNLIKELY(_upb_ArenaHas(a) < size)) { + return _upb_Arena_SlowMalloc(a, size); } ret = h->ptr; @@ -464,7 +464,7 @@ UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { #if UPB_ASAN { size_t guard_size = 32; - if (_upb_arenahas(a) >= guard_size) { + if (_upb_ArenaHas(a) >= guard_size) { h->ptr += guard_size; } else { h->ptr = h->end; @@ -475,9 +475,9 @@ UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { return ret; } -UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, +UPB_INLINE void* upb_Arena_Realloc(upb_Arena* a, void* ptr, size_t oldsize, size_t size) { - void *ret = upb_arena_malloc(a, size); + void* ret = upb_Arena_Malloc(a, size); if (ret && oldsize > 0) { memcpy(ret, ptr, oldsize); @@ -486,100 +486,77 @@ UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, return ret; } -UPB_INLINE upb_arena *upb_arena_new(void) { - return upb_arena_init(NULL, 0, &upb_alloc_global); +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; + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; /* 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; + kUpb_CType_Bool = 1, + kUpb_CType_Float = 2, + kUpb_CType_Int32 = 3, + kUpb_CType_UInt32 = 4, + kUpb_CType_Enum = 5, /* Enum values are int32. */ + kUpb_CType_Message = 6, + kUpb_CType_Double = 7, + kUpb_CType_Int64 = 8, + kUpb_CType_UInt64 = 9, + kUpb_CType_String = 10, + kUpb_CType_Bytes = 11 +} upb_CType; /* 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; + kUpb_Label_Optional = 1, + kUpb_Label_Required = 2, + kUpb_Label_Repeated = 3 +} upb_Label; /* 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) { + kUpb_FieldType_Double = 1, + kUpb_FieldType_Float = 2, + kUpb_FieldType_Int64 = 3, + kUpb_FieldType_UInt64 = 4, + kUpb_FieldType_Int32 = 5, + kUpb_FieldType_Fixed64 = 6, + kUpb_FieldType_Fixed32 = 7, + kUpb_FieldType_Bool = 8, + kUpb_FieldType_String = 9, + kUpb_FieldType_Group = 10, + kUpb_FieldType_Message = 11, + kUpb_FieldType_Bytes = 12, + kUpb_FieldType_UInt32 = 13, + kUpb_FieldType_Enum = 14, + kUpb_FieldType_SFixed32 = 15, + kUpb_FieldType_SFixed64 = 16, + kUpb_FieldType_SInt32 = 17, + kUpb_FieldType_SInt64 = 18 +} upb_FieldType; + +#define kUpb_Map_Begin ((size_t)-1) + +UPB_INLINE bool _upb_IsLittleEndian(void) { int x = 1; return *(char*)&x == 1; } -UPB_INLINE uint32_t _upb_be_swap32(uint32_t val) { - if (_upb_isle()) { +UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { + if (_upb_IsLittleEndian()) { return val; } else { return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | @@ -587,15 +564,16 @@ UPB_INLINE uint32_t _upb_be_swap32(uint32_t val) { } } -UPB_INLINE uint64_t _upb_be_swap64(uint64_t val) { - if (_upb_isle()) { +UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { + if (_upb_IsLittleEndian()) { return val; } else { - return ((uint64_t)_upb_be_swap32(val) << 32) | _upb_be_swap32(val >> 32); + return ((uint64_t)_upb_BigEndian_Swap32(val) << 32) | + _upb_BigEndian_Swap32(val >> 32); } } -UPB_INLINE int _upb_lg2ceil(int x) { +UPB_INLINE int _upb_Log2Ceiling(int x) { if (x <= 1) return 0; #ifdef __GNUC__ return 32 - __builtin_clz(x - 1); @@ -606,54 +584,59 @@ UPB_INLINE int _upb_lg2ceil(int x) { #endif } -UPB_INLINE int _upb_lg2ceilsize(int x) { - return 1 << _upb_lg2ceil(x); -} +UPB_INLINE int _upb_Log2Ceilingsize(int x) { return 1 << _upb_Log2Ceiling(x); } #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_H_ */ +#endif /* UPB_H_ */ #ifdef __cplusplus extern "C" { #endif -typedef void upb_msg; +/** upb_Message + * *******************************************************************/ + +typedef void upb_Message; -/* For users these are opaque. They can be obtained from upb_msgdef_layout() - * but users cannot access any of the members. */ -struct upb_msglayout; -typedef struct upb_msglayout upb_msglayout; +/* For users these are opaque. They can be obtained from + * upb_MessageDef_MiniTable() but users cannot access any of the members. */ +struct upb_MiniTable; +typedef struct upb_MiniTable upb_MiniTable; /* 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); +void upb_Message_AddUnknown(upb_Message* 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); +const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len); -/** upb_extreg *******************************************************************/ +/* Returns the number of extensions present in this message. */ +size_t upb_Message_ExtensionCount(const upb_Message* msg); + +/** upb_ExtensionRegistry *****************************************************/ /* Extension registry: a dynamic data structure that stores a map of: - * (upb_msglayout, number) -> extension info + * (upb_MiniTable, number) -> extension info * - * upb_decode() uses upb_extreg to look up extensions while parsing binary - * format. + * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing + * binary format. * - * upb_extreg is part of the mini-table (msglayout) family of objects. Like all - * mini-table objects, it is suitable for reflection-less builds that do not - * want to expose names into the binary. + * upb_ExtensionRegistry is part of the mini-table (msglayout) family of + * objects. Like all mini-table objects, it is suitable for reflection-less + * builds that do not want to expose names into the binary. * - * Unlike most mini-table types, upb_extreg requires dynamic memory allocation - * and dynamic initialization: - * * If reflection is being used, then upb_symtab will construct an appropriate - * upb_extreg automatically. + * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory + * allocation and dynamic initialization: + * * If reflection is being used, then upb_DefPool will construct an appropriate + * upb_ExtensionRegistry automatically. * * For a mini-table only build, the user must manually construct the - * upb_extreg and populate it with all of the extensions the user cares about. + * upb_ExtensionRegistry and populate it with all of the extensions the user + * cares about. * * A third alternative is to manually unpack relevant extensions after the * main parse is complete, similar to how Any works. This is perhaps the * nicest solution from the perspective of reducing dependencies, avoiding @@ -667,19 +650,19 @@ const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); * extensions from a generated module and pass the extension registry to the * binary decoder. * - * A upb_symtab provides a upb_extreg, so any users who use reflection do not - * need to populate a upb_extreg directly. + * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use + * reflection do not need to populate a upb_ExtensionRegistry directly. */ -struct upb_extreg; -typedef struct upb_extreg upb_extreg; +struct upb_ExtensionRegistry; +typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; -/* Creates a upb_extreg in the given arena. The arena must outlive any use of - * the extreg. */ -upb_extreg *upb_extreg_new(upb_arena *arena); +/* Creates a upb_ExtensionRegistry in the given arena. The arena must outlive + * any use of the extreg. */ +upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #endif /* UPB_MSG_INT_H_ */ @@ -693,27 +676,53 @@ extern "C" { enum { /* If set, strings will alias the input buffer instead of copying into the * arena. */ - UPB_DECODE_ALIAS = 1, + kUpb_DecodeOption_AliasString = 1, + + /* If set, the parse will return failure if any message is missing any + * required fields when the message data ends. The parse will still continue, + * and the failure will only be reported at the end. + * + * IMPORTANT CAVEATS: + * + * 1. This can throw a false positive failure if an incomplete message is seen + * on the wire but is later completed when the sub-message occurs again. + * For this reason, a second pass is required to verify a failure, to be + * truly robust. + * + * 2. This can return a false success if you are decoding into a message that + * already has some sub-message fields present. If the sub-message does + * not occur in the binary payload, we will never visit it and discover the + * incomplete sub-message. For this reason, this check is only useful for + * implemting ParseFromString() semantics. For MergeFromString(), a + * post-parse validation step will always be necessary. */ + kUpb_DecodeOption_CheckRequired = 2, }; #define UPB_DECODE_MAXDEPTH(depth) ((depth) << 16) -bool _upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, const upb_extreg *extreg, int options, - upb_arena *arena); - -UPB_INLINE -bool upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena) { - return _upb_decode(buf, size, msg, l, NULL, 0, arena); -} +typedef enum { + kUpb_DecodeStatus_Ok = 0, + kUpb_DecodeStatus_Malformed = 1, // Wire format was corrupt + kUpb_DecodeStatus_OutOfMemory = 2, // Arena alloc failed + kUpb_DecodeStatus_BadUtf8 = 3, // String field had bad UTF-8 + kUpb_DecodeStatus_MaxDepthExceeded = 4, // Exceeded UPB_DECODE_MAXDEPTH + + // kUpb_DecodeOption_CheckRequired failed (see above), but the parse otherwise + // succeeded. + kUpb_DecodeStatus_MissingRequired = 5, +} upb_DecodeStatus; + +upb_DecodeStatus upb_Decode(const char* buf, size_t size, upb_Message* msg, + const upb_MiniTable* l, + const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_DECODE_H_ */ +#endif /* UPB_DECODE_H_ */ /** upb/decode_internal.h ************************************************************/ /* @@ -726,8 +735,10 @@ bool upb_decode(const char *buf, size_t size, upb_msg *msg, #include +#include "third_party/utf8_range/utf8_range.h" -/** upb/msg_internal.h ************************************************************//* +/** upb/msg_internal.h ************************************************************/ +/* ** Our memory representation for parsing tables and messages themselves. ** Functions in this file are used by generated code and possibly reflection. ** @@ -769,10 +780,15 @@ bool upb_decode(const char *buf, size_t size, upb_msg *msg, #include +// Must be last. + #ifdef __cplusplus extern "C" { #endif +uint64_t Wyhash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[]); +extern const uint64_t kWyhashSalt[5]; /* upb_value ******************************************************************/ @@ -782,11 +798,9 @@ typedef struct { /* 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_arena *a); +char* upb_strdup2(const char* s, size_t len, upb_Arena* a); -UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) { - v->val = val; -} +UPB_INLINE void _upb_value_setval(upb_value* v, uint64_t val) { v->val = val; } /* For each value ctype, define the following set of functions: * @@ -796,36 +810,35 @@ UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) { * * // 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; \ +#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) +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) #undef FUNCS -UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) { +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) { +UPB_INLINE void upb_value_setdouble(upb_value* val, double cval) { memcpy(&val->val, &cval, sizeof(cval)); } @@ -843,7 +856,6 @@ UPB_INLINE upb_value upb_value_double(double cval) { #undef SET_TYPE - /* upb_tabkey *****************************************************************/ /* Either: @@ -855,14 +867,14 @@ UPB_INLINE upb_value upb_value_double(double cval) { * initializing a non-first union member. */ typedef uintptr_t upb_tabkey; -UPB_INLINE char *upb_tabstr(upb_tabkey key, uint32_t *len) { +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_INLINE upb_strview upb_tabstrview(upb_tabkey key) { - upb_strview ret; +UPB_INLINE upb_StringView upb_tabstrview(upb_tabkey key) { + upb_StringView ret; uint32_t len; ret.data = upb_tabstr(key, &len); ret.size = len; @@ -875,14 +887,11 @@ typedef struct upb_tabval { uint64_t val; } upb_tabval; -#define UPB_TABVALUE_EMPTY_INIT {-1} +#define UPB_TABVALUE_EMPTY_INIT \ + { -1 } /* upb_table ******************************************************************/ -uint64_t Wyhash(const void *data, size_t len, uint64_t seed, - const uint64_t salt[]); -extern const uint64_t kWyhashSalt[5]; - typedef struct _upb_tabent { upb_tabkey key; upb_tabval val; @@ -891,15 +900,15 @@ typedef struct _upb_tabent { * 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; + 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. */ - upb_tabent *entries; + 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. */ + upb_tabent* entries; } upb_table; typedef struct { @@ -907,13 +916,13 @@ typedef struct { } 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_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; -UPB_INLINE size_t upb_table_size(const upb_table *t) { +UPB_INLINE size_t upb_table_size(const upb_table* t) { if (t->size_lg2 == 0) return 0; else @@ -921,22 +930,20 @@ UPB_INLINE size_t upb_table_size(const upb_table *t) { } /* Internal-only functions, in .h file only out of necessity. */ -UPB_INLINE bool upb_tabent_isempty(const upb_tabent *e) { - return e->key == 0; -} +UPB_INLINE bool upb_tabent_isempty(const upb_tabent* e) { return e->key == 0; } /* Initialize and uninitialize a table, respectively. If memory allocation * failed, false is returned that the table is uninitialized. */ -bool upb_inttable_init(upb_inttable *table, upb_arena *a); -bool upb_strtable_init(upb_strtable *table, size_t expected_size, upb_arena *a); +bool upb_inttable_init(upb_inttable* table, upb_Arena* a); +bool upb_strtable_init(upb_strtable* table, size_t expected_size, upb_Arena* a); /* 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) { +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_strtable_clear(upb_strtable *t); +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 @@ -945,45 +952,84 @@ void upb_strtable_clear(upb_strtable *t); * * If a table resize was required but memory allocation failed, false is * returned and the table is unchanged. */ -bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, - upb_arena *a); -bool upb_strtable_insert(upb_strtable *t, const char *key, size_t len, - upb_value val, upb_arena *a); +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a); +bool upb_strtable_insert(upb_strtable* t, const char* key, size_t len, + upb_value val, upb_Arena* a); /* 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); +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) { +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_remove(upb_strtable *t, const char *key, size_t len, - upb_value *val); +bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val); +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val); + +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); +bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val); /* 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_compact(upb_inttable *t, upb_arena *a); +void upb_inttable_compact(upb_inttable* t, upb_Arena* a); /* Exposed for testing only. */ -bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a); +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a); /* Iterators ******************************************************************/ -/* Iterators for int and string tables. We are subject to some kind of unusual +/* Iteration over inttable. + * + * intptr_t iter = UPB_INTTABLE_BEGIN; + * uintptr_t key; + * upb_value val; + * while (upb_inttable_next2(t, &key, &val, &iter)) { + * // ... + * } + */ + +#define UPB_INTTABLE_BEGIN -1 + +bool upb_inttable_next2(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter); +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter); + +/* Iteration over strtable. + * + * intptr_t iter = UPB_INTTABLE_BEGIN; + * upb_StringView key; + * upb_value val; + * while (upb_strtable_next2(t, &key, &val, &iter)) { + * // ... + * } + */ + +#define UPB_STRTABLE_BEGIN -1 + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter); +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter); + +/* DEPRECATED iterators, slated for removal. + * + * Iterators for int and string tables. We are subject to some kind of unusual * design constraints: * * For high-level languages: @@ -1004,7 +1050,6 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a); * guaranteed not to crash and to return real table elements (except when done() * is true). */ - /* upb_strtable_iter **********************************************************/ /* upb_strtable_iter i; @@ -1017,19 +1062,18 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a); */ typedef struct { - const upb_strtable *t; + 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); - +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_StringView 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 **********************************************************/ @@ -1043,31 +1087,30 @@ bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, */ typedef struct { - const upb_inttable *t; + 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) { +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); - +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" */ +} /* extern "C" */ #endif -#endif /* UPB_TABLE_H_ */ +#endif /* UPB_TABLE_H_ */ /* Must be last. */ @@ -1075,110 +1118,196 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, extern "C" { #endif -/** upb_msglayout *************************************************************/ +/** upb_MiniTable *************************************************************/ -/* upb_msglayout represents the memory layout of a given upb_msgdef. The +/* upb_MiniTable represents the memory layout of a given upb_MessageDef. 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. */ + int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index + uint16_t submsg_index; // undefined if descriptortype != MESSAGE/GROUP/ENUM uint8_t descriptortype; - int8_t mode; /* upb_fieldmode, with flags from upb_labelflags */ -} upb_msglayout_field; + uint8_t mode; /* upb_FieldMode | upb_LabelFlags | + (upb_FieldRep << upb_FieldRep_Shift) */ +} upb_MiniTable_Field; typedef enum { - _UPB_MODE_MAP = 0, - _UPB_MODE_ARRAY = 1, - _UPB_MODE_SCALAR = 2, -} upb_fieldmode; + kUpb_FieldMode_Map = 0, + kUpb_FieldMode_Array = 1, + kUpb_FieldMode_Scalar = 2, + + kUpb_FieldMode_Mask = 3, /* Mask to isolate the mode from upb_FieldRep. */ +} upb_FieldMode; /* Extra flags on the mode field. */ -enum upb_labelflags { - _UPB_MODE_IS_PACKED = 4, +enum upb_LabelFlags { + upb_LabelFlags_IsPacked = 4, + upb_LabelFlags_IsExtension = 8, +}; + +/* Representation in the message. Derivable from descriptortype and mode, but + * fast access helps the serializer. */ +enum upb_FieldRep { + upb_FieldRep_1Byte = 0, + upb_FieldRep_4Byte = 1, + upb_FieldRep_8Byte = 2, + upb_FieldRep_StringView = 3, + +#if UINTPTR_MAX == 0xffffffff + upb_FieldRep_Pointer = upb_FieldRep_4Byte, +#else + upb_FieldRep_Pointer = upb_FieldRep_8Byte, +#endif + + upb_FieldRep_Shift = + 6, /* Bit offset of the rep in upb_MiniTable_Field.mode */ }; -UPB_INLINE upb_fieldmode _upb_getmode(const upb_msglayout_field *field) { - return (upb_fieldmode)(field->mode & 3); +UPB_INLINE upb_FieldMode upb_FieldMode_Get(const upb_MiniTable_Field* field) { + return (upb_FieldMode)(field->mode & 3); } -UPB_INLINE bool _upb_repeated_or_map(const upb_msglayout_field *field) { - /* This works because upb_fieldmode has no value 3. */ - return !(field->mode & _UPB_MODE_SCALAR); +UPB_INLINE bool upb_IsRepeatedOrMap(const upb_MiniTable_Field* field) { + /* This works because upb_FieldMode has no value 3. */ + return !(field->mode & kUpb_FieldMode_Scalar); } -UPB_INLINE bool _upb_issubmsg(const upb_msglayout_field *field) { - return field->descriptortype == UPB_DTYPE_MESSAGE || - field->descriptortype == UPB_DTYPE_GROUP; +UPB_INLINE bool upb_IsSubMessage(const upb_MiniTable_Field* field) { + return field->descriptortype == kUpb_FieldType_Message || + field->descriptortype == kUpb_FieldType_Group; } -struct upb_decstate; -struct upb_msglayout; +struct upb_Decoder; +struct upb_MiniTable; -typedef const char *_upb_field_parser(struct upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, - uint64_t hasbits, uint64_t data); +typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); typedef struct { uint64_t field_data; - _upb_field_parser *field_parser; -} _upb_fasttable_entry; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef struct { + const int32_t* values; // List of values <0 or >63 + uint64_t mask; // Bits are set for acceptable value 0 <= x < 64 + int value_count; +} upb_MiniTable_Enum; + +UPB_INLINE bool upb_MiniTable_Enum_CheckValue(const upb_MiniTable_Enum* e, + int32_t val) { + uint32_t uval = (uint32_t)val; + if (uval < 64) return e->mask & (1 << uval); + // OPT: binary search long lists? + int n = e->value_count; + for (int i = 0; i < n; i++) { + if (e->values[i] == val) return true; + } + return false; +} + +typedef union { + const struct upb_MiniTable* submsg; + const upb_MiniTable_Enum* subenum; +} upb_MiniTable_Sub; -struct upb_msglayout { - const struct upb_msglayout *const* submsgs; - const upb_msglayout_field *fields; +typedef enum { + upb_ExtMode_NonExtendable = 0, // Non-extendable message. + upb_ExtMode_Extendable = 1, // Normal extendable message. + upb_ExtMode_IsMessageSet = 2, // MessageSet message. + upb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) +} upb_ExtMode; + +/* MessageSet wire format is: + * message MessageSet { + * repeated group Item = 1 { + * required int32 type_id = 2; + * required string message = 3; + * } + * } + */ +typedef enum { + _UPB_MSGSET_ITEM = 1, + _UPB_MSGSET_TYPEID = 2, + _UPB_MSGSET_MESSAGE = 3, +} upb_msgext_fieldnum; + +struct upb_MiniTable { + const upb_MiniTable_Sub* subs; + const upb_MiniTable_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; + uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 uint8_t dense_below; uint8_t table_mask; - /* To constant-initialize the tables of variable length, we need a flexible - * array member, and we need to compile in C99 mode. */ - _upb_fasttable_entry fasttable[]; + uint8_t required_count; // Required fields have the lowest hasbits. + /* To statically initialize the tables of variable length, we need a flexible + * array member, and we need to compile in gnu99 mode (constant initialization + * of flexible array members is a GNU extension, not in C99 unfortunately. */ + _upb_FastTable_Entry fasttable[]; }; typedef struct { - upb_msglayout_field field; - const upb_msglayout *extendee; - const upb_msglayout *submsg; /* NULL for non-submessage fields. */ -} upb_msglayout_ext; + upb_MiniTable_Field field; + const upb_MiniTable* extendee; + upb_MiniTable_Sub sub; /* NULL unless submessage or proto2 enum */ +} upb_MiniTable_Extension; + +typedef struct { + const upb_MiniTable** msgs; + const upb_MiniTable_Enum** enums; + const upb_MiniTable_Extension** exts; + int msg_count; + int enum_count; + int ext_count; +} upb_MiniTable_File; + +// Computes a bitmask in which the |l->required_count| lowest bits are set, +// except that we skip the lowest bit (because upb never uses hasbit 0). +// +// Sample output: +// requiredmask(1) => 0b10 (0x2) +// requiredmask(5) => 0b111110 (0x3e) +UPB_INLINE uint64_t upb_MiniTable_requiredmask(const upb_MiniTable* l) { + int n = l->required_count; + assert(0 < n && n <= 63); + return ((1ULL << n) - 1) << 1; +} -/** upb_extreg ****************************************************************/ +/** upb_ExtensionRegistry + * ****************************************************************/ /* Adds the given extension info for message type |l| and field number |num| * into the registry. Returns false if this message type and field number were * already in the map, or if memory allocation fails. */ -bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count); +bool _upb_extreg_add(upb_ExtensionRegistry* r, + const upb_MiniTable_Extension** e, size_t count); /* Looks up the extension (if any) defined for message type |l| and field * number |num|. If an extension was found, copies the field info into |*ext| * and returns true. Otherwise returns false. */ -const upb_msglayout_field *_upb_extreg_get(const upb_extreg *r, - const upb_msglayout *l, - uint32_t num); +const upb_MiniTable_Extension* _upb_extreg_get(const upb_ExtensionRegistry* r, + const upb_MiniTable* l, + uint32_t num); -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ -/* Internal members of a upb_msg that track unknown fields and/or extensions. - * 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. */ +/* Internal members of a upb_Message that track unknown fields and/or + * extensions. We can change this without breaking binary compatibility. We put + * these before the user's data. The user's upb_Message* points after the + * upb_Message_Internal. */ typedef struct { /* Total size of this structure, including the data that follows. - * Must be aligned to 8, which is alignof(upb_msg_ext) */ + * Must be aligned to 8, which is alignof(upb_Message_Extension) */ uint32_t size; /* Offsets relative to the beginning of this structure. @@ -1188,160 +1317,176 @@ typedef struct { * When the two meet, we're out of data and have to realloc. * * If we imagine that the final member of this struct is: - * char data[size - overhead]; // overhead = sizeof(upb_msg_internaldata) - * + * char data[size - overhead]; // overhead = + * sizeof(upb_Message_InternalData) + * * Then we have: * unknown data: data[0 .. (unknown_end - overhead)] * extensions data: data[(ext_begin - overhead) .. (size - overhead)] */ uint32_t unknown_end; uint32_t ext_begin; /* Data follows, as if there were an array: - * char data[size - sizeof(upb_msg_internaldata)]; */ -} upb_msg_internaldata; + * char data[size - sizeof(upb_Message_InternalData)]; */ +} upb_Message_InternalData; typedef struct { - upb_msg_internaldata *internal; -} upb_msg_internal; + upb_Message_InternalData* internal; + /* Message data follows. */ +} upb_Message_Internal; -/* Maps upb_fieldtype_t -> memory size. */ -extern char _upb_fieldtype_to_size[12]; +/* Maps upb_CType -> memory size. */ +extern char _upb_CTypeo_size[12]; -UPB_INLINE size_t upb_msg_sizeof(const upb_msglayout *l) { - return l->size + sizeof(upb_msg_internal); +UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* l) { + return l->size + sizeof(upb_Message_Internal); } -UPB_INLINE upb_msg *_upb_msg_new_inl(const upb_msglayout *l, upb_arena *a) { +UPB_INLINE upb_Message* _upb_Message_New_inl(const upb_MiniTable* l, + upb_Arena* a) { size_t size = upb_msg_sizeof(l); - void *mem = upb_arena_malloc(a, size); - upb_msg *msg; + void* mem = upb_Arena_Malloc(a, size); + upb_Message* msg; if (UPB_UNLIKELY(!mem)) return NULL; - msg = UPB_PTR_AT(mem, sizeof(upb_msg_internal), upb_msg); + msg = UPB_PTR_AT(mem, sizeof(upb_Message_Internal), upb_Message); 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_Message* _upb_Message_New(const upb_MiniTable* 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); +UPB_INLINE upb_Message_Internal* upb_Message_Getinternal(upb_Message* msg) { + ptrdiff_t size = sizeof(upb_Message_Internal); + return (upb_Message_Internal*)((char*)msg - size); } /* Clears the given message. */ -void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l); +void _upb_Message_Clear(upb_Message* msg, const upb_MiniTable* l); /* Discards the unknown fields for this message only. */ -void _upb_msg_discardunknown_shallow(upb_msg *msg); +void _upb_Message_DiscardUnknown_shallow(upb_Message* 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); +bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, + upb_Arena* arena); -/** upb_msg_ext ***************************************************************/ +/** upb_Message_Extension + * ***************************************************************/ /* The internal representation of an extension is self-describing: it contains * enough information that we can serialize it to binary format without needing - * to look it up in a registry. */ + * to look it up in a upb_ExtensionRegistry. + * + * This representation allocates 16 bytes to data on 64-bit platforms. This is + * rather wasteful for scalars (in the extreme case of bool, it wastes 15 + * bytes). We accept this because we expect messages to be the most common + * extension type. */ typedef struct { - const upb_msglayout_ext *ext; + const upb_MiniTable_Extension* ext; union { - upb_strview str; - void *ptr; - double dbl; + upb_StringView str; + void* ptr; char scalar_data[8]; } data; -} upb_msg_ext; +} upb_Message_Extension; -/* Adds the given extension data to the given message. The returned extension will - * have its "ext" member initialized according to |ext|. */ -upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *ext, - upb_arena *arena); +/* Adds the given extension data to the given message. |ext| is copied into the + * message instance. This logically replaces any previously-added extension with + * this number */ +upb_Message_Extension* _upb_Message_Getorcreateext( + upb_Message* msg, const upb_MiniTable_Extension* ext, upb_Arena* arena); /* Returns an array of extensions for this message. Note: the array is * ordered in reverse relative to the order of creation. */ -const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count); +const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, + size_t* count); /* Returns an extension for the given field number, or NULL if no extension * exists for this field number. */ -const upb_msg_ext *_upb_msg_getext(const upb_msg *msg, - const upb_msglayout_ext *ext); +const upb_Message_Extension* _upb_Message_Getext( + const upb_Message* msg, const upb_MiniTable_Extension* ext); + +void _upb_Message_Clearext(upb_Message* msg, + const upb_MiniTable_Extension* ext); + +void _upb_Message_Clearext(upb_Message* msg, + const upb_MiniTable_Extension* ext); /** Hasbit access *************************************************************/ -UPB_INLINE bool _upb_hasbit(const upb_msg *msg, size_t idx) { +UPB_INLINE bool _upb_hasbit(const upb_Message* msg, size_t idx) { return (*UPB_PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; } -UPB_INLINE void _upb_sethas(const upb_msg *msg, size_t idx) { +UPB_INLINE void _upb_sethas(const upb_Message* msg, size_t idx) { (*UPB_PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); } -UPB_INLINE void _upb_clearhas(const upb_msg *msg, size_t idx) { +UPB_INLINE void _upb_clearhas(const upb_Message* msg, size_t idx) { (*UPB_PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); } -UPB_INLINE size_t _upb_msg_hasidx(const upb_msglayout_field *f) { +UPB_INLINE size_t _upb_Message_Hasidx(const upb_MiniTable_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 bool _upb_hasbit_field(const upb_Message* msg, + const upb_MiniTable_Field* f) { + return _upb_hasbit(msg, _upb_Message_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_sethas_field(const upb_Message* msg, + const upb_MiniTable_Field* f) { + _upb_sethas(msg, _upb_Message_Hasidx(f)); } -UPB_INLINE void _upb_clearhas_field(const upb_msg *msg, - const upb_msglayout_field *f) { - _upb_clearhas(msg, _upb_msg_hasidx(f)); +UPB_INLINE void _upb_clearhas_field(const upb_Message* msg, + const upb_MiniTable_Field* f) { + _upb_clearhas(msg, _upb_Message_Hasidx(f)); } /** Oneof case access *********************************************************/ -UPB_INLINE uint32_t *_upb_oneofcase(upb_msg *msg, size_t case_ofs) { +UPB_INLINE uint32_t* _upb_oneofcase(upb_Message* msg, size_t case_ofs) { return UPB_PTR_AT(msg, case_ofs, uint32_t); } -UPB_INLINE uint32_t _upb_getoneofcase(const void *msg, size_t case_ofs) { +UPB_INLINE uint32_t _upb_getoneofcase(const void* msg, size_t case_ofs) { return *UPB_PTR_AT(msg, case_ofs, uint32_t); } -UPB_INLINE size_t _upb_oneofcase_ofs(const upb_msglayout_field *f) { +UPB_INLINE size_t _upb_oneofcase_ofs(const upb_MiniTable_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) { +UPB_INLINE uint32_t* _upb_oneofcase_field(upb_Message* msg, + const upb_MiniTable_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) { +UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_Message* msg, + const upb_MiniTable_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 *UPB_PTR_AT(msg, ofs, const upb_msg*) != NULL; +UPB_INLINE bool _upb_has_submsg_nohasbit(const upb_Message* msg, size_t ofs) { + return *UPB_PTR_AT(msg, ofs, const upb_Message*) != NULL; } -/** upb_array *****************************************************************/ +/** 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. */ + 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_Array; -UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) { +UPB_INLINE const void* _upb_array_constptr(const upb_Array* arr) { UPB_ASSERT((arr->data & 7) <= 4); return (void*)(arr->data & ~(uintptr_t)7); } @@ -1351,7 +1496,7 @@ UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) { return (uintptr_t)ptr | elem_size_lg2; } -UPB_INLINE void *_upb_array_ptr(upb_array *arr) { +UPB_INLINE void* _upb_array_ptr(upb_Array* arr) { return (void*)_upb_array_constptr(arr); } @@ -1361,11 +1506,11 @@ UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) { return (uintptr_t)ptr | (unsigned)elem_size_lg2; } -UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size, +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); + 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; @@ -1374,30 +1519,30 @@ UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size, } /* 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); +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); +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) { +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) { +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 = *UPB_PTR_AT(msg, ofs, const upb_array*); +UPB_INLINE const void* _upb_array_accessor(const void* msg, size_t ofs, + size_t* size) { + const upb_Array* arr = *UPB_PTR_AT(msg, ofs, const upb_Array*); if (arr) { if (size) *size = arr->len; return _upb_array_constptr(arr); @@ -1407,9 +1552,9 @@ UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, } } -UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, - size_t *size) { - upb_array *arr = *UPB_PTR_AT(msg, ofs, upb_array*); +UPB_INLINE void* _upb_array_mutable_accessor(void* msg, size_t ofs, + size_t* size) { + upb_Array* arr = *UPB_PTR_AT(msg, ofs, upb_Array*); if (arr) { if (size) *size = arr->len; return _upb_array_ptr(arr); @@ -1419,28 +1564,28 @@ UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, } } -UPB_INLINE void *_upb_array_resize_accessor2(void *msg, size_t ofs, size_t size, +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 = UPB_PTR_AT(msg, ofs, upb_array *); - upb_array *arr = *arr_ptr; + upb_Arena* arena) { + upb_Array** arr_ptr = UPB_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); + 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, +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 = UPB_PTR_AT(msg, ofs, upb_array *); + const void* value, + upb_Arena* arena) { + upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*); size_t elem_size = 1 << elem_size_lg2; - upb_array *arr = *arr_ptr; - void *ptr; + 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); + return _upb_Array_Append_fallback(arr_ptr, value, elem_size_lg2, arena); } ptr = _upb_array_ptr(arr); memcpy(UPB_PTR_AT(ptr, arr->len * elem_size, char), value, elem_size); @@ -1449,42 +1594,41 @@ UPB_INLINE bool _upb_array_append_accessor2(void *msg, size_t ofs, } /* Used by old generated code, remove once all code has been regenerated. */ -UPB_INLINE int _upb_sizelg2(upb_fieldtype_t type) { +UPB_INLINE int _upb_sizelg2(upb_CType type) { switch (type) { - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return 0; - case UPB_TYPE_FLOAT: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_ENUM: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: return 2; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: return UPB_SIZE(2, 3); - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: return 3; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_String: + case kUpb_CType_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 void* _upb_Array_Resize_accessor(void* msg, size_t ofs, size_t size, + upb_CType 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) { +UPB_INLINE bool _upb_Array_Append_accessor(void* msg, size_t ofs, + size_t elem_size, upb_CType type, + const void* value, + upb_Arena* arena) { (void)elem_size; - return _upb_array_append_accessor2(msg, ofs, _upb_sizelg2(type), value, + return _upb_Array_Append_accessor2(msg, ofs, _upb_sizelg2(type), value, arena); } -/** upb_map *******************************************************************/ +/** upb_Map *******************************************************************/ /* Right now we use strmaps for everything. We'll likely want to use * integer-specific maps for integer-keyed maps.*/ @@ -1495,25 +1639,25 @@ typedef struct { char val_size; upb_strtable table; -} upb_map; +} 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; + upb_Message_Internal internal; union { - upb_strview str; /* For str/bytes. */ - upb_value val; /* For all other types. */ + upb_StringView 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. */ + upb_StringView str; /* For str/bytes. */ + upb_value val; /* For all other types. */ } v; -} upb_map_entry; +} upb_MapEntry; /* 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); +upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size); /* Converting between internal table representation and user values. * @@ -1524,15 +1668,15 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size); * from other types when stored in a map. */ -UPB_INLINE upb_strview _upb_map_tokey(const void *key, size_t size) { +UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) { if (size == UPB_MAPTYPE_STRING) { - return *(upb_strview*)key; + return *(upb_StringView*)key; } else { - return upb_strview_make((const char*)key, size); + return upb_StringView_FromDataAndSize((const char*)key, size); } } -UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { +UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) { if (size == UPB_MAPTYPE_STRING) { memcpy(out, &key, sizeof(key)); } else { @@ -1540,12 +1684,12 @@ UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { } } -UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval, - upb_arena *a) { +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)); + upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp)); if (!strp) return false; - *strp = *(upb_strview*)val; + *strp = *(upb_StringView*)val; *msgval = upb_value_ptr(strp); } else { memcpy(msgval, val, size); @@ -1555,8 +1699,8 @@ UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval 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)); + const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_StringView)); } else { memcpy(out, &val, size); } @@ -1564,14 +1708,14 @@ UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { /* Map operations, shared by reflection and generated code. */ -UPB_INLINE size_t _upb_map_size(const upb_map *map) { +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_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); + upb_StringView 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); @@ -1579,7 +1723,7 @@ UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key, return ret; } -UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { +UPB_INLINE void* _upb_map_next(const upb_Map* map, size_t* iter) { upb_strtable_iter it; it.t = &map->table; it.index = *iter; @@ -1589,108 +1733,111 @@ UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { 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 *a) { - upb_strview strkey = _upb_map_tokey(key, key_size); +UPB_INLINE bool _upb_Map_Set(upb_Map* map, const void* key, size_t key_size, + void* val, size_t val_size, upb_Arena* a) { + upb_StringView strkey = _upb_map_tokey(key, key_size); upb_value tabval = {0}; if (!_upb_map_tovalue(val, val_size, &tabval, a)) return false; /* TODO(haberman): add overwrite operation to minimize number of lookups. */ - upb_strtable_remove(&map->table, strkey.data, strkey.size, NULL); + upb_strtable_remove2(&map->table, strkey.data, strkey.size, NULL); return upb_strtable_insert(&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_remove(&map->table, k.data, k.size, NULL); +UPB_INLINE bool _upb_Map_Delete(upb_Map* map, const void* key, + size_t key_size) { + upb_StringView k = _upb_map_tokey(key, key_size); + return upb_strtable_remove2(&map->table, k.data, k.size, NULL); } -UPB_INLINE void _upb_map_clear(upb_map *map) { +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 size_t _upb_msg_map_size(const upb_Message* 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, +UPB_INLINE bool _upb_msg_map_get(const upb_Message* 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 *); + 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); + 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 *); +UPB_INLINE void* _upb_msg_map_next(const upb_Message* 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 = UPB_PTR_AT(msg, ofs, upb_map *); +UPB_INLINE bool _upb_msg_map_set(upb_Message* msg, size_t ofs, const void* key, + size_t key_size, void* val, size_t val_size, + upb_Arena* arena) { + upb_Map** map = UPB_PTR_AT(msg, ofs, upb_Map*); if (!*map) { - *map = _upb_map_new(arena, key_size, val_size); + *map = _upb_Map_New(arena, key_size, val_size); } - return _upb_map_set(*map, key, key_size, val, val_size, arena); + 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 *); +UPB_INLINE bool _upb_msg_map_delete(upb_Message* 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); + 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 *); +UPB_INLINE void _upb_msg_map_clear(upb_Message* msg, size_t ofs) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); if (!map) return; - _upb_map_clear(map); + _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; + const upb_tabent* ent = (const upb_tabent*)msg; uint32_t u32len; - upb_strview k; + upb_StringView 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; + const upb_tabent* ent = (const upb_tabent*)msg; upb_value 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; +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. */ + * reuse the allocated upb_StringView for string fields. */ if (size == UPB_MAPTYPE_STRING) { - upb_strview *strp = (upb_strview*)(uintptr_t)ent->val.val; + upb_StringView* strp = (upb_StringView*)(uintptr_t)ent->val.val; memcpy(strp, val, sizeof(*strp)); } else { memcpy(&ent->val.val, val, size); } } -/** _upb_mapsorter *************************************************************/ +/** _upb_mapsorter + * *************************************************************/ /* _upb_mapsorter sorts maps and provides ordered iteration over the entries. - * Since maps can be recursive (map values can be messages which contain other maps). - * _upb_mapsorter can contain a stack of maps. */ + * Since maps can be recursive (map values can be messages which contain other + * maps). _upb_mapsorter can contain a stack of maps. */ typedef struct { - upb_tabent const**entries; + upb_tabent const** entries; int size; int cap; } _upb_mapsorter; @@ -1701,29 +1848,29 @@ typedef struct { int end; } _upb_sortedmap; -UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter *s) { +UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter* s) { s->entries = NULL; s->size = 0; s->cap = 0; } -UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter *s) { +UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter* s) { if (s->entries) free(s->entries); } -bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, - const upb_map *map, _upb_sortedmap *sorted); +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const upb_Map* map, _upb_sortedmap* sorted); -UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter *s, _upb_sortedmap *sorted) { +UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter* s, + _upb_sortedmap* sorted) { s->size = sorted->start; } -UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, - _upb_sortedmap *sorted, - upb_map_entry *ent) { +UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter* s, const upb_Map* map, + _upb_sortedmap* sorted, upb_MapEntry* ent) { if (sorted->pos == sorted->end) return false; - const upb_tabent *tabent = s->entries[sorted->pos++]; - upb_strview key = upb_tabstrview(tabent->key); + const upb_tabent* tabent = s->entries[sorted->pos++]; + upb_StringView key = upb_tabstrview(tabent->key); _upb_map_fromkey(key, &ent->k, map->key_size); upb_value val = {tabent->val.val}; _upb_map_fromvalue(val, &ent->v, map->val_size); @@ -1731,7 +1878,7 @@ UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, } #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif @@ -1745,8 +1892,8 @@ UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, struct mem_block; typedef struct mem_block mem_block; -struct upb_arena { - _upb_arena_head head; +struct upb_Arena { + _upb_ArenaHead head; /* Stores cleanup metadata for this arena. * - a pointer to the current cleanup counter. * - a boolean indicating if there is an unowned initial block. */ @@ -1754,38 +1901,58 @@ struct upb_arena { /* Allocator to allocate arena blocks. We are responsible for freeing these * when we are destroyed. */ - upb_alloc *block_alloc; + 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; + 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_ */ +// Encodes a float or double that is round-trippable, but as short as possible. +// These routines are not fully optimal (not guaranteed to be shortest), but are +// short-ish and match the implementation that has been used in protobuf since +// the beginning. +// +// The given buffer size must be at least kUpb_RoundTripBufferSize. +enum { + kUpb_RoundTripBufferSize = 32 +}; +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size); +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size); + +#endif /* UPB_INT_H_ */ /* Must be last. */ -#define DECODE_NOGROUP (uint32_t)-1 - -typedef struct upb_decstate { - const char *end; /* Can read up to 16 bytes slop beyond this. */ - const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */ - upb_msg *unknown_msg; /* If non-NULL, add unknown data at buffer flip. */ - const char *unknown; /* Start of unknown data. */ - int limit; /* Submessage limit relative to end. */ - int depth; - uint32_t end_group; /* field number of END_GROUP tag, else DECODE_NOGROUP */ - bool alias; +#define DECODE_NOGROUP (uint32_t) - 1 + +typedef struct upb_Decoder { + const char* end; /* Can read up to 16 bytes slop beyond this. */ + const char* limit_ptr; /* = end + UPB_MIN(limit, 0) */ + upb_Message* unknown_msg; /* If non-NULL, add unknown data at buffer flip. */ + const char* unknown; /* Start of unknown data. */ + const upb_ExtensionRegistry* + extreg; /* For looking up extensions during the parse. */ + int limit; /* Submessage limit relative to end. */ + int depth; /* Tracks recursion depth to bound stack usage. */ + uint32_t end_group; /* field number of END_GROUP tag, else DECODE_NOGROUP */ + uint16_t options; + bool missing_required; char patch[32]; - upb_arena arena; + upb_Arena arena; jmp_buf err; -} upb_decstate; + +#ifndef NDEBUG + const char* debug_tagstart; + const char* debug_valstart; +#endif +} upb_Decoder; /* Error function that will abort decoding with longjmp(). We can't declare this * UPB_NORETURN, even though it is appropriate, because if we do then compilers @@ -1794,50 +1961,58 @@ typedef struct upb_decstate { * of our optimizations. That is also why we must declare it in a separate file, * otherwise the compiler will see that it calls longjmp() and deduce that it is * noreturn. */ -const char *fastdecode_err(upb_decstate *d); +const char* fastdecode_err(upb_Decoder* d, int status); extern const uint8_t upb_utf8_offsets[]; UPB_INLINE -bool decode_verifyutf8_inl(const char *buf, int len) { - int i, j; - uint8_t offset; - - i = 0; - while (i < len) { - offset = upb_utf8_offsets[(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; +bool decode_verifyutf8_inl(const char* ptr, int len) { + const char* end = ptr + len; + + // Check 8 bytes at a time for any non-ASCII char. + while (end - ptr >= 8) { + uint64_t data; + memcpy(&data, ptr, 8); + if (data & 0x8080808080808080) goto non_ascii; + ptr += 8; + } + + // Check one byte at a time for non-ASCII. + while (ptr < end) { + if (*ptr & 0x80) goto non_ascii; + ptr++; } - return i == len; + + return true; + +non_ascii: + return utf8_range2((const unsigned char*)ptr, end - ptr) == 0; } +const char* decode_checkrequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* l); + /* x86-64 pointers always have the high 16 bits matching. So we can shift * left 8 and right 8 without loss of information. */ -UPB_INLINE intptr_t decode_totable(const upb_msglayout *tablep) { +UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { return ((intptr_t)tablep << 8) | tablep->table_mask; } -UPB_INLINE const upb_msglayout *decode_totablep(intptr_t table) { - return (const upb_msglayout*)(table >> 8); +UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { + return (const upb_MiniTable*)(table >> 8); } UPB_INLINE -const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr, - int overrun) { +const char* decode_isdonefallback_inl(upb_Decoder* d, const char* ptr, + int overrun, int* status) { if (overrun < d->limit) { /* Need to copy remaining data into patch buffer. */ UPB_ASSERT(overrun < 16); if (d->unknown_msg) { - if (!_upb_msg_addunknown(d->unknown_msg, d->unknown, ptr - d->unknown, - &d->arena)) { + if (!_upb_Message_AddUnknown(d->unknown_msg, d->unknown, ptr - d->unknown, + &d->arena)) { + *status = kUpb_DecodeStatus_OutOfMemory; return NULL; } d->unknown = &d->patch[0] + overrun; @@ -1848,19 +2023,19 @@ const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr, d->end = &d->patch[16]; d->limit -= 16; d->limit_ptr = d->end + d->limit; - d->alias = false; + d->options &= ~kUpb_DecodeOption_AliasString; UPB_ASSERT(ptr < d->limit_ptr); return ptr; } else { + *status = kUpb_DecodeStatus_Malformed; return NULL; } } -const char *decode_isdonefallback(upb_decstate *d, const char *ptr, - int overrun); +const char* decode_isdonefallback(upb_Decoder* d, const char* ptr, int overrun); UPB_INLINE -bool decode_isdone(upb_decstate *d, const char **ptr) { +bool decode_isdone(upb_Decoder* d, const char** ptr) { int overrun = *ptr - d->end; if (UPB_LIKELY(*ptr < d->limit_ptr)) { return false; @@ -1874,10 +2049,10 @@ bool decode_isdone(upb_decstate *d, const char **ptr) { #if UPB_FASTTABLE UPB_INLINE -const char *fastdecode_tagdispatch(upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, - uint64_t hasbits, uint64_t tag) { - const upb_msglayout *table_p = decode_totablep(table); +const char* fastdecode_tagdispatch(upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t tag) { + const upb_MiniTable* table_p = decode_totablep(table); uint8_t mask = table; uint64_t data; size_t idx = tag & mask; @@ -1895,11 +2070,11 @@ UPB_INLINE uint32_t fastdecode_loadtag(const char* ptr) { return tag; } -UPB_INLINE void decode_checklimit(upb_decstate *d) { +UPB_INLINE void decode_checklimit(upb_Decoder* d) { UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit)); } -UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size) { +UPB_INLINE int decode_pushlimit(upb_Decoder* d, const char* ptr, int size) { int limit = size + (int)(ptr - d->end); int delta = d->limit - limit; decode_checklimit(d); @@ -1909,7 +2084,7 @@ UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size) { return delta; } -UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr, +UPB_INLINE void decode_poplimit(upb_Decoder* d, const char* ptr, int saved_delta) { UPB_ASSERT(ptr - d->end == d->limit); decode_checklimit(d); @@ -1919,11 +2094,11 @@ UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr, } -#endif /* UPB_DECODE_INT_H_ */ +#endif /* UPB_DECODE_INT_H_ */ /** upb/encode.h ************************************************************/ /* - * upb_encode: parsing into a upb_msg using a upb_msglayout. + * upb_Encode: parsing into a upb_Message using a upb_MiniTable. */ #ifndef UPB_ENCODE_H_ @@ -1943,28 +2118,26 @@ enum { * * If your proto contains maps, the encoder will need to malloc()/free() * memory during encode. */ - UPB_ENCODE_DETERMINISTIC = 1, + kUpb_Encode_Deterministic = 1, /* When set, unknown fields are not printed. */ - UPB_ENCODE_SKIPUNKNOWN = 2, + kUpb_Encode_SkipUnknown = 2, + + /* When set, the encode will fail if any required fields are missing. */ + kUpb_Encode_CheckRequired = 4, }; #define UPB_ENCODE_MAXDEPTH(depth) ((depth) << 16) -char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options, - upb_arena *arena, size_t *size); - -UPB_INLINE char *upb_encode(const void *msg, const upb_msglayout *l, - upb_arena *arena, size_t *size) { - return upb_encode_ex(msg, l, 0, arena, size); -} +char* upb_Encode(const void* msg, const upb_MiniTable* l, int options, + upb_Arena* arena, size_t* size); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_ENCODE_H_ */ +#endif /* UPB_ENCODE_H_ */ /** upb/decode_fast.h ************************************************************/ // These are the specialized field parser functions for the fast parser. @@ -2005,22 +2178,22 @@ UPB_INLINE char *upb_encode(const void *msg, const upb_msglayout *l, #define UPB_DECODE_FAST_H_ -struct upb_decstate; +struct upb_Decoder; // The fallback, generic parsing function that can handle any field type. // This just uses the regular (non-fast) parser to parse a single field. -const char *fastdecode_generic(struct upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, uint64_t hasbits, - uint64_t data); +const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); -#define UPB_PARSE_PARAMS \ - struct upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \ +#define UPB_PARSE_PARAMS \ + struct upb_Decoder *d, const char *ptr, upb_Message *msg, intptr_t table, \ uint64_t hasbits, uint64_t data /* primitive fields ***********************************************************/ #define F(card, type, valbytes, tagbytes) \ - const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS); + const char* upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS); #define TYPES(card, tagbytes) \ F(card, b, 1, tagbytes) \ @@ -2047,8 +2220,8 @@ TAGBYTES(p) /* string fields **************************************************************/ #define F(card, tagbytes, type) \ - const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); \ - const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); + const char* upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); \ + const char* upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); #define UTF8(card, tagbytes) \ F(card, tagbytes, s) \ @@ -2068,17 +2241,17 @@ TAGBYTES(r) /* sub-message fields *********************************************************/ #define F(card, tagbytes, size_ceil, ceil_arg) \ - const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b(UPB_PARSE_PARAMS); + const char* upb_p##card##m_##tagbytes##bt_max##size_ceil##b(UPB_PARSE_PARAMS); #define SIZES(card, tagbytes) \ - F(card, tagbytes, 64, 64) \ + F(card, tagbytes, 64, 64) \ F(card, tagbytes, 128, 128) \ F(card, tagbytes, 192, 192) \ F(card, tagbytes, 256, 256) \ F(card, tagbytes, max, -1) #define TAGBYTES(card) \ - SIZES(card, 1) \ + SIZES(card, 1) \ SIZES(card, 2) TAGBYTES(s) @@ -2091,7 +2264,7 @@ TAGBYTES(r) #undef UPB_PARSE_PARAMS -#endif /* UPB_DECODE_FAST_H_ */ +#endif /* UPB_DECODE_FAST_H_ */ /** google/protobuf/descriptor.upb.h ************************************************************//* This file was generated by upbc (the upb compiler) from the input * file: @@ -2164,33 +2337,33 @@ 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; +extern const upb_MiniTable google_protobuf_FileDescriptorSet_msginit; +extern const upb_MiniTable google_protobuf_FileDescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_DescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_DescriptorProto_ExtensionRange_msginit; +extern const upb_MiniTable google_protobuf_DescriptorProto_ReservedRange_msginit; +extern const upb_MiniTable google_protobuf_ExtensionRangeOptions_msginit; +extern const upb_MiniTable google_protobuf_FieldDescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_OneofDescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_EnumDescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; +extern const upb_MiniTable google_protobuf_EnumValueDescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_ServiceDescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_MethodDescriptorProto_msginit; +extern const upb_MiniTable google_protobuf_FileOptions_msginit; +extern const upb_MiniTable google_protobuf_MessageOptions_msginit; +extern const upb_MiniTable google_protobuf_FieldOptions_msginit; +extern const upb_MiniTable google_protobuf_OneofOptions_msginit; +extern const upb_MiniTable google_protobuf_EnumOptions_msginit; +extern const upb_MiniTable google_protobuf_EnumValueOptions_msginit; +extern const upb_MiniTable google_protobuf_ServiceOptions_msginit; +extern const upb_MiniTable google_protobuf_MethodOptions_msginit; +extern const upb_MiniTable google_protobuf_UninterpretedOption_msginit; +extern const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msginit; +extern const upb_MiniTable google_protobuf_SourceCodeInfo_msginit; +extern const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msginit; +extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_msginit; +extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msginit; typedef enum { google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, @@ -2244,44 +2417,56 @@ typedef enum { } google_protobuf_MethodOptions_IdempotencyLevel; +extern const upb_MiniTable_Enum google_protobuf_FieldDescriptorProto_Label_enuminit; +extern const upb_MiniTable_Enum google_protobuf_FieldDescriptorProto_Type_enuminit; +extern const upb_MiniTable_Enum google_protobuf_FieldOptions_CType_enuminit; +extern const upb_MiniTable_Enum google_protobuf_FieldOptions_JSType_enuminit; +extern const upb_MiniTable_Enum google_protobuf_FileOptions_OptimizeMode_enuminit; +extern const upb_MiniTable_Enum google_protobuf_MethodOptions_IdempotencyLevel_enuminit; + /* 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_new(upb_Arena* arena) { + return (google_protobuf_FileDescriptorSet*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); +UPB_INLINE google_protobuf_FileDescriptorSet* google_protobuf_FileDescriptorSet_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileDescriptorSet* ret = google_protobuf_FileDescriptorSet_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_FileDescriptorSet_serialize_ex(const google_protobuf_FileDescriptorSet* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_FileDescriptorSet_msginit, options, 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 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( +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_Message_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; @@ -2289,35 +2474,44 @@ 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); +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_FileDescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileDescriptorProto* ret = google_protobuf_FileDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_FileDescriptorProto_serialize_ex(const google_protobuf_FileDescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_FileDescriptorProto_msginit, options, 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 upb_StringView google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} 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 upb_StringView google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_StringView); +} +UPB_INLINE upb_StringView const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_StringView 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)); } @@ -2327,41 +2521,47 @@ UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_ 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, 3); } -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 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, 4); } -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 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, 5); } -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 upb_StringView google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_StringView); +} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_StringView) = 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_StringView* google_protobuf_FileDescriptorProto_mutable_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (upb_StringView*)_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 upb_StringView* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_Arena *arena) { + return (upb_StringView*)_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, +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_StringView 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 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( +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_Message_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; @@ -2369,12 +2569,12 @@ UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescripto 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 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( +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_Message_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; @@ -2382,12 +2582,12 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescr 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 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( +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_Message_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; @@ -2395,12 +2595,12 @@ UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDe 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 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( +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_Message_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; @@ -2409,10 +2609,10 @@ UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_ _upb_sethas(msg, 3); *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) { +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_Message_New(&google_protobuf_FileOptions_msginit, arena); if (!sub) return NULL; google_protobuf_FileDescriptorProto_set_options(msg, sub); } @@ -2422,10 +2622,10 @@ UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_ _upb_sethas(msg, 4); *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) { +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_Message_New(&google_protobuf_SourceCodeInfo_msginit, arena); if (!sub) return NULL; google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub); } @@ -2434,56 +2634,63 @@ UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptor 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 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, +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 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, +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_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 5); - *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_StringView) = 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_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto* ret = google_protobuf_DescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_DescriptorProto_serialize_ex(const google_protobuf_DescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_DescriptorProto_msginit, options, 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 upb_StringView google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} 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)); } @@ -2495,26 +2702,28 @@ UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_p 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 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 upb_StringView const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg, size_t *len) { return (upb_StringView 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_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = 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 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( +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_Message_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; @@ -2522,12 +2731,12 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_Descript 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 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( +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_Message_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; @@ -2535,12 +2744,12 @@ UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorPro 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 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( +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_Message_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; @@ -2548,12 +2757,12 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_Descripto 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 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( +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_Message_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; @@ -2561,12 +2770,12 @@ UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobu 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 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( +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_Message_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; @@ -2575,10 +2784,10 @@ UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_Desc _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) { +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_Message_New(&google_protobuf_MessageOptions_msginit, arena); if (!sub) return NULL; google_protobuf_DescriptorProto_set_options(msg, sub); } @@ -2587,12 +2796,12 @@ UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProt 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 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( +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_Message_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; @@ -2600,59 +2809,70 @@ UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_Descript 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 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( +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_Message_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_StringView* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto *msg, size_t *len) { + return (upb_StringView*)_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 upb_StringView* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_Arena *arena) { + return (upb_StringView*)_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, +UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_StringView 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_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto_ExtensionRange*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto_ExtensionRange* ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_DescriptorProto_ExtensionRange_serialize_ex(const google_protobuf_DescriptorProto_ExtensionRange* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, options, 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 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 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 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); @@ -2666,10 +2886,10 @@ UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(googl _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) { +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_Message_New(&google_protobuf_ExtensionRangeOptions_msginit, arena); if (!sub) return NULL; google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub); } @@ -2678,34 +2898,43 @@ 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); +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto_ReservedRange*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto_ReservedRange* ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_DescriptorProto_ReservedRange_serialize_ex(const google_protobuf_DescriptorProto_ReservedRange* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, options, 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 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 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); @@ -2718,42 +2947,47 @@ UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_pro /* 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_new(upb_Arena* arena) { + return (google_protobuf_ExtensionRangeOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); +UPB_INLINE google_protobuf_ExtensionRangeOptions* google_protobuf_ExtensionRangeOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions* ret = google_protobuf_ExtensionRangeOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_serialize_ex(const google_protobuf_ExtensionRangeOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, options, 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 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( +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_Message_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; @@ -2761,60 +2995,87 @@ 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); +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_FieldDescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldDescriptorProto* ret = google_protobuf_FieldDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_FieldDescriptorProto_serialize_ex(const google_protobuf_FieldDescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_FieldDescriptorProto_msginit, options, arena, len); } - UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); } -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 upb_StringView google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_StringView); +} UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -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 upb_StringView google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_StringView); +} 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 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, 4); } -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 int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto* msg) { + return google_protobuf_FieldDescriptorProto_has_label(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) : 1; +} UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); } -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 int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto* msg) { + return google_protobuf_FieldDescriptorProto_has_type(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) : 1; +} UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); } -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 upb_StringView google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_StringView); +} UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); } -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 upb_StringView google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_StringView); +} UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); } -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 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, 9); } -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 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 upb_StringView google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_StringView); +} UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); } -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 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_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_StringView) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 3); @@ -2828,22 +3089,22 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_Fi _upb_sethas(msg, 5); *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_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 6); - *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 7); - *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_StringView) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { _upb_sethas(msg, 8); *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) { +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_Message_New(&google_protobuf_FieldOptions_msginit, arena); if (!sub) return NULL; google_protobuf_FieldDescriptorProto_set_options(msg, sub); } @@ -2853,9 +3114,9 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_prot _upb_sethas(msg, 9); *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_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 10); - *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_StringView) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) { _upb_sethas(msg, 11); @@ -2864,47 +3125,56 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_ /* 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_new(upb_Arena* arena) { + return (google_protobuf_OneofDescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); +UPB_INLINE google_protobuf_OneofDescriptorProto* google_protobuf_OneofDescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_OneofDescriptorProto* ret = google_protobuf_OneofDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_OneofDescriptorProto_serialize_ex(const google_protobuf_OneofDescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_OneofDescriptorProto_msginit, options, 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 upb_StringView google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} 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 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_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = 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) { +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_Message_New(&google_protobuf_OneofOptions_msginit, arena); if (!sub) return NULL; google_protobuf_OneofDescriptorProto_set_options(msg, sub); } @@ -2913,53 +3183,62 @@ 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); +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_EnumDescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumDescriptorProto* ret = google_protobuf_EnumDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_serialize_ex(const google_protobuf_EnumDescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_EnumDescriptorProto_msginit, options, 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 upb_StringView google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} 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 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 upb_StringView const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (upb_StringView 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_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = 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 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( +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_Message_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; @@ -2968,10 +3247,10 @@ UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_ _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) { +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_Message_New(&google_protobuf_EnumOptions_msginit, arena); if (!sub) return NULL; google_protobuf_EnumDescriptorProto_set_options(msg, sub); } @@ -2980,57 +3259,66 @@ UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorPro 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 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( +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_Message_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_StringView* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t *len) { + return (upb_StringView*)_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 upb_StringView* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_Arena *arena) { + return (upb_StringView*)_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, +UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_StringView 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_new(upb_Arena* arena) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize_ex(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, options, 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 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 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); @@ -3043,40 +3331,51 @@ UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(go /* 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_new(upb_Arena* arena) { + return (google_protobuf_EnumValueDescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); +UPB_INLINE google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumValueDescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumValueDescriptorProto* ret = google_protobuf_EnumValueDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_EnumValueDescriptorProto_serialize_ex(const google_protobuf_EnumValueDescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, options, arena, len); } - UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 1); } -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 upb_StringView google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_StringView); +} UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -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 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 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_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_StringView) = value; } UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 2); @@ -3086,10 +3385,10 @@ UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_prot _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) { +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_Message_New(&google_protobuf_EnumValueOptions_msginit, arena); if (!sub) return NULL; google_protobuf_EnumValueDescriptorProto_set_options(msg, sub); } @@ -3098,50 +3397,59 @@ 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); +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_ServiceDescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ServiceDescriptorProto* ret = google_protobuf_ServiceDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_ServiceDescriptorProto_serialize_ex(const google_protobuf_ServiceDescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, options, 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 upb_StringView google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} 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 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_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = 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 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( +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_Message_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; @@ -3150,10 +3458,10 @@ UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protob _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) { +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_Message_New(&google_protobuf_ServiceOptions_msginit, arena); if (!sub) return NULL; google_protobuf_ServiceDescriptorProto_set_options(msg, sub); } @@ -3162,63 +3470,80 @@ 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); +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_MethodDescriptorProto*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MethodDescriptorProto* ret = google_protobuf_MethodDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_MethodDescriptorProto_serialize_ex(const google_protobuf_MethodDescriptorProto* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_MethodDescriptorProto_msginit, options, arena, len); } - UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 1); } -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 upb_StringView google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -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 upb_StringView google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_StringView); +} UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 3); } -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 upb_StringView google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_StringView); +} UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 4); } -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 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, 5); } -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_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, 6); } -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 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_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = value; } -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_StringView) = value; } -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_StringView value) { _upb_sethas(msg, 3); - *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_StringView) = value; } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) { _upb_sethas(msg, 4); *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) { +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_Message_New(&google_protobuf_MethodOptions_msginit, arena); if (!sub) return NULL; google_protobuf_MethodDescriptorProto_set_options(msg, sub); } @@ -3235,80 +3560,125 @@ UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(googl /* 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_new(upb_Arena* arena) { + return (google_protobuf_FileOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_FileOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileOptions* ret = google_protobuf_FileOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_FileOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_FileOptions_serialize_ex(const google_protobuf_FileOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_FileOptions_msginit, options, arena, len); } - UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); } -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 upb_StringView google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); } -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 upb_StringView google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); } -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 int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions* msg) { + return google_protobuf_FileOptions_has_optimize_for(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) : 1; +} UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); } -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_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, 5); } -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 upb_StringView google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); } -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_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, 7); } -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_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, 8); } -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_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, 9); } -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_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, 10); } -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_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, 11); } -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_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, 12); } -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_cc_enable_arenas(const google_protobuf_FileOptions* msg) { + return google_protobuf_FileOptions_has_cc_enable_arenas(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) : true; +} UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); } -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 upb_StringView google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); } -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 upb_StringView google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); } -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 upb_StringView google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); } -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 upb_StringView google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); } -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 upb_StringView google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_StringView); +} UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); } -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_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 upb_StringView google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_StringView); +} 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 upb_StringView google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_StringView); +} 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_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_StringView) = value; } UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) { _upb_sethas(msg, 3); @@ -3318,9 +3688,9 @@ UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_proto _upb_sethas(msg, 4); *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_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 5); - *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_StringView) = value; } UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 6); @@ -3350,47 +3720,47 @@ UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf _upb_sethas(msg, 12); *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_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 13); - *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 14); - *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 15); - *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 16); - *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 17); - *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_StringView) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 18); *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_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 19); - *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_StringView) = value; } -UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) { +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_StringView value) { _upb_sethas(msg, 20); - *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_StringView) = 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 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( +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_Message_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; @@ -3398,38 +3768,51 @@ 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); +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_new(upb_Arena* arena) { + return (google_protobuf_MessageOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MessageOptions* ret = google_protobuf_MessageOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_MessageOptions_serialize_ex(const google_protobuf_MessageOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_MessageOptions_msginit, options, 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_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_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_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_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); } @@ -3452,12 +3835,12 @@ UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_Mes 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 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( +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_Message_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; @@ -3465,42 +3848,59 @@ 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); +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_new(upb_Arena* arena) { + return (google_protobuf_FieldOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldOptions* ret = google_protobuf_FieldOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_FieldOptions_serialize_ex(const google_protobuf_FieldOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_FieldOptions_msginit, options, 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 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, 2); } -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_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, 3); } -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_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, 4); } -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_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, 5); } -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 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_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); } @@ -3531,12 +3931,12 @@ UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptio 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 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( +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_Message_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; @@ -3544,42 +3944,47 @@ 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); +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_new(upb_Arena* arena) { + return (google_protobuf_OneofOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_OneofOptions* ret = google_protobuf_OneofOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_OneofOptions_serialize_ex(const google_protobuf_OneofOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_OneofOptions_msginit, options, 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 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( +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_Message_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; @@ -3587,34 +3992,43 @@ 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); +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_new(upb_Arena* arena) { + return (google_protobuf_EnumOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumOptions* ret = google_protobuf_EnumOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_EnumOptions_serialize_ex(const google_protobuf_EnumOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_EnumOptions_msginit, options, 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_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_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); } @@ -3629,12 +4043,12 @@ UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumO 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 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( +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_Message_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; @@ -3642,32 +4056,39 @@ 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); +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_new(upb_Arena* arena) { + return (google_protobuf_EnumValueOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumValueOptions* ret = google_protobuf_EnumValueOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_EnumValueOptions_serialize_ex(const google_protobuf_EnumValueOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_EnumValueOptions_msginit, options, 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_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); } @@ -3678,12 +4099,12 @@ UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_ 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 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( +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_Message_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; @@ -3691,32 +4112,39 @@ 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); +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_new(upb_Arena* arena) { + return (google_protobuf_ServiceOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ServiceOptions* ret = google_protobuf_ServiceOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_ServiceOptions_serialize_ex(const google_protobuf_ServiceOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_ServiceOptions_msginit, options, 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_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); } @@ -3727,12 +4155,12 @@ UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_Se 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 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( +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_Message_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; @@ -3740,34 +4168,43 @@ 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); +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_new(upb_Arena* arena) { + return (google_protobuf_MethodOptions*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MethodOptions* ret = google_protobuf_MethodOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_MethodOptions_serialize_ex(const google_protobuf_MethodOptions* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_MethodOptions_msginit, options, arena, len); } - UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); } -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_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, 2); } -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 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); } @@ -3782,12 +4219,12 @@ UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_proto 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 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( +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_Message_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; @@ -3795,61 +4232,78 @@ 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); +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_new(upb_Arena* arena) { + return (google_protobuf_UninterpretedOption*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_UninterpretedOption* ret = google_protobuf_UninterpretedOption_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_UninterpretedOption_serialize_ex(const google_protobuf_UninterpretedOption* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_UninterpretedOption_msginit, options, 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, 1); } -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 upb_StringView google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_StringView); +} UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 2); } -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 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, 3); } -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 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, 4); } -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 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 upb_StringView google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_StringView); +} 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 upb_StringView google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_StringView); +} 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 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( +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_Message_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_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_StringView) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) { _upb_sethas(msg, 2); @@ -3863,49 +4317,58 @@ UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_prot _upb_sethas(msg, 4); *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_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_StringView value) { _upb_sethas(msg, 5); - *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_StringView) = value; } -UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_StringView value) { _upb_sethas(msg, 6); - *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_StringView) = 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_new(upb_Arena* arena) { + return (google_protobuf_UninterpretedOption_NamePart*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena); +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_NamePart_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_UninterpretedOption_NamePart* ret = google_protobuf_UninterpretedOption_NamePart_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_UninterpretedOption_NamePart_serialize_ex(const google_protobuf_UninterpretedOption_NamePart* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, options, arena, len); } - UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 1); } -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 upb_StringView google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 2); } -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 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_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) { _upb_sethas(msg, 2); @@ -3914,42 +4377,47 @@ UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(go /* 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_new(upb_Arena* arena) { + return (google_protobuf_SourceCodeInfo*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_SourceCodeInfo* ret = google_protobuf_SourceCodeInfo_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_serialize_ex(const google_protobuf_SourceCodeInfo* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_SourceCodeInfo_msginit, options, 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 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( +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_Message_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; @@ -3957,115 +4425,129 @@ 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); +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_new(upb_Arena* arena) { + return (google_protobuf_SourceCodeInfo_Location*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena); +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_SourceCodeInfo_Location* ret = google_protobuf_SourceCodeInfo_Location_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_Location_serialize_ex(const google_protobuf_SourceCodeInfo_Location* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, options, 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 upb_StringView google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView); +} 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 upb_StringView google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_StringView); +} +UPB_INLINE upb_StringView const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_StringView 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 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, +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 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, +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_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = value; } -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_StringView value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_StringView) = 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_StringView* google_protobuf_SourceCodeInfo_Location_mutable_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { + return (upb_StringView*)_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 upb_StringView* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_Arena *arena) { + return (upb_StringView*)_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, +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_StringView 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_new(upb_Arena* arena) { + return (google_protobuf_GeneratedCodeInfo*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); +UPB_INLINE google_protobuf_GeneratedCodeInfo* google_protobuf_GeneratedCodeInfo_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo* ret = google_protobuf_GeneratedCodeInfo_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_serialize_ex(const google_protobuf_GeneratedCodeInfo* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, options, 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 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( +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_Message_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; @@ -4073,51 +4555,62 @@ 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); +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_new(upb_Arena* arena) { + return (google_protobuf_GeneratedCodeInfo_Annotation*)_upb_Message_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); +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); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) return NULL; + if (upb_Decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } return ret; } -UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size, - const upb_extreg *extreg, int options, - upb_arena *arena) { - google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo_Annotation* ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, extreg, options, arena)) { + if (upb_Decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { return NULL; } return ret; } -UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) { - return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len); +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, 0, arena, len); +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_Annotation_serialize_ex(const google_protobuf_GeneratedCodeInfo_Annotation* msg, int options, + upb_Arena* arena, size_t* len) { + return upb_Encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, options, 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, 1); } -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 upb_StringView google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_StringView); +} UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 2); } -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 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, 3); } -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_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 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, +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_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_StringView value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_StringView) = value; } UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { _upb_sethas(msg, 2); @@ -4128,6 +4621,12 @@ UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_prot *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } +extern const upb_MiniTable_File google_protobuf_descriptor_proto_upb_file_layout; + +/* Max size 32 is google.protobuf.FileOptions */ +/* Max size 64 is google.protobuf.FileOptions */ +#define _UPB_MAXOPT_SIZE UPB_SIZE(104, 192) + #ifdef __cplusplus } /* extern "C" */ #endif @@ -4136,19 +4635,6 @@ UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_prot #endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */ /** upb/def.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_ @@ -4157,288 +4643,364 @@ UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_prot #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; +#endif /* __cplusplus */ + +struct upb_EnumDef; +typedef struct upb_EnumDef upb_EnumDef; +struct upb_EnumValueDef; +typedef struct upb_EnumValueDef upb_EnumValueDef; +struct upb_ExtensionRange; +typedef struct upb_ExtensionRange upb_ExtensionRange; +struct upb_FieldDef; +typedef struct upb_FieldDef upb_FieldDef; +struct upb_FileDef; +typedef struct upb_FileDef upb_FileDef; +struct upb_MethodDef; +typedef struct upb_MethodDef upb_MethodDef; +struct upb_MessageDef; +typedef struct upb_MessageDef upb_MessageDef; +struct upb_OneofDef; +typedef struct upb_OneofDef upb_OneofDef; +struct upb_ServiceDef; +typedef struct upb_ServiceDef upb_ServiceDef; +struct upb_streamdef; +typedef struct upb_streamdef upb_streamdef; +struct upb_DefPool; +typedef struct upb_DefPool upb_DefPool; + +typedef enum { kUpb_Syntax_Proto2 = 2, kUpb_Syntax_Proto3 = 3 } upb_Syntax; /* 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, + kUpb_WellKnown_Unspecified, + kUpb_WellKnown_Any, + kUpb_WellKnown_FieldMask, + kUpb_WellKnown_Duration, + kUpb_WellKnown_Timestamp, /* number wrappers */ - UPB_WELLKNOWN_DOUBLEVALUE, - UPB_WELLKNOWN_FLOATVALUE, - UPB_WELLKNOWN_INT64VALUE, - UPB_WELLKNOWN_UINT64VALUE, - UPB_WELLKNOWN_INT32VALUE, - UPB_WELLKNOWN_UINT32VALUE, + kUpb_WellKnown_DoubleValue, + kUpb_WellKnown_FloatValue, + kUpb_WellKnown_Int64Value, + kUpb_WellKnown_UInt64Value, + kUpb_WellKnown_Int32Value, + kUpb_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; + kUpb_WellKnown_StringValue, + kUpb_WellKnown_BytesValue, + kUpb_WellKnown_BoolValue, + kUpb_WellKnown_Value, + kUpb_WellKnown_ListValue, + kUpb_WellKnown_Struct +} upb_WellKnown; -/* upb_fielddef ***************************************************************/ +/* 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); - -/* 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); +#define kUpb_MaxFieldNumber ((1 << 29) - 1) + +const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f); +bool upb_FieldDef_HasOptions(const upb_FieldDef* f); +const char* upb_FieldDef_FullName(const upb_FieldDef* f); +upb_CType upb_FieldDef_CType(const upb_FieldDef* f); +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); +upb_Label 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_HasJsonName(const upb_FieldDef* f); +bool upb_FieldDef_IsExtension(const upb_FieldDef* f); +bool upb_FieldDef_IsPacked(const upb_FieldDef* f); +const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_ExtensionScope(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_IsSubMessage(const upb_FieldDef* f); +bool upb_FieldDef_IsString(const upb_FieldDef* f); +bool upb_FieldDef_IsRepeated(const upb_FieldDef* f); +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f); +bool upb_FieldDef_IsMap(const upb_FieldDef* f); +bool upb_FieldDef_HasDefault(const upb_FieldDef* f); +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f); +bool upb_FieldDef_HasPresence(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f); +const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f); +const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f); +const upb_MiniTable_Extension* _upb_FieldDef_ExtensionMiniTable( + const upb_FieldDef* f); +bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f); + +/* upb_OneofDef ***************************************************************/ + +const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o); +bool upb_OneofDef_HasOptions(const upb_OneofDef* o); +const char* upb_OneofDef_Name(const upb_OneofDef* o); +const upb_MessageDef* 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; +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, + const char* name, + size_t length); +UPB_INLINE const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, + const char* name) { + return upb_OneofDef_LookupNameWithSize(o, name, strlen(name)); +} +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num); + +/* upb_MessageDef *************************************************************/ /* Well-known field tag numbers for map-entry messages. */ -#define UPB_MAPENTRY_KEY 1 -#define UPB_MAPENTRY_VALUE 2 +#define kUpb_MapEntry_KeyFieldNumber 1 +#define kUpb_MapEntry_ValueFieldNumber 2 /* Well-known field tag numbers for Any messages. */ -#define UPB_ANY_TYPE 1 -#define UPB_ANY_VALUE 2 +#define kUpb_Any_TypeFieldNumber 1 +#define kUpb_Any_ValueFieldNumber 2 /* Well-known field tag numbers for timestamp messages. */ -#define UPB_DURATION_SECONDS 1 -#define UPB_DURATION_NANOS 2 +#define kUpb_Duration_SecondsFieldNumber 1 +#define kUpb_Duration_NanosFieldNumber 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)); -} +#define kUpb_Timestamp_SecondsFieldNumber 1 +#define kUpb_Timestamp_NanosFieldNumber 2 + +const google_protobuf_MessageOptions* upb_MessageDef_Options( + const upb_MessageDef* m); +bool upb_MessageDef_HasOptions(const upb_MessageDef* m); +const char* upb_MessageDef_FullName(const upb_MessageDef* m); +const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m); +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m); +const char* upb_MessageDef_Name(const upb_MessageDef* m); +upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m); +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m); +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m); +int upb_MessageDef_FieldCount(const upb_MessageDef* m); +int upb_MessageDef_OneofCount(const upb_MessageDef* m); +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i); +const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i); +const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i); +const upb_FieldDef* upb_MessageDef_FindFieldByNumberWithSize( + const upb_MessageDef* m, uint32_t i); +const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len); +const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len); +const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m); + +UPB_INLINE const upb_OneofDef* upb_MessageDef_FindOneofByName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindOneofByNameWithSize(m, name, strlen(name)); +} + +UPB_INLINE const upb_FieldDef* upb_MessageDef_FindFieldByName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindFieldByNameWithSize(m, name, strlen(name)); +} + +UPB_INLINE bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m) { + return google_protobuf_MessageOptions_map_entry(upb_MessageDef_Options(m)); +} + +/* Nested entities. */ +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m); +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m); +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m); +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i); +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i); +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i); /* 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); +bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* 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); +UPB_INLINE bool upb_MessageDef_FindByName(const upb_MessageDef* m, + const char* name, + const upb_FieldDef** f, + const upb_OneofDef** o) { + return upb_MessageDef_FindByNameWithSize(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); -const upb_symtab *upb_filedef_symtab(const upb_filedef *f); - -/* 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); -upb_arena *_upb_symtab_arena(const upb_symtab *s); +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t len); +UPB_INLINE const upb_FieldDef* upb_MessageDef_FindByJsonName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindByJsonNameWithSize(m, name, strlen(name)); +} + +/* upb_ExtensionRange *********************************************************/ + +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r); +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r); +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r); +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r); + +/* upb_EnumDef ****************************************************************/ + +const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e); +bool upb_EnumDef_HasOptions(const upb_EnumDef* e); +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); +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e); +int32_t upb_EnumDef_Default(const upb_EnumDef* e); +int upb_EnumDef_ValueCount(const upb_EnumDef* e); +const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i); + +const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* e, const char* name, size_t len); +const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, + int32_t num); +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num); + +// Convenience wrapper. +UPB_INLINE const upb_EnumValueDef* upb_EnumDef_FindValueByName( + const upb_EnumDef* e, const char* name) { + return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name)); +} + +/* upb_EnumValueDef ***********************************************************/ + +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* e); +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* e); +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* e); +const char* upb_EnumValueDef_Name(const upb_EnumValueDef* e); +int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* e); +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* e); +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* e); + +/* upb_FileDef ****************************************************************/ + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f); +bool upb_FileDef_HasOptions(const upb_FileDef* f); +const char* upb_FileDef_Name(const upb_FileDef* f); +const char* upb_FileDef_Package(const upb_FileDef* f); +upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f); +int upb_FileDef_DependencyCount(const upb_FileDef* f); +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f); +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f); +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f); +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f); +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f); +int upb_FileDef_ServiceCount(const upb_FileDef* f); +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i); +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i); +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i); +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i); +const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i); +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i); +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i); +const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f); +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f); +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f); + +/* upb_MethodDef **************************************************************/ + +const google_protobuf_MethodOptions* upb_MethodDef_Options( + const upb_MethodDef* m); +bool upb_MethodDef_HasOptions(const upb_MethodDef* m); +const char* upb_MethodDef_FullName(const upb_MethodDef* m); +const char* upb_MethodDef_Name(const upb_MethodDef* m); +const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m); +const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m); +const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m); +bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m); +bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m); + +/* upb_ServiceDef *************************************************************/ + +const google_protobuf_ServiceOptions* upb_ServiceDef_Options( + const upb_ServiceDef* s); +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s); +const char* upb_ServiceDef_FullName(const upb_ServiceDef* s); +const char* upb_ServiceDef_Name(const upb_ServiceDef* s); +int upb_ServiceDef_Index(const upb_ServiceDef* s); +const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s); +int upb_ServiceDef_MethodCount(const upb_ServiceDef* s); +const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i); +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name); + +/* upb_DefPool ****************************************************************/ + +upb_DefPool* upb_DefPool_New(void); +void upb_DefPool_Free(upb_DefPool* s); +const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, + const char* sym); +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); +const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym); +const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s, + const char* sym); +const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, + const char* sym); +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); +const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name); +const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, + const char* name); +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size); +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name); +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len); +const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file, + upb_Status* status); +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s); +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s); +const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTable_Extension* ext); +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum); +const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s); +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count); /* 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; +typedef struct _upb_DefPool_Init { + struct _upb_DefPool_Init** deps; /* Dependencies of this file. */ + const upb_MiniTable_File* layout; + const char* filename; + upb_StringView descriptor; /* Serialized descriptor. */ +} _upb_DefPool_Init; -bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init); #ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ +} /* extern "C" */ +#endif /* __cplusplus */ #endif /* UPB_DEF_H_ */ @@ -4447,7 +5009,6 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); #define UPB_REFLECTION_H_ - #ifdef __cplusplus extern "C" { #endif @@ -4460,57 +5021,63 @@ typedef union { 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; + const upb_Map* map_val; + const upb_Message* msg_val; + const upb_Array* array_val; + upb_StringView str_val; +} upb_MessageValue; typedef union { - upb_map* map; - upb_msg* msg; - upb_array* array; -} upb_mutmsgval; + upb_Map* map; + upb_Message* msg; + upb_Array* array; +} upb_MutableMessageValue; -upb_msgval upb_fielddef_default(const upb_fielddef *f); +upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f); -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ /* 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_Message* upb_Message_New(const upb_MessageDef* m, upb_Arena* a); /* Returns the value associated with this field. */ -upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f); +upb_MessageValue upb_Message_Get(const upb_Message* 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); +upb_MutableMessageValue upb_Message_Mutable(upb_Message* 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); +/* May only be called for fields where upb_FieldDef_HasPresence(f) == true. */ +bool upb_Message_Has(const upb_Message* 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); +const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* 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); + * caller must ensure that the target data outlives |msg| (by living either in + * the same arena or a different arena that outlives it). + * + * Returns false if allocation fails. */ +bool upb_Message_Set(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue 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); +void upb_Message_ClearField(upb_Message* msg, const upb_FieldDef* f); /* Clear all data and unknown fields. */ -void upb_msg_clear(upb_msg *msg, const upb_msgdef *m); +void upb_Message_Clear(upb_Message* msg, const upb_MessageDef* 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)) { + * size_t iter = kUpb_Message_Begin; + * const upb_FieldDef *f; + * upb_MessageValue val; + * while (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) { * process_field(f, val); * } * @@ -4519,90 +5086,109 @@ void upb_msg_clear(upb_msg *msg, const upb_msgdef *m); * 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); +#define kUpb_Message_Begin -1 +bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, const upb_FieldDef** f, + upb_MessageValue* val, size_t* iter); /* Clears all unknown field data from this message and all submessages. */ -bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth); +bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + int maxdepth); -/** upb_array *****************************************************************/ +/** 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); +upb_Array* upb_Array_New(upb_Arena* a, upb_CType type); /* Returns the size of the array. */ -size_t upb_array_size(const upb_array *arr); +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); +upb_MessageValue 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); +void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue 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); +bool upb_Array_Append(upb_Array* array, upb_MessageValue val, upb_Arena* arena); + +/* Moves elements within the array using memmove(). Like memmove(), the source + * and destination elements may be overlapping. */ +void upb_Array_Move(upb_Array* array, size_t dst_idx, size_t src_idx, + size_t count); + +/* Inserts one or more empty elements into the array. Existing elements are + * shifted right. The new elements have undefined state and must be set with + * `upb_Array_Set()`. + * REQUIRES: `i <= upb_Array_Size(arr)` */ +bool upb_Array_Insert(upb_Array* array, size_t i, size_t count, + upb_Arena* arena); + +/* Deletes one or more elements from the array. Existing elements are shifted + * left. + * REQUIRES: `i + count <= upb_Array_Size(arr)` */ +void upb_Array_Delete(upb_Array* array, size_t i, size_t count); /* 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); +bool upb_Array_Resize(upb_Array* array, size_t size, upb_Arena* arena); -/** upb_map *******************************************************************/ +/** 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); +upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, upb_CType value_type); /* Returns the number of entries in the map. */ -size_t upb_map_size(const upb_map *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); +bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* val); /* Removes all entries in the map. */ -void upb_map_clear(upb_map *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); +bool upb_Map_Set(upb_Map* map, upb_MessageValue key, upb_MessageValue 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); +bool upb_Map_Delete(upb_Map* map, upb_MessageValue 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); + * size_t iter = kUpb_Map_Begin; + * while (upb_MapIterator_Next(map, &iter)) { + * upb_MessageValue key = upb_MapIterator_Key(map, iter); + * upb_MessageValue val = upb_MapIterator_Value(map, iter); * * // If mutating is desired. - * upb_mapiter_setvalue(map, iter, value2); + * upb_MapIterator_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); +bool upb_MapIterator_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); + * kUpb_Map_Begin (you must call next() at least once first). */ +bool upb_MapIterator_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); +upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter); +upb_MessageValue upb_MapIterator_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); +void upb_MapIterator_SetValue(upb_Map* map, size_t iter, + upb_MessageValue value); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif @@ -4617,19 +5203,17 @@ void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); extern "C" { #endif -enum { - UPB_JSONDEC_IGNOREUNKNOWN = 1 -}; +enum { upb_JsonDecode_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); +bool upb_JsonDecode(const char* buf, size_t size, upb_Message* msg, + const upb_MessageDef* m, const upb_DefPool* symtab, + int options, upb_Arena* arena, upb_Status* status); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_JSONDECODE_H_ */ +#endif /* UPB_JSONDECODE_H_ */ /** upb/json_encode.h ************************************************************/ #ifndef UPB_JSONENCODE_H_ @@ -4642,11 +5226,11 @@ extern "C" { enum { /* When set, emits 0/default values. TODO(haberman): proto3 only? */ - UPB_JSONENC_EMITDEFAULTS = 1, + upb_JsonEncode_EmitDefaults = 1, /* When set, use normal (snake_caes) field names instead of JSON (camelCase) names. */ - UPB_JSONENC_PROTONAMES = 2 + upb_JsonEncode_UseProtoNames = 2 }; /* Encodes the given |msg| to JSON format. The message's reflection is given in @@ -4657,15 +5241,15 @@ enum { * 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); +size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, char* buf, + size_t size, upb_Status* status); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_JSONENCODE_H_ */ +#endif /* UPB_JSONENCODE_H_ */ /** upb/port_undef.inc ************************************************************/ /* See port_def.inc. This should #undef all macros #defined there. */ diff --git a/ruby/ext/google/protobuf_c/wrap_memcpy.c b/ruby/ext/google/protobuf_c/wrap_memcpy.c index 18c036780cdd5..6bbd4bad35316 100644 --- a/ruby/ext/google/protobuf_c/wrap_memcpy.c +++ b/ruby/ext/google/protobuf_c/wrap_memcpy.c @@ -33,7 +33,8 @@ // On x86-64 Linux with glibc, we link against the 2.2.5 version of memcpy so // that we avoid depending on the 2.14 version of the symbol. This way, // distributions that are using pre-2.14 versions of glibc can successfully use -// the gem we distribute (https://github.com/protocolbuffers/protobuf/issues/2783). +// the gem we distribute +// (https://github.com/protocolbuffers/protobuf/issues/2783). // // This wrapper is enabled by passing the linker flags -Wl,-wrap,memcpy in // extconf.rb. @@ -41,11 +42,11 @@ #if defined(__x86_64__) && defined(__GNU_LIBRARY__) __asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); void *__wrap_memcpy(void *dest, const void *src, size_t n) { - return memcpy(dest, src, n); + return memcpy(dest, src, n); } #else void *__wrap_memcpy(void *dest, const void *src, size_t n) { - return memmove(dest, src, n); + return memmove(dest, src, n); } #endif #endif diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index 7a9e3f38b761e..87d75a3ba7759 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.18.1" + s.version = "3.19.4" 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,7 +17,7 @@ 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", ">= 1.1.0", "< 2.0" + s.add_development_dependency "rake-compiler-dock", "= 1.1.0" end s.test_files = ["tests/basic.rb", "tests/stress.rb", @@ -25,5 +25,4 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 2.3' 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 index 37f8d5b675cd6..2d06ca27422a4 100755 --- a/ruby/lib/google/protobuf/well_known_types.rb +++ b/ruby/lib/google/protobuf/well_known_types.rb @@ -82,9 +82,14 @@ def to_time end end + def self.from_time(time) + new.from_time(time) + end + def from_time(time) self.seconds = time.to_i self.nanos = time.nsec + self end def to_i @@ -132,10 +137,14 @@ def to_ruby(recursive = false) end end + def self.from_ruby(value) + self.new.from_ruby(value) + end + def from_ruby(value) case value when NilClass - self.null_value = 0 + self.null_value = :NULL_VALUE when Numeric self.number_value = value when String @@ -155,6 +164,8 @@ def from_ruby(value) else raise UnexpectedStructType end + + self end end @@ -225,6 +236,5 @@ def self.from_a(arr) ret end end - end end diff --git a/ruby/pom.xml b/ruby/pom.xml index 0b13996d827d3..c9ae9e66339e7 100644 --- a/ruby/pom.xml +++ b/ruby/pom.xml @@ -9,7 +9,7 @@ com.google.protobuf.jruby protobuf-jruby - 3.18.1 + 3.19.4 Protocol Buffer JRuby native extension Protocol Buffers are a way of encoding structured data in an efficient yet @@ -19,7 +19,7 @@ https://developers.google.com/protocol-buffers/ - 3-Clause BSD License + BSD-3-Clause https://opensource.org/licenses/BSD-3-Clause repo @@ -76,7 +76,7 @@ com.google.protobuf protobuf-java-util - 3.18.1 + 3.19.4 org.jruby diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java index 8140ec5b64d83..f7379b148edfb 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java @@ -332,7 +332,7 @@ public IRubyObject hasKey(ThreadContext context, IRubyObject key) { * * Returns the number of entries (key-value pairs) in the map. */ - @JRubyMethod + @JRubyMethod(name = {"length", "size"}) public IRubyObject length(ThreadContext context) { return context.runtime.newFixnum(this.table.size()); } diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index 2a7a251f2e8d7..b9d1554dbd33a 100755 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -71,6 +71,14 @@ def test_issue_8559_crash TestMessage.encode(msg) end + def test_issue_9440 + msg = HelloRequest.new + msg.id = 8 + assert_equal 8, msg.id + msg.version = '1' + assert_equal 8, msg.id + end + def test_has_field m = TestSingularFields.new assert !m.has_singular_msg? @@ -620,5 +628,21 @@ def test_map_freeze assert_raise(FrozenErrorType) { m.map_string_int32.delete('a') } assert_raise(FrozenErrorType) { m.map_string_int32.clear } end + + def test_map_length + m = proto_module::MapMessage.new + assert_equal 0, m.map_string_int32.length + assert_equal 0, m.map_string_msg.length + assert_equal 0, m.map_string_int32.size + assert_equal 0, m.map_string_msg.size + + m.map_string_int32['a'] = 1 + m.map_string_int32['b'] = 2 + m.map_string_msg['a'] = proto_module::TestMessage2.new + assert_equal 2, m.map_string_int32.length + assert_equal 1, m.map_string_msg.length + assert_equal 2, m.map_string_int32.size + assert_equal 1, m.map_string_msg.size + end end end diff --git a/ruby/tests/basic_test.proto b/ruby/tests/basic_test.proto index bca172a722ece..fb70f479db5bf 100644 --- a/ruby/tests/basic_test.proto +++ b/ruby/tests/basic_test.proto @@ -215,3 +215,38 @@ message WithJsonName { optional int32 foo_bar = 1 [json_name="jsonFooBar"]; repeated WithJsonName baz = 2 [json_name="jsonBaz"]; } + +message HelloRequest { + optional uint32 id = 1; + optional uint32 random_name_a0 = 2; + optional uint32 random_name_a1 = 3; + optional uint32 random_name_a2 = 4; + optional uint32 random_name_a3 = 5; + optional uint32 random_name_a4 = 6; + optional uint32 random_name_a5 = 7; + optional uint32 random_name_a6 = 8; + optional uint32 random_name_a7 = 9; + optional uint32 random_name_a8 = 10; + optional uint32 random_name_a9 = 11; + optional uint32 random_name_b0 = 12; + optional uint32 random_name_b1 = 13; + optional uint32 random_name_b2 = 14; + optional uint32 random_name_b3 = 15; + optional uint32 random_name_b4 = 16; + optional uint32 random_name_b5 = 17; + optional uint32 random_name_b6 = 18; + optional uint32 random_name_b7 = 19; + optional uint32 random_name_b8 = 20; + optional uint32 random_name_b9 = 21; + optional uint32 random_name_c0 = 22; + optional uint32 random_name_c1 = 23; + optional uint32 random_name_c2 = 24; + optional uint32 random_name_c3 = 25; + optional uint32 random_name_c4 = 26; + optional uint32 random_name_c5 = 27; + optional uint32 random_name_c6 = 28; + optional uint32 random_name_c7 = 29; + optional uint32 random_name_c8 = 30; + optional uint32 random_name_c9 = 31; + optional string version = 32; +} diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb index 3d9f67eb938f9..3ab9a0ca841a0 100644 --- a/ruby/tests/common_tests.rb +++ b/ruby/tests/common_tests.rb @@ -816,11 +816,17 @@ def test_parse_serialize :optional_enum => :B, :repeated_string => ["a", "b", "c"], :repeated_int32 => [42, 43, 44], - :repeated_enum => [:A, :B, :C, 100], + :repeated_enum => [:A, :B, :C], :repeated_msg => [proto_module::TestMessage2.new(:foo => 1), proto_module::TestMessage2.new(:foo => 2)]) + if proto_module == ::BasicTest + # For proto3 we can add an unknown enum value safely. + m.repeated_enum << 100 + end + data = proto_module::TestMessage.encode m m2 = proto_module::TestMessage.decode data + assert_equal m, m2 data = Google::Protobuf.encode m diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb index ea042eb024417..fbdee38a29693 100755 --- a/ruby/tests/well_known_types_test.rb +++ b/ruby/tests/well_known_types_test.rb @@ -15,16 +15,30 @@ def test_timestamp # millisecond accuracy time = Time.at(123456, 654321) - ts.from_time(time) + resp = ts.from_time(time) assert_equal 123456, ts.seconds assert_equal 654321000, ts.nanos assert_equal time, ts.to_time + assert_equal resp, ts # nanosecond accuracy time = Time.at(123456, Rational(654321321, 1000)) - ts.from_time(time) + resp = ts.from_time(time) + assert_equal 123456, ts.seconds assert_equal 654321321, ts.nanos assert_equal time, ts.to_time + assert_equal resp, ts + + # Class based initialisation using from_time + time = Time.at(123456, Rational(654321321, 1000)) + ts = Google::Protobuf::Timestamp.from_time(time) + assert_equal 123456, ts.seconds + assert_equal 654321321, ts.nanos + assert_equal time, ts.to_time + + # Instance method returns the same value as class method + assert_equal Google::Protobuf::Timestamp.new.from_time(time), + Google::Protobuf::Timestamp.from_time(time) end def test_duration @@ -201,4 +215,33 @@ def test_b8325 ) assert_equal '[]', value_field.get(proto).inspect end + + def test_from_ruby + pb = Google::Protobuf::Value.from_ruby(nil) + assert_equal pb.null_value, :NULL_VALUE + + pb = Google::Protobuf::Value.from_ruby(1.23) + assert_equal pb.number_value, 1.23 + + pb = Google::Protobuf::Value.from_ruby('1.23') + assert_equal pb.string_value, '1.23' + + pb = Google::Protobuf::Value.from_ruby(true) + assert_equal pb.bool_value, true + + pb = Google::Protobuf::Value.from_ruby(false) + assert_equal pb.bool_value, false + + pb = Google::Protobuf::Value.from_ruby(Google::Protobuf::Struct.from_hash({ 'a' => 1, 'b' => '2', 'c' => [1, 2, 3], 'd' => nil, 'e' => true })) + assert_equal pb.struct_value, Google::Protobuf::Struct.from_hash({ 'a' => 1, 'b' => '2', 'c' => [1, 2, 3], 'd' => nil, 'e' => true }) + + pb = Google::Protobuf::Value.from_ruby({ 'a' => 1, 'b' => '2', 'c' => [1, 2, 3], 'd' => nil, 'e' => true }) + assert_equal pb.struct_value, Google::Protobuf::Struct.from_hash({ 'a' => 1, 'b' => '2', 'c' => [1, 2, 3], 'd' => nil, 'e' => true }) + + pb = Google::Protobuf::Value.from_ruby(Google::Protobuf::ListValue.from_a([1, 2, 3])) + assert_equal pb.list_value, Google::Protobuf::ListValue.from_a([1, 2, 3]) + + pb = Google::Protobuf::Value.from_ruby([1, 2, 3]) + assert_equal pb.list_value, Google::Protobuf::ListValue.from_a([1, 2, 3]) + end end diff --git a/src/Makefile.am b/src/Makefile.am index 232955f904938..ca9b81b238027 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -71,6 +71,7 @@ nobase_include_HEADERS = \ google/protobuf/arena.h \ google/protobuf/arena_impl.h \ google/protobuf/arenastring.h \ + google/protobuf/arenaz_sampler.h \ google/protobuf/compiler/code_generator.h \ google/protobuf/compiler/command_line_interface.h \ google/protobuf/compiler/cpp/cpp_file.h \ @@ -93,6 +94,7 @@ nobase_include_HEADERS = \ google/protobuf/compiler/plugin.h \ google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/python/python_generator.h \ + google/protobuf/compiler/python/python_pyi_generator.h \ google/protobuf/compiler/ruby/ruby_generator.h \ google/protobuf/descriptor.h \ google/protobuf/descriptor.pb.h \ @@ -109,11 +111,8 @@ nobase_include_HEADERS = \ google/protobuf/generated_enum_util.h \ google/protobuf/generated_message_bases.h \ google/protobuf/generated_message_reflection.h \ - google/protobuf/generated_message_table_driven.h \ - google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_tctable_decl.h \ google/protobuf/generated_message_tctable_impl.h \ - google/protobuf/generated_message_tctable_impl.inc \ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/implicit_weak_message.h \ @@ -194,9 +193,9 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/any_lite.cc \ google/protobuf/arena.cc \ google/protobuf/arenastring.cc \ + google/protobuf/arenaz_sampler.cc \ google/protobuf/extension_set.cc \ google/protobuf/generated_enum_util.cc \ - google/protobuf/generated_message_table_driven_lite.cc \ google/protobuf/generated_message_tctable_lite.cc \ google/protobuf/generated_message_util.cc \ google/protobuf/implicit_weak_message.cc \ @@ -254,7 +253,6 @@ libprotobuf_la_SOURCES = \ google/protobuf/field_mask.pb.cc \ google/protobuf/generated_message_bases.cc \ google/protobuf/generated_message_reflection.cc \ - google/protobuf/generated_message_table_driven.cc \ google/protobuf/generated_message_tctable_full.cc \ google/protobuf/io/gzip_stream.cc \ google/protobuf/io/printer.cc \ @@ -473,6 +471,9 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/plugin.cc \ google/protobuf/compiler/plugin.pb.cc \ google/protobuf/compiler/python/python_generator.cc \ + google/protobuf/compiler/python/python_helpers.cc \ + google/protobuf/compiler/python/python_helpers.h \ + google/protobuf/compiler/python/python_pyi_generator.cc \ google/protobuf/compiler/ruby/ruby_generator.cc \ google/protobuf/compiler/scc.h \ google/protobuf/compiler/subprocess.cc \ @@ -738,6 +739,7 @@ protobuf_test_SOURCES = \ google/protobuf/any_test.cc \ google/protobuf/arena_unittest.cc \ google/protobuf/arenastring_unittest.cc \ + google/protobuf/arenaz_sampler_test.cc \ google/protobuf/compiler/annotation_test_util.cc \ google/protobuf/compiler/annotation_test_util.h \ google/protobuf/compiler/command_line_interface_unittest.cc \ @@ -764,6 +766,7 @@ protobuf_test_SOURCES = \ google/protobuf/dynamic_message_unittest.cc \ google/protobuf/extension_set_unittest.cc \ google/protobuf/generated_message_reflection_unittest.cc \ + google/protobuf/generated_message_tctable_lite_test.cc \ google/protobuf/inlined_string_field_unittest.cc \ google/protobuf/io/coded_stream_unittest.cc \ google/protobuf/io/io_win32_unittest.cc \ diff --git a/src/README.md b/src/README.md index 9db40fdde4672..80e8668d99c32 100644 --- a/src/README.md +++ b/src/README.md @@ -48,7 +48,7 @@ Buffer compiler (protoc) execute the following: ./configure - make + make -j$(nproc) # $(nproc) ensures it uses all cores for compilation make check sudo make install sudo ldconfig # refresh shared library cache. diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc index 73c002f60409f..8d37008bd953f 100644 --- a/src/google/protobuf/any.cc +++ b/src/google/protobuf/any.cc @@ -35,6 +35,7 @@ #include #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h index e8336fa14a37c..d688a0ca738fa 100644 --- a/src/google/protobuf/any.h +++ b/src/google/protobuf/any.h @@ -37,6 +37,7 @@ #include #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 52c6ccca2f243..5539413defb6a 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -16,25 +16,33 @@ #include PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + +#if defined(__llvm__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wuninitialized" +#endif // __llvm__ PROTOBUF_NAMESPACE_OPEN constexpr Any::Any( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , _any_metadata_(&type_url_, &value_){} struct AnyDefaultTypeInternal { constexpr AnyDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~AnyDefaultTypeInternal() {} union { Any _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT AnyDefaultTypeInternal _Any_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 AnyDefaultTypeInternal _Any_default_instance_; PROTOBUF_NAMESPACE_CLOSE -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; +static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1]; +static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; +static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; const uint32_t TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ @@ -46,12 +54,12 @@ const uint32_t TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] PROTOBUF_S PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, type_url_), PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, value_), }; -static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Any)}, }; -static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Any_default_instance_), +static const ::_pb::Message* const file_default_instances[] = { + &::PROTOBUF_NAMESPACE_ID::_Any_default_instance_._instance, }; const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -62,19 +70,21 @@ const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_ "anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownT" "ypesb\006proto3" ; -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = { - false, false, 212, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", - &descriptor_table_google_2fprotobuf_2fany_2eproto_once, nullptr, 0, 1, - schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets, - file_level_metadata_google_2fprotobuf_2fany_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto, +static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once; +const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = { + false, false, 212, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, + "google/protobuf/any.proto", + &descriptor_table_google_2fprotobuf_2fany_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fany_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, + file_level_service_descriptors_google_2fprotobuf_2fany_2eproto, }; -PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() { +PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fany_2eproto; } // Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -83,14 +93,13 @@ bool Any::GetAnyFieldDescriptors( const ::PROTOBUF_NAMESPACE_ID::Message& message, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field) { - return ::PROTOBUF_NAMESPACE_ID::internal::GetAnyFieldDescriptors( + return ::_pbi::GetAnyFieldDescriptors( message, type_url_field, value_field); } 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); + return ::_pbi::ParseAnyTypeUrl(type_url, full_type_name); } class Any::_Internal { @@ -102,16 +111,13 @@ Any::Any(::PROTOBUF_NAMESPACE_ID::Arena* arena, : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), _any_metadata_(&type_url_, &value_) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.Any) } Any::Any(const Any& from) : ::PROTOBUF_NAMESPACE_ID::Message(), _any_metadata_(&type_url_, &value_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -119,7 +125,7 @@ Any::Any(const Any& from) type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), GetArenaForAllocation()); } - value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + value_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -131,11 +137,11 @@ Any::Any(const Any& from) } inline void Any::SharedCtor() { -type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +value_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -143,9 +149,11 @@ value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlread Any::~Any() { // @@protoc_insertion_point(destructor:google.protobuf.Any) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Any::SharedDtor() { @@ -154,12 +162,6 @@ inline void Any::SharedDtor() { 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); } @@ -175,19 +177,19 @@ void Any::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Any::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string type_url = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_type_url(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Any.type_url")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Any.type_url")); } else goto handle_unusual; continue; @@ -195,7 +197,7 @@ const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_value(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); } else goto handle_unusual; @@ -246,7 +248,7 @@ uint8_t* Any::_InternalSerialize( } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -335,7 +337,7 @@ void Any::InternalSwap(Any* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fany_2eproto_getter, &descriptor_table_google_2fprotobuf_2fany_2eproto_once, file_level_metadata_google_2fprotobuf_2fany_2eproto[0]); } @@ -343,10 +345,14 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const { // @@protoc_insertion_point(namespace_scope) PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Any* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Any >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Any* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Any >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Any >(arena); } PROTOBUF_NAMESPACE_CLOSE // @@protoc_insertion_point(global_scope) +#if defined(__llvm__) + #pragma clang diagnostic pop +#endif // __llvm__ #include diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 60308ffbaf61c..034b7e1692efd 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -42,14 +41,6 @@ PROTOBUF_NAMESPACE_CLOSE // Internal implementation detail -- do not use these members. 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::AuxiliaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; static const uint32_t offsets[]; }; PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto; @@ -205,9 +196,6 @@ class PROTOBUF_EXPORT Any final : protected: explicit Any(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -319,7 +307,7 @@ inline void Any::set_allocated_type_url(std::string* type_url) { type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (type_url_.IsDefault()) { type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -370,7 +358,7 @@ inline void Any::set_allocated_value(std::string* value) { value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (value_.IsDefault()) { value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index a98559da140ca..d66a485655613 100644 --- a/src/google/protobuf/any_lite.cc +++ b/src/google/protobuf/any_lite.cc @@ -28,12 +28,11 @@ // (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 namespace google { namespace protobuf { diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 72cc72e03c023..604a231a092c2 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -16,9 +16,13 @@ #include PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + PROTOBUF_NAMESPACE_OPEN constexpr Api::Api( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : methods_() , options_() , mixins_() @@ -29,15 +33,15 @@ constexpr Api::Api( {} struct ApiDefaultTypeInternal { constexpr ApiDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~ApiDefaultTypeInternal() {} union { Api _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ApiDefaultTypeInternal _Api_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ApiDefaultTypeInternal _Api_default_instance_; constexpr Method::Method( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : options_() , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , request_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) @@ -48,30 +52,30 @@ constexpr Method::Method( {} struct MethodDefaultTypeInternal { constexpr MethodDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~MethodDefaultTypeInternal() {} union { Method _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodDefaultTypeInternal _Method_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDefaultTypeInternal _Method_default_instance_; constexpr Mixin::Mixin( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , root_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} struct MixinDefaultTypeInternal { constexpr MixinDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~MixinDefaultTypeInternal() {} union { Mixin _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MixinDefaultTypeInternal _Mixin_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MixinDefaultTypeInternal _Mixin_default_instance_; PROTOBUF_NAMESPACE_CLOSE -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; +static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3]; +static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; +static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; const uint32_t TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ @@ -109,16 +113,16 @@ const uint32_t TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] PROTOBUF_S PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, name_), PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, root_), }; -static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Api)}, { 13, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Method)}, { 26, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Mixin)}, }; -static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Api_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Method_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_), +static const ::_pb::Message* const file_default_instances[] = { + &::PROTOBUF_NAMESPACE_ID::_Api_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::_Method_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_._instance, }; const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -142,23 +146,25 @@ const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_ "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] = { +static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = { &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, &::descriptor_table_google_2fprotobuf_2ftype_2eproto, }; -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = { - false, false, 751, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", - &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 2, 3, - schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets, - file_level_metadata_google_2fprotobuf_2fapi_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto, +static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once; +const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = { + false, false, 751, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, + "google/protobuf/api.proto", + &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 2, 3, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fapi_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, + file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto, }; -PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() { +PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fapi_2eproto; } // Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -188,9 +194,6 @@ Api::Api(::PROTOBUF_NAMESPACE_ID::Arena* arena, options_(arena), mixins_(arena) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.Api) } Api::Api(const Api& from) @@ -199,7 +202,7 @@ Api::Api(const Api& from) options_(from.options_), mixins_(from.mixins_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -207,7 +210,7 @@ Api::Api(const Api& from) name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArenaForAllocation()); } - version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + version_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -225,11 +228,11 @@ Api::Api(const Api& from) } inline void Api::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +version_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -241,9 +244,11 @@ ::memset(reinterpret_cast(this) + static_cast( Api::~Api() { // @@protoc_insertion_point(destructor:google.protobuf.Api) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Api::SharedDtor() { @@ -253,12 +258,6 @@ inline void Api::SharedDtor() { 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); } @@ -282,19 +281,19 @@ void Api::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Api::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.name")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Api.name")); } else goto handle_unusual; continue; @@ -328,9 +327,9 @@ const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern case 4: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { auto str = _internal_mutable_version(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.version")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Api.version")); } else goto handle_unusual; continue; @@ -404,19 +403,19 @@ uint8_t* Api::_InternalSerialize( } // repeated .google.protobuf.Method methods = 2; - for (unsigned int i = 0, - n = static_cast(this->_internal_methods_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_methods_size()); i < n; i++) { + const auto& repfield = this->_internal_methods(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(2, this->_internal_methods(i), target, stream); + InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream); } // repeated .google.protobuf.Option options = 3; - for (unsigned int i = 0, - n = static_cast(this->_internal_options_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_options_size()); i < n; i++) { + const auto& repfield = this->_internal_options(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(3, this->_internal_options(i), target, stream); + InternalWriteMessage(3, repfield, repfield.GetCachedSize(), target, stream); } // string version = 4; @@ -431,29 +430,28 @@ uint8_t* Api::_InternalSerialize( // .google.protobuf.SourceContext source_context = 5; if (this->_internal_has_source_context()) { - target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage( - 5, _Internal::source_context(this), target, stream); + InternalWriteMessage(5, _Internal::source_context(this), + _Internal::source_context(this).GetCachedSize(), target, stream); } // repeated .google.protobuf.Mixin mixins = 6; - for (unsigned int i = 0, - n = static_cast(this->_internal_mixins_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_mixins_size()); i < n; i++) { + const auto& repfield = this->_internal_mixins(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(6, this->_internal_mixins(i), target, stream); + InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream); } // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + target = ::_pbi::WireFormatLite::WriteEnumToArray( 7, this->_internal_syntax(), target); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -513,7 +511,7 @@ size_t Api::ByteSizeLong() const { // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax()); } return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); @@ -594,7 +592,7 @@ void Api::InternalSwap(Api* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]); } @@ -613,16 +611,13 @@ Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena, : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), options_(arena) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.Method) } Method::Method(const Method& from) : ::PROTOBUF_NAMESPACE_ID::Message(), options_(from.options_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -630,7 +625,7 @@ Method::Method(const Method& from) name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArenaForAllocation()); } - request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + request_type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -638,7 +633,7 @@ Method::Method(const Method& from) request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_request_type_url(), GetArenaForAllocation()); } - response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + response_type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -653,15 +648,15 @@ Method::Method(const Method& from) } inline void Method::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +request_type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +response_type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -673,9 +668,11 @@ ::memset(reinterpret_cast(this) + static_cast( Method::~Method() { // @@protoc_insertion_point(destructor:google.protobuf.Method) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Method::SharedDtor() { @@ -685,12 +682,6 @@ inline void Method::SharedDtor() { 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); } @@ -711,19 +702,19 @@ void Method::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Method::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.name")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.name")); } else goto handle_unusual; continue; @@ -731,9 +722,9 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_request_type_url(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.request_type_url")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.request_type_url")); } else goto handle_unusual; continue; @@ -749,9 +740,9 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int case 4: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { auto str = _internal_mutable_response_type_url(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.response_type_url")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.response_type_url")); } else goto handle_unusual; continue; @@ -837,7 +828,7 @@ uint8_t* Method::_InternalSerialize( // bool request_streaming = 3; if (this->_internal_request_streaming() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_request_streaming(), target); + target = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_request_streaming(), target); } // string response_type_url = 4; @@ -853,26 +844,26 @@ uint8_t* Method::_InternalSerialize( // bool response_streaming = 5; if (this->_internal_response_streaming() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target); + target = ::_pbi::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target); } // repeated .google.protobuf.Option options = 6; - for (unsigned int i = 0, - n = static_cast(this->_internal_options_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_options_size()); i < n; i++) { + const auto& repfield = this->_internal_options(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(6, this->_internal_options(i), target, stream); + InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream); } // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + target = ::_pbi::WireFormatLite::WriteEnumToArray( 7, this->_internal_syntax(), target); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -928,7 +919,7 @@ size_t Method::ByteSizeLong() const { // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax()); } return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); @@ -1016,7 +1007,7 @@ void Method::InternalSwap(Method* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]); } @@ -1031,15 +1022,12 @@ Mixin::Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin) } Mixin::Mixin(const Mixin& from) : ::PROTOBUF_NAMESPACE_ID::Message() { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1047,7 +1035,7 @@ Mixin::Mixin(const Mixin& from) name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArenaForAllocation()); } - root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + root_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1059,11 +1047,11 @@ Mixin::Mixin(const Mixin& from) } inline void Mixin::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +root_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1071,9 +1059,11 @@ root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlready Mixin::~Mixin() { // @@protoc_insertion_point(destructor:google.protobuf.Mixin) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Mixin::SharedDtor() { @@ -1082,12 +1072,6 @@ inline void Mixin::SharedDtor() { 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); } @@ -1103,19 +1087,19 @@ void Mixin::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Mixin::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.name")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Mixin.name")); } else goto handle_unusual; continue; @@ -1123,9 +1107,9 @@ const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_root(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.root")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Mixin.root")); } else goto handle_unusual; continue; @@ -1179,7 +1163,7 @@ uint8_t* Mixin::_InternalSerialize( } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -1268,7 +1252,7 @@ void Mixin::InternalSwap(Mixin* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]); } @@ -1276,13 +1260,16 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const { // @@protoc_insertion_point(namespace_scope) PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Api* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Api >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Api* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Api >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Api >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Method* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Method >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Method* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Method >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Method >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Mixin* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Mixin >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Mixin* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Mixin >(Arena* 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 e614f07a32724..fd834c7e13614 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -44,14 +43,6 @@ PROTOBUF_NAMESPACE_CLOSE // Internal implementation detail -- do not use these members. 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::AuxiliaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[3] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; static const uint32_t offsets[]; }; PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto; @@ -182,9 +173,6 @@ class PROTOBUF_EXPORT Api final : protected: explicit Api(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -440,9 +428,6 @@ class PROTOBUF_EXPORT Method final : protected: explicit Method(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -676,9 +661,6 @@ class PROTOBUF_EXPORT Mixin final : protected: explicit Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -789,7 +771,7 @@ inline void Api::set_allocated_name(std::string* name) { name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (name_.IsDefault()) { name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -917,7 +899,7 @@ inline void Api::set_allocated_version(std::string* version) { version_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (version_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (version_.IsDefault()) { version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1118,7 +1100,7 @@ inline void Method::set_allocated_name(std::string* name) { name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (name_.IsDefault()) { name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1169,7 +1151,7 @@ inline void Method::set_allocated_request_type_url(std::string* request_type_url request_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), request_type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (request_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (request_type_url_.IsDefault()) { request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1240,7 +1222,7 @@ inline void Method::set_allocated_response_type_url(std::string* response_type_u response_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), response_type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (response_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (response_type_url_.IsDefault()) { response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1372,7 +1354,7 @@ inline void Mixin::set_allocated_name(std::string* name) { name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (name_.IsDefault()) { name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1423,7 +1405,7 @@ inline void Mixin::set_allocated_root(std::string* root) { root_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), root, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (root_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (root_.IsDefault()) { root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 7624e0b2f3fa9..6ba508a5f0f34 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -38,12 +38,15 @@ #include #include +#include +#include #include #ifdef ADDRESS_SANITIZER #include #endif // ADDRESS_SANITIZER +// Must be included last. #include namespace google { @@ -91,11 +94,7 @@ class GetDeallocator { 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 + internal::SizedDelete(mem.ptr, mem.size); } *space_allocated_ += mem.size; } @@ -105,18 +104,22 @@ class GetDeallocator { size_t* space_allocated_; }; -SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size) { +SerialArena::SerialArena(Block* b, void* owner, ThreadSafeArenaStats* stats) + : space_allocated_(b->size) { owner_ = owner; head_ = b; ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize); limit_ = b->Pointer(b->size & static_cast(-8)); + arena_stats_ = stats; } -SerialArena* SerialArena::New(Memory mem, void* owner) { +SerialArena* SerialArena::New(Memory mem, void* owner, + ThreadSafeArenaStats* stats) { GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size); - + ThreadSafeArenaStats::RecordAllocateStats( + stats, /*requested=*/mem.size, /*allocated=*/mem.size, /*wasted=*/0); auto b = new (mem.ptr) Block{nullptr, mem.size}; - return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner); + return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner, stats); } template @@ -151,7 +154,14 @@ void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { head_->start = reinterpret_cast(limit_); // Record how much used in this block. - space_used_ += ptr_ - head_->Pointer(kBlockHeaderSize); + size_t used = ptr_ - head_->Pointer(kBlockHeaderSize); + size_t wasted = head_->size - used; + space_used_ += used; + + // TODO(sbenza): Evaluate if pushing unused space into the cached blocks is a + // win. In preliminary testing showed increased memory savings as expected, + // but with a CPU regression. The regression might have been an artifact of + // the microbenchmark. auto mem = AllocateMemory(policy, head_->size, n); // We don't want to emit an expensive RMW instruction that requires @@ -159,6 +169,8 @@ void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { // regular add. auto relaxed = std::memory_order_relaxed; space_allocated_.store(space_allocated_.load(relaxed) + mem.size, relaxed); + ThreadSafeArenaStats::RecordAllocateStats(arena_stats_, /*requested=*/n, + /*allocated=*/mem.size, wasted); head_ = new (mem.ptr) Block{head_, mem.size}; ptr_ = head_->Pointer(kBlockHeaderSize); limit_ = head_->Pointer(head_->size); @@ -312,10 +324,12 @@ void ThreadSafeArena::Init() { #ifndef NDEBUG GOOGLE_CHECK_EQ(was_message_owned, IsMessageOwned()); #endif // NDEBUG + arena_stats_ = Sample(); } void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) { - SerialArena* serial = SerialArena::New({mem, size}, &thread_cache()); + SerialArena* serial = SerialArena::New({mem, size}, &thread_cache(), + arena_stats_.MutableStats()); serial->set_next(NULL); threads_.store(serial, std::memory_order_relaxed); CacheSerialArena(serial); @@ -334,6 +348,10 @@ ThreadSafeArena::~ThreadSafeArena() { ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr; if (alloc_policy_.is_user_owned_initial_block()) { +#ifdef ADDRESS_SANITIZER + // Unpoison the initial block, now that it's going back to the user. + ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size); +#endif // ADDRESS_SANITIZER space_allocated += mem.size; } else { GetDeallocator(alloc_policy_.get(), &space_allocated)(mem); @@ -360,6 +378,7 @@ uint64_t ThreadSafeArena::Reset() { // Discard all blocks except the special block (if present). size_t space_allocated = 0; auto mem = Free(&space_allocated); + arena_stats_.RecordReset(); AllocationPolicy* policy = alloc_policy_.get(); if (policy) { @@ -474,7 +493,8 @@ SerialArena* ThreadSafeArena::GetSerialArenaFallback(void* me) { // 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. serial = SerialArena::New( - AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me); + AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me, + arena_stats_.MutableStats()); SerialArena* head = threads_.load(std::memory_order_relaxed); do { @@ -499,6 +519,12 @@ void* Arena::AllocateAlignedWithHook(size_t n, const std::type_info* type) { return impl_.AllocateAligned(n, type); } +PROTOBUF_FUNC_ALIGN(32) +void* Arena::AllocateAlignedWithHookForArray(size_t n, + const std::type_info* type) { + return impl_.AllocateAligned(n, type); +} + PROTOBUF_FUNC_ALIGN(32) std::pair Arena::AllocateAlignedWithCleanup(size_t n, const std::type_info* type) { diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 6dd6467f58bbf..2b93a4104f31b 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -55,6 +55,7 @@ using type_info = ::type_info; #include #include +// Must be included last. #include #ifdef SWIG @@ -83,10 +84,11 @@ class ReflectionTester; // defined in test_util.h namespace internal { -struct ArenaStringPtr; // defined in arenastring.h -class InlinedStringField; // defined in inlined_string_field.h -class LazyField; // defined in lazy_field.h -class EpsCopyInputStream; // defined in parse_context.h +struct ArenaTestPeer; // defined in arena_test_util.h +class InternalMetadata; // defined in metadata_lite.h +class LazyField; // defined in lazy_field.h +class EpsCopyInputStream; // defined in parse_context.h +class RepeatedPtrFieldBase; // defined in repeated_ptr_field.h template class GenericTypeHandler; // defined in repeated_field.h @@ -316,6 +318,20 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { static_cast(args)...); } + // Allocates memory with the specific size and alignment. + void* AllocateAligned(size_t size, size_t align = 8) { + if (align <= 8) { + return AllocateAlignedNoHook(internal::AlignUpTo8(size)); + } 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(size + align - 8), align); + } + } + // Create an array of object type T on the arena *without* invoking the // constructor of T. If `arena` is null, then the return value should be freed // with `delete[] x;` (or `::operator delete[](x);`). @@ -532,6 +548,10 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { return impl_.IsMessageOwned(); } + void ReturnArrayMemory(void* p, size_t size) { + impl_.ReturnArrayMemory(p, size); + } + template PROTOBUF_NDEBUG_INLINE static T* CreateMessageInternal(Arena* arena, Args&&... args) { @@ -622,7 +642,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // 8 AlignUpTo can be elided. const size_t n = sizeof(T) * num_elements; return static_cast( - AllocateAlignedWithHook(n, alignof(T), RTTI_TYPE_ID(T))); + AllocateAlignedWithHookForArray(n, alignof(T), RTTI_TYPE_ID(T))); } template @@ -765,17 +785,18 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { return nullptr; } - // For friends of arena. - void* AllocateAligned(size_t n, size_t align = 8) { + void* AllocateAlignedWithHookForArray(size_t n, size_t align, + const std::type_info* type) { if (align <= 8) { - return AllocateAlignedNoHook(internal::AlignUpTo8(n)); + return AllocateAlignedWithHookForArray(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 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); + return internal::AlignTo( + AllocateAlignedWithHookForArray(n + align - 8, type), align); } } @@ -786,7 +807,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { } 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 + // 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(AllocateAlignedWithHook(n + align - 8, type), @@ -796,18 +817,22 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { void* AllocateAlignedNoHook(size_t n); void* AllocateAlignedWithHook(size_t n, const std::type_info* type); + void* AllocateAlignedWithHookForArray(size_t n, const std::type_info* type); std::pair AllocateAlignedWithCleanup(size_t n, const std::type_info* type); template friend class internal::GenericTypeHandler; - friend struct internal::ArenaStringPtr; // For AllocateAligned. - friend class internal::InlinedStringField; // For AllocateAligned. + friend class internal::InternalMetadata; // For user_arena(). friend class internal::LazyField; // For CreateMaybeMessage. friend class internal::EpsCopyInputStream; // For parser performance friend class MessageLite; template friend class Map; + template + friend class RepeatedField; // For ReturnArrayMemory + friend class internal::RepeatedPtrFieldBase; // For ReturnArrayMemory + friend struct internal::ArenaTestPeer; }; // Defined above for supporting environments without RTTI. diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index 2ffac319b4110..d02ad93985ed5 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -39,11 +39,15 @@ #include #include +#include #ifdef ADDRESS_SANITIZER #include #endif // ADDRESS_SANITIZER +#include + +// Must be included last. #include @@ -177,6 +181,8 @@ class TaggedAllocationPolicyPtr { uintptr_t policy_; }; +enum class AllocationClient { kDefault, kArray }; + // 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 @@ -208,11 +214,47 @@ class PROTOBUF_EXPORT SerialArena { } uint64_t SpaceUsed() const; - bool HasSpace(size_t n) { return n <= static_cast(limit_ - ptr_); } + bool HasSpace(size_t n) const { + return n <= static_cast(limit_ - ptr_); + } + + // See comments on `cached_blocks_` member for details. + PROTOBUF_ALWAYS_INLINE void* TryAllocateFromCachedBlock(size_t size) { + if (PROTOBUF_PREDICT_FALSE(size < 16)) return nullptr; + // We round up to the next larger block in case the memory doesn't match + // the pattern we are looking for. + const size_t index = Bits::Log2FloorNonZero64(size - 1) - 3; + + if (index >= cached_block_length_) return nullptr; + auto& cached_head = cached_blocks_[index]; + if (cached_head == nullptr) return nullptr; + + void* ret = cached_head; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, size); +#endif // ADDRESS_SANITIZER + cached_head = cached_head->next; + return ret; + } + // In kArray mode we look through cached blocks. + // We do not do this by default because most non-array allocations will not + // have the right size and will fail to find an appropriate cached block. + // + // TODO(sbenza): Evaluate if we should use cached blocks for message types of + // the right size. We can statically know if the allocation size can benefit + // from it. + template 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 (alloc_client == AllocationClient::kArray) { + if (void* res = TryAllocateFromCachedBlock(n)) { + return res; + } + } + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { return AllocateAlignedFallback(n, policy); } @@ -229,6 +271,50 @@ class PROTOBUF_EXPORT SerialArena { return ret; } + // See comments on `cached_blocks_` member for details. + void ReturnArrayMemory(void* p, size_t size) { + // We only need to check for 32-bit platforms. + // In 64-bit platforms the minimum allocation size from Repeated*Field will + // be 16 guaranteed. + if (sizeof(void*) < 8) { + if (PROTOBUF_PREDICT_FALSE(size < 16)) return; + } else { + GOOGLE_DCHECK(size >= 16); + } + + // We round down to the next smaller block in case the memory doesn't match + // the pattern we are looking for. eg, someone might have called Reserve() + // on the repeated field. + const size_t index = Bits::Log2FloorNonZero64(size) - 4; + + if (PROTOBUF_PREDICT_FALSE(index >= cached_block_length_)) { + // We can't put this object on the freelist so make this object the + // freelist. It is guaranteed it is larger than the one we have, and + // large enough to hold another allocation of `size`. + CachedBlock** new_list = static_cast(p); + size_t new_size = size / sizeof(CachedBlock*); + + std::copy(cached_blocks_, cached_blocks_ + cached_block_length_, + new_list); + std::fill(new_list + cached_block_length_, new_list + new_size, nullptr); + cached_blocks_ = new_list; + // Make the size fit in uint8_t. This is the power of two, so we don't + // need anything larger. + cached_block_length_ = + static_cast(std::min(size_t{64}, new_size)); + + return; + } + + auto& cached_head = cached_blocks_[index]; + auto* new_node = static_cast(p); + new_node->next = cached_head; + cached_head = new_node; +#ifdef ADDRESS_SANITIZER + ASAN_POISON_MEMORY_REGION(p, size); +#endif // ADDRESS_SANITIZER + } + public: // Allocate space if the current region provides enough space. bool MaybeAllocateAligned(size_t n, void** out) { @@ -279,7 +365,8 @@ class PROTOBUF_EXPORT SerialArena { // Creates a new SerialArena inside mem using the remaining memory as for // future allocations. - static SerialArena* New(SerialArena::Memory mem, void* owner); + static SerialArena* New(SerialArena::Memory mem, void* owner, + ThreadSafeArenaStats* stats); // Free SerialArena returning the memory passed in to New template Memory Free(Deallocator deallocator); @@ -310,10 +397,28 @@ class PROTOBUF_EXPORT SerialArena { // head_ (and head_->pos will always be non-canonical). We keep these // here to reduce indirection. char* ptr_; + // Limiting address up to which memory can be allocated from the head block. char* limit_; + // For holding sampling information. The pointer is owned by the + // ThreadSafeArena that holds this serial arena. + ThreadSafeArenaStats* arena_stats_; + + // Repeated*Field and Arena play together to reduce memory consumption by + // reusing blocks. Currently, natural growth of the repeated field types makes + // them allocate blocks of size `8 + 2^N, N>=3`. + // When the repeated field grows returns the previous block and we put it in + // this free list. + // `cached_blocks_[i]` points to the free list for blocks of size `8+2^(i+3)`. + // The array of freelists is grown when needed in `ReturnArrayMemory()`. + struct CachedBlock { + // Simple linked list. + CachedBlock* next; + }; + uint8_t cached_block_length_ = 0; + CachedBlock** cached_blocks_ = nullptr; // Constructor is private as only New() should be used. - inline SerialArena(Block* b, void* owner); + inline SerialArena(Block* b, void* owner, ThreadSafeArenaStats* stats); void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy); std::pair AllocateAlignedWithCleanupFallback( size_t n, const AllocationPolicy* policy); @@ -368,16 +473,24 @@ class PROTOBUF_EXPORT ThreadSafeArena { uint64_t SpaceAllocated() const; uint64_t SpaceUsed() const; + template void* AllocateAligned(size_t n, const std::type_info* type) { SerialArena* arena; if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() && GetSerialArenaFast(&arena))) { - return arena->AllocateAligned(n, AllocPolicy()); + return arena->AllocateAligned(n, AllocPolicy()); } else { return AllocateAlignedFallback(n, type); } } + void ReturnArrayMemory(void* p, size_t size) { + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { + arena->ReturnArrayMemory(p, size); + } + } + // This function allocates n bytes if the common happy case is true and // returns true. Otherwise does nothing and returns false. This strange // semantics is necessary to allow callers to program functions that only @@ -411,6 +524,8 @@ class PROTOBUF_EXPORT ThreadSafeArena { TaggedAllocationPolicyPtr alloc_policy_; // Tagged pointer to AllocPolicy. + static_assert(std::is_trivially_destructible{}, + "SerialArena needs to be trivially destructible."); // Pointer to a linked list of SerialArena. std::atomic threads_; std::atomic hint_; // Fast thread-local block access @@ -535,6 +650,8 @@ class PROTOBUF_EXPORT ThreadSafeArena { static ThreadCache& thread_cache() { return thread_cache_; } #endif + ThreadSafeArenaStatsHandle arena_stats_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadSafeArena); // All protos have pointers back to the arena hence Arena must have // pointer stability. diff --git a/src/google/protobuf/arena_test_util.h b/src/google/protobuf/arena_test_util.h index 33f5cf4192937..728676905c6aa 100644 --- a/src/google/protobuf/arena_test_util.h +++ b/src/google/protobuf/arena_test_util.h @@ -76,6 +76,12 @@ void TestParseCorruptedString(const T& message) { namespace internal { +struct ArenaTestPeer { + static void ReturnArrayMemory(Arena* arena, void* p, size_t size) { + arena->ReturnArrayMemory(p, size); + } +}; + class NoHeapChecker { public: NoHeapChecker() { capture_alloc.Hook(); } diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 76d9126ac3900..0a38352b97dd6 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -47,6 +47,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -54,14 +57,13 @@ #include #include #include -#include -#include // Must be included last #include using proto2_arena_unittest::ArenaMessage; +using protobuf_unittest::ForeignMessage; using protobuf_unittest::TestAllExtensions; using protobuf_unittest::TestAllTypes; using protobuf_unittest::TestEmptyMessage; @@ -542,6 +544,18 @@ TEST(ArenaTest, UnsafeArenaSwap) { TestUtil::ExpectAllFieldsSet(*message2); } +TEST(ArenaTest, GetOwningArena) { + Arena arena; + auto* m1 = Arena::CreateMessage(&arena); + EXPECT_EQ(Arena::InternalHelper::GetOwningArena(m1), &arena); + EXPECT_EQ( + &arena, + Arena::InternalHelper>::GetOwningArena( + m1->mutable_repeated_foreign_message())); + EXPECT_EQ(&arena, Arena::InternalHelper>::GetOwningArena( + m1->mutable_repeated_int32())); +} + TEST(ArenaTest, SwapBetweenArenasUsingReflection) { Arena arena1; TestAllTypes* arena1_message = Arena::CreateMessage(&arena1); @@ -1465,6 +1479,71 @@ TEST(ArenaTest, AddCleanup) { } } +TEST(ArenaTest, SpaceReuseForArraysSizeChecks) { + // Limit to 1<<20 to avoid using too much memory on the test. + for (int i = 0; i < 20; ++i) { + SCOPED_TRACE(i); + Arena arena; + std::vector pointers; + + const size_t size = 16 << i; + + for (int j = 0; j < 10; ++j) { + pointers.push_back(Arena::CreateArray(&arena, size)); + } + + for (void* p : pointers) { + internal::ArenaTestPeer::ReturnArrayMemory(&arena, p, size); + } + + std::vector second_pointers; + for (int j = 9; j != 0; --j) { + second_pointers.push_back(Arena::CreateArray(&arena, size)); + } + + // The arena will give us back the pointers we returned, except the first + // one. That one becomes part of the freelist data structure. + ASSERT_THAT(second_pointers, + testing::UnorderedElementsAreArray( + std::vector(pointers.begin() + 1, pointers.end()))); + } +} + +TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) { +#ifdef ADDRESS_SANITIZER + char buf[1024]{}; + { + Arena arena(buf, sizeof(buf)); + std::vector pointers; + for (int i = 0; i < 100; ++i) { + pointers.push_back(Arena::CreateArray(&arena, 16)); + } + for (void* p : pointers) { + internal::ArenaTestPeer::ReturnArrayMemory(&arena, p, 16); + // The first one is not poisoned because it becomes the freelist. + if (p != pointers[0]) EXPECT_TRUE(__asan_address_is_poisoned(p)); + } + + bool found_poison = false; + for (char& c : buf) { + if (__asan_address_is_poisoned(&c)) { + found_poison = true; + break; + } + } + EXPECT_TRUE(found_poison); + } + + // Should not be poisoned after destruction. + for (char& c : buf) { + ASSERT_FALSE(__asan_address_is_poisoned(&c)); + } + +#else // ADDRESS_SANITIZER + GTEST_SKIP(); +#endif // ADDRESS_SANITIZER +} + namespace { uint32_t hooks_num_init = 0; uint32_t hooks_num_allocations = 0; diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc index 169f52729d616..4c19c919cdda8 100644 --- a/src/google/protobuf/arenastring.cc +++ b/src/google/protobuf/arenastring.cc @@ -32,11 +32,11 @@ #include #include -#include #include -#include #include #include +#include +#include #include // clang-format off @@ -47,6 +47,25 @@ namespace google { namespace protobuf { namespace internal { +namespace { + +// Enforce that allocated data aligns to at least 8 bytes, and that +// the alignment of the global const string value does as well. +// The alignment guaranteed by `new std::string` depends on both: +// - new align = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / max_align_t +// - alignof(std::string) +#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ +constexpr size_t kNewAlign = __STDCPP_DEFAULT_NEW_ALIGNMENT__; +#else +constexpr size_t kNewAlign = alignof(std::max_align_t); +#endif +constexpr size_t kStringAlign = alignof(std::string); + +static_assert((kStringAlign > kNewAlign ? kStringAlign : kNewAlign) >= 8, ""); +static_assert(alignof(ExplicitlyConstructedArenaString) >= 8, ""); + +} // namespace + const std::string& LazyString::Init() const { static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED}; mu.Lock(); @@ -61,38 +80,61 @@ const std::string& LazyString::Init() const { return *res; } +namespace { + + +// Creates a heap allocated std::string value. +inline TaggedPtr CreateString(ConstStringParam value) { + TaggedPtr res; + res.SetAllocated(new std::string(value.data(), value.length())); + return res; +} + +#if !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL + +// Creates an arena allocated std::string value. +TaggedPtr CreateArenaString(Arena& arena, ConstStringParam s) { + TaggedPtr res; + res.SetMutableArena(Arena::Create(&arena, s.data(), s.length())); + return res; +} + +#endif // !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL + +} // namespace std::string* ArenaStringPtr::SetAndReturnNewString() { std::string* new_string = new std::string(); - tagged_ptr_.Set(new_string); + tagged_ptr_.SetAllocated(new_string); return new_string; } -void ArenaStringPtr::DestroyNoArenaSlowPath() { delete UnsafeMutablePointer(); } +void ArenaStringPtr::DestroyNoArenaSlowPath() { + GOOGLE_DCHECK(tagged_ptr_.IsAllocated()); + delete UnsafeMutablePointer(); +} -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)); +void ArenaStringPtr::Set(const std::string*, ConstStringParam value, + ::google::protobuf::Arena* arena) { + if (IsDefault()) { + // If we're not on an arena, skip straight to a true string to avoid + // possible copy cost later. + tagged_ptr_ = arena != nullptr ? CreateArenaString(*arena, value) + : CreateString(value); } else { UnsafeMutablePointer()->assign(value.data(), value.length()); } } - -void ArenaStringPtr::Set(const std::string* default_value, std::string&& value, +void ArenaStringPtr::Set(const std::string*, 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()) { + if (IsDefault()) { + NewString(arena, std::move(value)); + } else if (IsFixedSizeArena()) { std::string* current = tagged_ptr_.Get(); auto* s = new (current) std::string(std::move(value)); arena->OwnDestructor(s); - tagged_ptr_.Set(s); - } else /* !IsDonatedString() */ { + tagged_ptr_.SetMutableArena(s); + } else /* !IsFixedSizeArena() */ { *UnsafeMutablePointer() = std::move(value); } } @@ -118,7 +160,7 @@ void ArenaStringPtr::Set(NonEmptyDefault, std::string&& value, } std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) { + if (!IsFixedSizeArena() && !IsDefault()) { return UnsafeMutablePointer(); } else { return MutableSlow(arena); @@ -127,41 +169,34 @@ std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* ar std::string* ArenaStringPtr::Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(nullptr)) { + if (!IsFixedSizeArena() && !IsDefault()) { return UnsafeMutablePointer(); } else { return MutableSlow(arena, default_value); } } -std::string* ArenaStringPtr::MutableNoCopy(const std::string* default_value, +std::string* ArenaStringPtr::MutableNoCopy(const std::string*, ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(default_value)) { + if (!IsFixedSizeArena() && !IsDefault()) { return UnsafeMutablePointer(); } else { - GOOGLE_DCHECK(IsDefault(default_value)); + GOOGLE_DCHECK(IsDefault()); // Allocate empty. The contents are not relevant. - std::string* new_string = Arena::Create(arena); - tagged_ptr_.Set(new_string); - return new_string; + return NewString(arena); } } 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; + GOOGLE_DCHECK(IsDefault()); + return NewString(arena, lazy_default.get()...); } std::string* ArenaStringPtr::Release(const std::string* default_value, ::google::protobuf::Arena* arena) { - if (IsDefault(default_value)) { + if (IsDefault()) { return nullptr; } else { return ReleaseNonDefault(default_value, arena); @@ -170,9 +205,9 @@ std::string* ArenaStringPtr::Release(const std::string* default_value, std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value, ::google::protobuf::Arena* arena) { - GOOGLE_DCHECK(!IsDefault(default_value)); + GOOGLE_DCHECK(!IsDefault()); - if (!IsDonatedString()) { + if (!IsFixedSizeArena()) { std::string* released; if (arena != nullptr) { released = new std::string; @@ -180,12 +215,12 @@ std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value, } else { released = UnsafeMutablePointer(); } - tagged_ptr_.Set(const_cast(default_value)); + tagged_ptr_.SetDefault(default_value); return released; - } else /* IsDonatedString() */ { + } else /* IsFixedSizeArena() */ { GOOGLE_DCHECK(arena != nullptr); std::string* released = new std::string(Get()); - tagged_ptr_.Set(const_cast(default_value)); + tagged_ptr_.SetDefault(default_value); return released; } } @@ -193,33 +228,28 @@ std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value, 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)) { + if (arena == nullptr && !IsDefault()) { delete UnsafeMutablePointer(); } if (value == nullptr) { - tagged_ptr_.Set(const_cast(default_value)); + tagged_ptr_.SetDefault(default_value); } else { -#ifdef NDEBUG - tagged_ptr_.Set(value); - if (arena != nullptr) { - arena->Own(value); - } -#else +#ifndef NDEBUG // 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); + std::string* new_value = new std::string(std::move(*value)); delete value; - tagged_ptr_.Set(new_value); -#endif + value = new_value; +#endif // !NDEBUG + InitAllocated(value, arena); } } -void ArenaStringPtr::Destroy(const std::string* default_value, - ::google::protobuf::Arena* arena) { +void ArenaStringPtr::Destroy(const std::string*, ::google::protobuf::Arena* arena) { if (arena == nullptr) { - GOOGLE_DCHECK(!IsDonatedString()); - if (!IsDefault(default_value)) { + GOOGLE_DCHECK(!IsFixedSizeArena()); + if (!IsDefault()) { delete UnsafeMutablePointer(); } } @@ -234,12 +264,12 @@ void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) } void ArenaStringPtr::ClearToEmpty() { - if (IsDefault(&GetEmptyStringAlreadyInited())) { + if (IsDefault()) { // Already set to default -- do nothing. } else { // Unconditionally mask away the tag. // - // UpdateDonatedString uses assign when capacity is larger than the new + // UpdateArenaString 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(); @@ -249,19 +279,13 @@ void ArenaStringPtr::ClearToEmpty() { void ArenaStringPtr::ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena) { (void)arena; - if (IsDefault(nullptr)) { + if (IsDefault()) { // Already set to default -- do nothing. - } else if (!IsDonatedString()) { + } else { UnsafeMutablePointer()->assign(default_value.get()); } } -inline void SetStrWithHeapBuffer(std::string* str, ArenaStringPtr* s) { - TaggedPtr res; - res.Set(str); - s->UnsafeSetTaggedPointer(res); -} - const char* EpsCopyInputStream::ReadArenaString(const char* ptr, ArenaStringPtr* s, Arena* arena) { @@ -270,12 +294,9 @@ const char* EpsCopyInputStream::ReadArenaString(const char* ptr, int size = ReadSize(&ptr); if (!ptr) return nullptr; - auto* str = Arena::Create(arena); + auto* str = s->NewString(arena); ptr = ReadString(ptr, size, str); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); - - SetStrWithHeapBuffer(str, s); - return ptr; } diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 38c36378cd30b..9d2eab0e5513e 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ #define GOOGLE_PROTOBUF_ARENASTRING_H__ +#include #include #include #include @@ -39,7 +40,9 @@ #include #include #include +#include +// must be last: #include #ifdef SWIG @@ -50,12 +53,14 @@ namespace google { namespace protobuf { namespace internal { - -template -class ExplicitlyConstructed; +class EpsCopyInputStream; class SwapFieldHelper; +// Declared in message_lite.h +PROTOBUF_EXPORT extern ExplicitlyConstructedArenaString + fixed_address_empty_string; + // Lazy string instance to support string fields with non-empty default. // These are initialized on the first call to .get(). class PROTOBUF_EXPORT LazyString { @@ -92,25 +97,102 @@ class PROTOBUF_EXPORT LazyString { template class TaggedPtr { public: + // Bit flags qualifying string properties. We can use up to 3 bits as + // ptr_ is guaranteed and enforced to be aligned on 8 byte boundaries. + enum Flags { + kArenaBit = 0x1, // ptr is arena allocated + kAllocatedBit = 0x2, // ptr is heap allocated + kMutableBit = 0x4, // ptr contents are fully mutable + kMask = 0x7 // Bit mask + }; + + // Composed logical types + enum Type { + // Default strings are immutable and never owned. + kDefault = 0, + + // Allocated strings are mutable and (as the name implies) owned. + // A heap allocated string must be deleted. + kAllocated = kAllocatedBit | kMutableBit, + + // Mutable arena strings are strings where the string instance is owned + // by the arena, but the string contents itself are owned by the string + // instance. Mutable arena string instances need to be destroyed which is + // typically done through a cleanup action added to the arena owning it. + kMutableArena = kArenaBit | kMutableBit, + + // Fixed size arena strings are strings where both the string instance and + // the string contents are fully owned by the arena. Fixed size arena + // strings are a platform and c++ library specific customization. Fixed + // size arena strings are immutable, with the exception of custom internal + // updates to the content that fit inside the existing capacity. + // Fixed size arena strings must never be deleted or destroyed. + kFixedSizeArena = kArenaBit, + }; + TaggedPtr() = default; - explicit constexpr TaggedPtr(const ExplicitlyConstructed* ptr) - : ptr_(const_cast*>(ptr)) {} + explicit constexpr TaggedPtr(ExplicitlyConstructedArenaString* ptr) + : ptr_(ptr) {} - void SetTagged(T* p) { - Set(p); - ptr_ = reinterpret_cast(as_int() | 1); + // Sets the value to `p`, tagging the value as being a 'default' value. + // See documentation for kDefault for more info. + inline const T* SetDefault(const T* p) { + return TagAs(kDefault, const_cast(p)); } - void Set(T* p) { ptr_ = p; } - T* Get() const { return reinterpret_cast(as_int() & -2); } - bool IsTagged() const { return as_int() & 1; } - // Returned value is only safe to dereference if IsTagged() == false. - // It is safe to compare. - T* UnsafeGet() const { return static_cast(ptr_); } + // Sets the value to `p`, tagging the value as a heap allocated value. + // Allocated strings are mutable and (as the name implies) owned. + // `p` must not be null + inline T* SetAllocated(T* p) { return TagAs(kAllocated, p); } + + // Sets the value to `p`, tagging the value as a fixed size arena string. + // See documentation for kFixedSizeArena for more info. + // `p` must not be null + inline T* SetFixedSizeArena(T* p) { return TagAs(kFixedSizeArena, p); } + + // Sets the value to `p`, tagging the value as a mutable arena string. + // See documentation for kMutableArena for more info. + // `p` must not be null + inline T* SetMutableArena(T* p) { return TagAs(kMutableArena, p); } + + // Returns true if the contents of the current string are fully mutable. + inline bool IsMutable() const { return as_int() & kMutableBit; } - bool IsNull() { return ptr_ == nullptr; } + // Returns true if the current string is an immutable default value. + inline bool IsDefault() const { return (as_int() & kMask) == kDefault; } + + // Returns true if the current string is a heap allocated mutable value. + inline bool IsAllocated() const { return as_int() & kAllocatedBit; } + + // Returns true if the current string is an arena allocated value. + // This means it's either a mutable or fixed size arena string. + inline bool IsArena() const { return as_int() & kArenaBit; } + + // Returns true if the current string is a fixed size arena allocated value. + inline bool IsFixedSizeArena() const { + return (as_int() & kMask) == kFixedSizeArena; + } + + // Returns the contained string pointer. + inline T* Get() const { return reinterpret_cast(as_int() & ~kMask); } + + // Returns true if the contained pointer is null, indicating some error. + // The Null value is only used during parsing for temporary values. + // A persisted ArenaStringPtr value is never null. + inline bool IsNull() { return ptr_ == nullptr; } private: + static inline void assert_aligned(const void* p) { + GOOGLE_DCHECK_EQ(reinterpret_cast(p) & kMask, 0UL); + } + + inline T* TagAs(Type type, T* p) { + GOOGLE_DCHECK(type == kDefault || p != nullptr); + assert_aligned(p); + ptr_ = reinterpret_cast(reinterpret_cast(p) | type); + return p; + } + uintptr_t as_int() const { return reinterpret_cast(ptr_); } void* ptr_; }; @@ -118,66 +200,29 @@ class TaggedPtr { static_assert(std::is_trivial>::value, "TaggedPtr must be trivial"); -// 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 is never nullptr 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. +// This class encapsulates a pointer to a std::string with or without arena +// owned contents, tagged by the bottom bits of the string pointer. 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. // -// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string -// instance with a buffer on the arena (arena is never nullptr in this case). +// The string pointer is tagged to be either a default, externally owned value, +// a mutable heap allocated value, or an arena allocated value. The object uses +// a single global instance of an empty string that is used as the initial +// default value. Fields that have empty default values directly use this global +// default. Fields that have non empty default values are supported through +// lazily initialized default values managed by the LazyString class. // -// Generated code and reflection code both ensure that ptr_ is never null for -// fields with an empty default. +// Generated code and reflection code both ensure that ptr_ is never null. // Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and -// so the field is always manually initialized via method calls. +// 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.) +// See TaggedPtr for more information about the types of string values being +// held, and the mutable and ownership invariants for each type. struct PROTOBUF_EXPORT ArenaStringPtr { ArenaStringPtr() = default; explicit constexpr ArenaStringPtr( - const ExplicitlyConstructed* default_value) + ExplicitlyConstructedArenaString* default_value) : tagged_ptr_(default_value) {} // Some methods below are overloaded on a `default_value` and on tags. @@ -282,11 +327,23 @@ struct PROTOBUF_EXPORT ArenaStringPtr { void ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena); // 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); + // 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). + // This function allows an explicit default value other than the default + // global empty string. This is used in unit tests and by fields with + // explicit non-empty default string values using null defaults. + inline void InitDefault(); + inline void InitDefault(const std::string* str); + + // Called from generated code / reflection runtime only. Resets the value of + // this instances to the heap allocated value in `str`. `str` must not be + // null. Invokes `arena->Own(str)` to transfer ownership into the arena if + // `arena` is not null, else, `str` will be owned by ArenaStringPtr. This + // function should only be used to initialize a ArenaStringPtr or on an + // instance known to not carry any heap allocated value. + inline void InitAllocated(std::string* str, Arena* arena); // Returns a mutable pointer, but doesn't initialize the string to the // default value. @@ -311,18 +368,24 @@ struct PROTOBUF_EXPORT ArenaStringPtr { // 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; - } + // Returns true if this instances holds an immutable default value. + inline bool IsDefault() const { return tagged_ptr_.IsDefault(); } private: + template + inline std::string* NewString(Arena* arena, Args&&... args) { + if (arena == nullptr) { + auto* s = new std::string(std::forward(args)...); + return tagged_ptr_.SetAllocated(s); + } else { + auto* s = Arena::Create(arena, std::forward(args)...); + return tagged_ptr_.SetMutableArena(s); + } + } + TaggedPtr tagged_ptr_; - bool IsDonatedString() const { return false; } + bool IsFixedSizeArena() const { return false; } // Swaps tagged pointer without debug hardening. This is to allow python // protobuf to maintain pointer stability even in DEBUG builds. @@ -332,6 +395,7 @@ struct PROTOBUF_EXPORT ArenaStringPtr { } friend class ::google::protobuf::internal::SwapFieldHelper; + friend class TcParser; // Slow paths. @@ -346,32 +410,49 @@ struct PROTOBUF_EXPORT ArenaStringPtr { // Destroys the non-default string value out-of-line void DestroyNoArenaSlowPath(); + friend class EpsCopyInputStream; }; -inline void ArenaStringPtr::UnsafeSetDefault(const std::string* value) { - tagged_ptr_.Set(const_cast(value)); +inline void ArenaStringPtr::InitDefault() { + tagged_ptr_ = TaggedPtr(&fixed_address_empty_string); +} + +inline void ArenaStringPtr::InitDefault(const std::string* str) { + tagged_ptr_.SetDefault(str); +} + +inline void ArenaStringPtr::InitAllocated(std::string* str, Arena* arena) { + if (arena != nullptr) { + tagged_ptr_.SetMutableArena(str); + arena->Own(str); + } else { + tagged_ptr_.SetAllocated(str); + } } // Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs. inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( // - const std::string* default_value, // + const std::string*, // ArenaStringPtr* rhs, Arena* rhs_arena, // ArenaStringPtr* lhs, Arena* lhs_arena) { // Silence unused variable warnings in release buildls. - (void)default_value; (void)rhs_arena; (void)lhs_arena; std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_); #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - auto force_realloc = [default_value](ArenaStringPtr* p, Arena* arena) { - if (p->IsDefault(default_value)) return; + auto force_realloc = [](ArenaStringPtr* p, Arena* arena) { + if (p->IsDefault()) return; std::string* old_value = p->tagged_ptr_.Get(); std::string* new_value = - p->IsDonatedString() + p->IsFixedSizeArena() ? Arena::Create(arena, *old_value) : Arena::Create(arena, std::move(*old_value)); - if (arena == nullptr) delete old_value; - p->tagged_ptr_.Set(new_value); + if (arena == nullptr) { + delete old_value; + p->tagged_ptr_.SetAllocated(new_value); + } else { + p->tagged_ptr_.SetMutableArena(new_value); + } }; // Because, at this point, tagged_ptr_ has been swapped, arena should also be // swapped. @@ -386,28 +467,31 @@ inline void ArenaStringPtr::ClearNonDefaultToEmpty() { } inline std::string* ArenaStringPtr::MutableNoArenaNoDefault( - const std::string* default_value) { + 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)) { + GOOGLE_DCHECK(!tagged_ptr_.IsArena()); + if (IsDefault()) { return SetAndReturnNewString(); } else { return UnsafeMutablePointer(); } } -inline void ArenaStringPtr::DestroyNoArena(const std::string* default_value) { - if (!IsDefault(default_value)) { +inline void ArenaStringPtr::DestroyNoArena( + const std::string* /* default_value */) { + GOOGLE_DCHECK(!tagged_ptr_.IsArena()); + if (!IsDefault()) { DestroyNoArenaSlowPath(); } } inline std::string* ArenaStringPtr::UnsafeMutablePointer() { - GOOGLE_DCHECK(!tagged_ptr_.IsTagged()); - GOOGLE_DCHECK(tagged_ptr_.UnsafeGet() != nullptr); - return tagged_ptr_.UnsafeGet(); + GOOGLE_DCHECK(tagged_ptr_.IsMutable()); + GOOGLE_DCHECK(tagged_ptr_.Get() != nullptr); + return tagged_ptr_.Get(); } diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc index db988afb54dfb..bb48309a9eef8 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -72,7 +72,7 @@ INSTANTIATE_TEST_SUITE_P(ArenaString, SingleArena, testing::Bool()); TEST_P(SingleArena, GetSet) { auto arena = GetArena(); ArenaStringPtr field; - field.UnsafeSetDefault(empty_default); + field.InitDefault(empty_default); EXPECT_EQ("", field.Get()); field.Set(empty_default, "Test short", arena.get()); EXPECT_EQ("Test short", field.Get()); @@ -86,7 +86,7 @@ TEST_P(SingleArena, MutableAccessor) { auto arena = GetArena(); ArenaStringPtr field; const std::string* empty_default = &internal::GetEmptyString(); - field.UnsafeSetDefault(empty_default); + field.InitDefault(empty_default); std::string* mut = field.Mutable(EmptyDefault{}, arena.get()); EXPECT_EQ(mut, field.Mutable(EmptyDefault{}, arena.get())); @@ -102,7 +102,7 @@ TEST_P(SingleArena, NullDefault) { auto arena = GetArena(); ArenaStringPtr field; - field.UnsafeSetDefault(nullptr); + field.InitDefault(nullptr); std::string* mut = field.Mutable(nonempty_default, arena.get()); EXPECT_EQ(mut, field.Mutable(nonempty_default, arena.get())); EXPECT_EQ(mut, &field.Get()); @@ -131,9 +131,9 @@ INSTANTIATE_TEST_SUITE_P(ArenaString, DualArena, TEST_P(DualArena, Swap) { auto lhs_arena = GetLhsArena(); ArenaStringPtr lhs; - lhs.UnsafeSetDefault(empty_default); + lhs.InitDefault(empty_default); ArenaStringPtr rhs; - rhs.UnsafeSetDefault(empty_default); + rhs.InitDefault(empty_default); { auto rhs_arena = GetRhsArena(); diff --git a/src/google/protobuf/arenaz_sampler.cc b/src/google/protobuf/arenaz_sampler.cc new file mode 100644 index 0000000000000..b0aed50f139ab --- /dev/null +++ b/src/google/protobuf/arenaz_sampler.cc @@ -0,0 +1,177 @@ +// 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 + + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace internal { + +ThreadSafeArenazSampler& GlobalThreadSafeArenazSampler() { + static auto* sampler = new ThreadSafeArenazSampler(); + return *sampler; +} + +void UnsampleSlow(ThreadSafeArenaStats* info) { + GlobalThreadSafeArenazSampler().Unregister(info); +} + +#if defined(PROTOBUF_ARENAZ_SAMPLE) +namespace { + +PROTOBUF_CONSTINIT std::atomic g_arenaz_enabled{true}; +PROTOBUF_CONSTINIT std::atomic g_arenaz_sample_parameter{1 << 20}; +PROTOBUF_THREAD_LOCAL absl::profiling_internal::ExponentialBiased + g_exponential_biased_generator; + +} // namespace + +PROTOBUF_THREAD_LOCAL int64_t global_next_sample = 1LL << 20; + +ThreadSafeArenaStats::ThreadSafeArenaStats() { PrepareForSampling(); } +ThreadSafeArenaStats::~ThreadSafeArenaStats() = default; + +void ThreadSafeArenaStats::PrepareForSampling() { + num_allocations.store(0, std::memory_order_relaxed); + num_resets.store(0, std::memory_order_relaxed); + bytes_requested.store(0, std::memory_order_relaxed); + bytes_allocated.store(0, std::memory_order_relaxed); + bytes_wasted.store(0, std::memory_order_relaxed); + max_bytes_allocated.store(0, std::memory_order_relaxed); + thread_ids.store(0, std::memory_order_relaxed); + // The inliner makes hardcoded skip_count difficult (especially when combined + // with LTO). We use the ability to exclude stacks by regex when encoding + // instead. + depth = absl::GetStackTrace(stack, kMaxStackDepth, /* skip_count= */ 0); +} + +void RecordResetSlow(ThreadSafeArenaStats* info) { + const size_t max_bytes = + info->max_bytes_allocated.load(std::memory_order_relaxed); + const size_t allocated_bytes = + info->bytes_allocated.load(std::memory_order_relaxed); + if (max_bytes < allocated_bytes) { + info->max_bytes_allocated.store(allocated_bytes); + } + info->bytes_requested.store(0, std::memory_order_relaxed); + info->bytes_allocated.store(0, std::memory_order_relaxed); + info->bytes_wasted.fetch_add(0, std::memory_order_relaxed); + info->num_allocations.fetch_add(0, std::memory_order_relaxed); + info->num_resets.fetch_add(1, std::memory_order_relaxed); +} + +void RecordAllocateSlow(ThreadSafeArenaStats* info, size_t requested, + size_t allocated, size_t wasted) { + info->bytes_requested.fetch_add(requested, std::memory_order_relaxed); + info->bytes_allocated.fetch_add(allocated, std::memory_order_relaxed); + info->bytes_wasted.fetch_add(wasted, std::memory_order_relaxed); + info->num_allocations.fetch_add(1, std::memory_order_relaxed); + const uint64_t tid = (1ULL << (GetCachedTID() % 63)); + const uint64_t thread_ids = info->thread_ids.load(std::memory_order_relaxed); + if (!(thread_ids & tid)) { + info->thread_ids.store(thread_ids | tid, std::memory_order_relaxed); + } +} + +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample) { + bool first = *next_sample < 0; + *next_sample = g_exponential_biased_generator.GetStride( + g_arenaz_sample_parameter.load(std::memory_order_relaxed)); + // Small values of interval are equivalent to just sampling next time. + ABSL_ASSERT(*next_sample >= 1); + + // g_arenaz_enabled can be dynamically flipped, we need to set a threshold low + // enough that we will start sampling in a reasonable time, so we just use the + // default sampling rate. + if (!g_arenaz_enabled.load(std::memory_order_relaxed)) return nullptr; + // We will only be negative on our first count, so we should just retry in + // that case. + if (first) { + if (PROTOBUF_PREDICT_TRUE(--*next_sample > 0)) return nullptr; + return SampleSlow(next_sample); + } + + return GlobalThreadSafeArenazSampler().Register(); +} + +void SetThreadSafeArenazEnabled(bool enabled) { + g_arenaz_enabled.store(enabled, std::memory_order_release); +} + +void SetThreadSafeArenazSampleParameter(int32_t rate) { + if (rate > 0) { + g_arenaz_sample_parameter.store(rate, std::memory_order_release); + } else { + ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz sample rate: %lld", + static_cast(rate)); // NOLINT(runtime/int) + } +} + +void SetThreadSafeArenazMaxSamples(int32_t max) { + if (max > 0) { + GlobalThreadSafeArenazSampler().SetMaxSamples(max); + } else { + ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz max samples: %lld", + static_cast(max)); // NOLINT(runtime/int) + } +} + +void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) { + if (next_sample >= 0) { + global_next_sample = next_sample; + } else { + ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz next sample: %lld", + static_cast(next_sample)); // NOLINT(runtime/int) + } +} + +#else +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample) { + *next_sample = std::numeric_limits::max(); + return nullptr; +} + +void SetThreadSafeArenazEnabled(bool enabled) {} +void SetThreadSafeArenazSampleParameter(int32_t rate) {} +void SetThreadSafeArenazMaxSamples(int32_t max) {} +void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) {} +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/arenaz_sampler.h b/src/google/protobuf/arenaz_sampler.h new file mode 100644 index 0000000000000..b04b0cc678c5b --- /dev/null +++ b/src/google/protobuf/arenaz_sampler.h @@ -0,0 +1,207 @@ +// 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_SRC_GOOGLE_PROTOBUF_ARENAZ_SAMPLER_H__ +#define GOOGLE_PROTOBUF_SRC_GOOGLE_PROTOBUF_ARENAZ_SAMPLER_H__ + +#include +#include +#include + + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace internal { + +#if defined(PROTOBUF_ARENAZ_SAMPLE) +struct ThreadSafeArenaStats; +void RecordResetSlow(ThreadSafeArenaStats* info); +void RecordAllocateSlow(ThreadSafeArenaStats* info, size_t requested, + size_t allocated, size_t wasted); +// Stores information about a sampled thread safe arena. All mutations to this +// *must* be made through `Record*` functions below. All reads from this *must* +// only occur in the callback to `ThreadSafeArenazSampler::Iterate`. +struct ThreadSafeArenaStats + : public absl::profiling_internal::Sample { + // Constructs the object but does not fill in any fields. + ThreadSafeArenaStats(); + ~ThreadSafeArenaStats(); + + // Puts the object into a clean state, fills in the logically `const` members, + // blocking for any readers that are currently sampling the object. + void PrepareForSampling() ABSL_EXCLUSIVE_LOCKS_REQUIRED(init_mu); + + // These fields are mutated by the various Record* APIs and need to be + // thread-safe. + std::atomic num_allocations; + std::atomic num_resets; + std::atomic bytes_requested; + std::atomic bytes_allocated; + std::atomic bytes_wasted; + // Records the largest size an arena ever had. Maintained across resets. + std::atomic max_bytes_allocated; + // Bit i when set to 1 indicates that a thread with tid % 63 = i accessed the + // underlying arena. The field is maintained across resets. + std::atomic thread_ids; + + // All of the fields below are set by `PrepareForSampling`, they must not + // be mutated in `Record*` functions. They are logically `const` in that + // sense. These are guarded by init_mu, but that is not externalized to + // clients, who can only read them during + // `ThreadSafeArenazSampler::Iterate` which will hold the lock. + static constexpr int kMaxStackDepth = 64; + int32_t depth; + void* stack[kMaxStackDepth]; + static void RecordAllocateStats(ThreadSafeArenaStats* info, size_t requested, + size_t allocated, size_t wasted) { + if (PROTOBUF_PREDICT_TRUE(info == nullptr)) return; + RecordAllocateSlow(info, requested, allocated, wasted); + } +}; + +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample); +void UnsampleSlow(ThreadSafeArenaStats* info); + +class ThreadSafeArenaStatsHandle { + public: + explicit ThreadSafeArenaStatsHandle() = default; + explicit ThreadSafeArenaStatsHandle(ThreadSafeArenaStats* info) + : info_(info) {} + + ~ThreadSafeArenaStatsHandle() { + if (PROTOBUF_PREDICT_TRUE(info_ == nullptr)) return; + UnsampleSlow(info_); + } + + ThreadSafeArenaStatsHandle(ThreadSafeArenaStatsHandle&& other) noexcept + : info_(absl::exchange(other.info_, nullptr)) {} + + ThreadSafeArenaStatsHandle& operator=( + ThreadSafeArenaStatsHandle&& other) noexcept { + if (PROTOBUF_PREDICT_FALSE(info_ != nullptr)) { + UnsampleSlow(info_); + } + info_ = absl::exchange(other.info_, nullptr); + return *this; + } + + void RecordReset() { + if (PROTOBUF_PREDICT_TRUE(info_ == nullptr)) return; + RecordResetSlow(info_); + } + + ThreadSafeArenaStats* MutableStats() { return info_; } + + friend void swap(ThreadSafeArenaStatsHandle& lhs, + ThreadSafeArenaStatsHandle& rhs) { + std::swap(lhs.info_, rhs.info_); + } + + friend class ThreadSafeArenaStatsHandlePeer; + + private: + ThreadSafeArenaStats* info_ = nullptr; +}; + +using ThreadSafeArenazSampler = + ::absl::profiling_internal::SampleRecorder; + +extern PROTOBUF_THREAD_LOCAL int64_t global_next_sample; + +// Returns an RAII sampling handle that manages registration and unregistation +// with the global sampler. +inline ThreadSafeArenaStatsHandle Sample() { + if (PROTOBUF_PREDICT_TRUE(--global_next_sample > 0)) { + return ThreadSafeArenaStatsHandle(nullptr); + } + return ThreadSafeArenaStatsHandle(SampleSlow(&global_next_sample)); +} + +#else +struct ThreadSafeArenaStats { + static void RecordAllocateStats(ThreadSafeArenaStats*, size_t /*requested*/, + size_t /*allocated*/, size_t /*wasted*/) {} +}; + +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample); +void UnsampleSlow(ThreadSafeArenaStats* info); + +class ThreadSafeArenaStatsHandle { + public: + explicit ThreadSafeArenaStatsHandle() = default; + explicit ThreadSafeArenaStatsHandle(ThreadSafeArenaStats*) {} + + void RecordReset() {} + + ThreadSafeArenaStats* MutableStats() { return nullptr; } + + friend void swap(ThreadSafeArenaStatsHandle&, ThreadSafeArenaStatsHandle&) {} + + private: + friend class ThreadSafeArenaStatsHandlePeer; +}; + +class ThreadSafeArenazSampler { + public: + void Unregister(ThreadSafeArenaStats*) {} + void SetMaxSamples(int32_t) {} +}; + +// Returns an RAII sampling handle that manages registration and unregistation +// with the global sampler. +inline ThreadSafeArenaStatsHandle Sample() { + return ThreadSafeArenaStatsHandle(nullptr); +} +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +// Returns a global Sampler. +ThreadSafeArenazSampler& GlobalThreadSafeArenazSampler(); + +// Enables or disables sampling for thread safe arenas. +void SetThreadSafeArenazEnabled(bool enabled); + +// Sets the rate at which thread safe arena will be sampled. +void SetThreadSafeArenazSampleParameter(int32_t rate); + +// Sets a soft max for the number of samples that will be kept. +void SetThreadSafeArenazMaxSamples(int32_t max); + +// Sets the current value for when arenas should be next sampled. +void SetThreadSafeArenazGlobalNextSample(int64_t next_sample); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include +#endif // GOOGLE_PROTOBUF_SRC_PROTOBUF_ARENAZ_SAMPLER_H__ diff --git a/src/google/protobuf/arenaz_sampler_test.cc b/src/google/protobuf/arenaz_sampler_test.cc new file mode 100644 index 0000000000000..1bfec542d60bd --- /dev/null +++ b/src/google/protobuf/arenaz_sampler_test.cc @@ -0,0 +1,382 @@ +// 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 + + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace internal { +#if defined(PROTOBUF_ARENAZ_SAMPLE) +class ThreadSafeArenaStatsHandlePeer { + public: + static bool IsSampled(const ThreadSafeArenaStatsHandle& h) { + return h.info_ != nullptr; + } + + static ThreadSafeArenaStats* GetInfo(ThreadSafeArenaStatsHandle* h) { + return h->info_; + } +}; +std::vector GetBytesAllocated(ThreadSafeArenazSampler* s) { + std::vector res; + s->Iterate([&](const ThreadSafeArenaStats& info) { + res.push_back(info.bytes_allocated.load(std::memory_order_acquire)); + }); + return res; +} + +ThreadSafeArenaStats* Register(ThreadSafeArenazSampler* s, size_t size) { + auto* info = s->Register(); + assert(info != nullptr); + info->bytes_allocated.store(size); + return info; +} + +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +namespace { + +#if defined(PROTOBUF_ARENAZ_SAMPLE) + +TEST(ThreadSafeArenaStatsTest, PrepareForSampling) { + ThreadSafeArenaStats info; + MutexLock l(&info.init_mu); + info.PrepareForSampling(); + + EXPECT_EQ(info.num_allocations.load(), 0); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 0); + EXPECT_EQ(info.bytes_wasted.load(), 0); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); + + info.num_allocations.store(1, std::memory_order_relaxed); + info.num_resets.store(1, std::memory_order_relaxed); + info.bytes_requested.store(1, std::memory_order_relaxed); + info.bytes_allocated.store(1, std::memory_order_relaxed); + info.bytes_wasted.store(1, std::memory_order_relaxed); + info.max_bytes_allocated.store(1, std::memory_order_relaxed); + + info.PrepareForSampling(); + EXPECT_EQ(info.num_allocations.load(), 0); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 0); + EXPECT_EQ(info.bytes_wasted.load(), 0); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); +} + +TEST(ThreadSafeArenaStatsTest, RecordAllocateSlow) { + ThreadSafeArenaStats info; + MutexLock l(&info.init_mu); + info.PrepareForSampling(); + RecordAllocateSlow(&info, /*requested=*/100, /*allocated=*/128, /*wasted=*/0); + EXPECT_EQ(info.num_allocations.load(), 1); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 100); + EXPECT_EQ(info.bytes_allocated.load(), 128); + EXPECT_EQ(info.bytes_wasted.load(), 0); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); + RecordAllocateSlow(&info, /*requested=*/100, /*allocated=*/256, + /*wasted=*/28); + EXPECT_EQ(info.num_allocations.load(), 2); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 200); + EXPECT_EQ(info.bytes_allocated.load(), 384); + EXPECT_EQ(info.bytes_wasted.load(), 28); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); +} + +TEST(ThreadSafeArenaStatsTest, RecordResetSlow) { + ThreadSafeArenaStats info; + MutexLock l(&info.init_mu); + info.PrepareForSampling(); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 0); + RecordAllocateSlow(&info, /*requested=*/100, /*allocated=*/128, /*wasted=*/0); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 128); + RecordResetSlow(&info); + EXPECT_EQ(info.num_resets.load(), 1); + EXPECT_EQ(info.bytes_allocated.load(), 0); +} + +TEST(ThreadSafeArenazSamplerTest, SmallSampleParameter) { + SetThreadSafeArenazEnabled(true); + SetThreadSafeArenazSampleParameter(100); + + for (int i = 0; i < 1000; ++i) { + int64_t next_sample = 0; + ThreadSafeArenaStats* sample = SampleSlow(&next_sample); + EXPECT_GT(next_sample, 0); + EXPECT_NE(sample, nullptr); + UnsampleSlow(sample); + } +} + +TEST(ThreadSafeArenazSamplerTest, LargeSampleParameter) { + SetThreadSafeArenazEnabled(true); + SetThreadSafeArenazSampleParameter(std::numeric_limits::max()); + + for (int i = 0; i < 1000; ++i) { + int64_t next_sample = 0; + ThreadSafeArenaStats* sample = SampleSlow(&next_sample); + EXPECT_GT(next_sample, 0); + EXPECT_NE(sample, nullptr); + UnsampleSlow(sample); + } +} + +TEST(ThreadSafeArenazSamplerTest, Sample) { + SetThreadSafeArenazEnabled(true); + SetThreadSafeArenazSampleParameter(100); + SetThreadSafeArenazGlobalNextSample(0); + int64_t num_sampled = 0; + int64_t total = 0; + double sample_rate = 0.0; + for (int i = 0; i < 1000000; ++i) { + ThreadSafeArenaStatsHandle h = Sample(); + ++total; + if (ThreadSafeArenaStatsHandlePeer::IsSampled(h)) { + ++num_sampled; + } + sample_rate = static_cast(num_sampled) / total; + if (0.005 < sample_rate && sample_rate < 0.015) break; + } + EXPECT_NEAR(sample_rate, 0.01, 0.005); +} + +TEST(ThreadSafeArenazSamplerTest, Handle) { + auto& sampler = GlobalThreadSafeArenazSampler(); + ThreadSafeArenaStatsHandle h(sampler.Register()); + auto* info = ThreadSafeArenaStatsHandlePeer::GetInfo(&h); + info->bytes_allocated.store(0x12345678, std::memory_order_relaxed); + + bool found = false; + sampler.Iterate([&](const ThreadSafeArenaStats& h) { + if (&h == info) { + EXPECT_EQ(h.bytes_allocated.load(), 0x12345678); + found = true; + } + }); + EXPECT_TRUE(found); + + h = ThreadSafeArenaStatsHandle(); + found = false; + sampler.Iterate([&](const ThreadSafeArenaStats& h) { + if (&h == info) { + // this will only happen if some other thread has resurrected the info + // the old handle was using. + if (h.bytes_allocated.load() == 0x12345678) { + found = true; + } + } + }); + EXPECT_FALSE(found); +} + +TEST(ThreadSafeArenazSamplerTest, Registration) { + ThreadSafeArenazSampler sampler; + auto* info1 = Register(&sampler, 1); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(1)); + + auto* info2 = Register(&sampler, 2); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(1, 2)); + info1->bytes_allocated.store(3); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(3, 2)); + + sampler.Unregister(info1); + sampler.Unregister(info2); +} + +TEST(ThreadSafeArenazSamplerTest, Unregistration) { + ThreadSafeArenazSampler sampler; + std::vector infos; + for (size_t i = 0; i < 3; ++i) { + infos.push_back(Register(&sampler, i)); + } + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 1, 2)); + + sampler.Unregister(infos[1]); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 2)); + + infos.push_back(Register(&sampler, 3)); + infos.push_back(Register(&sampler, 4)); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 2, 3, 4)); + sampler.Unregister(infos[3]); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 2, 4)); + + sampler.Unregister(infos[0]); + sampler.Unregister(infos[2]); + sampler.Unregister(infos[4]); + EXPECT_THAT(GetBytesAllocated(&sampler), IsEmpty()); +} + +TEST(ThreadSafeArenazSamplerTest, MultiThreaded) { + ThreadSafeArenazSampler sampler; + absl::Notification stop; + ThreadPool pool(10); + + for (int i = 0; i < 10; ++i) { + pool.Schedule([&sampler, &stop]() { + std::random_device rd; + std::mt19937 gen(rd()); + + std::vector infoz; + while (!stop.HasBeenNotified()) { + if (infoz.empty()) { + infoz.push_back(sampler.Register()); + } + switch (std::uniform_int_distribution<>(0, 1)(gen)) { + case 0: { + infoz.push_back(sampler.Register()); + break; + } + case 1: { + size_t p = + std::uniform_int_distribution<>(0, infoz.size() - 1)(gen); + ThreadSafeArenaStats* info = infoz[p]; + infoz[p] = infoz.back(); + infoz.pop_back(); + sampler.Unregister(info); + break; + } + } + } + }); + } + // The threads will hammer away. Give it a little bit of time for tsan to + // spot errors. + absl::SleepFor(absl::Seconds(3)); + stop.Notify(); +} + +TEST(ThreadSafeArenazSamplerTest, Callback) { + ThreadSafeArenazSampler sampler; + + auto* info1 = Register(&sampler, 1); + auto* info2 = Register(&sampler, 2); + + static const ThreadSafeArenaStats* expected; + + auto callback = [](const ThreadSafeArenaStats& info) { + // We can't use `info` outside of this callback because the object will be + // disposed as soon as we return from here. + EXPECT_EQ(&info, expected); + }; + + // Set the callback. + EXPECT_EQ(sampler.SetDisposeCallback(callback), nullptr); + expected = info1; + sampler.Unregister(info1); + + // Unset the callback. + EXPECT_EQ(callback, sampler.SetDisposeCallback(nullptr)); + expected = nullptr; // no more calls. + sampler.Unregister(info2); +} + +class ThreadSafeArenazSamplerTestThread : public Thread { + protected: + void Run() override { + google::protobuf::ArenaSafeUniquePtr< + protobuf_test_messages::proto2::TestAllTypesProto2> + message = google::protobuf::MakeArenaSafeUnique< + protobuf_test_messages::proto2::TestAllTypesProto2>(arena_); + GOOGLE_CHECK(message != nullptr); + // Signal that a message on the arena has been created. This should create + // a SerialArena for this thread. + if (barrier_->Block()) { + delete barrier_; + } + } + + public: + ThreadSafeArenazSamplerTestThread(const thread::Options& options, + StringPiece name, + google::protobuf::Arena* arena, + absl::Barrier* barrier) + : Thread(options, name), arena_(arena), barrier_(barrier) {} + + private: + google::protobuf::Arena* arena_; + absl::Barrier* barrier_; +}; + +TEST(ThreadSafeArenazSamplerTest, MultiThread) { + SetThreadSafeArenazEnabled(true); + // Setting 1 as the parameter value means one in every two arenas would be + // sampled, on average. + SetThreadSafeArenazSampleParameter(1); + SetThreadSafeArenazGlobalNextSample(0); + auto& sampler = GlobalThreadSafeArenazSampler(); + int count = 0; + for (int i = 0; i < 10; ++i) { + const int kNumThreads = 10; + absl::Barrier* barrier = new absl::Barrier(kNumThreads + 1); + google::protobuf::Arena arena; + thread::Options options; + options.set_joinable(true); + std::vector> threads; + for (int i = 0; i < kNumThreads; i++) { + auto t = std::make_unique( + options, StrCat("thread", i), &arena, barrier); + t->Start(); + threads.push_back(std::move(t)); + } + // Wait till each thread has created a message on the arena. + if (barrier->Block()) { + delete barrier; + } + sampler.Iterate([&](const ThreadSafeArenaStats& h) { ++count; }); + for (int i = 0; i < kNumThreads; i++) { + threads[i]->Join(); + } + } + EXPECT_GT(count, 0); +} +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/annotation_test_util.cc b/src/google/protobuf/compiler/annotation_test_util.cc index 3c47aa42dbfdf..f0815c5639a62 100644 --- a/src/google/protobuf/compiler/annotation_test_util.cc +++ b/src/google/protobuf/compiler/annotation_test_util.cc @@ -58,9 +58,8 @@ class DescriptorCapturingGenerator : public CodeGenerator { explicit DescriptorCapturingGenerator(FileDescriptorProto* file) : file_(file) {} - 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 { file->CopyTo(file_); return true; } @@ -128,7 +127,7 @@ const GeneratedCodeInfo::Annotation* FindAnnotationOnPath( std::vector annotations; FindAnnotationsOnPath(info, source_file, path, &annotations); if (annotations.empty()) { - return NULL; + return nullptr; } return annotations[0]; } diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index 4544f3e710576..dc9d450a4f42b 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -76,13 +76,13 @@ GeneratorContext::~GeneratorContext() {} io::ZeroCopyOutputStream* GeneratorContext::OpenForAppend( const std::string& filename) { - return NULL; + return nullptr; } io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert( const std::string& filename, const std::string& insertion_point) { GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion."; - return NULL; // make compiler happy + return nullptr; // make compiler happy } io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo( diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 2cbda270b4917..0a99fe1196ab7 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -43,6 +43,7 @@ #include #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index bfc6b0552de09..3dff6c5cc7113 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -53,6 +53,7 @@ #endif #include #include + #include #include @@ -87,6 +88,7 @@ #include +// Must be included last. #include namespace google { @@ -289,12 +291,12 @@ class CommandLineInterface::ErrorPrinter public io::ErrorCollector, public DescriptorPool::ErrorCollector { public: - ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = NULL) + ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = nullptr) : format_(format), tree_(tree), found_errors_(false), found_warnings_(false) {} - ~ErrorPrinter() {} + ~ErrorPrinter() override {} // implements MultiFileErrorCollector ------------------------------ void AddError(const std::string& filename, int line, int column, @@ -341,8 +343,8 @@ class CommandLineInterface::ErrorPrinter std::ostream& out) { // Print full path when running under MSVS std::string dfile; - if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && tree_ != NULL && - tree_->VirtualFileToDiskFile(filename, &dfile)) { + if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && + tree_ != nullptr && tree_->VirtualFileToDiskFile(filename, &dfile)) { out << dfile; } else { out << filename; @@ -434,7 +436,7 @@ class CommandLineInterface::MemoryOutputStream const std::string& filename, const std::string& insertion_point, const google::protobuf::GeneratedCodeInfo& info); - virtual ~MemoryOutputStream(); + ~MemoryOutputStream() override; // implements ZeroCopyOutputStream --------------------------------- bool Next(void** data, int* size) override { @@ -1116,7 +1118,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { FileDescriptorProto file; file.set_name("empty_message.proto"); file.add_message_type()->set_name("EmptyMessage"); - GOOGLE_CHECK(pool.BuildFile(file) != NULL); + GOOGLE_CHECK(pool.BuildFile(file) != nullptr); codec_type_ = "EmptyMessage"; if (!EncodeOrDecode(&pool)) { return 1; @@ -1270,7 +1272,7 @@ bool CommandLineInterface::ParseInputFiles( // Import the file. const FileDescriptor* parsed_file = descriptor_pool->FindFileByName(input_file); - if (parsed_file == NULL) { + if (parsed_file == nullptr) { result = false; break; } @@ -1496,7 +1498,7 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( for (std::vector::const_iterator j = output_directives_.begin(); j != output_directives_.end(); ++j) { - if (j->generator == NULL) { + if (j->generator == nullptr) { std::string plugin_name = PluginName(plugin_prefix_, j->name); if (plugin_name == i->first) { foundImplicitPlugin = true; @@ -1606,7 +1608,7 @@ bool CommandLineInterface::ParseArgument(const char* arg, std::string* name, // Two dashes: Multi-character name, with '=' separating name and // value. const char* equals_pos = strchr(arg, '='); - if (equals_pos != NULL) { + if (equals_pos != nullptr) { *name = std::string(arg, equals_pos - arg); *value = equals_pos + 1; parsed_value = true; @@ -1946,11 +1948,11 @@ CommandLineInterface::InterpretArgument(const std::string& name, // Some other flag. Look it up in the generators list. const GeneratorInfo* generator_info = FindOrNull(generators_by_flag_name_, name); - if (generator_info == NULL && + if (generator_info == nullptr && (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { // Check if it's a generator option flag. generator_info = FindOrNull(generators_by_option_name_, name); - if (generator_info != NULL) { + if (generator_info != nullptr) { std::string* parameters = &generator_parameters_[generator_info->flag_name]; if (!parameters->empty()) { @@ -1979,8 +1981,8 @@ CommandLineInterface::InterpretArgument(const std::string& name, OutputDirective directive; directive.name = name; - if (generator_info == NULL) { - directive.generator = NULL; + if (generator_info == nullptr) { + directive.generator = nullptr; } else { directive.generator = generator_info->generator; } @@ -2136,7 +2138,7 @@ bool CommandLineInterface::GenerateOutput( GeneratorContext* generator_context) { // Call the generator. std::string error; - if (output_directive.generator == NULL) { + if (output_directive.generator == nullptr) { // This is a plugin. GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") && HasSuffixString(output_directive.name, "_out")) @@ -2317,7 +2319,7 @@ bool CommandLineInterface::GeneratePluginOutput( // before the new one is opened. current_output.reset(); current_output.reset(generator_context->Open(output_file.name())); - } else if (current_output == NULL) { + } else if (current_output == nullptr) { *error = strings::Substitute( "$0: First file chunk returned by plugin did not specify a file " "name.", @@ -2347,7 +2349,7 @@ bool CommandLineInterface::GeneratePluginOutput( bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { // Look up the type. const Descriptor* type = pool->FindMessageTypeByName(codec_type_); - if (type == NULL) { + if (type == nullptr) { std::cerr << "Type not defined: " << codec_type_ << std::endl; return false; } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 27178b1beeca7..e8425508b1a3c 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -49,6 +49,8 @@ #include #include + +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 9cc8cf98c7cb7..46c36b32a6120 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -96,8 +96,8 @@ bool FileExists(const std::string& path) { class CommandLineInterfaceTest : public testing::Test { protected: - virtual void SetUp(); - virtual void TearDown(); + void SetUp() override; + void TearDown() override; // Runs the CommandLineInterface with the given command line. The // command is automatically split on spaces, and the string "$tmpdir" @@ -256,14 +256,14 @@ class CommandLineInterfaceTest : public testing::Test { class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { public: NullCodeGenerator() : called_(false) {} - ~NullCodeGenerator() {} + ~NullCodeGenerator() override {} mutable bool called_; mutable std::string parameter_; // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* context, std::string* error) const { + GeneratorContext* context, std::string* error) const override { called_ = true; parameter_ = parameter; return true; @@ -2518,12 +2518,12 @@ enum EncodeDecodeTestMode { PROTO_PATH, DESCRIPTOR_SET_IN }; class EncodeDecodeTest : public testing::TestWithParam { protected: - virtual void SetUp() { + void SetUp() override { WriteUnittestProtoDescriptorSet(); duped_stdin_ = dup(STDIN_FILENO); } - virtual void TearDown() { + void TearDown() override { dup2(duped_stdin_, STDIN_FILENO); close(duped_stdin_); } diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index 60619f107648e..6ed3a07d729bd 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -69,13 +69,13 @@ namespace { class MockErrorCollector : public MultiFileErrorCollector { public: MockErrorCollector() {} - ~MockErrorCollector() {} + ~MockErrorCollector() override {} std::string text_; // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, int line, int column, - const std::string& message) { + const std::string& message) override { strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, message); } @@ -113,7 +113,7 @@ class MockGeneratorContext : public GeneratorContext { // implements GeneratorContext -------------------------------------- - virtual io::ZeroCopyOutputStream* Open(const std::string& filename) { + io::ZeroCopyOutputStream* Open(const std::string& filename) override { auto& map_slot = files_[filename]; map_slot.reset(new std::string); return new io::StringOutputStream(map_slot.get()); @@ -137,9 +137,9 @@ TEST(BootstrapTest, GeneratedFilesMatch) { // of the data to compare to. std::map vpath_map; std::map rpath_map; - rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto2"] = + rpath_map["third_party/protobuf/test_messages_proto2"] = "net/proto2/z_generated_example/test_messages_proto2"; - rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto3"] = + rpath_map["third_party/protobuf/test_messages_proto3"] = "net/proto2/z_generated_example/test_messages_proto3"; rpath_map["net/proto2/internal/proto2_weak"] = "net/proto2/z_generated_example/proto2_weak"; diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 6ae5cf42500a7..fb72b7578b1a7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -38,10 +38,10 @@ #include #include -#include -#include #include #include +#include +#include namespace google { namespace protobuf { @@ -88,7 +88,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, variables_["nested_name"] = descriptor_->name(); variables_["resolved_name"] = ResolveKeyword(descriptor_->name()); variables_["prefix"] = - (descriptor_->containing_type() == NULL) ? "" : classname_ + "_"; + (descriptor_->containing_type() == nullptr) ? "" : classname_ + "_"; } EnumGenerator::~EnumGenerator() {} @@ -405,7 +405,7 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) { descriptor_->value_count()); } - if (descriptor_->containing_type() != NULL) { + if (descriptor_->containing_type() != nullptr) { std::string parent = ClassName(descriptor_->containing_type(), false); // Before C++17, we must define the static constants which were // declared in the header, to give the linker a place to put them. diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h index 3687f04c271f8..2a17ede290d68 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum.h @@ -38,8 +38,9 @@ #include #include #include -#include + #include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 70311dde40edf..b27ed1e4f89a5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -33,10 +33,11 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include -#include + #include #include #include +#include namespace google { namespace protobuf { @@ -143,7 +144,7 @@ void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( Formatter format(printer, variables_); format( "target = stream->EnsureSpace(target);\n" - "target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n" + "target = ::_pbi::WireFormatLite::WriteEnumToArray(\n" " $number$, this->_internal_$name$(), target);\n"); } @@ -151,9 +152,7 @@ void EnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { Formatter format(printer, variables_); format( "total_size += $tag_size$ +\n" - " " - "::$proto_ns$::internal::WireFormatLite::EnumSize(this->_internal_$name$(" - "));\n"); + " ::_pbi::WireFormatLite::EnumSize(this->_internal_$name$());\n"); } void EnumFieldGenerator::GenerateConstinitInitializer( @@ -352,7 +351,7 @@ void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n" " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n" + " target = ::_pbi::WireFormatLite::WriteEnumToArray(\n" " $number$, this->_internal_$name$(i), target);\n" "}\n"); } @@ -368,7 +367,7 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { format.Indent(); format( "for (unsigned int i = 0; i < count; i++) {\n" - " data_size += ::$proto_ns$::internal::WireFormatLite::EnumSize(\n" + " data_size += ::_pbi::WireFormatLite::EnumSize(\n" " this->_internal_$name$(static_cast(i)));\n" "}\n"); @@ -376,10 +375,9 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { format( "if (data_size > 0) {\n" " total_size += $tag_size$ +\n" - " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n" - " static_cast<$int32$>(data_size));\n" + " ::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n" "}\n" - "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n" + "int cached_size = ::_pbi::ToCachedSize(data_size);\n" "_$name$_cached_byte_size_.store(cached_size,\n" " std::memory_order_relaxed);\n" "total_size += data_size;\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h index e65ec0f5c0754..2a4ca5162bf61 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { @@ -47,7 +48,7 @@ namespace cpp { class EnumFieldGenerator : public FieldGenerator { public: EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~EnumFieldGenerator(); + ~EnumFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -71,7 +72,7 @@ class EnumOneofFieldGenerator : public EnumFieldGenerator { public: EnumOneofFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~EnumOneofFieldGenerator(); + ~EnumOneofFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; @@ -87,7 +88,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { public: RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~RepeatedEnumFieldGenerator(); + ~RepeatedEnumFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index 8604da5f275f0..d5d0520e72216 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -33,11 +33,13 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include + #include -#include -#include + #include #include +#include +#include namespace google { namespace protobuf { @@ -91,6 +93,19 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, variables_["scope"] = scope; variables_["scoped_name"] = ExtensionName(descriptor_); variables_["number"] = StrCat(descriptor_->number()); + + bool add_verify_fn = + // Only verify msgs. + descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + // Options say to verify. + ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) && + ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_); + + variables_["verify_fn"] = + add_verify_fn + ? StrCat("&", FieldMessageTypeName(descriptor_, options_), + "::InternalVerify") + : "nullptr"; } ExtensionGenerator::~ExtensionGenerator() {} @@ -164,23 +179,11 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { } format( - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 " "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n" - " $scoped_name$($constant_name$, $1$);\n", + " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$>\n" + " $scoped_name$($constant_name$, $1$, $verify_fn$);\n", default_str); - - // Register extension verify function if needed. - if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) && - ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_)) { - format( - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " - "::$proto_ns$::internal::RegisterExtensionVerify< $extendee$,\n" - " $1$, $number$> $2$_$name$_register;\n", - ClassName(descriptor_->message_type(), true), - IsScoped() ? ClassName(descriptor_->extension_scope(), false) : ""); - } } } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index a95dd33e91b9f..143102de3211f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -38,19 +38,19 @@ #include #include +#include +#include #include #include #include -#include -#include #include #include +#include +#include #include #include #include #include -#include -#include namespace google { namespace protobuf { @@ -114,7 +114,7 @@ std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor, if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) { return strings::Substitute( - "$0.IsDefault(nullptr) ? &$1.get() : $0.GetPointer()", field_member, + "$0.IsDefault() ? &$1.get() : $0.GetPointer()", field_member, MakeDefaultName(descriptor)); } @@ -153,9 +153,6 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, std::string field_member = (*variables)["field_member"]; const google::protobuf::OneofDescriptor* oneof_member = descriptor->real_containing_oneof(); - if (oneof_member) { - field_member = StrCat(oneof_member->name(), "_.", field_member); - } const std::string proto_ns = (*variables)["proto_ns"]; const std::string substitute_template_prefix = " _tracker_.$1<$0>(this, "; std::string prepared_template; @@ -178,7 +175,7 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, } else if (descriptor->is_map()) { prepared_template = "nullptr"; } else if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE && - !descriptor->options().lazy()) { + !IsExplicitLazy(descriptor)) { prepared_template = "nullptr"; } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { if (oneof_member) { @@ -244,7 +241,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["number"] = StrCat(descriptor->number()); (*variables)["classname"] = ClassName(FieldScope(descriptor), false); (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - (*variables)["field_member"] = FieldName(descriptor) + "_"; + (*variables)["field_member"] = FieldMemberName(descriptor); (*variables)["tag_size"] = StrCat( WireFormat::TagSize(descriptor->number(), descriptor->type())); @@ -287,6 +284,9 @@ void FieldGenerator::SetInlinedStringIndex(int32_t inlined_string_index) { GOOGLE_CHECK_EQ(inlined_string_index, -1); return; } + // The first bit is the tracking bit for on demand registering ArenaDtor. + GOOGLE_CHECK_GT(inlined_string_index, 0) + << "_inlined_string_donated_'s bit 0 is reserved for arena dtor tracking"; variables_["inlined_string_donated"] = StrCat( "(_inlined_string_donated_[", inlined_string_index / 32, "] & 0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), @@ -303,8 +303,6 @@ void SetCommonOneofFieldVariables( std::map* variables) { const std::string prefix = descriptor->containing_oneof()->name() + "_."; (*variables)["oneof_name"] = descriptor->containing_oneof()->name(); - (*variables)["field_member"] = - StrCat(prefix, (*variables)["name"], "_"); } FieldGenerator::~FieldGenerator() {} diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index e0eb679b4c916..165b6fab47f09 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -40,9 +40,9 @@ #include #include +#include #include #include -#include namespace google { namespace protobuf { @@ -158,11 +158,10 @@ class FieldGenerator { // Generate a manual destructor invocation for use when the message is on an // arena. The code that this method generates will be executed inside a // shared-for-the-whole-message-class method registered with - // OwnDestructor(). The method should return |true| if it generated any code - // that requires a call; this allows the message generator to eliminate the - // OwnDestructor() registration if no fields require it. - virtual bool GenerateArenaDestructorCode(io::Printer* printer) const { - return false; + // OwnDestructor(). + virtual void GenerateArenaDestructorCode(io::Printer* printer) const { + GOOGLE_CHECK(NeedsArenaDestructor() == ArenaDtorNeeds::kNone) + << descriptor_->cpp_type_name(); } // Generate initialization code for private members declared by @@ -187,6 +186,10 @@ class FieldGenerator { virtual bool IsInlined() const { return false; } + virtual ArenaDtorNeeds NeedsArenaDestructor() const { + return ArenaDtorNeeds::kNone; + } + void SetHasBitIndex(int32_t has_bit_index); void SetInlinedStringIndex(int32_t inlined_string_index); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index c7816b546e93a..dfce01a3ef6d4 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -42,16 +42,16 @@ #include #include +#include +#include +#include #include #include #include #include #include #include -#include #include -#include -#include // Must be last. #include @@ -87,6 +87,23 @@ std::vector Sorted(const std::unordered_set& vals) { return sorted; } +// TODO(b/203101078): remove pragmas that suppresses uninitialized warnings when +// clang bug is fixed. +inline void MuteWuninitialized(Formatter& format) { + format( + "#if defined(__llvm__)\n" + " #pragma clang diagnostic push\n" + " #pragma clang diagnostic ignored \"-Wuninitialized\"\n" + "#endif // __llvm__\n"); +} + +inline void UnmuteWuninitialized(Formatter& format) { + format( + "#if defined(__llvm__)\n" + " #pragma clang diagnostic pop\n" + "#endif // __llvm__\n"); +} + } // namespace FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) @@ -335,7 +352,14 @@ void FileGenerator::DoIncludeFile(const std::string& google3_name, options_.runtime_include_base, path); } } else { - format("#include \"$1$\"", google3_name); + std::string path = google3_name; + // The bootstrapped proto generated code needs to use the + // third_party/protobuf header paths to avoid circular dependencies. + if (options_.bootstrap) { + path = StringReplace(google3_name, "net/proto2/public", + "third_party/protobuf", false); + } + format("#include \"$1$\"", path); } if (do_export) { @@ -428,12 +452,28 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { format("// @@protoc_insertion_point(includes)\n"); IncludeFile("net/proto2/public/port_def.inc", printer); +} + +void FileGenerator::GenerateSourcePrelude(io::Printer* printer) { + Formatter format(printer, variables_); // 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"); + + // Generate convenience aliases. + format( + "\n" + "namespace _pb = ::$1$;\n" + "namespace _pbi = _pb::internal;\n", + ProtobufNamespace(options_)); + if (HasGeneratedMethods(file_, options_) && + options_.tctable_mode != Options::kTCTableNever) { + format("namespace _fl = _pbi::field_layout;\n"); + } + format("\n"); } void FileGenerator::GenerateSourceDefaultInstance(int idx, @@ -447,7 +487,7 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, format( "struct $1$ {\n" " constexpr $1$()\n" - " : _instance(::$proto_ns$::internal::ConstantInitialized{}) {}\n" + " : _instance(::_pbi::ConstantInitialized{}) {}\n" " ~$1$() {}\n" " union {\n" " $2$ _instance;\n" @@ -459,7 +499,8 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, // enough. However, the empty destructor fails to be elided in some // configurations (like non-opt or with certain sanitizers). NO_DESTROY is // there just to improve performance and binary size in these builds. - format("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT $1$ $2$;\n", + format("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT " + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $1$ $2$;\n", DefaultInstanceType(generator->descriptor_, options_), DefaultInstanceName(generator->descriptor_, options_)); @@ -468,7 +509,7 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, if (IsStringInlined(field, options_)) { // Force the initialization of the inlined string in the default instance. format( - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY std::true_type " + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 std::true_type " "$1$::_init_inline_$2$_ = " "($3$._instance.$2$_.Init(), std::true_type{});\n", ClassName(generator->descriptor_), FieldName(field), @@ -477,10 +518,11 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, } if (options_.lite_implicit_weak_fields) { - format("$1$* $2$ = &$3$;\n", - DefaultInstanceType(generator->descriptor_, options_), - DefaultInstancePtr(generator->descriptor_, options_), - DefaultInstanceName(generator->descriptor_, options_)); + format( + "PROTOBUF_CONSTINIT const void* $1$ =\n" + " &$2$;\n", + DefaultInstancePtr(generator->descriptor_, options_), + DefaultInstanceName(generator->descriptor_, options_)); } } @@ -534,11 +576,10 @@ void FileGenerator::GenerateInternalForwardDeclarations( for (auto instance : Sorted(refs.weak_default_instances)) { ns.ChangeTo(Namespace(instance, options_)); if (options_.lite_implicit_weak_fields) { - format("extern $1$ $2$;\n", DefaultInstanceType(instance, options_), - DefaultInstanceName(instance, options_)); - format("__attribute__((weak)) $1$* $2$ = nullptr;\n", - DefaultInstanceType(instance, options_), - DefaultInstancePtr(instance, options_)); + format( + "PROTOBUF_CONSTINIT __attribute__((weak)) const void* $1$ =\n" + " &::_pbi::implicit_weak_message_default_instance;\n", + DefaultInstancePtr(instance, options_)); } else { format("extern __attribute__((weak)) $1$ $2$;\n", DefaultInstanceType(instance, options_), @@ -549,8 +590,7 @@ void FileGenerator::GenerateInternalForwardDeclarations( for (auto file : Sorted(refs.weak_reflection_files)) { format( - "extern __attribute__((weak)) const " - "::$proto_ns$::internal::DescriptorTable $1$;\n", + "extern __attribute__((weak)) const ::_pbi::DescriptorTable $1$;\n", DescriptorTableName(file, options_)); } } @@ -558,6 +598,9 @@ void FileGenerator::GenerateInternalForwardDeclarations( void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); + + if (IsAnyMessage(file_, options_)) MuteWuninitialized(format); CrossFileReferences refs; ForEachField(message_generators_[idx]->descriptor_, @@ -586,6 +629,8 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { message_generators_[idx]->GenerateSourceInProto2Namespace(printer); } + if (IsAnyMessage(file_, options_)) UnmuteWuninitialized(format); + format( "\n" "// @@protoc_insertion_point(global_scope)\n"); @@ -594,6 +639,7 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); NamespaceOpener ns(Namespace(file_, options_), format); extension_generators_[idx]->GenerateDefinition(printer); } @@ -601,10 +647,9 @@ void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) { void FileGenerator::GenerateGlobalSource(io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); { - GenerateTables(printer); - // Define the code to initialize reflection. This code uses a global // constructor to register reflection data with the runtime pre-main. if (HasDescriptorMethods(file_, options_)) { @@ -623,10 +668,13 @@ void FileGenerator::GenerateGlobalSource(io::Printer* printer) { void FileGenerator::GenerateSource(io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); CrossFileReferences refs; GetCrossFileReferencesForFile(file_, &refs); GenerateInternalForwardDeclarations(refs, printer); + if (IsAnyMessage(file_, options_)) MuteWuninitialized(format); + { NamespaceOpener ns(Namespace(file_, options_), format); @@ -637,8 +685,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) { } { - GenerateTables(printer); - if (HasDescriptorMethods(file_, options_)) { // Define the code to initialize reflection. This code uses a global // constructor to register reflection data with the runtime pre-main. @@ -695,6 +741,8 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "\n" "// @@protoc_insertion_point(global_scope)\n"); + if (IsAnyMessage(file_, options_)) UnmuteWuninitialized(format); + IncludeFile("net/proto2/public/port_undef.inc", printer); } @@ -702,31 +750,30 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { Formatter format(printer, variables_); if (!message_generators_.empty()) { - format("static ::$proto_ns$::Metadata $file_level_metadata$[$1$];\n", + format("static ::_pb::Metadata $file_level_metadata$[$1$];\n", message_generators_.size()); } if (!enum_generators_.empty()) { format( - "static " - "const ::$proto_ns$::EnumDescriptor* " + "static const ::_pb::EnumDescriptor* " "$file_level_enum_descriptors$[$1$];\n", enum_generators_.size()); } else { format( "static " - "constexpr ::$proto_ns$::EnumDescriptor const** " + "constexpr ::_pb::EnumDescriptor const** " "$file_level_enum_descriptors$ = nullptr;\n"); } if (HasGenericServices(file_, options_) && file_->service_count() > 0) { format( "static " - "const ::$proto_ns$::ServiceDescriptor* " + "const ::_pb::ServiceDescriptor* " "$file_level_service_descriptors$[$1$];\n", file_->service_count()); } else { format( "static " - "constexpr ::$proto_ns$::ServiceDescriptor const** " + "constexpr ::_pb::ServiceDescriptor const** " "$file_level_service_descriptors$ = nullptr;\n"); } @@ -744,7 +791,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { format.Outdent(); format( "};\n" - "static const ::$proto_ns$::internal::MigrationSchema schemas[] " + "static const ::_pbi::MigrationSchema schemas[] " "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); format.Indent(); { @@ -758,16 +805,13 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { format.Outdent(); format( "};\n" - "\nstatic " - "::$proto_ns$::Message const * const file_default_instances[] = {\n"); + "\nstatic const ::_pb::Message* const file_default_instances[] = {\n"); format.Indent(); for (int i = 0; i < message_generators_.size(); i++) { const Descriptor* descriptor = message_generators_[i]->descriptor_; - format( - "reinterpret_cast(&$1$::_$2$_default_instance_),\n", - Namespace(descriptor, options_), // 1 - ClassName(descriptor)); // 2 + format("&$1$::_$2$_default_instance_._instance,\n", + Namespace(descriptor, options_), // 1 + ClassName(descriptor)); // 2 } format.Outdent(); format( @@ -778,10 +822,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { format( // MSVC doesn't like empty arrays, so we add a dummy. "const $uint32$ $tablename$::offsets[1] = {};\n" - "static constexpr ::$proto_ns$::internal::MigrationSchema* schemas = " - "nullptr;" - "\n" - "static constexpr ::$proto_ns$::Message* const* " + "static constexpr ::_pbi::MigrationSchema* schemas = nullptr;\n" + "static constexpr ::_pb::Message* const* " "file_default_instances = nullptr;\n" "\n"); } @@ -836,7 +878,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // Build array of DescriptorTable deps. if (num_deps > 0) { format( - "static const ::$proto_ns$::internal::DescriptorTable*const " + "static const ::_pbi::DescriptorTable* const " "$desc_table$_deps[$1$] = {\n", num_deps); @@ -856,13 +898,14 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // so disable for now. bool eager = false; format( - "static ::$proto_ns$::internal::once_flag $desc_table$_once;\n" - "const ::$proto_ns$::internal::DescriptorTable $desc_table$ = {\n" - " false, $1$, $2$, $3$, \"$filename$\", \n" - " &$desc_table$_once, $4$, $5$, $6$,\n" - " schemas, file_default_instances, $tablename$::offsets,\n" - " $7$, $file_level_enum_descriptors$, " - "$file_level_service_descriptors$,\n" + "static ::_pbi::once_flag $desc_table$_once;\n" + "const ::_pbi::DescriptorTable $desc_table$ = {\n" + " false, $1$, $2$, $3$,\n" + " \"$filename$\",\n" + " &$desc_table$_once, $4$, $5$, $6$,\n" + " schemas, file_default_instances, $tablename$::offsets,\n" + " $7$, $file_level_enum_descriptors$,\n" + " $file_level_service_descriptors$,\n" "};\n" // This function exists to be marked as weak. // It can significantly speed up compilation by breaking up LLVM's SCC in @@ -875,7 +918,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // vtables -> GetMetadata // By adding a weak function here we break the connection from the // individual vtables back into the descriptor table. - "PROTOBUF_ATTRIBUTE_WEAK const ::$proto_ns$::internal::DescriptorTable* " + "PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* " "$desc_table$_getter() {\n" " return &$desc_table$;\n" "}\n" @@ -893,123 +936,12 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { if (file_->name() != "net/proto2/proto/descriptor.proto") { format( "// Force running AddDescriptors() at dynamic initialization time.\n" - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " - "static ::$proto_ns$::internal::AddDescriptorsRunner " - "$1$(&$desc_table$);\n", + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 " + "static ::_pbi::AddDescriptorsRunner $1$(&$desc_table$);\n", UniqueName("dynamic_init_dummy", file_, options_)); } } -void FileGenerator::GenerateTables(io::Printer* printer) { - Formatter format(printer, variables_); - if (options_.table_driven_parsing) { - // TODO(ckennelly): Gate this with the same options flag to enable - // table-driven parsing. - format( - "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTableField\n" - " const $tablename$::entries[] " - "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); - format.Indent(); - - std::vector entries; - size_t count = 0; - for (int i = 0; i < message_generators_.size(); i++) { - size_t value = message_generators_[i]->GenerateParseOffsets(printer); - entries.push_back(value); - count += value; - } - - // We need these arrays to exist, and MSVC does not like empty arrays. - if (count == 0) { - format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n"); - } - - format.Outdent(); - format( - "};\n" - "\n" - "PROTOBUF_CONSTEXPR_VAR " - "::$proto_ns$::internal::AuxiliaryParseTableField\n" - " const $tablename$::aux[] " - "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); - format.Indent(); - - std::vector aux_entries; - count = 0; - for (int i = 0; i < message_generators_.size(); i++) { - size_t value = message_generators_[i]->GenerateParseAuxTable(printer); - aux_entries.push_back(value); - count += value; - } - - if (count == 0) { - format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n"); - } - - format.Outdent(); - format( - "};\n" - "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTable const\n" - " $tablename$::schema[] " - "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); - format.Indent(); - - size_t offset = 0; - size_t aux_offset = 0; - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateParseTable(printer, offset, aux_offset); - offset += entries[i]; - aux_offset += aux_entries[i]; - } - - if (message_generators_.empty()) { - format("{ nullptr, nullptr, 0, -1, -1, false },\n"); - } - - format.Outdent(); - format( - "};\n" - "\n"); - } - - if (!message_generators_.empty() && options_.table_driven_serialization) { - format( - "const ::$proto_ns$::internal::FieldMetadata " - "$tablename$::field_metadata[] " - "= {\n"); - format.Indent(); - std::vector field_metadata_offsets; - int idx = 0; - for (int i = 0; i < message_generators_.size(); i++) { - field_metadata_offsets.push_back(idx); - idx += message_generators_[i]->GenerateFieldMetadata(printer); - } - field_metadata_offsets.push_back(idx); - format.Outdent(); - format( - "};\n" - "const ::$proto_ns$::internal::SerializationTable " - "$tablename$::serialization_table[] = {\n"); - format.Indent(); - // We rely on the order we layout the tables to match the order we - // calculate them with FlattenMessagesInFile, so we check here that - // these match exactly. - std::vector calculated_order = - FlattenMessagesInFile(file_); - GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size()); - for (int i = 0; i < message_generators_.size(); i++) { - GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_); - format("{$1$, $tablename$::field_metadata + $2$},\n", - field_metadata_offsets[i + 1] - field_metadata_offsets[i], // 1 - field_metadata_offsets[i]); // 2 - } - format.Outdent(); - format( - "};\n" - "\n"); - } -} - class FileGenerator::ForwardDeclarations { public: void AddMessage(const Descriptor* d) { classes_[ClassName(d)] = d; } @@ -1185,7 +1117,6 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { if (HasSimpleBaseClasses(file_, options_)) { IncludeFile("net/proto2/public/generated_message_bases.h", printer); } - IncludeFile("net/proto2/public/generated_message_table_driven.h", printer); if (HasGeneratedMethods(file_, options_) && options_.tctable_mode != Options::kTCTableNever) { IncludeFile("net/proto2/public/generated_message_tctable_decl.h", printer); @@ -1297,20 +1228,8 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations( "\n" "// Internal implementation detail -- do not use these members.\n" "struct $dllexport_decl $$tablename$ {\n" - // These tables describe how to serialize and parse messages. Used - // for table driven code. - " static const ::$proto_ns$::internal::ParseTableField entries[]\n" - " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\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" - " static const ::$proto_ns$::internal::FieldMetadata field_metadata[];\n" - " static const ::$proto_ns$::internal::SerializationTable " - "serialization_table[];\n" " static const $uint32$ offsets[];\n" - "};\n", - std::max(size_t(1), message_generators_.size())); + "};\n"); if (HasDescriptorMethods(file_, options_)) { format( "$dllexport_decl $extern const ::$proto_ns$::internal::DescriptorTable " diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index e8816020dde37..b69202fa1eb99 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h @@ -40,11 +40,12 @@ #include #include #include + #include #include #include -#include #include +#include namespace google { namespace protobuf { @@ -122,11 +123,11 @@ class FileGenerator { void GenerateInternalForwardDeclarations(const CrossFileReferences& refs, io::Printer* printer); void GenerateSourceIncludes(io::Printer* printer); + void GenerateSourcePrelude(io::Printer* printer); void GenerateSourceDefaultInstance(int idx, io::Printer* printer); void GenerateInitForSCC(const SCC* scc, const CrossFileReferences& refs, io::Printer* printer); - void GenerateTables(io::Printer* printer); void GenerateReflectionInitializationCode(io::Printer* printer); // For other imports, generates their forward-declarations. diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index 085157102bb4e..5abcd45d90f8b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -40,11 +40,11 @@ #include #include +#include +#include #include #include #include -#include -#include namespace google { namespace protobuf { @@ -109,7 +109,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_options.lite_implicit_weak_fields = true; if (!options[i].second.empty()) { file_options.num_cc_files = - strto32(options[i].second.c_str(), NULL, 10); + strto32(options[i].second.c_str(), nullptr, 10); } } else if (options[i].first == "annotate_accessor") { file_options.annotate_accessor = true; @@ -127,14 +127,14 @@ bool CppGenerator::Generate(const FileDescriptor* file, .insert(options[i].second.substr(pos, next_pos - pos)); pos = next_pos + 1; } while (pos < options[i].second.size()); + } else if (options[i].first == "verified_lazy_message_sets") { + file_options.unverified_lazy_message_sets = false; + } else if (options[i].first == "unverified_lazy_message_sets") { + file_options.unverified_lazy_message_sets = true; } else if (options[i].first == "eagerly_verified_lazy") { file_options.eagerly_verified_lazy = true; } else if (options[i].first == "force_eagerly_verified_lazy") { file_options.force_eagerly_verified_lazy = true; - } else if (options[i].first == "table_driven_parsing") { - file_options.table_driven_parsing = true; - } else if (options[i].first == "table_driven_serialization") { - file_options.table_driven_serialization = true; } else if (options[i].first == "experimental_tail_call_table_mode") { if (options[i].second == "never") { file_options.tctable_mode = Options::kTCTableNever; @@ -183,7 +183,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, std::string info_path = basename + ".proto.h.meta"; io::Printer printer( output.get(), '$', - file_options.annotate_headers ? &annotation_collector : NULL); + file_options.annotate_headers ? &annotation_collector : nullptr); file_generator.GenerateProtoHeader( &printer, file_options.annotate_headers ? info_path : ""); if (file_options.annotate_headers) { @@ -202,7 +202,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, std::string info_path = basename + ".pb.h.meta"; io::Printer printer( output.get(), '$', - file_options.annotate_headers ? &annotation_collector : NULL); + file_options.annotate_headers ? &annotation_collector : nullptr); file_generator.GeneratePBHeader( &printer, file_options.annotate_headers ? info_path : ""); if (file_options.annotate_headers) { diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h index 97e848dc4f50e..1a374b9f1685d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.h +++ b/src/google/protobuf/compiler/cpp/cpp_generator.h @@ -40,6 +40,7 @@ #include #include +// Must be included last. #include namespace google { @@ -54,7 +55,7 @@ namespace cpp { class PROTOC_EXPORT CppGenerator : public CodeGenerator { public: CppGenerator(); - ~CppGenerator(); + ~CppGenerator() override; enum class Runtime { kGoogle3, // Use the internal google3 runtime. diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 9fe47bff5ff2c..2eb91f3327170 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -44,10 +44,10 @@ #include #include -#include +#include #include +#include #include -#include #include #include #include @@ -453,6 +453,14 @@ std::string FieldName(const FieldDescriptor* field) { return result; } +std::string FieldMemberName(const FieldDescriptor* field) { + if (field->real_containing_oneof() == nullptr) { + return StrCat(FieldName(field), "_"); + } + return StrCat(field->containing_oneof()->name(), "_.", FieldName(field), + "_"); +} + std::string OneofCaseConstantName(const FieldDescriptor* field) { GOOGLE_DCHECK(field->containing_oneof()); std::string field_name = UnderscoresToCamelCase(field->name(), true); @@ -1147,7 +1155,6 @@ 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->real_containing_oneof() && !IsWellKnownMessage(field->message_type()->file()) && field->message_type()->file()->name() != "net/proto2/proto/descriptor.proto" && @@ -1264,7 +1271,7 @@ bool GetBootstrapBasename(const Options& options, const std::string& basename, std::unordered_map bootstrap_mapping{ {"net/proto2/proto/descriptor", - "net/proto2/internal/descriptor"}, + "third_party/protobuf/descriptor"}, {"net/proto2/compiler/proto/plugin", "net/proto2/compiler/proto/plugin"}, {"net/proto2/compiler/proto/profile", @@ -1297,7 +1304,7 @@ bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context, *basename = bootstrap_basename; return false; } else { - std::string forward_to_basename = bootstrap_basename; + const std::string& forward_to_basename = bootstrap_basename; // Generate forwarding headers and empty .pb.cc. { @@ -1486,8 +1493,9 @@ FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file, return FileOptions::SPEED; } -bool EnableMessageOwnedArena(const Descriptor* desc) { +bool EnableMessageOwnedArena(const Descriptor* desc, const Options& options) { (void)desc; + (void)options; return false; } diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index bd4f48bc8ed1e..c0217259ad4a7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -41,10 +41,10 @@ #include #include -#include -#include #include #include +#include +#include #include #include #include @@ -59,6 +59,8 @@ namespace protobuf { namespace compiler { namespace cpp { +enum class ArenaDtorNeeds { kNone = 0, kOnDemand = 1, kRequired = 2 }; + inline std::string ProtobufNamespace(const Options& /* options */) { return "PROTOBUF_NAMESPACE_ID"; } @@ -186,6 +188,9 @@ std::string ResolveKeyword(const std::string& name); // anyway, so normally this just returns field->name(). std::string FieldName(const FieldDescriptor* field); +// Returns the (unqualified) private member name for this field in C++ code. +std::string FieldMemberName(const FieldDescriptor* field); + // Returns an estimate of the compiler's alignment for the field. This // can't guarantee to be correct because the generated code could be compiled on // different systems with different alignment rules. The estimates below assume @@ -348,9 +353,17 @@ bool HasLazyFields(const FileDescriptor* file, const Options& options, bool IsLazy(const FieldDescriptor* field, const Options& options, MessageSCCAnalyzer* scc_analyzer); +// Is this an explicit (non-profile driven) lazy field, as denoted by +// lazy/unverified_lazy in the descriptor? +inline bool IsExplicitLazy(const FieldDescriptor* field) { + return field->options().lazy() || field->options().unverified_lazy(); +} + inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field, const Options& options) { - return field->options().lazy() && !field->is_repeated() && + // TODO(b/211906113): Make lazy() imply eagerly verified lazy. + return IsExplicitLazy(field) && + !field->is_repeated() && field->type() == FieldDescriptor::TYPE_MESSAGE && GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME && !options.opensource_runtime; @@ -359,7 +372,8 @@ inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field, inline bool IsEagerlyVerifiedLazy(const FieldDescriptor* field, const Options& options, MessageSCCAnalyzer* scc_analyzer) { - return IsLazy(field, options, scc_analyzer) && !field->options().lazy(); + // TODO(b/211906113): Make lazy() imply eagerly verified lazy. + return IsLazy(field, options, scc_analyzer) && !IsExplicitLazy(field); } inline bool IsFieldUsed(const FieldDescriptor* /* field */, @@ -955,7 +969,7 @@ inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; } PROTOC_EXPORT std::string StripProto(const std::string& filename); -bool EnableMessageOwnedArena(const Descriptor* desc); +bool EnableMessageOwnedArena(const Descriptor* desc, const Options& options); bool ShouldVerify(const Descriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index 130e90ebbe0aa..4c7765892acc0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -30,10 +30,10 @@ #include -#include #include #include #include +#include namespace google { @@ -53,10 +53,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["type"] = ClassName(descriptor->message_type(), false); (*variables)["full_name"] = descriptor->full_name(); - const FieldDescriptor* key = - descriptor->message_type()->FindFieldByName("key"); - const FieldDescriptor* val = - descriptor->message_type()->FindFieldByName("value"); + const FieldDescriptor* key = descriptor->message_type()->map_key(); + const FieldDescriptor* val = descriptor->message_type()->map_value(); (*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type()); switch (val->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: @@ -169,35 +167,27 @@ void MapFieldGenerator::GenerateCopyConstructorCode( GenerateMergingCode(printer); } -static void GenerateSerializationLoop(const Formatter& format, bool string_key, +static void GenerateSerializationLoop(Formatter& format, bool string_key, bool string_value, bool is_deterministic) { - std::string ptr; if (is_deterministic) { - format("for (size_type i = 0; i < n; i++) {\n"); - ptr = string_key ? "items[static_cast(i)]" - : "items[static_cast(i)].second"; - } else { format( - "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = this->_internal_$name$().begin();\n" - " it != this->_internal_$name$().end(); ++it) {\n"); - ptr = "it"; + "for (const auto& entry : " + "::_pbi::MapSorter$1$(map_field)) {\n", + (string_key ? "Ptr" : "Flat")); + } else { + format("for (const auto& entry : map_field) {\n"); } - format.Indent(); + { + auto loop_scope = format.ScopedIndent(); + format( + "target = WireHelper::InternalSerialize($number$, " + "entry.first, entry.second, target, stream);\n"); - format( - "target = $map_classname$::Funcs::InternalSerialize($number$, " - "$1$->first, $1$->second, target, stream);\n", - ptr); - - if (string_key || string_value) { - // ptr is either an actual pointer or an iterator, either way we can - // create a pointer by taking the address after de-referencing it. - format("Utf8Check::Check(&(*$1$));\n", ptr); + if (string_key || string_value) { + format("check_utf8(entry);\n"); + } } - - format.Outdent(); format("}\n"); } @@ -206,77 +196,53 @@ void MapFieldGenerator::GenerateSerializeWithCachedSizesToArray( Formatter format(printer, variables_); format("if (!this->_internal_$name$().empty()) {\n"); format.Indent(); - const FieldDescriptor* key_field = - descriptor_->message_type()->FindFieldByName("key"); - const FieldDescriptor* value_field = - descriptor_->message_type()->FindFieldByName("value"); + const FieldDescriptor* key_field = descriptor_->message_type()->map_key(); + const FieldDescriptor* value_field = descriptor_->message_type()->map_value(); const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING; const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING; format( - "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n" - " ConstPtr;\n"); - if (string_key) { - format( - "typedef ConstPtr SortItem;\n" - "typedef ::$proto_ns$::internal::" - "CompareByDerefFirst Less;\n"); - } else { - format( - "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > " - "SortItem;\n" - "typedef ::$proto_ns$::internal::CompareByFirstField " - "Less;\n"); - } + "using MapType = ::_pb::Map<$key_cpp$, $val_cpp$>;\n" + "using WireHelper = $map_classname$::Funcs;\n" + "const auto& map_field = this->_internal_$name$();\n"); bool utf8_check = string_key || string_value; if (utf8_check) { - format( - "struct Utf8Check {\n" - " static void Check(ConstPtr p) {\n" - // p may be unused when GetUtf8CheckMode evaluates to kNone, - // thus disabling the validation. - " (void)p;\n"); - format.Indent(); - format.Indent(); - if (string_key) { - GenerateUtf8CheckCodeForString( - key_field, options_, false, - "p->first.data(), static_cast(p->first.length()),\n", format); + format("auto check_utf8 = [](const MapType::value_type& entry) {\n"); + { + auto check_scope = format.ScopedIndent(); + // p may be unused when GetUtf8CheckMode evaluates to kNone, + // thus disabling the validation. + format("(void)entry;\n"); + if (string_key) { + GenerateUtf8CheckCodeForString( + key_field, options_, false, + "entry.first.data(), static_cast(entry.first.length()),\n", + format); + } + if (string_value) { + GenerateUtf8CheckCodeForString( + value_field, options_, false, + "entry.second.data(), static_cast(entry.second.length()),\n", + format); + } } - if (string_value) { - GenerateUtf8CheckCodeForString( - value_field, options_, false, - "p->second.data(), static_cast(p->second.length()),\n", format); - } - format.Outdent(); - format.Outdent(); format( - " }\n" "};\n"); } format( "\n" - "if (stream->IsSerializationDeterministic() &&\n" - " this->_internal_$name$().size() > 1) {\n" - " ::std::unique_ptr items(\n" - " new SortItem[this->_internal_$name$().size()]);\n" - " typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type " - "size_type;\n" - " size_type n = 0;\n" - " for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = this->_internal_$name$().begin();\n" - " it != this->_internal_$name$().end(); ++it, ++n) {\n" - " items[static_cast(n)] = SortItem(&*it);\n" - " }\n" - " ::std::sort(&items[0], &items[static_cast(n)], Less());\n"); - format.Indent(); - GenerateSerializationLoop(format, string_key, string_value, true); - format.Outdent(); + "if (stream->IsSerializationDeterministic() && " + "map_field.size() > 1) {\n"); + { + auto deterministic_scope = format.ScopedIndent(); + GenerateSerializationLoop(format, string_key, string_value, true); + } format("} else {\n"); - format.Indent(); - GenerateSerializationLoop(format, string_key, string_value, false); - format.Outdent(); + { + auto map_order_scope = format.ScopedIndent(); + GenerateSerializationLoop(format, string_key, string_value, false); + } format("}\n"); format.Outdent(); format("}\n"); @@ -315,17 +281,28 @@ void MapFieldGenerator::GenerateConstinitInitializer( } } -bool MapFieldGenerator::GenerateArenaDestructorCode( - io::Printer* printer) const { +void MapFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); - if (HasDescriptorMethods(descriptor_->file(), options_)) { - // _this is the object being destructed (we are inside a static method - // here). - format("_this->$name$_. ~MapField();\n"); - return true; - } else { - return false; + format("$name$_.Destruct();\n"); +} + +void MapFieldGenerator::GenerateArenaDestructorCode( + io::Printer* printer) const { + if (NeedsArenaDestructor() == ArenaDtorNeeds::kNone) { + return; } + + Formatter format(printer, variables_); + // _this is the object being destructed (we are inside a static method here). + format("_this->$name$_.Destruct();\n"); +} + +ArenaDtorNeeds MapFieldGenerator::NeedsArenaDestructor() const { + return HasDescriptorMethods(descriptor_->file(), options_) + ? ArenaDtorNeeds::kRequired + : ArenaDtorNeeds::kNone; } } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h index c01ae498b1aa9..9e71267c0f155 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h @@ -62,7 +62,9 @@ class MapFieldGenerator : public FieldGenerator { void GenerateByteSize(io::Printer* printer) const override; void GenerateIsInitialized(io::Printer* printer) const override; void GenerateConstinitInitializer(io::Printer* printer) const override; - bool GenerateArenaDestructorCode(io::Printer* printer) const override; + void GenerateDestructorCode(io::Printer* printer) const override; + void GenerateArenaDestructorCode(io::Printer* printer) const override; + ArenaDtorNeeds NeedsArenaDestructor() const override; private: const bool has_required_fields_; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 70d8a57e3a9e3..030fc4be397ea 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -44,22 +44,21 @@ #include #include -#include -#include -#include -#include -#include -#include -#include #include #include #include -#include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include @@ -276,8 +275,8 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor, std::map* variables) { GOOGLE_CHECK(IsMapEntryMessage(descriptor)); std::map& vars = *variables; - const FieldDescriptor* key = descriptor->FindFieldByName("key"); - const FieldDescriptor* val = descriptor->FindFieldByName("value"); + const FieldDescriptor* key = descriptor->map_key(); + const FieldDescriptor* val = descriptor->map_value(); vars["key_cpp"] = PrimitiveTypeName(options, key->cpp_type()); switch (val->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: @@ -323,64 +322,6 @@ bool ShouldSerializeInOrder(const Descriptor* descriptor, return true; } -bool TableDrivenParsingEnabled(const Descriptor* descriptor, - const Options& options, - MessageSCCAnalyzer* scc_analyzer) { - if (!options.table_driven_parsing) { - return false; - } - - // 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). - 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)) { - if (max_field_number < field->number()) { - max_field_number = field->number(); - } - - // - There are no weak fields. - if (IsWeak(field, options)) { - return false; - } - - // - There are no lazy fields (they require the non-lite library). - if (IsLazy(field, options, scc_analyzer)) { - return false; - } - } - - // - There range of field numbers is "small" - if (max_field_number >= (2 << 14)) { - return false; - } - - // - Field numbers are relatively dense within the actual number of fields. - // We check for strictly greater than in the case where there are no fields - // (only extensions) so max_field_number == descriptor->field_count() == 0. - if (max_field_number * table_sparseness > descriptor->field_count()) { - return false; - } - - // - This is not a MapEntryMessage. - if (IsMapEntryMessage(descriptor)) { - return false; - } - - return true; -} - bool IsCrossFileMapField(const FieldDescriptor* field) { if (!field->is_map()) { return false; @@ -406,8 +347,8 @@ bool IsRequired(const std::vector& v) { bool HasSingularString(const Descriptor* desc, const Options& options) { for (const auto* field : FieldRange(desc)) { - if (IsString(field, options) && !IsStringInlined(field, options) && - !field->is_repeated() && !field->real_containing_oneof()) { + if (IsString(field, options) && !field->is_repeated() && + !field->real_containing_oneof()) { return true; } } @@ -738,6 +679,9 @@ MessageGenerator::MessageGenerator( if (IsStringInlined(field, options_)) { if (inlined_string_indices_.empty()) { inlined_string_indices_.resize(descriptor_->field_count(), kNoHasbit); + // The bitset[0] is for arena dtor tracking. Donating states start from + // bitset[1]; + max_inlined_string_index_++; } inlined_string_indices_[field->index()] = max_inlined_string_index_++; } @@ -758,8 +702,6 @@ MessageGenerator::MessageGenerator( } } - table_driven_ = - TableDrivenParsingEnabled(descriptor_, options_, scc_analyzer_); parse_function_generator_.reset(new ParseFunctionGenerator( descriptor_, max_has_bit_index_, has_bit_indices_, inlined_string_indices_, options_, scc_analyzer_, variables_)); @@ -1432,7 +1374,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "" " ::$proto_ns$::Metadata GetMetadata() const final;\n"); } - format("};\n"); + format( + " friend struct ::$tablename$;\n" + "};\n"); return; } @@ -1444,7 +1388,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format(" public:\n"); format.Indent(); - if (EnableMessageOwnedArena(descriptor_)) { + if (EnableMessageOwnedArena(descriptor_, options_)) { format( "inline $classname$() : $classname$(" "::$proto_ns$::Arena::InternalHelper<$classname$>::\n" @@ -1484,14 +1428,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "}\n" "\n"); - if (options_.table_driven_serialization) { - format( - "private:\n" - "const void* InternalGetTable() const override;\n" - "public:\n" - "\n"); - } - if (PublicUnknownFieldsAccessors(descriptor_)) { format( "inline const $unknown_fields_type$& unknown_fields() const {\n" @@ -1756,13 +1692,30 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // we rely on. "protected:\n" "explicit $classname$(::$proto_ns$::Arena* arena,\n" - " bool is_message_owned = false);\n" - "private:\n"); + " bool is_message_owned = false);\n"); - if (!HasSimpleBaseClass(descriptor_, options_)) { - format( - "static void ArenaDtor(void* object);\n" - "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); + switch (NeedsArenaDestructor()) { + case ArenaDtorNeeds::kOnDemand: + format( + "private:\n" + "static void ArenaDtor(void* object);\n" + "inline void OnDemandRegisterArenaDtor(::$proto_ns$::Arena* arena) " + "override {\n" + " if (arena == nullptr || (_inlined_string_donated_[0] & 0x1u) == " + "0) {\n" + " return;\n" + " }\n" + " _inlined_string_donated_[0] &= 0xFFFFFFFEu;\n" + " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" + "}\n"); + break; + case ArenaDtorNeeds::kRequired: + format( + "private:\n" + "static void ArenaDtor(void* object);\n"); + break; + case ArenaDtorNeeds::kNone: + break; } format( @@ -1866,7 +1819,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // Prepare decls for _cached_size_ and _has_bits_. Their position in the // output will be determined later. - bool need_to_emit_cached_size = true; + bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_); const std::string cached_size_decl = "mutable ::$proto_ns$::internal::CachedSize _cached_size_;\n"; @@ -1917,8 +1870,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // _cached_size_ together with _has_bits_ improves cache locality despite // potential alignment padding. format(has_bits_decl.c_str()); - format(cached_size_decl.c_str()); - need_to_emit_cached_size = false; + if (need_to_emit_cached_size) { + format(cached_size_decl.c_str()); + need_to_emit_cached_size = false; + } } // Field members: @@ -2007,67 +1962,6 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) { } } -bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, - size_t aux_offset) { - Formatter format(printer, variables_); - - if (!table_driven_) { - format("{ nullptr, nullptr, 0, -1, -1, -1, -1, nullptr, false },\n"); - return false; - } - - int max_field_number = 0; - for (auto field : FieldRange(descriptor_)) { - if (max_field_number < field->number()) { - max_field_number = field->number(); - } - } - - format("{\n"); - format.Indent(); - - format( - "$tablename$::entries + $1$,\n" - "$tablename$::aux + $2$,\n" - "$3$,\n", - offset, aux_offset, max_field_number); - - 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_->real_oneof_decl_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n"); - } else { - format("-1, // no _oneof_case_\n"); - } - - if (descriptor_->extension_range_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n"); - } else { - format("-1, // no _extensions_\n"); - } - - // TODO(ckennelly): Consolidate this with the calculation for - // AuxiliaryParseTableField. - format( - "PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n" - "&$package_ns$::_$classname$_default_instance_,\n"); - - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - format("true,\n"); - } else { - format("false,\n"); - } - - format.Outdent(); - format("},\n"); - return true; -} - void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, int has_offset) { Formatter format(printer, variables_); @@ -2087,218 +1981,6 @@ void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, inlined_string_indices_offset); } -namespace { - -// We need to calculate for each field what function the table driven code -// should use to serialize it. This returns the index in a lookup table. -uint32_t CalcFieldNum(const FieldGenerator& generator, - const FieldDescriptor* field, const Options& options) { - bool is_a_map = IsMapEntryMessage(field->containing_type()); - int type = field->type(); - if (type == FieldDescriptor::TYPE_STRING || - type == FieldDescriptor::TYPE_BYTES) { - // string field - if (generator.IsInlined()) { - type = internal::FieldMetadata::kInlinedType; - } else if (IsCord(field, options)) { - type = internal::FieldMetadata::kCordType; - } else if (IsStringPiece(field, options)) { - type = internal::FieldMetadata::kStringPieceType; - } - } - - if (field->real_containing_oneof()) { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kOneOf); - } 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 (HasHasbit(field) || field->real_containing_oneof() || is_a_map) { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kPresence); - } else { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kNoPresence); - } -} - -int FindMessageIndexInFile(const Descriptor* descriptor) { - std::vector flatten = - FlattenMessagesInFile(descriptor->file()); - return std::find(flatten.begin(), flatten.end(), descriptor) - - flatten.begin(); -} - -} // namespace - -int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { - Formatter format(printer, variables_); - if (!options_.table_driven_serialization) { - return 0; - } - - std::vector sorted = SortFieldsByNumber(descriptor_); - if (IsMapEntryMessage(descriptor_)) { - for (int i = 0; i < 2; i++) { - const FieldDescriptor* field = sorted[i]; - const FieldGenerator& generator = field_generators_.get(field); - - uint32_t tag = internal::WireFormatLite::MakeTag( - field->number(), WireFormat::WireTypeForFieldType(field->type())); - - std::map vars; - vars["classtype"] = QualifiedClassName(descriptor_, options_); - vars["field_name"] = FieldName(field); - vars["tag"] = StrCat(tag); - vars["hasbit"] = StrCat(i); - vars["type"] = StrCat(CalcFieldNum(generator, field, options_)); - vars["ptr"] = "nullptr"; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - GOOGLE_CHECK(!IsMapEntryMessage(field->message_type())); - vars["ptr"] = - "::" + UniqueName("TableStruct", field->message_type(), options_) + - "::serialization_table + " + - StrCat(FindMessageIndexInFile(field->message_type())); - } - Formatter::SaveState saver(&format); - format.AddMap(vars); - format( - "{PROTOBUF_FIELD_OFFSET(" - "::$proto_ns$::internal::MapEntryHelper<$classtype$::" - "SuperType>, $field_name$_), $tag$," - "PROTOBUF_FIELD_OFFSET(" - "::$proto_ns$::internal::MapEntryHelper<$classtype$::" - "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, " - "$ptr$},\n"); - } - return 2; - } - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, _cached_size_)," - " 0, 0, 0, nullptr},\n"); - 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()); - for (int i = 0, extension_idx = 0; /* no range */; i++) { - for (; extension_idx < sorted_extensions.size() && - (i == sorted.size() || - sorted_extensions[extension_idx]->start < sorted[i]->number()); - extension_idx++) { - const Descriptor::ExtensionRange* range = - sorted_extensions[extension_idx]; - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, _extensions_), " - "$1$, $2$, ::$proto_ns$::internal::FieldMetadata::kSpecial, " - "reinterpret_cast(::$proto_ns$::internal::ExtensionSerializer)},\n", - range->start, range->end); - } - if (i == sorted.size()) break; - const FieldDescriptor* field = sorted[i]; - - uint32_t tag = internal::WireFormatLite::MakeTag( - field->number(), WireFormat::WireTypeForFieldType(field->type())); - if (field->is_packed()) { - tag = internal::WireFormatLite::MakeTag( - field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - } - - std::string classfieldname = FieldName(field); - if (field->real_containing_oneof()) { - classfieldname = field->containing_oneof()->name(); - } - format.Set("field_name", classfieldname); - std::string ptr = "nullptr"; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (IsMapEntryMessage(field->message_type())) { - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$, $2$, " - "::$proto_ns$::internal::FieldMetadata::kSpecial, " - "reinterpret_cast(static_cast< " - "::$proto_ns$::internal::SpecialSerializer>(" - "::$proto_ns$::internal::MapFieldSerializer< " - "::$proto_ns$::internal::MapEntryToMapField<" - "$3$>::MapFieldType, " - "$tablename$::serialization_table>))},\n", - tag, FindMessageIndexInFile(field->message_type()), - QualifiedClassName(field->message_type(), options_)); - continue; - } else if (!field->message_type()->options().message_set_wire_format()) { - // message_set doesn't have the usual table and we need to - // dispatch to generated serializer, hence ptr stays zero. - ptr = - "::" + UniqueName("TableStruct", field->message_type(), options_) + - "::serialization_table + " + - StrCat(FindMessageIndexInFile(field->message_type())); - } - } - - const FieldGenerator& generator = field_generators_.get(field); - int type = CalcFieldNum(generator, field, options_); - - if (IsLazy(field, options_, scc_analyzer_)) { - type = internal::FieldMetadata::kSpecial; - ptr = "reinterpret_cast(::" + variables_["proto_ns"] + - "::internal::LazyFieldSerializer"; - if (field->real_containing_oneof()) { - ptr += "OneOf"; - } else if (!HasHasbit(field)) { - ptr += "NoPresence"; - } - ptr += ")"; - } - - if (field->options().weak()) { - // TODO(gerbens) merge weak fields into ranges - format( - "{PROTOBUF_FIELD_OFFSET(" - "$classtype$, _weak_field_map_), $1$, $1$, " - "::$proto_ns$::internal::FieldMetadata::kSpecial, " - "reinterpret_cast(::$proto_ns$::internal::WeakFieldSerializer)},\n", - tag); - } else if (field->real_containing_oneof()) { - format.Set("oneofoffset", - sizeof(uint32_t) * field->containing_oneof()->index()); - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$," - " PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_) + " - "$oneofoffset$, $2$, $3$},\n", - tag, type, ptr); - } else if (HasHasbit(field)) { - format.Set("hasbitsoffset", has_bit_indices_[field->index()]); - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), " - "$1$, PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_) * 8 + " - "$hasbitsoffset$, $2$, $3$},\n", - tag, type, ptr); - } else { - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), " - "$1$, ~0u, $2$, $3$},\n", - tag, type, ptr); - } - } - int num_field_metadata = 1 + sorted.size() + sorted_extensions.size(); - num_field_metadata++; - std::string serializer = UseUnknownFieldSet(descriptor_->file(), options_) - ? "UnknownFieldSetSerializer" - : "UnknownFieldSerializerLite"; - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_), 0, ~0u, " - "::$proto_ns$::internal::FieldMetadata::kSpecial, reinterpret_cast(::$proto_ns$::internal::$1$)},\n", - serializer); - return num_field_metadata; -} - void MessageGenerator::GenerateClassMethods(io::Printer* printer) { Formatter format(printer, variables_); if (IsMapEntryMessage(descriptor_)) { @@ -2314,7 +1996,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" "$annotate_reflection$" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2322,7 +2004,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { } else { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2339,7 +2021,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { " const ::$proto_ns$::Message& message,\n" " const ::$proto_ns$::FieldDescriptor** type_url_field,\n" " const ::$proto_ns$::FieldDescriptor** value_field) {\n" - " return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n" + " return ::_pbi::GetAnyFieldDescriptors(\n" " message, type_url_field, value_field);\n" "}\n"); } @@ -2347,8 +2029,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { "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" + " return ::_pbi::ParseAnyTypeUrl(type_url, full_type_name);\n" "}\n" "\n"); } @@ -2455,20 +2136,12 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { GenerateSwap(printer); format("\n"); - if (options_.table_driven_serialization) { - format( - "const void* $classname$::InternalGetTable() const {\n" - " return ::$tablename$::serialization_table + $1$;\n" - "}\n" - "\n", - index_in_file_messages_); - } if (HasDescriptorMethods(descriptor_->file(), options_)) { if (!descriptor_->options().map_entry()) { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" "$annotate_reflection$" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2476,7 +2149,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { } else { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2500,202 +2173,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { } } -size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { - Formatter format(printer, variables_); - - if (!table_driven_) { - return 0; - } - - // Field "0" is special: We use it in our switch statement of processing - // types to handle the successful end tag case. - format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n"); - int last_field_number = 1; - - std::vector ordered_fields = - SortFieldsByNumber(descriptor_); - - 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( - "{ 0, 0, ::$proto_ns$::internal::kInvalidMask,\n" - " ::$proto_ns$::internal::kInvalidMask, 0, 0 },\n"); - } - last_field_number++; - - unsigned char normal_wiretype, packed_wiretype, processing_type; - normal_wiretype = WireFormat::WireTypeForFieldType(field->type()); - - if (field->is_packable()) { - packed_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED; - } else { - packed_wiretype = internal::kNotPackedMask; - } - - 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; - case FieldOptions::CORD: - processing_type = internal::TYPE_STRING_CORD; - break; - case FieldOptions::STRING_PIECE: - processing_type = internal::TYPE_STRING_STRING_PIECE; - break; - } - } else if (field->type() == FieldDescriptor::TYPE_BYTES) { - switch (EffectiveStringCType(field, options_)) { - case FieldOptions::STRING: - if (generator.IsInlined()) { - processing_type = internal::TYPE_BYTES_INLINED; - } - break; - case FieldOptions::CORD: - processing_type = internal::TYPE_BYTES_CORD; - break; - case FieldOptions::STRING_PIECE: - processing_type = internal::TYPE_BYTES_STRING_PIECE; - break; - } - } - - processing_type |= static_cast( - field->is_repeated() ? internal::kRepeatedMask : 0); - processing_type |= static_cast( - field->real_containing_oneof() ? internal::kOneofMask : 0); - - if (field->is_map()) { - processing_type = internal::TYPE_MAP; - } - - const unsigned char tag_size = - WireFormat::TagSize(field->number(), field->type()); - - std::map vars; - if (field->real_containing_oneof()) { - vars["name"] = field->containing_oneof()->name(); - vars["presence"] = StrCat(field->containing_oneof()->index()); - } else { - vars["name"] = FieldName(field); - vars["presence"] = StrCat(has_bit_indices_[field->index()]); - } - vars["nwtype"] = StrCat(normal_wiretype); - vars["pwtype"] = StrCat(packed_wiretype); - vars["ptype"] = StrCat(processing_type); - vars["tag_size"] = StrCat(tag_size); - - format.AddMap(vars); - - format( - "{\n" - " PROTOBUF_FIELD_OFFSET($classtype$, $name$_),\n" - " static_cast<$uint32$>($presence$),\n" - " $nwtype$, $pwtype$, $ptype$, $tag_size$\n" - "},\n"); - } - - return last_field_number; -} - -size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { - Formatter format(printer, variables_); - - if (!table_driven_) { - return 0; - } - - std::vector ordered_fields = - SortFieldsByNumber(descriptor_); - - 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::AuxiliaryParseTableField(),\n"); - } - - std::map vars; - SetCommonFieldVariables(field, &vars, options_); - format.AddMap(vars); - - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_ENUM: - if (HasPreservingUnknownEnumSemantics(field)) { - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{" - "nullptr}},\n"); - } else { - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{" - "$1$_IsValid}},\n", - ClassName(field->enum_type(), true)); - } - last_field_number++; - break; - case FieldDescriptor::CPPTYPE_MESSAGE: { - if (field->is_map()) { - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::map_" - "aux{&::$proto_ns$::internal::ParseMap<$1$>}},\n", - QualifiedClassName(field->message_type(), options_)); - last_field_number++; - break; - } - format.Set("field_classname", ClassName(field->message_type(), false)); - format.Set("default_instance", QualifiedDefaultInstanceName( - field->message_type(), options_)); - - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::message_aux{\n" - " &$default_instance$}},\n"); - last_field_number++; - break; - } - case FieldDescriptor::CPPTYPE_STRING: { - std::string default_val; - switch (EffectiveStringCType(field, options_)) { - case FieldOptions::STRING: - default_val = field->default_value_string().empty() - ? "&::" + variables_["proto_ns"] + - "::internal::fixed_address_empty_string" - : "&" + - QualifiedClassName(descriptor_, options_) + - "::" + MakeDefaultName(field); - break; - case FieldOptions::CORD: - case FieldOptions::STRING_PIECE: - default_val = - "\"" + CEscape(field->default_value_string()) + "\""; - break; - } - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::string_aux{\n" - " $1$,\n" - " \"$2$\"\n" - "}},\n", - default_val, field->full_name()); - last_field_number++; - break; - } - default: - break; - } - } - - return last_field_number; -} - std::pair MessageGenerator::GenerateOffsets( io::Printer* printer) { Formatter format(printer, variables_); @@ -2740,7 +2217,7 @@ std::pair MessageGenerator::GenerateOffsets( 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"); + format("::_pbi::kInvalidFieldOffsetTag"); } else { format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); } @@ -2787,11 +2264,12 @@ std::pair MessageGenerator::GenerateOffsets( } if (!inlined_string_indices_.empty()) { entries += inlined_string_indices_.size(); - for (int inlined_string_indice : inlined_string_indices_) { - const std::string index = inlined_string_indice >= 0 - ? StrCat(inlined_string_indice) - : "~0u"; - format("$1$,\n", index); + for (int inlined_string_index : inlined_string_indices_) { + const std::string index = + inlined_string_index >= 0 + ? StrCat(inlined_string_index, ", // inlined_string_index") + : "~0u,"; + format("$1$\n", index); } } @@ -2845,8 +2323,20 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { "\n"); } +ArenaDtorNeeds MessageGenerator::NeedsArenaDestructor() const { + if (HasSimpleBaseClass(descriptor_, options_)) return ArenaDtorNeeds::kNone; + ArenaDtorNeeds needs = ArenaDtorNeeds::kNone; + for (const auto* field : FieldRange(descriptor_)) { + if (IsFieldStripped(field, options_)) continue; + needs = + std::max(needs, field_generators_.get(field).NeedsArenaDestructor()); + } + return needs; +} + void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { - if (HasSimpleBaseClass(descriptor_, options_)) return; + GOOGLE_CHECK(NeedsArenaDestructor() > ArenaDtorNeeds::kNone); + Formatter format(printer, variables_); // Generate the ArenaDtor() method. Track whether any fields actually produced @@ -2858,48 +2348,25 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { // since that simplifies Arena's destructor list (ordinary function pointers // rather than member function pointers). _this is the object being // destructed. - format( - "$classname$* _this = reinterpret_cast< $classname$* >(object);\n" - // avoid an "unused variable" warning in case no fields have dtor code. - "(void)_this;\n"); + format("$classname$* _this = reinterpret_cast< $classname$* >(object);\n"); - bool need_registration = false; // Process non-oneof fields first. for (auto field : optimized_order_) { - if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) { - need_registration = true; - } + if (IsFieldStripped(field, options_)) continue; + const FieldGenerator& fg = field_generators_.get(field); + fg.GenerateArenaDestructorCode(printer); } // Process oneof fields. - // - // Note: As of 10/5/2016, GenerateArenaDestructorCode does not emit anything - // and returns false for oneof fields. for (auto oneof : OneOfRange(descriptor_)) { for (auto field : FieldRange(oneof)) { - if (!IsFieldStripped(field, options_) && - field_generators_.get(field).GenerateArenaDestructorCode(printer)) { - need_registration = true; - } + if (IsFieldStripped(field, options_)) continue; + field_generators_.get(field).GenerateArenaDestructorCode(printer); } } format.Outdent(); format("}\n"); - - if (need_registration) { - format( - "inline void $classname$::RegisterArenaDtor(::$proto_ns$::Arena* " - "arena) {\n" - " if (arena != nullptr) {\n" - " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" - " }\n" - "}\n"); - } else { - format( - "void $classname$::RegisterArenaDtor(::$proto_ns$::Arena*) {\n" - "}\n"); - } } void MessageGenerator::GenerateConstexprConstructor(io::Printer* printer) { @@ -2907,7 +2374,7 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* printer) { format( "constexpr $classname$::$classname$(\n" - " ::$proto_ns$::internal::ConstantInitialized)"); + " ::_pbi::ConstantInitialized)"); format.Indent(); const char* field_sep = ":"; const auto put_sep = [&] { @@ -3049,19 +2516,37 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { if (!inlined_string_indices_.empty()) { // Donate inline string fields. - format(" if (arena != nullptr) {\n"); - for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) { - format(" _inlined_string_donated_[$1$] = ~0u;\n", i); + format.Indent(); + // The last bit is the tracking bit for registering ArenaDtor. The bit is 1 + // means ArenaDtor is not registered on construction, and on demand register + // is needed. + format("if (arena != nullptr) {\n"); + if (NeedsArenaDestructor() == ArenaDtorNeeds::kOnDemand) { + format( + " if (!is_message_owned) {\n" + " _inlined_string_donated_[0] = ~0u;\n" + " } else {\n" + // We should not register ArenaDtor for MOA. + " _inlined_string_donated_[0] = 0xFFFFFFFEu;\n" + " }\n"); + } else { + format(" _inlined_string_donated_[0] = 0xFFFFFFFEu;\n"); } - format(" }\n"); + for (size_t i = 1; i < InlinedStringDonatedSize(); ++i) { + format(" _inlined_string_donated_[$1$] = ~0u;\n", i); + } + format("}\n"); + format.Outdent(); } if (!HasSimpleBaseClass(descriptor_, options_)) { - format( - " SharedCtor();\n" - " if (!is_message_owned) {\n" - " RegisterArenaDtor(arena);\n" - " }\n"); + format(" SharedCtor();\n"); + if (NeedsArenaDestructor() == ArenaDtorNeeds::kRequired) { + format( + " if (arena != nullptr && !is_message_owned) {\n" + " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" + " }\n"); + } } format( " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" @@ -3172,10 +2657,19 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { if (!HasSimpleBaseClass(descriptor_, options_)) { format( "$classname$::~$classname$() {\n" - " // @@protoc_insertion_point(destructor:$full_name$)\n" - " if (GetArenaForAllocation() != nullptr) return;\n" + " // @@protoc_insertion_point(destructor:$full_name$)\n"); + format( + " if (auto *arena = " + "_internal_metadata_.DeleteReturnArena<$unknown_fields_type$>()) {\n" + " (void)arena;\n"); + if (NeedsArenaDestructor() > ArenaDtorNeeds::kNone) { + format(" ArenaDtor(this);\n"); + } + format( + " return;\n" + " }\n"); + format( " SharedDtor();\n" - " _internal_metadata_.Delete<$unknown_fields_type$>();\n" "}\n" "\n"); } else { @@ -3190,7 +2684,9 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { GenerateSharedDestructorCode(printer); // Generate the arena-specific destructor code. - GenerateArenaDestructorCode(printer); + if (NeedsArenaDestructor() > ArenaDtorNeeds::kNone) { + GenerateArenaDestructorCode(printer); + } if (!HasSimpleBaseClass(descriptor_, options_)) { // Generate SetCachedSize. @@ -3205,8 +2701,8 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { Formatter format(printer, variables_); format( "template<> " - "PROTOBUF_NOINLINE " - "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" + "PROTOBUF_NOINLINE $classtype$*\n" + "Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" " return Arena::CreateMessageInternal< $classtype$ >(arena);\n" "}\n"); } @@ -3508,6 +3004,15 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (num_weak_fields_) { format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n"); } + + if (!inlined_string_indices_.empty()) { + for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) { + format( + "swap(_inlined_string_donated_[$1$], " + "other->_inlined_string_donated_[$1$]);\n", + i); + } + } } else { format("GetReflection()->Swap(this, other);"); } @@ -3549,7 +3054,7 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { format( "void $classname$::CheckTypeAndMergeFrom(\n" " const ::$proto_ns$::MessageLite& from) {\n" - " MergeFrom(*::$proto_ns$::internal::DownCast(\n" + " MergeFrom(*::_pbi::DownCast(\n" " &from));\n" "}\n"); } @@ -3882,7 +3387,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray( SetUnknownFieldsVariable(descriptor_, options_, &vars); format.AddMap(vars); format( - " target = ::$proto_ns$::internal::" + " target = ::_pbi::" "InternalSerializeUnknownMessageSetItemsToArray(\n" " $unknown_fields$, target, stream);\n"); format( @@ -4077,7 +3582,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( ExtensionRangeSorter()); if (num_weak_fields_) { format( - "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" + "::_pbi::WeakFieldMap::FieldWriter field_writer(" "_weak_field_map_);\n"); } @@ -4126,7 +3631,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( if (UseUnknownFieldSet(descriptor_->file(), options_)) { format( "target = " - "::$proto_ns$::internal::WireFormat::" + "::_pbi::WireFormat::" "InternalSerializeUnknownFieldsToArray(\n" " $unknown_fields$, target, stream);\n"); } else { @@ -4167,7 +3672,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( if (num_weak_fields_) { format( - "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" + "::_pbi::WeakFieldMap::FieldWriter field_writer(" "_weak_field_map_);\n"); } @@ -4218,7 +3723,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( if (UseUnknownFieldSet(descriptor_->file(), options_)) { format( "target = " - "::$proto_ns$::internal::WireFormat::" + "::_pbi::WireFormat::" "InternalSerializeUnknownFieldsToArray(\n" " $unknown_fields$, target, stream);\n"); } else { @@ -4261,11 +3766,11 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" " size_t total_size = _extensions_.MessageSetByteSize();\n" " if ($have_unknown_fields$) {\n" - " total_size += ::$proto_ns$::internal::\n" + " total_size += ::_pbi::\n" " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" " }\n" " int cached_size = " - "::$proto_ns$::internal::ToCachedSize(total_size);\n" + "::_pbi::ToCachedSize(total_size);\n" " SetCachedSize(cached_size);\n" " return total_size;\n" "}\n"); @@ -4496,7 +4001,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { // where even relaxed memory order might have perf impact to replace it with // ordinary loads and stores. format( - "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n" + "int cached_size = ::_pbi::ToCachedSize(total_size);\n" "SetCachedSize(cached_size);\n" "return total_size;\n"); } diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 64af2bf89b52a..a076563419526 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -96,22 +96,10 @@ class MessageGenerator { void GenerateFieldAccessorDeclarations(io::Printer* printer); void GenerateFieldAccessorDefinitions(io::Printer* printer); - // Generate the table-driven parsing array. Returns the number of entries - // generated. - size_t GenerateParseOffsets(io::Printer* printer); - size_t GenerateParseAuxTable(io::Printer* printer); - // Generates a ParseTable entry. Returns whether the proto uses - // table-driven parsing. - bool GenerateParseTable(io::Printer* printer, size_t offset, - size_t aux_offset); - // 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); - // For each field generates a table entry describing the field for the - // table driven serializer. - int GenerateFieldMetadata(io::Printer* printer); // Generate constructors and destructor. void GenerateStructors(io::Printer* printer); @@ -177,6 +165,18 @@ class MessageGenerator { std::vector already_processed, bool copy_constructor) const; + // Returns the level that this message needs ArenaDtor. If the message has + // a field that is not arena-exclusive, it needs an ArenaDtor + // (go/proto-destructor). + // + // - Returning kNone means we don't need to generate ArenaDtor. + // - Returning kOnDemand means we need to generate ArenaDtor, but don't need + // to register ArenaDtor at construction. Such as when the message's + // ArenaDtor code is only for destructing inlined string. + // - Returning kRequired means we meed to generate ArenaDtor and register it + // at construction. + ArenaDtorNeeds NeedsArenaDestructor() const; + size_t HasBitsSize() const; size_t InlinedStringDonatedSize() const; int HasBitIndex(const FieldDescriptor* a) const; @@ -209,8 +209,6 @@ class MessageGenerator { std::vector extension_generators_; int num_required_fields_; int num_weak_fields_; - // table_driven_ indicates the generated message uses table-driven parsing. - bool table_driven_; std::unique_ptr message_layout_helper_; std::unique_ptr parse_function_generator_; diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 6199903371fb0..845dc05634174 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -33,8 +33,9 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include -#include + #include +#include #include @@ -60,11 +61,16 @@ void SetMessageVariables(const FieldDescriptor* descriptor, SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = FieldMessageTypeName(descriptor, options); (*variables)["casted_member"] = ReinterpretCast( - (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak); + (*variables)["type"] + "*", (*variables)["field_member"], implicit_weak); + (*variables)["casted_member_const"] = + ReinterpretCast("const " + (*variables)["type"] + "&", + "*" + (*variables)["field_member"], implicit_weak); (*variables)["type_default_instance"] = QualifiedDefaultInstanceName(descriptor->message_type(), options); - (*variables)["type_default_instance_ptr"] = - QualifiedDefaultInstancePtr(descriptor->message_type(), options); + (*variables)["type_default_instance_ptr"] = ReinterpretCast( + "const ::PROTOBUF_NAMESPACE_ID::MessageLite*", + QualifiedDefaultInstancePtr(descriptor->message_type(), options), + implicit_weak); (*variables)["type_reference_function"] = implicit_weak ? (" ::" + (*variables)["proto_ns"] + "::internal::StrongReference(reinterpret_cast$name$_ != nullptr) {\n" - " return *msg->$name$_;\n" - " } else if ($type_default_instance_ptr$ != nullptr) {\n" - " return *reinterpret_cast(\n" - " $type_default_instance_ptr$);\n" + " if (msg->$field_member$ != nullptr) {\n" + " return *msg->$field_member$;\n" " } else {\n" - " return " - "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n" + " return *$type_default_instance_ptr$;\n" " }\n" "}\n"); format( @@ -338,20 +340,19 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( if (HasHasbit(descriptor_)) { format(" msg->$set_hasbit$\n"); } + if (descriptor_->real_containing_oneof() == nullptr) { + format(" if (msg->$field_member$ == nullptr) {\n"); + } else { + format( + " if (!msg->_internal_has_$name$()) {\n" + " msg->clear_$oneof_name$();\n" + " msg->set_has_$name$();\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->GetArenaForAllocation());\n" - " } else {\n" - " msg->$name$_ = \n" - " reinterpret_cast(\n" - " $type_default_instance_ptr$)->New(\n" - " msg->GetArenaForAllocation());\n" - " }\n" + " msg->$field_member$ = $type_default_instance_ptr$->New(\n" + " msg->GetArenaForAllocation());\n" " }\n" - " return msg->$name$_;\n" + " return msg->$field_member$;\n" "}\n"); } else { // This inline accessor directly returns member field and is used in @@ -371,7 +372,7 @@ void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); if (!HasHasbit(descriptor_)) { // If we don't have has-bits, message presence is indicated only by ptr != - // NULL. Thus on clear, we need to delete the object. + // nullptr. Thus on clear, we need to delete the object. format( "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n" " delete $name$_;\n" @@ -389,7 +390,7 @@ void MessageFieldGenerator::GenerateMessageClearingCode( Formatter format(printer, variables_); if (!HasHasbit(descriptor_)) { // If we don't have has-bits, message presence is indicated only by ptr != - // NULL. Thus on clear, we need to delete the object. + // nullptr. Thus on clear, we need to delete the object. format( "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n" " delete $name$_;\n" @@ -465,11 +466,18 @@ void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format( - "target = stream->EnsureSpace(target);\n" - "target = ::$proto_ns$::internal::WireFormatLite::\n" - " InternalWrite$declared_type$(\n" - " $number$, _Internal::$name$(this), target, stream);\n"); + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + format( + "target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, _Internal::$name$(this),\n" + " _Internal::$name$(this).GetCachedSize(), target, stream);\n"); + } else { + format( + "target = stream->EnsureSpace(target);\n" + "target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$(\n" + " $number$, _Internal::$name$(this), target, stream);\n"); + } } void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const { @@ -554,9 +562,10 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( "inline $type$* $classname$::$release_name$() {\n" "$annotate_release$" " // @@protoc_insertion_point(field_release:$full_name$)\n" + "$type_reference_function$" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n" + " $type$* temp = $casted_member$;\n" " if (GetArenaForAllocation() != nullptr) {\n" " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" " }\n" @@ -569,8 +578,9 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const $type$& $classname$::_internal_$name$() const {\n" + "$type_reference_function$" " return _internal_has_$name$()\n" - " ? *$field_member$\n" + " ? $casted_member_const$\n" " : reinterpret_cast< $type$&>($type_default_instance$);\n" "}\n" "inline const $type$& $classname$::$name$() const {\n" @@ -582,9 +592,10 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_release$" " // @@protoc_insertion_point(field_unsafe_arena_release" ":$full_name$)\n" + "$type_reference_function$" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n" + " $type$* temp = $casted_member$;\n" " $field_member$ = nullptr;\n" " return temp;\n" " } else {\n" @@ -598,21 +609,38 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( // new value. " clear_$oneof_name$();\n" " if ($name$) {\n" - " set_has_$name$();\n" - " $field_member$ = $name$;\n" + " set_has_$name$();\n"); + if (implicit_weak_field_) { + format( + " $field_member$ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); + } else { + format(" $field_member$ = $name$;\n"); + } + format( " }\n" "$annotate_set$" " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" "$full_name$)\n" "}\n" "inline $type$* $classname$::_internal_mutable_$name$() {\n" + "$type_reference_function$" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$ = CreateMaybeMessage< $type$ " - ">(GetArenaForAllocation());\n" + " set_has_$name$();\n"); + if (implicit_weak_field_) { + format( + " $field_member$ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>(CreateMaybeMessage< " + "$type$ >(GetArenaForAllocation()));\n"); + } else { + format( + " $field_member$ = CreateMaybeMessage< $type$ " + ">(GetArenaForAllocation());\n"); + } + format( " }\n" - " return $field_member$;\n" + " return $casted_member$;\n" "}\n" "inline $type$* $classname$::mutable_$name$() {\n" " $type$* _msg = _internal_mutable_$name$();\n" @@ -830,22 +858,40 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( if (implicit_weak_field_) { format( "for (auto it = this->$name$_.pointer_begin(),\n" - " end = this->$name$_.pointer_end(); it < end; ++it) {\n" - " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::\n" - " InternalWrite$declared_type$($number$, **it, target, stream);\n" - "}\n"); + " end = this->$name$_.pointer_end(); it < end; ++it) {\n"); + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + format( + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, " + "**it, (**it).GetCachedSize(), target, stream);\n"); + } else { + format( + " target = stream->EnsureSpace(target);\n" + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, **it, target, " + "stream);\n"); + } + format("}\n"); } else { format( - "for (unsigned int i = 0,\n" - " n = static_cast(this->_internal_$name$_size()); i < " - "n; i++) " - "{\n" - " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::\n" - " InternalWrite$declared_type$($number$, " - "this->_internal_$name$(i), target, stream);\n" - "}\n"); + "for (unsigned i = 0,\n" + " n = static_cast(this->_internal_$name$_size());" + " i < n; i++) {\n"); + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + format( + " const auto& repfield = this->_internal_$name$(i);\n" + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, " + "repfield, repfield.GetCachedSize(), target, stream);\n" + "}\n"); + } else { + format( + " target = stream->EnsureSpace(target);\n" + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, " + "this->_internal_$name$(i), target, stream);\n" + "}\n"); + } } } diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h index 2beac6253b9fa..528b419704838 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -37,6 +37,7 @@ #include #include + #include #include diff --git a/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h index 9d8063d9cab36..80860053f1742 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h @@ -35,8 +35,8 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ -#include #include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/cpp/cpp_names.h b/src/google/protobuf/compiler/cpp/cpp_names.h index 6bcbff0616813..b27b596970fba 100644 --- a/src/google/protobuf/compiler/cpp/cpp_names.h +++ b/src/google/protobuf/compiler/cpp/cpp_names.h @@ -33,6 +33,7 @@ #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index d0f16d03479a9..aaecda58eb894 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -57,34 +57,38 @@ struct FieldListenerOptions { // Generator options (see generator.cc for a description of each): struct Options { + const AccessInfoMap* access_info_map = nullptr; std::string dllexport_decl; + std::string runtime_include_base; + std::string annotation_pragma_name; + std::string annotation_guard_name; + FieldListenerOptions field_listener_options; + EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement; + enum { + kTCTableNever, + kTCTableGuarded, + kTCTableAlways + } tctable_mode = kTCTableNever; + int num_cc_files = 0; bool safe_boundary_check = false; bool proto_h = false; bool transitive_pb_h = true; bool annotate_headers = false; - EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement; - bool table_driven_parsing = false; - bool table_driven_serialization = false; bool lite_implicit_weak_fields = false; bool bootstrap = false; bool opensource_runtime = false; bool annotate_accessor = false; bool unused_field_stripping = false; + bool unverified_lazy_message_sets = true; + bool eagerly_verified_lazy = true; bool profile_driven_inline_string = true; - bool force_inline_string = false; - std::string runtime_include_base; - int num_cc_files = 0; - std::string annotation_pragma_name; - std::string annotation_guard_name; - const AccessInfoMap* access_info_map = nullptr; - enum { - kTCTableNever, - kTCTableGuarded, - kTCTableAlways - } tctable_mode = kTCTableNever; - FieldListenerOptions field_listener_options; - bool eagerly_verified_lazy = false; +#ifdef PROTOBUF_STABLE_EXPERIMENTS + bool force_eagerly_verified_lazy = true; + bool force_inline_string = true; +#else // PROTOBUF_STABLE_EXPERIMENTS bool force_eagerly_verified_lazy = false; + bool force_inline_string = false; +#endif // !PROTOBUF_STABLE_EXPERIMENTS }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc index 0b660c75b7b3d..f48ba718a54db 100644 --- a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc +++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc @@ -47,7 +47,7 @@ class FieldGroup { FieldGroup() : preferred_location_(0) {} // A group with a single field. - FieldGroup(float preferred_location, const FieldDescriptor* field) + FieldGroup(double preferred_location, const FieldDescriptor* field) : preferred_location_(preferred_location), fields_(1, field) {} // Append the fields in 'other' to this group. @@ -63,7 +63,7 @@ class FieldGroup { fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); } - void SetPreferredLocation(float location) { preferred_location_ = location; } + void SetPreferredLocation(double location) { preferred_location_ = location; } const std::vector& fields() const { return fields_; } // FieldGroup objects sort by their preferred location. @@ -77,7 +77,7 @@ class FieldGroup { // field in this group in the original ordering of fields. This is very // approximate, but should put this group close to where its member fields // originally went. - float preferred_location_; + double preferred_location_; std::vector fields_; // We rely on the default copy constructor and operator= so this type can be // used in a vector. @@ -203,7 +203,7 @@ void PaddingOptimizer::OptimizeLayout( field_group.SetPreferredLocation(-1); } else { // Move incomplete 4-byte block to the end. - field_group.SetPreferredLocation(fields->size() + 1); + field_group.SetPreferredLocation(double{FieldDescriptor::kMaxNumber}); } } aligned_to_8[f].push_back(field_group); diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc index 810f240a89a17..43a5adeda0f07 100644 --- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc @@ -33,9 +33,10 @@ #include #include #include +#include -#include #include +#include namespace google { namespace protobuf { @@ -43,7 +44,6 @@ namespace compiler { namespace cpp { namespace { -using google::protobuf::internal::TcFieldData; using google::protobuf::internal::WireFormat; using google::protobuf::internal::WireFormatLite; @@ -77,163 +77,314 @@ const char* CodedTagType(int tag_size) { return tag_size == 1 ? "uint8_t" : "uint16_t"; } -const char* TagType(const FieldDescriptor* field) { - return CodedTagType(TagSize(field->number())); -} +std::string FieldParseFunctionName( + const TailCallTableInfo::FieldEntryInfo& entry, const Options& options); + +bool IsFieldEligibleForFastParsing( + const TailCallTableInfo::FieldEntryInfo& entry, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + const auto* field = entry.field; + // Map, oneof, weak, and lazy fields are not handled on the fast path. + if (field->is_map() || field->real_containing_oneof() || + field->options().weak() || + IsImplicitWeakField(field, options, scc_analyzer) || + IsLazy(field, options, scc_analyzer)) { + return false; + } + switch (field->type()) { + // Strings, enums, and groups are not handled on the fast path. + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_GROUP: + return false; -std::string TcParserName(const Options& options) { - return StrCat("::", ProtobufNamespace(options), - "::internal::TcParser::"); -} + case FieldDescriptor::TYPE_ENUM: + // If enum values are not validated at parse time, then this field can be + // handled on the fast path like an int32. + if (HasPreservingUnknownEnumSemantics(field)) { + break; + } + if (field->is_repeated() && field->is_packed()) { + return false; + } + break; + + // Some bytes fields can be handled on fast path. + case FieldDescriptor::TYPE_BYTES: + if (field->options().ctype() != FieldOptions::STRING || + !field->default_value_string().empty() || + IsStringInlined(field, options)) { + return false; + } + break; + + default: + break; + } -std::string MessageTcParseFunctionName(const FieldDescriptor* field, - const Options& options) { - if (field->message_type()->field_count() == 0 || - !HasGeneratedMethods(field->message_type()->file(), options)) { - // For files with `option optimize_for = CODE_SIZE`, or which derive from - // `ZeroFieldsBase`, we need to call the `_InternalParse` function, because - // there is no generated tailcall function. For tailcall parsing, this is - // done by helpers in TcParser. - return StrCat(TcParserName(options), - (field->is_repeated() ? "Repeated" : "Singular"), - "ParseMessage<", - QualifiedClassName(field->message_type()), // - ", ", TagType(field), ">"); + if (HasHasbit(field)) { + // The tailcall parser can only update the first 32 hasbits. Fields with + // has-bits beyond the first 32 are handled by mini parsing/fallback. + GOOGLE_CHECK_GE(entry.hasbit_idx, 0) << field->DebugString(); + if (entry.hasbit_idx >= 32) return false; + } + + // If the field needs auxiliary data, then the aux index is needed. This + // must fit in a uint8_t. + if (entry.aux_idx > std::numeric_limits::max()) { + return false; } - // This matches macros in generated_message_tctable_impl.h: - return StrCat("PROTOBUF_TC_PARSE_", - (field->is_repeated() ? "REPEATED" : "SINGULAR"), - TagSize(field->number()), "(", - QualifiedClassName(field->message_type()), ")"); + + // The largest tag that can be read by the tailcall parser is two bytes + // when varint-coded. This allows 14 bits for the numeric tag value: + // byte 0 byte 1 + // 1nnnnttt 0nnnnnnn + // ^^^^^^^ ^^^^^^^ + if (field->number() >= 1 << 11) return false; + + return true; } -std::string FieldParseFunctionName(const FieldDescriptor* field, - const Options& options); +std::vector SplitFastFieldsForSize( + const std::vector& field_entries, + int table_size_log2, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + std::vector result(1 << table_size_log2); + const uint32_t idx_mask = result.size() - 1; -} // namespace + for (const auto& entry : field_entries) { + if (!IsFieldEligibleForFastParsing(entry, options, scc_analyzer)) { + continue; + } -TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor, - const Options& options, - const std::vector& has_bit_indices, - MessageSCCAnalyzer* scc_analyzer) { - std::vector ordered_fields = - GetOrderedFields(descriptor, options); - - // The table size is rounded up to the nearest power of 2, clamping at 2^5. - // Note that this is a naive approach: a better approach should only consider - // table-eligible fields. We may also want to push rarely-encountered fields - // into the fallback, to make the table smaller. - table_size_log2 = ordered_fields.size() >= 16 ? 5 - : ordered_fields.size() >= 8 ? 4 - : ordered_fields.size() >= 4 ? 3 - : ordered_fields.size() >= 2 ? 2 - : 1; - const unsigned table_size = 1 << table_size_log2; - - // Construct info for each possible entry. Fields that do not use table-driven - // parsing will still have an entry that nominates the fallback function. - fast_path_fields.resize(table_size); - - for (const auto* field : ordered_fields) { - // Eagerly assume slow path. If we can handle this field on the fast path, - // we will pop its entry from `fallback_fields`. - fallback_fields.push_back(field); - - // Anything difficult slow path: - if (field->is_map()) continue; - if (field->real_containing_oneof()) continue; - if (field->options().weak()) continue; - if (IsImplicitWeakField(field, options, scc_analyzer)) continue; - if (IsLazy(field, options, scc_analyzer)) continue; - - // The largest tag that can be read by the tailcall parser is two bytes - // when varint-coded. This allows 14 bits for the numeric tag value: - // byte 0 byte 1 - // 1nnnnttt 0nnnnnnn - // ^^^^^^^ ^^^^^^^ + const auto* field = entry.field; uint32_t tag = WireFormat::MakeTag(field); - if (tag >= 1 << 14) { - continue; - } else if (tag >= 1 << 7) { - tag = ((tag << 1) & 0x7F00) | 0x80 | (tag & 0x7F); + + // Construct the varint-coded tag. If it is more than 7 bits, we need to + // shift the high bits and add a continue bit. + if (uint32_t hibits = tag & 0xFFFFFF80) { + tag = tag + hibits + 128; // tag = lobits + 2*hibits + 128 } + // The field index is determined by the low bits of the field number, where // the table size determines the width of the mask. The largest table // supported is 32 entries. The parse loop uses these bits directly, so that // the dispatch does not require arithmetic: - // byte 0 byte 1 - // 1nnnnttt 0nnnnnnn - // ^^^^^ + // byte 0 byte 1 + // tag: 1nnnnttt 0nnnnnnn + // ^^^^^ + // idx (table_size_log2=5) // This means that any field number that does not fit in the lower 4 bits - // will always have the top bit of its table index asserted: - uint32_t idx = (tag >> 3) & (table_size - 1); - // If this entry in the table is already used, then this field will be - // handled by the generated fallback function. - if (!fast_path_fields[idx].func_name.empty()) continue; - - // Determine the hasbit mask for this field, if needed. (Note that fields - // without hasbits use different parse functions.) - int hasbit_idx; - if (HasHasbit(field)) { - hasbit_idx = has_bit_indices[field->index()]; - GOOGLE_CHECK_NE(-1, hasbit_idx) << field->DebugString(); - // The tailcall parser can only update the first 32 hasbits. If this - // field's has-bit is beyond that, then it will need to be handled by the - // fallback parse function. - if (hasbit_idx >= 32) continue; - } else { - // The tailcall parser only ever syncs 32 has-bits, so if there is no - // presence, set a bit that will not be used. - hasbit_idx = 63; + // will always have the top bit of its table index asserted. + const uint32_t fast_idx = (tag >> 3) & idx_mask; + + TailCallTableInfo::FastFieldInfo& info = result[fast_idx]; + if (info.field != nullptr) { + // This field entry is already filled. + continue; } - // Determine the name of the fastpath parse function to use for this field. - std::string name; + // Fill in this field's entry: + GOOGLE_CHECK(info.func_name.empty()) << info.func_name; + info.func_name = FieldParseFunctionName(entry, options); + info.field = field; + info.coded_tag = tag; + // If this field does not have presence, then it can set an out-of-bounds + // bit (tailcall parsing uses a uint64_t for hasbits, but only stores 32). + info.hasbit_idx = HasHasbit(field) ? entry.hasbit_idx : 63; + info.aux_idx = static_cast(entry.aux_idx); + } + return result; +} - switch (field->type()) { - case FieldDescriptor::TYPE_MESSAGE: - name = MessageTcParseFunctionName(field, options); - break; +// Filter out fields that will be handled by mini parsing. +std::vector FilterMiniParsedFields( + const std::vector& fields, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + std::vector generated_fallback_fields; - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_SFIXED64: - case FieldDescriptor::TYPE_SFIXED32: + for (const auto* field : fields) { + bool handled = false; + switch (field->type()) { case FieldDescriptor::TYPE_DOUBLE: case FieldDescriptor::TYPE_FLOAT: - case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + case FieldDescriptor::TYPE_BOOL: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT32: case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_UINT32: case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_BOOL: - name = FieldParseFunctionName(field, options); + case FieldDescriptor::TYPE_INT64: + // These are handled by MiniParse, so we don't need any generated + // fallback code. + handled = true; break; + case FieldDescriptor::TYPE_ENUM: + if (field->is_repeated() && + !HasPreservingUnknownEnumSemantics(field)) { + // TODO(b/206890171): handle packed repeated closed enums + // Non-packed repeated can be handled using tables, but we still + // need to generate fallback code for all repeated enums in order to + // handle packed encoding. This is because of the lite/full split + // when handling invalid enum values in a packed field. + handled = false; + } else { + handled = true; + } + break; + + // TODO(b/209516305): add TYPE_STRING once field names are available. case FieldDescriptor::TYPE_BYTES: - if (field->options().ctype() == FieldOptions::STRING && - field->default_value_string().empty() && - !IsStringInlined(field, options)) { - name = FieldParseFunctionName(field, options); + if (IsStringInlined(field, options)) { + // TODO(b/198211897): support InilnedStringField. + handled = false; + } else { + handled = true; + } + break; + + case FieldDescriptor::TYPE_MESSAGE: + // TODO(b/210762816): support remaining field types. + if (field->is_map() || IsWeak(field, options) || + IsImplicitWeakField(field, options, scc_analyzer) || + IsLazy(field, options, scc_analyzer)) { + handled = false; + } else { + handled = true; } break; default: + handled = false; break; } + if (!handled) generated_fallback_fields.push_back(field); + } - if (name.empty()) { - continue; + return generated_fallback_fields; +} + +} // namespace + +TailCallTableInfo::TailCallTableInfo( + const Descriptor* descriptor, const Options& options, + const std::vector& ordered_fields, + const std::vector& has_bit_indices, MessageSCCAnalyzer* scc_analyzer) { + int oneof_count = descriptor->real_oneof_decl_count(); + // If this message has any oneof fields, store the case offset in the first + // auxiliary entry. + if (oneof_count > 0) { + GOOGLE_LOG_IF(DFATAL, ordered_fields.empty()) + << "Invalid message: " << descriptor->full_name() << " has " + << oneof_count << " oneof declarations, but no fields"; + aux_entries.push_back(StrCat( + "_fl::Offset{offsetof(", ClassName(descriptor), ", _oneof_case_)}")); + } + // Fill in mini table entries. + for (const FieldDescriptor* field : ordered_fields) { + field_entries.push_back( + {field, (HasHasbit(field) ? has_bit_indices[field->index()] : -1)}); + auto& entry = field_entries.back(); + + if (field->type() == FieldDescriptor::TYPE_MESSAGE || + field->type() == FieldDescriptor::TYPE_GROUP) { + // Message-typed fields have a FieldAux with the default instance pointer. + if (field->is_map()) { + // TODO(b/205904770): generate aux entries for maps + } else if (IsWeak(field, options)) { + // Don't generate anything for weak fields. They are handled by the + // generated fallback. + } else if (IsImplicitWeakField(field, options, scc_analyzer)) { + // Implicit weak fields don't need to store a default instance pointer. + } else if (IsLazy(field, options, scc_analyzer)) { + // Lazy fields are handled by the generated fallback function. + } else { + field_entries.back().aux_idx = aux_entries.size(); + const Descriptor* field_type = field->message_type(); + aux_entries.push_back(StrCat( + "reinterpret_cast(&", QualifiedDefaultInstanceName(field_type, options), ")")); + } + } else if (field->type() == FieldDescriptor::TYPE_ENUM && + !HasPreservingUnknownEnumSemantics(field)) { + // Enum fields which preserve unknown values (proto3 behavior) are + // effectively int32 fields with respect to parsing -- i.e., the value + // does not need to be validated at parse time. + // + // Enum fields which do not preserve unknown values (proto2 behavior) use + // a FieldAux to store validation information. If the enum values are + // sequential (and within a range we can represent), then the FieldAux + // entry represents the range using the minimum value (which must fit in + // an int16_t) and count (a uint16_t). Otherwise, the entry holds a + // pointer to the generated Name_IsValid function. + + entry.aux_idx = aux_entries.size(); + const EnumDescriptor* enum_type = field->enum_type(); + GOOGLE_CHECK_GT(enum_type->value_count(), 0) << enum_type->DebugString(); + + // Check if the enum values are a single, continguous range. + std::vector enum_values; + for (int i = 0, N = enum_type->value_count(); i < N; ++i) { + enum_values.push_back(enum_type->value(i)->number()); + } + auto values_begin = enum_values.begin(); + auto values_end = enum_values.end(); + std::sort(values_begin, values_end); + enum_values.erase(std::unique(values_begin, values_end), values_end); + + if (enum_values.back() - enum_values[0] == enum_values.size() - 1 && + enum_values[0] >= std::numeric_limits::min() && + enum_values[0] <= std::numeric_limits::max() && + enum_values.size() <= std::numeric_limits::max()) { + entry.is_enum_range = true; + aux_entries.push_back( + StrCat(enum_values[0], ", ", enum_values.size())); + } else { + entry.is_enum_range = false; + aux_entries.push_back( + StrCat(QualifiedClassName(enum_type, options), "_IsValid")); + } } - // This field made it into the fast path, so remove it from the fallback - // fields and fill in the table entry. - fallback_fields.pop_back(); - fast_path_fields[idx].func_name = name; - fast_path_fields[idx].bits = TcFieldData(tag, hasbit_idx, 0); - fast_path_fields[idx].field = field; } + // Choose the smallest fast table that covers the maximum number of fields. + table_size_log2 = 0; // fallback value + int num_fast_fields = -1; + for (int try_size_log2 : {0, 1, 2, 3, 4, 5}) { + size_t try_size = 1 << try_size_log2; + auto split_fields = SplitFastFieldsForSize(field_entries, try_size_log2, + options, scc_analyzer); + GOOGLE_CHECK_EQ(split_fields.size(), try_size); + int try_num_fast_fields = 0; + for (const auto& info : split_fields) { + if (info.field != nullptr) ++try_num_fast_fields; + } + // Use this size if (and only if) it covers more fields. + if (try_num_fast_fields > num_fast_fields) { + fast_path_fields = std::move(split_fields); + table_size_log2 = try_size_log2; + num_fast_fields = try_num_fast_fields; + } + // The largest table we allow has the same number of entries as the message + // has fields, rounded up to the next power of 2 (e.g., a message with 5 + // fields can have a fast table of size 8). A larger table *might* cover + // more fields in certain cases, but a larger table in that case would have + // mostly empty entries; so, we cap the size to avoid pathologically sparse + // tables. + if (try_size > ordered_fields.size()) { + break; + } + } + + // Filter out fields that are handled by MiniParse. We don't need to generate + // a fallback for these, which saves code size. + fallback_fields = FilterMiniParsedFields(ordered_fields, options, + scc_analyzer); + // If there are no fallback fields, and at most one extension range, the // parser can use a generic fallback function. Otherwise, a message-specific // fallback routine is needed. @@ -252,10 +403,11 @@ ParseFunctionGenerator::ParseFunctionGenerator( options_(options), variables_(vars), inlined_string_indices_(inlined_string_indices), + ordered_fields_(GetOrderedFields(descriptor_, options_)), num_hasbits_(max_has_bit_index) { if (should_generate_tctable()) { - tc_table_info_.reset(new TailCallTableInfo(descriptor_, options_, - has_bit_indices, scc_analyzer)); + tc_table_info_.reset(new TailCallTableInfo( + descriptor_, options_, ordered_fields_, has_bit_indices, scc_analyzer)); } SetCommonVars(options_, &variables_); SetUnknownFieldsVariable(descriptor_, options_, &variables_); @@ -265,45 +417,18 @@ ParseFunctionGenerator::ParseFunctionGenerator( void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) { Formatter format(printer, variables_); if (should_generate_tctable()) { - auto declare_function = [&format](const char* name, - const std::string& guard) { - if (!guard.empty()) { - format.Outdent(); - format("#if $1$\n", guard); - format.Indent(); - } - format("static const char* $1$(PROTOBUF_TC_PARAM_DECL);\n", name); - if (!guard.empty()) { - format.Outdent(); - format("#endif // $1$\n", guard); - format.Indent(); - } - }; + format.Outdent(); if (should_generate_guarded_tctable()) { - format.Outdent(); format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - format.Indent(); - } - format("// The Tct_* functions are internal to the protobuf runtime:\n"); - // These guards are defined in port_def.inc: - declare_function("Tct_ParseS1", "PROTOBUF_TC_STATIC_PARSE_SINGULAR1"); - declare_function("Tct_ParseS2", "PROTOBUF_TC_STATIC_PARSE_SINGULAR2"); - declare_function("Tct_ParseR1", "PROTOBUF_TC_STATIC_PARSE_REPEATED1"); - declare_function("Tct_ParseR2", "PROTOBUF_TC_STATIC_PARSE_REPEATED2"); - if (tc_table_info_->use_generated_fallback) { - format.Outdent(); - format( - " private:\n" - " "); - declare_function("Tct_ParseFallback", ""); - format(" public:\n"); - format.Indent(); } + format( + " private:\n" + " static const char* Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL);\n" + " public:\n"); if (should_generate_guarded_tctable()) { - format.Outdent(); format("#endif\n"); - format.Indent(); } + format.Indent(); } format( "const char* _InternalParse(const char* ptr, " @@ -318,8 +443,14 @@ void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) { need_parse_function = false; format( "const char* $classname$::_InternalParse(const char* ptr,\n" - " ::$proto_ns$::internal::ParseContext* ctx) {\n" - "$annotate_deserialize$" + " ::_pbi::ParseContext* ctx) {\n" + "$annotate_deserialize$"); + if (!options_.unverified_lazy_message_sets && + ShouldVerify(descriptor_, options_, scc_analyzer_)) { + format( + " ctx->set_lazy_eager_verify_func(&$classname$::InternalVerify);\n"); + } + format( " return _extensions_.ParseMessageSet(ptr, \n" " internal_default_instance(), &_internal_metadata_, ctx);\n" "}\n"); @@ -339,7 +470,6 @@ void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) { if (tc_table_info_->use_generated_fallback) { GenerateTailcallFallbackFunction(format); } - GenerateTailcallFieldParseFunctions(format); if (should_generate_guarded_tctable()) { if (need_parse_function) { format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); @@ -362,10 +492,10 @@ void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) { // Generate an `_InternalParse` that starts the tail-calling loop. format( "const char* $classname$::_InternalParse(\n" - " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n" + " const char* ptr, ::_pbi::ParseContext* ctx) {\n" "$annotate_deserialize$" - " ptr = ::$proto_ns$::internal::TcParser::ParseLoop(\n" - " this, ptr, ctx, &_table_.header);\n"); + " ptr = ::_pbi::TcParser::ParseLoop(this, ptr, ctx, " + "&_table_.header);\n"); format( " return ptr;\n" "}\n\n"); @@ -384,6 +514,7 @@ void ParseFunctionGenerator::GenerateTailcallFallbackFunction( // Sync hasbits format("typed_msg->_has_bits_[0] = hasbits;\n"); } + format("uint32_t tag = data.tag();\n"); format.Set("msg", "typed_msg->"); format.Set("this", "typed_msg"); @@ -401,63 +532,6 @@ void ParseFunctionGenerator::GenerateTailcallFallbackFunction( "}\n"); } -void ParseFunctionGenerator::GenerateTailcallFieldParseFunctions( - Formatter& format) { - GOOGLE_CHECK(should_generate_tctable()); - // There are four cases where a tailcall target are needed for messages: - // {singular, repeated} x {1, 2}-byte tag - struct { - const char* type; - int size; - } const kTagLayouts[] = { - {"uint8_t", 1}, - {"uint16_t", 2}, - }; - // Singular: - for (const auto& layout : kTagLayouts) { - // Guard macros are defined in port_def.inc. - format( - "#if PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n" - "const char* $classname$::Tct_ParseS$1$(PROTOBUF_TC_PARAM_DECL) {\n" - " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0))\n" - " PROTOBUF_MUSTTAIL " - "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" - " ptr += $1$;\n" - " hasbits |= (uint64_t{1} << data.hasbit_idx());\n" - " ::$proto_ns$::internal::TcParser::SyncHasbits" - "(msg, hasbits, table);\n" - " auto& field = ::$proto_ns$::internal::TcParser::" - "RefAt<$classtype$*>(msg, data.offset());\n" - " if (field == nullptr)\n" - " field = CreateMaybeMessage<$classtype$>(ctx->data().arena);\n" - " return ctx->ParseMessage(field, ptr);\n" - "}\n" - "#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n", - layout.size, layout.type); - } - // Repeated: - for (const auto& layout : kTagLayouts) { - // Guard macros are defined in port_def.inc. - format( - "#if PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n" - "const char* $classname$::Tct_ParseR$1$(PROTOBUF_TC_PARAM_DECL) {\n" - " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0)) {\n" - " PROTOBUF_MUSTTAIL " - "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" - " }\n" - " ptr += $1$;\n" - " auto& field = ::$proto_ns$::internal::TcParser::RefAt<" - "::$proto_ns$::RepeatedPtrField<$classname$>>(msg, data.offset());\n" - " ::$proto_ns$::internal::TcParser::SyncHasbits" - "(msg, hasbits, table);\n" - " ptr = ctx->ParseMessage(field.Add(), ptr);\n" - " return ptr;\n" - "}\n" - "#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n", - layout.size, layout.type); - } -} - void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { if (!should_generate_tctable()) { return; @@ -469,9 +543,10 @@ void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { format.Indent(); } format( - "static const ::$proto_ns$::internal::TcParseTable<$1$>\n" - " _table_;\n", - tc_table_info_->table_size_log2); + "static const ::$proto_ns$::internal::TcParseTable<$1$, $2$, $3$, $4$> " + "_table_;\n", + tc_table_info_->table_size_log2, ordered_fields_.size(), + tc_table_info_->aux_entries.size(), CalculateFieldNamesSize()); if (should_generate_guarded_tctable()) { format.Outdent(); format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); @@ -496,7 +571,7 @@ void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* printer) { void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) { format( "const char* $classname$::_InternalParse(const char* ptr, " - "::$proto_ns$::internal::ParseContext* ctx) {\n" + "::_pbi::ParseContext* ctx) {\n" "$annotate_deserialize$" "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n"); format.Indent(); @@ -518,8 +593,10 @@ void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) { format("while (!ctx->Done(&ptr)) {\n"); format.Indent(); - GenerateParseIterationBody(format, descriptor_, - GetOrderedFields(descriptor_, options_)); + format( + "uint32_t tag;\n" + "ptr = ::_pbi::ReadTag(ptr, &tag);\n"); + GenerateParseIterationBody(format, descriptor_, ordered_fields_); format.Outdent(); format("} // while\n"); @@ -544,7 +621,7 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { if (tc_table_info_->use_generated_fallback) { fallback = ClassName(descriptor_) + "::Tct_ParseFallback"; } else { - fallback = TcParserName(options_) + "GenericFallback"; + fallback = "::_pbi::TcParser::GenericFallback"; if (GetOptimizeFor(descriptor_->file(), options_) == FileOptions::LITE_RUNTIME) { fallback += "Lite"; @@ -559,9 +636,11 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { // the table is sufficient we can use a generic routine, that just handles // unknown fields and potentially an extension range. format( - "const ::$proto_ns$::internal::TcParseTable<$1$>\n" - " $classname$::_table_ = {\n", - tc_table_info_->table_size_log2); + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1\n" + "const ::_pbi::TcParseTable<$1$, $2$, $3$, $4$> $classname$::_table_ = " + "{\n", + tc_table_info_->table_size_log2, ordered_fields_.size(), + tc_table_info_->aux_entries.size(), CalculateFieldNamesSize()); { auto table_scope = format.ScopedIndent(); format("{\n"); @@ -581,44 +660,336 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { } else { format("0, 0, 0, // no _extensions_\n"); } + format("$1$, $2$, // max_field_number, fast_idx_mask\n", + (ordered_fields_.empty() ? 0 : ordered_fields_.back()->number()), + (((1 << tc_table_info_->table_size_log2) - 1) << 3)); + + // Determine the sequential fields that can be looked up by index: + uint16_t num_sequential_fields = 0; + uint16_t sequential_fields_start = 0; + if (!ordered_fields_.empty() && + ordered_fields_.front()->number() <= + std::numeric_limits::max()) { + sequential_fields_start = ordered_fields_[0]->number(); + const FieldDescriptor* previous_field = ordered_fields_[0]; + const int N = std::min(ordered_fields_.size(), + size_t{std::numeric_limits::max()} + 1); + for (int i = 1; i < N; ++i) { + const FieldDescriptor* current_field = ordered_fields_[i]; + if (current_field->number() > previous_field->number() + 1) { + break; + } + ++num_sequential_fields; + previous_field = current_field; + } + } + format("$1$, $2$, // num_sequential_fields, sequential_fields_start\n", + num_sequential_fields, sequential_fields_start); + + format( + "$1$, // num_field_entries\n" + "$2$, // num_aux_entries\n", + ordered_fields_.size(), tc_table_info_->aux_entries.size()); + if (tc_table_info_->aux_entries.empty()) { + format( + "offsetof(decltype(_table_), field_names), // no aux_entries\n"); + } else { + format("offsetof(decltype(_table_), aux_entries),\n"); + } format( - "$1$, 0, $2$, // fast_idx_mask, reserved, num_fields\n" - "&$3$._instance,\n" - "$4$ // fallback\n", - (((1 << tc_table_info_->table_size_log2) - 1) << 3), - descriptor_->field_count(), + "&$1$._instance,\n" + "$2$, // fallback\n" + "", DefaultInstanceName(descriptor_, options_), fallback); } - format("}, {\n"); + format("}, {{\n"); { + // fast_entries[] auto fast_scope = format.ScopedIndent(); - GenerateFastFieldEntries(format, fallback); + GenerateFastFieldEntries(format); } - format("},\n"); // entries[] + if (ordered_fields_.empty()) { + GOOGLE_LOG_IF(DFATAL, !tc_table_info_->aux_entries.empty()) + << "Invalid message: " << descriptor_->full_name() << " has " + << tc_table_info_->aux_entries.size() + << " auxiliary field entries, but no fields"; + format("}},\n" + "// no field_numbers, field_entries, or aux_entries\n" + "{{\n"); + } else { + format("}}, {{\n"); + { + // field_numbers[] + auto field_number_scope = format.ScopedIndent(); + for (int i = 0, N = ordered_fields_.size(); i < N; ++i) { + const FieldDescriptor* field = ordered_fields_[i]; + if (i > 0) { + if (i % 10 == 0) { + format(",\n"); + } else { + format(", "); + } + } + format("$1$", field->number()); + } + format("\n"); + } + format("}}, {{\n"); + { + // field_entries[] + auto field_scope = format.ScopedIndent(); + GenerateFieldEntries(format); + } + if (tc_table_info_->aux_entries.empty()) { + format( + "}},\n" + "// no aux_entries\n" + "{{\n"); + } else { + format("}}, {{\n"); + { + // aux_entries[] + auto aux_scope = format.ScopedIndent(); + for (const std::string& aux_entry : tc_table_info_->aux_entries) { + format("{$1$},\n", aux_entry); + } + } + format("}}, {{\n"); + } + } // ordered_fields_.empty() + { + // field_names[] + auto field_scope = format.ScopedIndent(); + GenerateFieldNames(format); + } + format("}},\n"); } format("};\n\n"); // _table_ } -void ParseFunctionGenerator::GenerateFastFieldEntries( - Formatter& format, const std::string& fallback) { +void ParseFunctionGenerator::GenerateFastFieldEntries(Formatter& format) { for (const auto& info : tc_table_info_->fast_path_fields) { if (info.field != nullptr) { PrintFieldComment(format, info.field); } - format("{$1$, ", info.func_name.empty() ? fallback : info.func_name); - if (info.bits.data) { - GOOGLE_DCHECK_NE(nullptr, info.field); + if (info.func_name.empty()) { + format("{::_pbi::TcParser::MiniParse, {}},\n"); + } else { format( - "{$1$, $2$, " - "static_cast(PROTOBUF_FIELD_OFFSET($classname$, $3$_))}", - info.bits.coded_tag(), info.bits.hasbit_idx(), FieldName(info.field)); + "{$1$,\n" + " {$2$, $3$, $4$, PROTOBUF_FIELD_OFFSET($classname$, $5$_)}},\n", + info.func_name, info.coded_tag, info.hasbit_idx, info.aux_idx, + FieldName(info.field)); + } + } +} + +static void FormatFieldKind(Formatter& format, + const TailCallTableInfo::FieldEntryInfo& entry, + const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + const FieldDescriptor* field = entry.field; + // Spell the field kind in proto language declaration order, starting with + // cardinality: + format("(::_fl::kFc"); + if (HasHasbit(field)) { + format("Optional"); + } else if (field->is_repeated()) { + format("Repeated"); + } else if (field->real_containing_oneof()) { + format("Oneof"); + } else { + format("Singular"); + } + + // The rest of the type uses convenience aliases: + format(" | ::_fl::k"); + if (field->is_repeated() && field->is_packed()) { + format("Packed"); + } + switch (field->type()) { + case FieldDescriptor::TYPE_DOUBLE: + format("Double"); + break; + case FieldDescriptor::TYPE_FLOAT: + format("Float"); + break; + case FieldDescriptor::TYPE_FIXED32: + format("Fixed32"); + break; + case FieldDescriptor::TYPE_SFIXED32: + format("SFixed32"); + break; + case FieldDescriptor::TYPE_FIXED64: + format("Fixed64"); + break; + case FieldDescriptor::TYPE_SFIXED64: + format("SFixed64"); + break; + case FieldDescriptor::TYPE_BOOL: + format("Bool"); + break; + case FieldDescriptor::TYPE_ENUM: + if (HasPreservingUnknownEnumSemantics(field)) { + // No validation is required. + format("OpenEnum"); + } else if (entry.is_enum_range) { + // Validation is done by range check (start/length in FieldAux). + format("EnumRange"); + } else { + // Validation uses the generated _IsValid function. + format("Enum"); + } + break; + case FieldDescriptor::TYPE_UINT32: + format("UInt32"); + break; + case FieldDescriptor::TYPE_SINT32: + format("SInt32"); + break; + case FieldDescriptor::TYPE_INT32: + format("Int32"); + break; + case FieldDescriptor::TYPE_UINT64: + format("UInt64"); + break; + case FieldDescriptor::TYPE_SINT64: + format("SInt64"); + break; + case FieldDescriptor::TYPE_INT64: + format("Int64"); + break; + + case FieldDescriptor::TYPE_BYTES: + format("Bytes"); + break; + case FieldDescriptor::TYPE_STRING: { + auto mode = GetUtf8CheckMode(field, options); + switch (mode) { + case Utf8CheckMode::kStrict: + format("Utf8String"); + break; + case Utf8CheckMode::kVerify: + format("RawString"); + break; + case Utf8CheckMode::kNone: + // Treat LITE_RUNTIME strings as bytes. + format("Bytes"); + break; + default: + GOOGLE_LOG(FATAL) << "Invalid Utf8CheckMode (" << static_cast(mode) + << ") for " << field->DebugString(); + } + break; + } + + case FieldDescriptor::TYPE_GROUP: + format("Message | ::_fl::kRepGroup"); + break; + case FieldDescriptor::TYPE_MESSAGE: + if (field->is_map()) { + format("Map"); + } else { + format("Message"); + if (IsLazy(field, options, scc_analyzer)) { + format(" | ::_fl::kRepLazy"); + } else if (IsImplicitWeakField(field, options, scc_analyzer)) { + format(" | ::_fl::kRepIWeak"); + } + } + break; + } + + // Fill in extra information about string and bytes field representations. + if (field->type() == FieldDescriptor::TYPE_BYTES || + field->type() == FieldDescriptor::TYPE_STRING) { + if (field->is_repeated()) { + format(" | ::_fl::kRepSString"); } else { - format("{}"); + format(" | ::_fl::kRepAString"); + } + } + + format(")"); +} + +void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) { + for (const auto& entry : tc_table_info_->field_entries) { + const FieldDescriptor* field = entry.field; + PrintFieldComment(format, field); + format("{"); + if (IsWeak(field, options_)) { + // Weak fields are handled by the generated fallback function. + // (These are handled by legacy Google-internal logic.) + format("/* weak */ 0, 0, 0, 0"); + } else { + const OneofDescriptor* oneof = field->real_containing_oneof(); + format("PROTOBUF_FIELD_OFFSET($classname$, $1$), $2$, $3$,\n ", + FieldMemberName(field), + (oneof ? oneof->index() : entry.hasbit_idx), entry.aux_idx); + FormatFieldKind(format, entry, options_, scc_analyzer_); } format("},\n"); } } +static constexpr int kMaxNameLength = 255; + +int ParseFunctionGenerator::CalculateFieldNamesSize() const { + // The full name of the message appears first. + int size = std::min(static_cast(descriptor_->full_name().size()), + kMaxNameLength); + int lengths_size = 1; + for (const auto& entry : tc_table_info_->field_entries) { + const FieldDescriptor* field = entry.field; + GOOGLE_CHECK_LE(field->name().size(), kMaxNameLength); + size += field->name().size(); + lengths_size += 1; + } + // align to an 8-byte boundary + lengths_size = (lengths_size + 7) & -8; + return size + lengths_size + 1; +} + +static void FormatOctal(Formatter& format, int size) { + int octal_size = ((size >> 6) & 3) * 100 + // + ((size >> 3) & 7) * 10 + // + ((size >> 0) & 7); + format("\\$1$", octal_size); +} + +void ParseFunctionGenerator::GenerateFieldNames(Formatter& format) { + // First, we output the size of each string, as an unsigned byte. The first + // string is the message name. + int count = 1; + format("\""); + FormatOctal(format, + std::min(static_cast(descriptor_->full_name().size()), 255)); + for (const auto& entry : tc_table_info_->field_entries) { + FormatOctal(format, entry.field->name().size()); + ++count; + } + while (count & 7) { // align to an 8-byte boundary + format("\\0"); + ++count; + } + format("\"\n"); + // The message name is stored at the beginning of the string + std::string message_name = descriptor_->full_name(); + if (message_name.size() > kMaxNameLength) { + static constexpr int kNameHalfLength = (kMaxNameLength - 3) / 2; + message_name = StrCat( + message_name.substr(0, kNameHalfLength), "...", + message_name.substr(message_name.size() - kNameHalfLength)); + } + format("\"$1$\"\n", message_name); + // Then we output the actual field names + for (const auto& entry : tc_table_info_->field_entries) { + const FieldDescriptor* field = entry.field; + format("\"$1$\"\n", field->name()); + } +} + void ParseFunctionGenerator::GenerateArenaString(Formatter& format, const FieldDescriptor* field) { if (HasHasbit(field)) { @@ -636,11 +1007,12 @@ void ParseFunctionGenerator::GenerateArenaString(Formatter& format, if (IsStringInlined(field, options_)) { GOOGLE_DCHECK(!inlined_string_indices_.empty()); int inlined_string_index = inlined_string_indices_[field->index()]; - GOOGLE_DCHECK_GE(inlined_string_index, 0); + GOOGLE_DCHECK_GT(inlined_string_index, 0); format( ", $msg$_internal_$name$_donated()" ", &$msg$_inlined_string_donated_[$1$]" - ", ~0x$2$u", + ", ~0x$2$u" + ", $this$", inlined_string_index / 32, strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8)); } else { @@ -649,7 +1021,7 @@ void ParseFunctionGenerator::GenerateArenaString(Formatter& format, format( ");\n" "} else {\n" - " ptr = ::$proto_ns$::internal::InlineGreedyStringParser(" + " ptr = ::_pbi::InlineGreedyStringParser(" "$msg$$name$_.MutableNoArenaNoDefault(&$1$), ptr, ctx);\n" "}\n" "const std::string* str = &$msg$$name$_.Get(); (void)str;\n", @@ -685,11 +1057,14 @@ void ParseFunctionGenerator::GenerateStrings(Formatter& format, } format( "auto str = $msg$$1$$2$_$name$();\n" - "ptr = ::$proto_ns$::internal::Inline$3$(str, ptr, ctx);\n", + "ptr = ::_pbi::Inline$3$(str, ptr, ctx);\n", HasInternalAccessors(ctype) ? "_internal_" : "", field->is_repeated() && !field->is_packable() ? "add" : "mutable", parser_name); } + // It is intentionally placed before VerifyUTF8 because it doesn't make sense + // to verify UTF8 when we already know parsing failed. + format("CHK_(ptr);\n"); if (!check_utf8) return; // return if this is a bytes field auto level = GetUtf8CheckMode(field, options_); switch (level) { @@ -707,7 +1082,7 @@ void ParseFunctionGenerator::GenerateStrings(Formatter& format, if (HasDescriptorMethods(field->file(), options_)) { field_name = StrCat("\"", field->full_name(), "\""); } - format("::$proto_ns$::internal::VerifyUTF8(str, $1$)", field_name); + format("::_pbi::VerifyUTF8(str, $1$)", field_name); switch (level) { case Utf8CheckMode::kNone: return; @@ -740,6 +1115,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, "$msg$_internal_mutable_$name$(), ptr, ctx);\n", DeclaredTypeMethodName(field->type())); } + format("CHK_(ptr);\n"); } else { auto field_type = field->type(); switch (field_type) { @@ -751,8 +1127,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, break; case FieldDescriptor::TYPE_MESSAGE: { if (field->is_map()) { - const FieldDescriptor* val = - field->message_type()->FindFieldByName("value"); + const FieldDescriptor* val = field->message_type()->map_value(); GOOGLE_CHECK(val); if (val->type() == FieldDescriptor::TYPE_ENUM && !HasPreservingUnknownEnumSemantics(field)) { @@ -768,6 +1143,16 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); } } else if (IsLazy(field, options_, scc_analyzer_)) { + bool eager_verify = + IsEagerlyVerifiedLazy(field, options_, scc_analyzer_); + if (ShouldVerify(descriptor_, options_, scc_analyzer_)) { + format( + "ctx->set_lazy_eager_verify_func($1$);\n", + eager_verify + ? StrCat("&", ClassName(field->message_type(), true), + "::InternalVerify") + : "nullptr"); + } if (field->real_containing_oneof()) { format( "if (!$msg$_internal_has_$name$()) {\n" @@ -790,9 +1175,16 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, "::$proto_ns$::internal::LazyFieldParseHelper<\n" " ::$proto_ns$::internal::LazyField> parse_helper(\n" " $1$::default_instance(),\n" - " $msg$GetArenaForAllocation(), lazy_field);\n" + " $msg$GetArenaForAllocation(),\n" + " ::google::protobuf::internal::LazyVerifyOption::$2$,\n" + " lazy_field);\n" "ptr = ctx->ParseMessage(&parse_helper, ptr);\n", - FieldMessageTypeName(field, options_)); + FieldMessageTypeName(field, options_), + eager_verify ? "kEager" : "kLazy"); + if (ShouldVerify(descriptor_, options_, scc_analyzer_) && + eager_verify) { + format("ctx->set_lazy_eager_verify_func(nullptr);\n"); + } } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) { if (!field->is_repeated()) { format( @@ -819,6 +1211,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, "ptr = ctx->ParseMessage($msg$_internal_$mutable_field$(), " "ptr);\n"); } + format("CHK_(ptr);\n"); break; } default: @@ -925,7 +1318,6 @@ void ParseFunctionGenerator::GenerateFieldBody( } case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { GenerateLengthDelim(format, field); - format("CHK_(ptr);\n"); break; } case WireFormatLite::WIRETYPE_START_GROUP: { @@ -983,13 +1375,9 @@ static uint32_t ExpectedTag(const FieldDescriptor* field, // parse the next tag in the stream. void ParseFunctionGenerator::GenerateParseIterationBody( Formatter& format, const Descriptor* descriptor, - const std::vector& ordered_fields) { - format( - "$uint32$ tag;\n" - "ptr = ::$proto_ns$::internal::ReadTag(ptr, &tag);\n"); - - if (!ordered_fields.empty()) { - GenerateFieldSwitch(format, ordered_fields); + const std::vector& fields) { + if (!fields.empty()) { + GenerateFieldSwitch(format, fields); // Each field `case` only considers field number. Field numbers that are // not defined in the message, or tags with an incompatible wire type, are // considered "unusual" cases. They will be handled by the logic below. @@ -1045,12 +1433,11 @@ void ParseFunctionGenerator::GenerateParseIterationBody( } void ParseFunctionGenerator::GenerateFieldSwitch( - Formatter& format, - const std::vector& ordered_fields) { + Formatter& format, const std::vector& fields) { format("switch (tag >> 3) {\n"); format.Indent(); - for (const auto* field : ordered_fields) { + for (const auto* field : fields) { PrintFieldComment(format, field); format("case $1$:\n", field->number()); format.Indent(); @@ -1104,64 +1491,68 @@ void ParseFunctionGenerator::GenerateFieldSwitch( namespace { -std::string FieldParseFunctionName(const FieldDescriptor* field, - const Options& options) { - ParseCardinality card = // - field->is_packed() ? ParseCardinality::kPacked - : field->is_repeated() ? ParseCardinality::kRepeated - : field->real_containing_oneof() ? ParseCardinality::kOneof - : ParseCardinality::kSingular; +std::string FieldParseFunctionName( + const TailCallTableInfo::FieldEntryInfo& entry, const Options& options) { + const FieldDescriptor* field = entry.field; + std::string name = "::_pbi::TcParser::Fast"; - TypeFormat type_format; switch (field->type()) { - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_SFIXED64: - case FieldDescriptor::TYPE_DOUBLE: - type_format = TypeFormat::kFixed64; - break; - case FieldDescriptor::TYPE_FIXED32: case FieldDescriptor::TYPE_SFIXED32: case FieldDescriptor::TYPE_FLOAT: - type_format = TypeFormat::kFixed32; + name.append("F32"); break; - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_UINT64: - type_format = TypeFormat::kVar64; + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + case FieldDescriptor::TYPE_DOUBLE: + name.append("F64"); break; + case FieldDescriptor::TYPE_BOOL: + name.append("V8"); + break; case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_UINT32: - type_format = TypeFormat::kVar32; + name.append("V32"); + break; + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + name.append("V64"); break; - case FieldDescriptor::TYPE_SINT64: - type_format = TypeFormat::kSInt64; + case FieldDescriptor::TYPE_ENUM: + if (HasPreservingUnknownEnumSemantics(field)) { + name.append("V32"); + break; + } + if (field->is_repeated() && field->is_packed()) { + GOOGLE_LOG(DFATAL) << "Enum validation not handled: " << field->DebugString(); + return ""; + } + name.append(entry.is_enum_range ? "Er" : "Ev"); break; case FieldDescriptor::TYPE_SINT32: - type_format = TypeFormat::kSInt32; + name.append("Z32"); break; - - case FieldDescriptor::TYPE_BOOL: - type_format = TypeFormat::kBool; + case FieldDescriptor::TYPE_SINT64: + name.append("Z64"); break; case FieldDescriptor::TYPE_BYTES: - type_format = TypeFormat::kBytes; + name.append("B"); break; - case FieldDescriptor::TYPE_STRING: switch (GetUtf8CheckMode(field, options)) { case Utf8CheckMode::kNone: - type_format = TypeFormat::kBytes; - break; - case Utf8CheckMode::kStrict: - type_format = TypeFormat::kString; + name.append("B"); break; case Utf8CheckMode::kVerify: - type_format = TypeFormat::kStringValidateOnly; + name.append("S"); + break; + case Utf8CheckMode::kStrict: + name.append("U"); break; default: GOOGLE_LOG(DFATAL) << "Mode not handled: " @@ -1170,133 +1561,32 @@ std::string FieldParseFunctionName(const FieldDescriptor* field, } break; + case FieldDescriptor::TYPE_MESSAGE: + name.append("M"); + break; + default: GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString(); return ""; } - return "::" + ProtobufNamespace(options) + "::internal::TcParser::" + - GetTailCallFieldHandlerName(card, type_format, - TagSize(field->number()), options); -} - -} // namespace - -std::string GetTailCallFieldHandlerName(ParseCardinality card, - TypeFormat type_format, - int tag_length_bytes, - const Options& options) { - std::string name; - // The field implementation functions are prefixed by cardinality: - // `Singular` for optional or implicit fields. - // `Repeated` for non-packed repeated. - // `Packed` for packed repeated. - switch (card) { - case ParseCardinality::kSingular: - name.append("Singular"); - break; - case ParseCardinality::kOneof: - name.append("Oneof"); - break; - case ParseCardinality::kRepeated: - name.append("Repeated"); - break; - case ParseCardinality::kPacked: - name.append("Packed"); - break; - } - - // Next in the function name is the TypeFormat-specific name. - switch (type_format) { - case TypeFormat::kFixed64: - case TypeFormat::kFixed32: - name.append("Fixed"); - break; - - case TypeFormat::kVar64: - case TypeFormat::kVar32: - case TypeFormat::kSInt64: - case TypeFormat::kSInt32: - case TypeFormat::kBool: - name.append("Varint"); - break; + // `S` for optional or implicit fields. + // `R` for non-packed repeated. + // `P` for packed repeated. + name.append(field->is_packed() ? "P" + : field->is_repeated() ? "R" + : field->real_containing_oneof() ? "O" + : "S"); - case TypeFormat::kBytes: - case TypeFormat::kString: - case TypeFormat::kStringValidateOnly: - name.append("String"); - break; - - default: - break; - } - - name.append("<"); - - // Determine the numeric layout type for the parser to use, independent of - // the specific parsing logic used. - switch (type_format) { - case TypeFormat::kVar64: - case TypeFormat::kFixed64: - name.append("uint64_t, "); - break; - - case TypeFormat::kSInt64: - name.append("int64_t, "); - break; + // Append the tag length. Fast parsing only handles 1- or 2-byte tags. + name.append(TagSize(field->number()) == 1 ? "1" : "2"); - case TypeFormat::kVar32: - case TypeFormat::kFixed32: - name.append("uint32_t, "); - break; - - case TypeFormat::kSInt32: - name.append("int32_t, "); - break; - - case TypeFormat::kBool: - name.append("bool, "); - break; - - default: - break; - } - - name.append(CodedTagType(tag_length_bytes)); - - switch (type_format) { - case TypeFormat::kVar64: - case TypeFormat::kVar32: - case TypeFormat::kBool: - StrAppend(&name, ", ", TcParserName(options), "kNoConversion"); - break; - - case TypeFormat::kSInt64: - case TypeFormat::kSInt32: - StrAppend(&name, ", ", TcParserName(options), "kZigZag"); - break; - - case TypeFormat::kBytes: - StrAppend(&name, ", ", TcParserName(options), "kNoUtf8"); - break; - - case TypeFormat::kString: - StrAppend(&name, ", ", TcParserName(options), "kUtf8"); - break; - - case TypeFormat::kStringValidateOnly: - StrAppend(&name, ", ", TcParserName(options), "kUtf8ValidateOnly"); - break; - - default: - break; - } - - name.append(">"); return name; } +} // namespace + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h index b921067bd2c50..a1621fd2d8380 100644 --- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h +++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h @@ -35,12 +35,11 @@ #include #include -#include -#include #include #include -#include #include +#include +#include namespace google { namespace protobuf { @@ -50,18 +49,34 @@ namespace cpp { // Helper class for generating tailcall parsing functions. struct TailCallTableInfo { TailCallTableInfo(const Descriptor* descriptor, const Options& options, + const std::vector& ordered_fields, const std::vector& has_bit_indices, MessageSCCAnalyzer* scc_analyzer); - // Information to generate field entries. - struct FieldInfo { - const FieldDescriptor* field; - google::protobuf::internal::TcFieldData bits; + + // Fields parsed by the table fast-path. + struct FastFieldInfo { std::string func_name; + const FieldDescriptor* field; + uint16_t coded_tag; + uint8_t hasbit_idx; + uint8_t aux_idx; }; - // Fields parsed by the table fast-path. - std::vector fast_path_fields; - // Fields parsed by slow-path fallback. + std::vector fast_path_fields; + + // Fields parsed by mini parsing routines. + struct FieldEntryInfo { + const FieldDescriptor* field; + int hasbit_idx; + uint16_t aux_idx; + // True for enums entirely covered by the start/length fields of FieldAux: + bool is_enum_range; + }; + std::vector field_entries; + std::vector aux_entries; + + // Fields parsed by generated fallback function. std::vector fallback_fields; + // Table size. int table_size_log2; // Mask for has-bits of required fields. @@ -110,15 +125,15 @@ class ParseFunctionGenerator { // Generates a fallback function for tailcall table-based parsing. void GenerateTailcallFallbackFunction(Formatter& format); - // Generates functions for parsing this message as a field. - void GenerateTailcallFieldParseFunctions(Formatter& format); - // Generates a looping `_InternalParse` function. void GenerateLoopingParseFunction(Formatter& format); // Generates the tail-call table definition. void GenerateTailCallTable(Formatter& format); - void GenerateFastFieldEntries(Formatter& format, const std::string& fallback); + void GenerateFastFieldEntries(Formatter& format); + void GenerateFieldEntries(Formatter& format); + int CalculateFieldNamesSize() const; + void GenerateFieldNames(Formatter& format); // Generates parsing code for an `ArenaString` field. void GenerateArenaString(Formatter& format, const FieldDescriptor* field); @@ -139,12 +154,11 @@ class ParseFunctionGenerator { // Generates code to parse the next field from the input stream. void GenerateParseIterationBody( Formatter& format, const Descriptor* descriptor, - const std::vector& ordered_fields); + const std::vector& fields); - // Generates a `switch` statement to parse each of `ordered_fields`. - void GenerateFieldSwitch( - Formatter& format, - const std::vector& ordered_fields); + // Generates a `switch` statement to parse each of `fields`. + void GenerateFieldSwitch(Formatter& format, + const std::vector& fields); const Descriptor* descriptor_; MessageSCCAnalyzer* scc_analyzer_; @@ -152,45 +166,10 @@ class ParseFunctionGenerator { std::map variables_; std::unique_ptr tc_table_info_; std::vector inlined_string_indices_; + const std::vector ordered_fields_; int num_hasbits_; }; -enum class ParseCardinality { - kSingular, - kOneof, - kRepeated, - kPacked, -}; - -// TypeFormat defines parsing types, which encapsulates the expected wire -// format, conversion or validation, and the in-memory layout. -enum class TypeFormat { - // Fixed types: - kFixed64, // fixed64, sfixed64, double - kFixed32, // fixed32, sfixed32, float - - // Varint types: - kVar64, // int64, uint64 - kVar32, // int32, uint32 - kSInt64, // sint64 - kSInt32, // sint32 - kBool, // bool - - // Length-delimited types: - kBytes, // bytes - kString, // string (proto3/UTF-8 strict) - kStringValidateOnly, // string (proto2/UTF-8 validate only) -}; - -// Returns the name of a field parser function. -// -// These are out-of-line functions generated by -// parse_function_inc_generator_main. -std::string GetTailCallFieldHandlerName(ParseCardinality card, - TypeFormat type_format, - int tag_length_bytes, - const Options& options); - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc index 373f38d80794a..5bc419d40281c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc @@ -54,11 +54,10 @@ namespace { class TestGenerator : public CodeGenerator { public: TestGenerator() {} - ~TestGenerator() {} + ~TestGenerator() override {} - 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 { TryInsert("test.pb.h", "includes", context); TryInsert("test.pb.h", "namespace_scope", context); TryInsert("test.pb.h", "global_scope", context); diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index ffccf08aae089..e09f93e143b09 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -34,10 +34,10 @@ #include -#include #include #include #include +#include namespace google { namespace protobuf { @@ -201,7 +201,7 @@ void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "target = stream->EnsureSpace(target);\n" "target = " - "::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray(" + "::_pbi::WireFormatLite::Write$declared_type$ToArray(" "$number$, this->_internal_$name$(), target);\n"); } @@ -214,12 +214,12 @@ void PrimitiveFieldGenerator::GenerateByteSize(io::Printer* printer) const { // Adding one is very common and it turns out it can be done for // free inside of WireFormatLite, so we can save an instruction here. format( - "total_size += ::$proto_ns$::internal::WireFormatLite::" + "total_size += ::_pbi::WireFormatLite::" "$declared_type$SizePlusOne(this->_internal_$name$());\n"); } else { format( "total_size += $tag_size$ +\n" - " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" + " ::_pbi::WireFormatLite::$declared_type$Size(\n" " this->_internal_$name$());\n"); } } else { @@ -440,7 +440,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n" " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::" + " target = ::_pbi::WireFormatLite::" "Write$declared_type$ToArray($number$, this->_internal_$name$(i), " "target);\n" "}\n"); @@ -455,7 +455,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize( int fixed_size = FixedSize(descriptor_->type()); if (fixed_size == -1) { format( - "size_t data_size = ::$proto_ns$::internal::WireFormatLite::\n" + "size_t data_size = ::_pbi::WireFormatLite::\n" " $declared_type$Size(this->$name$_);\n"); } else { format( @@ -468,12 +468,11 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize( format( "if (data_size > 0) {\n" " total_size += $tag_size$ +\n" - " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n" - " static_cast<$int32$>(data_size));\n" + " ::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n" "}\n"); if (FixedSize(descriptor_->type()) == -1) { format( - "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n" + "int cached_size = ::_pbi::ToCachedSize(data_size);\n" "_$name$_cached_byte_size_.store(cached_size,\n" " std::memory_order_relaxed);\n"); } @@ -482,7 +481,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize( format( "total_size += $tag_size$ *\n" " " - "::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n" + "::_pbi::FromIntSize(this->_internal_$name$_size());\n" "total_size += data_size;\n"); } format.Outdent(); diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h index ff7c208ff2941..0cdc12c06e298 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { @@ -48,7 +49,7 @@ class PrimitiveFieldGenerator : public FieldGenerator { public: PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~PrimitiveFieldGenerator(); + ~PrimitiveFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -72,7 +73,7 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { public: PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~PrimitiveOneofFieldGenerator(); + ~PrimitiveOneofFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; @@ -88,7 +89,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { public: RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~RepeatedPrimitiveFieldGenerator(); + ~RepeatedPrimitiveFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; diff --git a/src/google/protobuf/compiler/cpp/cpp_service.cc b/src/google/protobuf/compiler/cpp/cpp_service.cc index 6b1ca83eda7ea..c630e7fa66279 100644 --- a/src/google/protobuf/compiler/cpp/cpp_service.cc +++ b/src/google/protobuf/compiler/cpp/cpp_service.cc @@ -33,9 +33,10 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include -#include + #include #include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/cpp/cpp_service.h b/src/google/protobuf/compiler/cpp/cpp_service.h index 63c7ca44f8523..8b210af1131a8 100644 --- a/src/google/protobuf/compiler/cpp/cpp_service.h +++ b/src/google/protobuf/compiler/cpp/cpp_service.h @@ -37,8 +37,9 @@ #include #include -#include + #include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 607e81500cc5c..529cb86f4bdfc 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -33,10 +33,11 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include -#include -#include + #include #include +#include +#include namespace google { @@ -50,36 +51,36 @@ void SetStringVariables(const FieldDescriptor* descriptor, std::map* variables, const Options& options) { SetCommonFieldVariables(descriptor, variables, options); + + const std::string kNS = "::" + (*variables)["proto_ns"] + "::internal::"; + const std::string kArenaStringPtr = kNS + "ArenaStringPtr"; + const std::string kEmptyDefault = kArenaStringPtr + "::EmptyDefault{}"; + const std::string kNonEmptyDefault = kArenaStringPtr + "::NonEmptyDefault{}"; + (*variables)["default"] = DefaultValue(options, descriptor); (*variables)["default_length"] = StrCat(descriptor->default_value_string().length()); std::string default_variable_string = MakeDefaultName(descriptor); (*variables)["default_variable_name"] = default_variable_string; - if (!descriptor->default_value_string().empty()) { + if (descriptor->default_value_string().empty()) { + (*variables)["init_value"] = ""; + (*variables)["default_string"] = kNS + "GetEmptyStringAlreadyInited()"; + (*variables)["default_value"] = "&" + (*variables)["default_string"]; + (*variables)["default_value_tag"] = kEmptyDefault; + (*variables)["default_variable_or_tag"] = kEmptyDefault; + } else { (*variables)["lazy_variable"] = QualifiedClassName(descriptor->containing_type(), options) + "::" + default_variable_string; + + (*variables)["init_value"] = "nullptr"; + (*variables)["default_string"] = (*variables)["lazy_variable"] + ".get()"; + (*variables)["default_value"] = "nullptr"; + (*variables)["default_value_tag"] = kNonEmptyDefault; + (*variables)["default_variable_or_tag"] = (*variables)["lazy_variable"]; } - (*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()" - : "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)["setter"] = @@ -116,9 +117,14 @@ void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { if (!inlined_) { format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); } else { + // Skips the automatic destruction; rather calls it explicitly if + // allocating arena is null. This is required to support message-owned + // arena (go/path-to-arenas) where a root proto is destroyed but + // InlinedStringField may have arena-allocated memory. + // // `_init_inline_xxx` is used for initializing default instances. format( - "::$proto_ns$::internal::InlinedStringField $name$_;\n" + "union { ::$proto_ns$::internal::InlinedStringField $name$_; };\n" "static std::true_type _init_inline_$name$_;\n"); } } @@ -204,7 +210,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " // @@protoc_insertion_point(field_get:$full_name$)\n"); if (!descriptor_->default_value_string().empty()) { format( - " if ($name$_.IsDefault(nullptr)) return " + " if ($name$_.IsDefault()) return " "$default_variable_name$.get();\n"); } format( @@ -229,7 +235,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " $set_hasbit$\n" " $name$_.$setter$(nullptr, static_cast(arg0)," " args..., GetArenaForAllocation(), _internal_$name$_donated(), " - "&$donating_states_word$, $mask_for_undonate$);\n" + "&$donating_states_word$, $mask_for_undonate$, this);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" @@ -259,7 +265,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( format( " $name$_.Set(nullptr, value, GetArenaForAllocation(),\n" " _internal_$name$_donated(), &$donating_states_word$, " - "$mask_for_undonate$);\n" + "$mask_for_undonate$, this);\n" "}\n"); } format( @@ -274,7 +280,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( format( " return $name$_.Mutable($default_variable_or_tag$, " "GetArenaForAllocation(), _internal_$name$_donated(), " - "&$donating_states_word$, $mask_for_undonate$);\n" + "&$donating_states_word$, $mask_for_undonate$, this);\n" "}\n"); } format( @@ -290,13 +296,13 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " $clear_hasbit$\n"); if (!inlined_) { format( - " auto* p = $name$_.ReleaseNonDefault($init_value$, " + " auto* p = $name$_.ReleaseNonDefault($default_value$, " "GetArenaForAllocation());\n"); if (descriptor_->default_value_string().empty()) { format( "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" - " if ($name$_.IsDefault($init_value$)) {\n" - " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + " if ($name$_.IsDefault()) {\n" + " $name$_.Set($default_value$, \"\", GetArenaForAllocation());\n" " }\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } @@ -308,7 +314,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( } } else { format( - " return $name$_.Release($init_value$, GetArenaForAllocation());\n"); + " return $name$_.Release($default_value$, GetArenaForAllocation());\n"); } format( @@ -321,13 +327,13 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " }\n"); if (!inlined_) { format( - " $name$_.SetAllocated($init_value$, $name$,\n" + " $name$_.SetAllocated($default_value$, $name$,\n" " GetArenaForAllocation());\n"); if (descriptor_->default_value_string().empty()) { format( "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" - " if ($name$_.IsDefault($init_value$)) {\n" - " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + " if ($name$_.IsDefault()) {\n" + " $name$_.Set($default_value$, \"\", GetArenaForAllocation());\n" " }\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } @@ -336,7 +342,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( format( " $name$_.SetAllocated(nullptr, $name$, GetArenaForAllocation(), " "_internal_$name$_donated(), &$donating_states_word$, " - "$mask_for_undonate$);\n"); + "$mask_for_undonate$, this);\n"); } format( "$annotate_set$" @@ -388,7 +394,7 @@ void StringFieldGenerator::GenerateMessageClearingCode( // // For non-inlined strings, we distinguish from non-default by comparing // instances, rather than contents. - format("$DCHK$(!$name$_.IsDefault(nullptr));\n"); + format("$DCHK$(!$name$_.IsDefault());\n"); } if (descriptor_->default_value_string().empty()) { @@ -416,34 +422,32 @@ void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { if (!inlined_) { format( "::$proto_ns$::internal::ArenaStringPtr::InternalSwap(\n" - " $init_value$,\n" + " $default_value$,\n" " &$name$_, lhs_arena,\n" " &other->$name$_, rhs_arena\n" ");\n"); } else { - // At this point, it's guaranteed that the two fields being swapped are on - // the same arena. format( - "$name$_.Swap(&other->$name$_, nullptr, GetArenaForAllocation(), " - "_internal_$name$_donated(), other->_internal_$name$_donated(), " - "&$donating_states_word$, &(other->$donating_states_word$), " - "$mask_for_undonate$);\n"); + "::$proto_ns$::internal::InlinedStringField::InternalSwap(\n" + " &$name$_, lhs_arena, " + "(_inlined_string_donated_[0] & 0x1u) == 0, this,\n" + " &other->$name$_, rhs_arena, " + "(other->_inlined_string_donated_[0] & 0x1u) == 0, other);\n"); } } void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { Formatter format(printer, variables_); if (inlined_ && descriptor_->default_value_string().empty()) { - // Automatic initialization will construct the string. return; } GOOGLE_DCHECK(!inlined_); - format("$name$_.UnsafeSetDefault($init_value$);\n"); + format("$name$_.InitDefault($init_value$);\n"); if (IsString(descriptor_, options_) && descriptor_->default_value_string().empty()) { format( "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" - " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + " $name$_.Set($default_value$, \"\", GetArenaForAllocation());\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } } @@ -452,6 +456,9 @@ void StringFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); GenerateConstructorCode(printer); + if (inlined_) { + format("new (&$name$_) ::$proto_ns$::internal::InlinedStringField();\n"); + } if (HasHasbit(descriptor_)) { format("if (from._internal_has_$name$()) {\n"); @@ -469,7 +476,7 @@ void StringFieldGenerator::GenerateCopyConstructorCode( format( "$name$_.Set(nullptr, from._internal_$name$(),\n" " GetArenaForAllocation(), _internal_$name$_donated(), " - "&$donating_states_word$, $mask_for_undonate$);\n"); + "&$donating_states_word$, $mask_for_undonate$, this);\n"); } format.Outdent(); @@ -478,12 +485,30 @@ void StringFieldGenerator::GenerateCopyConstructorCode( void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - // The destructor is automatically invoked. + if (!inlined_) { + format("$name$_.DestroyNoArena($default_value$);\n"); return; } + // Explicitly calls ~InlinedStringField as its automatic call is disabled. + // Destructor has been implicitly skipped as a union, and even the + // message-owned arena is enabled, arena could still be missing for + // Arena::CreateMessage(nullptr). + format("$name$_.~InlinedStringField();\n"); +} + +ArenaDtorNeeds StringFieldGenerator::NeedsArenaDestructor() const { + return inlined_ ? ArenaDtorNeeds::kOnDemand : ArenaDtorNeeds::kNone; +} - format("$name$_.DestroyNoArena($init_value$);\n"); +void StringFieldGenerator::GenerateArenaDestructorCode( + io::Printer* printer) const { + if (!inlined_) return; + Formatter format(printer, variables_); + // _this is the object being destructed (we are inside a static method here). + format( + "if (!_this->_internal_$name$_donated()) {\n" + " _this->$name$_.~InlinedStringField();\n" + "}\n"); } void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -550,7 +575,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field_member$.InitDefault($init_value$);\n" " }\n" " $field_member$.$setter$($default_value_tag$," " static_cast(arg0), args..., GetArenaForAllocation());\n" @@ -574,7 +599,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field_member$.InitDefault($init_value$);\n" " }\n" " $field_member$.Set($default_value_tag$, value, " "GetArenaForAllocation());\n" @@ -584,7 +609,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field_member$.InitDefault($init_value$);\n" " }\n" " return $field_member$.Mutable(\n" " $default_variable_or_tag$, GetArenaForAllocation());\n" @@ -594,7 +619,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " return $field_member$.ReleaseNonDefault($init_value$, " + " return $field_member$.ReleaseNonDefault($default_value$, " "GetArenaForAllocation());\n" " } else {\n" " return nullptr;\n" @@ -606,11 +631,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " }\n" " if ($name$ != nullptr) {\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($name$);\n" - " ::$proto_ns$::Arena* arena = GetArenaForAllocation();\n" - " if (arena != nullptr) {\n" - " arena->Own($name$);\n" - " }\n" + " $field_member$.InitAllocated($name$, GetArenaForAllocation());\n" " }\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index 3f05443f58285..436643cf599b0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { @@ -48,7 +49,7 @@ class StringFieldGenerator : public FieldGenerator { public: StringFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~StringFieldGenerator(); + ~StringFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -64,11 +65,13 @@ class StringFieldGenerator : public FieldGenerator { void GenerateConstructorCode(io::Printer* printer) const override; void GenerateCopyConstructorCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override; + void GenerateArenaDestructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateConstinitInitializer(io::Printer* printer) const override; bool IsInlined() const override { return inlined_; } + ArenaDtorNeeds NeedsArenaDestructor() const override; private: bool inlined_; @@ -79,7 +82,7 @@ class StringOneofFieldGenerator : public StringFieldGenerator { public: StringOneofFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~StringOneofFieldGenerator(); + ~StringOneofFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; @@ -99,7 +102,7 @@ class RepeatedStringFieldGenerator : public FieldGenerator { public: RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~RepeatedStringFieldGenerator(); + ~RepeatedStringFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/src/google/protobuf/compiler/cpp/cpp_unittest.inc index 782d2263beb5b..cfaa8df157f57 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.inc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.inc @@ -95,7 +95,7 @@ void DoNothing() {} class MockErrorCollector : public MultiFileErrorCollector { public: MockErrorCollector() {} - ~MockErrorCollector() {} + ~MockErrorCollector() override {} std::string text_; @@ -126,7 +126,7 @@ TEST(GENERATED_DESCRIPTOR_TEST_NAME, IdenticalDescriptors) { const FileDescriptor* parsed_descriptor = importer.Import(TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH)); EXPECT_EQ("", error_collector.text_); - ASSERT_TRUE(parsed_descriptor != NULL); + ASSERT_TRUE(parsed_descriptor != nullptr); // Test that descriptors are generated correctly by converting them to // FileDescriptorProtos and comparing. @@ -147,7 +147,7 @@ TEST(GENERATED_DESCRIPTOR_TEST_NAME, EnormousDescriptor) { const Descriptor* generated_descriptor = ::protobuf_unittest::TestEnormousDescriptor::descriptor(); - EXPECT_TRUE(generated_descriptor != NULL); + EXPECT_TRUE(generated_descriptor != nullptr); } #endif @@ -249,11 +249,11 @@ TEST(GENERATED_MESSAGE_TEST_NAME, StringDefaults) { } TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseString) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestAllTypes message; - EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_EQ(nullptr, message.release_default_string()); EXPECT_FALSE(message.has_default_string()); EXPECT_EQ("hello", message.default_string()); @@ -261,30 +261,30 @@ TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseString) { EXPECT_TRUE(message.has_default_string()); std::unique_ptr str(message.release_default_string()); EXPECT_FALSE(message.has_default_string()); - ASSERT_TRUE(str != NULL); + ASSERT_TRUE(str != nullptr); EXPECT_EQ("blah", *str); - EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_EQ(nullptr, message.release_default_string()); EXPECT_FALSE(message.has_default_string()); EXPECT_EQ("hello", message.default_string()); } TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseMessage) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestAllTypes message; - EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_EQ(nullptr, message.release_optional_nested_message()); EXPECT_FALSE(message.has_optional_nested_message()); message.mutable_optional_nested_message()->set_bb(1); std::unique_ptr nest( message.release_optional_nested_message()); EXPECT_FALSE(message.has_optional_nested_message()); - ASSERT_TRUE(nest != NULL); + ASSERT_TRUE(nest != nullptr); EXPECT_EQ(1, nest->bb()); - EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_EQ(nullptr, message.release_optional_nested_message()); EXPECT_FALSE(message.has_optional_nested_message()); } @@ -297,7 +297,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedString) { message.set_optional_string(kHello); EXPECT_TRUE(message.has_optional_string()); - message.set_allocated_optional_string(NULL); + message.set_allocated_optional_string(nullptr); EXPECT_FALSE(message.has_optional_string()); EXPECT_EQ("", message.optional_string()); @@ -315,7 +315,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedMessage) { message.mutable_optional_nested_message()->set_bb(1); EXPECT_TRUE(message.has_optional_nested_message()); - message.set_allocated_optional_nested_message(NULL); + message.set_allocated_optional_nested_message(nullptr); EXPECT_FALSE(message.has_optional_nested_message()); EXPECT_EQ(&UNITTEST::TestAllTypes::NestedMessage::default_instance(), &message.optional_nested_message()); @@ -323,7 +323,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedMessage) { message.mutable_optional_nested_message()->set_bb(1); UNITTEST::TestAllTypes::NestedMessage* nest = message.release_optional_nested_message(); - ASSERT_TRUE(nest != NULL); + ASSERT_TRUE(nest != nullptr); EXPECT_FALSE(message.has_optional_nested_message()); message.set_allocated_optional_nested_message(nest); @@ -531,6 +531,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, CopyConstructor) { // None set. { UNITTEST::TestAllTypes message1; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) UNITTEST::TestAllTypes message2(message1); EXPECT_FALSE(message1.has_optional_string()); @@ -879,77 +880,81 @@ TEST(GENERATED_MESSAGE_TEST_NAME, TestEmbedOptimizedForSize) { } TEST(GENERATED_MESSAGE_TEST_NAME, TestSpaceUsed) { - UNITTEST::TestAllTypes message1; + // Allocate explicitly on the heap to prevent arena creation. + std::unique_ptr message1( + Arena::CreateMessage(nullptr)); // sizeof provides a lower bound on SpaceUsedLong(). - EXPECT_LE(sizeof(UNITTEST::TestAllTypes), message1.SpaceUsedLong()); - const size_t empty_message_size = message1.SpaceUsedLong(); + EXPECT_LE(sizeof(UNITTEST::TestAllTypes), message1->SpaceUsedLong()); + const size_t empty_message_size = message1->SpaceUsedLong(); // Setting primitive types shouldn't affect the space used. - message1.set_optional_int32(123); - message1.set_optional_int64(12345); - message1.set_optional_uint32(123); - message1.set_optional_uint64(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); + message1->set_optional_int32(123); + message1->set_optional_int64(12345); + message1->set_optional_uint32(123); + message1->set_optional_uint64(12345); + EXPECT_EQ(empty_message_size, message1->SpaceUsedLong()); // On some STL implementations, setting the string to a small value should // only increase SpaceUsedLong() by the size of a string object, though this // is not true everywhere. - message1.set_optional_string("abc"); - EXPECT_LE(empty_message_size + message1.optional_string().size(), - message1.SpaceUsedLong()); + message1->set_optional_string("abc"); + EXPECT_LE(empty_message_size + message1->optional_string().size(), + message1->SpaceUsedLong()); // Setting a string to a value larger than the string object itself should // increase SpaceUsedLong(), because it cannot store the value internally. - message1.set_optional_string(std::string(sizeof(std::string) + 1, 'x')); - int min_expected_increase = message1.optional_string().capacity(); + message1->set_optional_string(std::string(sizeof(std::string) + 1, 'x')); + int min_expected_increase = message1->optional_string().capacity(); EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); - size_t previous_size = message1.SpaceUsedLong(); + size_t previous_size = message1->SpaceUsedLong(); // Adding an optional message should increase the size by the size of the // nested message type. NestedMessage is simple enough (1 int field) that it // is equal to sizeof(NestedMessage) - message1.mutable_optional_nested_message(); + message1->mutable_optional_nested_message(); ASSERT_EQ(sizeof(UNITTEST::TestAllTypes::NestedMessage), - message1.optional_nested_message().SpaceUsedLong()); + message1->optional_nested_message().SpaceUsedLong()); EXPECT_EQ(previous_size + sizeof(UNITTEST::TestAllTypes::NestedMessage), - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); } TEST(GENERATED_MESSAGE_TEST_NAME, TestOneofSpaceUsed) { - UNITTEST::TestOneof2 message1; - EXPECT_LE(sizeof(UNITTEST::TestOneof2), message1.SpaceUsedLong()); + // Allocate explicitly on the heap to prevent arena creation. + std::unique_ptr message1( + Arena::CreateMessage(nullptr)); + EXPECT_LE(sizeof(UNITTEST::TestOneof2), message1->SpaceUsedLong()); - const size_t empty_message_size = message1.SpaceUsedLong(); + const size_t empty_message_size = message1->SpaceUsedLong(); // Setting primitive types shouldn't affect the space used. - message1.set_foo_int(123); - message1.set_bar_int(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); + message1->set_foo_int(123); + message1->set_bar_int(12345); + EXPECT_EQ(empty_message_size, message1->SpaceUsedLong()); // Setting a string in oneof to a small value should only increase // SpaceUsedLong() by the size of a string object. - message1.set_foo_string("abc"); - EXPECT_LE(empty_message_size + sizeof(std::string), message1.SpaceUsedLong()); + message1->set_foo_string("abc"); + EXPECT_LE(empty_message_size + sizeof(std::string), message1->SpaceUsedLong()); // Setting a string in oneof to a value larger than the string object itself // should increase SpaceUsedLong(), because it cannot store the value // internally. - message1.set_foo_string(std::string(sizeof(std::string) + 1, 'x')); + message1->set_foo_string(std::string(sizeof(std::string) + 1, 'x')); int min_expected_increase = - message1.foo_string().capacity() + sizeof(std::string); + message1->foo_string().capacity() + sizeof(std::string); EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); // Setting a message in oneof should delete the other fields and increase the // size by the size of the nested message type. NestedMessage is simple enough // that it is equal to sizeof(NestedMessage). It may be backed by LazyField, // increasing space used by LazyField and backing Cord. - message1.mutable_foo_message(); + message1->mutable_foo_message(); ASSERT_EQ(sizeof(UNITTEST::TestOneof2::NestedMessage), - message1.foo_message().SpaceUsedLong()); + message1->foo_message().SpaceUsedLong()); EXPECT_LE(empty_message_size + sizeof(UNITTEST::TestOneof2::NestedMessage), - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); } #endif // !PROTOBUF_TEST_NO_DESCRIPTORS @@ -1065,14 +1070,13 @@ TEST(GENERATED_ENUM_TEST_NAME, MinAndMax) { EXPECT_EQ(12589235, UNITTEST::TestSparseEnum_ARRAYSIZE); // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE. - void* null_pointer = 0; // NULL may be integer-type, not pointer-type. - EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MIN); - EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MAX); - EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE); + EXPECT_NE(nullptr, &UNITTEST::TestAllTypes::NestedEnum_MIN); + EXPECT_NE(nullptr, &UNITTEST::TestAllTypes::NestedEnum_MAX); + EXPECT_NE(nullptr, &UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE); - EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MIN); - EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MAX); - EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_ARRAYSIZE); + EXPECT_NE(nullptr, &UNITTEST::ForeignEnum_MIN); + EXPECT_NE(nullptr, &UNITTEST::ForeignEnum_MAX); + EXPECT_NE(nullptr, &UNITTEST::ForeignEnum_ARRAYSIZE); // Make sure we can use _MIN and _MAX as switch cases. switch (UNITTEST::SPARSE_A) { @@ -1146,14 +1150,14 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { class MockTestService : public UNITTEST::TestService { public: MockTestService() - : called_(false), - method_(""), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL) {} + : called_(false), + method_(""), + controller_(nullptr), + request_(nullptr), + response_(nullptr), + done_(nullptr) {} - ~MockTestService() {} + ~MockTestService() override {} void Reset() { called_ = false; } @@ -1194,16 +1198,16 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { class MockRpcChannel : public RpcChannel { public: MockRpcChannel() - : called_(false), - method_(NULL), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL), - destroyed_(NULL) {} - - ~MockRpcChannel() { - if (destroyed_ != NULL) *destroyed_ = true; + : called_(false), + method_(nullptr), + controller_(nullptr), + request_(nullptr), + response_(nullptr), + done_(nullptr), + destroyed_(nullptr) {} + + ~MockRpcChannel() override { + if (destroyed_ != nullptr) *destroyed_ = true; } void Reset() { called_ = false; } @@ -1269,8 +1273,8 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {} void SetUp() override { - ASSERT_TRUE(foo_ != NULL); - ASSERT_TRUE(bar_ != NULL); + ASSERT_TRUE(foo_ != nullptr); + ASSERT_TRUE(bar_ != nullptr); } const ServiceDescriptor* descriptor_; @@ -1585,21 +1589,21 @@ TEST_F(OneofTest, SetString) { } TEST_F(OneofTest, ReleaseString) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestOneof2 message; - EXPECT_EQ(NULL, message.release_foo_string()); + EXPECT_EQ(nullptr, message.release_foo_string()); EXPECT_FALSE(message.has_foo_string()); message.set_foo_string("blah"); EXPECT_TRUE(message.has_foo_string()); std::unique_ptr str(message.release_foo_string()); EXPECT_FALSE(message.has_foo_string()); - ASSERT_TRUE(str != NULL); + ASSERT_TRUE(str != nullptr); EXPECT_EQ("blah", *str); - EXPECT_EQ(NULL, message.release_foo_string()); + EXPECT_EQ(nullptr, message.release_foo_string()); EXPECT_FALSE(message.has_foo_string()); } @@ -1612,7 +1616,7 @@ TEST_F(OneofTest, SetAllocatedString) { message.set_foo_string(kHello); EXPECT_TRUE(message.has_foo_string()); - message.set_allocated_foo_string(NULL); + message.set_allocated_foo_string(nullptr); EXPECT_FALSE(message.has_foo_string()); EXPECT_EQ("", message.foo_string()); @@ -1632,7 +1636,7 @@ TEST_F(OneofTest, ArenaSetAllocatedString) { message->set_foo_string(kHello); EXPECT_TRUE(message->has_foo_string()); - message->set_allocated_foo_string(NULL); + message->set_allocated_foo_string(nullptr); EXPECT_FALSE(message->has_foo_string()); EXPECT_EQ("", message->foo_string()); @@ -1659,11 +1663,11 @@ TEST_F(OneofTest, SetMessage) { } TEST_F(OneofTest, ReleaseMessage) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestOneof2 message; - EXPECT_EQ(NULL, message.release_foo_message()); + EXPECT_EQ(nullptr, message.release_foo_message()); EXPECT_FALSE(message.has_foo_message()); message.mutable_foo_message()->set_qux_int(1); @@ -1671,10 +1675,10 @@ TEST_F(OneofTest, ReleaseMessage) { std::unique_ptr mes( message.release_foo_message()); EXPECT_FALSE(message.has_foo_message()); - ASSERT_TRUE(mes != NULL); + ASSERT_TRUE(mes != nullptr); EXPECT_EQ(1, mes->qux_int()); - EXPECT_EQ(NULL, message.release_foo_message()); + EXPECT_EQ(nullptr, message.release_foo_message()); EXPECT_FALSE(message.has_foo_message()); } @@ -1687,14 +1691,14 @@ TEST_F(OneofTest, SetAllocatedMessage) { message.mutable_foo_message()->set_qux_int(1); EXPECT_TRUE(message.has_foo_message()); - message.set_allocated_foo_message(NULL); + message.set_allocated_foo_message(nullptr); EXPECT_FALSE(message.has_foo_message()); EXPECT_EQ(&message.foo_message(), &UNITTEST::TestOneof2_NestedMessage::default_instance()); message.mutable_foo_message()->set_qux_int(1); UNITTEST::TestOneof2_NestedMessage* mes = message.release_foo_message(); - ASSERT_TRUE(mes != NULL); + ASSERT_TRUE(mes != nullptr); EXPECT_FALSE(message.has_foo_message()); message.set_allocated_foo_message(mes); diff --git a/src/google/protobuf/compiler/cpp/metadata_test.cc b/src/google/protobuf/compiler/cpp/metadata_test.cc index b5cac8f42f7f0..c48a971261594 100644 --- a/src/google/protobuf/compiler/cpp/metadata_test.cc +++ b/src/google/protobuf/compiler/cpp/metadata_test.cc @@ -76,12 +76,12 @@ class CppMetadataTest : public ::testing::Test { std::string output_base = TestTempDir() + "/" + StripProto(filename); - if (pb_cc != NULL) { + if (pb_cc != nullptr) { GOOGLE_CHECK_OK( File::GetContents(output_base + ".pb.cc", pb_cc, true)); } - if (pb_h != NULL && pb_h_info != NULL) { + if (pb_h != nullptr && pb_h_info != nullptr) { GOOGLE_CHECK_OK( File::GetContents(output_base + ".pb.h", pb_h, true)); if (!atu::DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) { @@ -89,7 +89,7 @@ class CppMetadataTest : public ::testing::Test { } } - if (proto_h != NULL && proto_h_info != NULL) { + if (proto_h != nullptr && proto_h_info != nullptr) { GOOGLE_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h, true)); if (!atu::DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) { @@ -112,15 +112,15 @@ TEST_F(CppMetadataTest, CapturesEnumNames) { GeneratedCodeInfo info; std::string pb_h; atu::AddFile("test.proto", kSmallTestFile); - EXPECT_TRUE( - CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); + EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr, + nullptr, nullptr)); EXPECT_EQ("Enum", file.enum_type(0).name()); std::vector enum_path; enum_path.push_back(FileDescriptorProto::kEnumTypeFieldNumber); enum_path.push_back(0); const GeneratedCodeInfo::Annotation* enum_annotation = atu::FindAnnotationOnPath(info, "test.proto", enum_path); - EXPECT_TRUE(NULL != enum_annotation); + EXPECT_TRUE(nullptr != enum_annotation); EXPECT_TRUE(atu::AnnotationMatchesSubstring(pb_h, enum_annotation, "Enum")); } @@ -129,8 +129,8 @@ TEST_F(CppMetadataTest, AddsPragma) { GeneratedCodeInfo info; std::string pb_h; atu::AddFile("test.proto", kSmallTestFile); - EXPECT_TRUE( - CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); + EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr, + nullptr, nullptr)); EXPECT_TRUE(pb_h.find("#ifdef guard_name") != std::string::npos); EXPECT_TRUE(pb_h.find("#pragma pragma_name \"test.pb.h.meta\"") != std::string::npos); @@ -141,15 +141,15 @@ TEST_F(CppMetadataTest, CapturesMessageNames) { GeneratedCodeInfo info; std::string pb_h; atu::AddFile("test.proto", kSmallTestFile); - EXPECT_TRUE( - CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); + EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr, + nullptr, nullptr)); EXPECT_EQ("Message", file.message_type(0).name()); std::vector message_path; message_path.push_back(FileDescriptorProto::kMessageTypeFieldNumber); message_path.push_back(0); const GeneratedCodeInfo::Annotation* message_annotation = atu::FindAnnotationOnPath(info, "test.proto", message_path); - EXPECT_TRUE(NULL != message_annotation); + EXPECT_TRUE(nullptr != message_annotation); EXPECT_TRUE( atu::AnnotationMatchesSubstring(pb_h, message_annotation, "Message")); } diff --git a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc index 86bacf8103bd2..84aacca57ea3a 100644 --- a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -110,13 +110,14 @@ class MockGeneratorContext : public GeneratorContext { class GenerateAndTest { public: GenerateAndTest() {} - void Run(const FileDescriptor* proto_file, std::string file1, std::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_)); context_.ExpectFileMatches(file1, file2); } - void SetParameter(string parameter) { + void SetParameter(std::string parameter) { parameter_ = parameter; } diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index 477b49e5f62c6..146ca9e5bde13 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -61,7 +61,7 @@ void FieldGeneratorBase::SetCommonFieldVariables( part_tag_size /= 2; } uint tag = internal::WireFormat::MakeTag(descriptor_); - uint8 tag_array[5]; + uint8_t tag_array[5]; io::CodedOutputStream::WriteTagToArray(tag, tag_array); std::string tag_bytes = StrCat(tag_array[0]); for (int i = 1; i < part_tag_size; i++) { diff --git a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc index 5755fee00b174..e21eff17ba887 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc @@ -30,14 +30,14 @@ #include +#include #include #include +#include #include #include -#include #include -#include namespace google { namespace protobuf { @@ -63,6 +63,17 @@ TEST(CSharpEnumValue, PascalCasedPrefixStripping) { EXPECT_EQ("_2", GetEnumValueName("Foo", "FOO___2")); } +TEST(DescriptorProtoHelpers, IsDescriptorProto) { + EXPECT_TRUE(IsDescriptorProto(DescriptorProto::descriptor()->file())); + EXPECT_FALSE(IsDescriptorProto(google::protobuf::Any::descriptor()->file())); +} + +TEST(DescriptorProtoHelpers, IsDescriptorOptionMessage) { + EXPECT_TRUE(IsDescriptorOptionMessage(FileOptions::descriptor())); + EXPECT_FALSE(IsDescriptorOptionMessage(google::protobuf::Any::descriptor())); + EXPECT_FALSE(IsDescriptorOptionMessage(DescriptorProto::descriptor())); +} + } // namespace } // namespace csharp } // namespace compiler diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h index a6009c8b1e4ec..619e7dba3ab63 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -130,7 +130,8 @@ uint GetGroupEndTag(const Descriptor* descriptor); // descriptors etc, for use in the runtime. This is the only type which is // allowed to use proto2 syntax, and it generates internal classes. inline bool IsDescriptorProto(const FileDescriptor* descriptor) { - return descriptor->name() == "google/protobuf/descriptor.proto"; + return descriptor->name() == "google/protobuf/descriptor.proto" || + descriptor->name() == "net/proto2/proto/descriptor.proto"; } // Determines whether the given message is an options message within descriptor.proto. @@ -138,15 +139,15 @@ inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) { if (!IsDescriptorProto(descriptor->file())) { return false; } - const std::string name = descriptor->full_name(); - return name == "google.protobuf.FileOptions" || - name == "google.protobuf.MessageOptions" || - name == "google.protobuf.FieldOptions" || - name == "google.protobuf.OneofOptions" || - name == "google.protobuf.EnumOptions" || - name == "google.protobuf.EnumValueOptions" || - name == "google.protobuf.ServiceOptions" || - name == "google.protobuf.MethodOptions"; + const std::string name = descriptor->name(); + return name == "FileOptions" || + name == "MessageOptions" || + name == "FieldOptions" || + name == "OneofOptions" || + name == "EnumOptions" || + name == "EnumValueOptions" || + name == "ServiceOptions" || + name == "MethodOptions"; } inline bool IsWrapperType(const FieldDescriptor* descriptor) { diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index 44c13e2f637ad..a13b995da8c99 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -57,9 +57,9 @@ MapFieldGenerator::~MapFieldGenerator() { void MapFieldGenerator::GenerateMembers(io::Printer* printer) { 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(); variables_["key_type_name"] = type_name(key_descriptor); variables_["value_type_name"] = type_name(value_descriptor); std::unique_ptr key_generator( diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index 998087492eb89..9dbce03c0252c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -717,7 +717,7 @@ void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_pars const FieldDescriptor* field = fields_by_number()[i]; internal::WireFormatLite::WireType wt = internal::WireFormat::WireTypeForFieldType(field->type()); - uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt); + uint32_t tag = internal::WireFormatLite::MakeTag(field->number(), wt); // Handle both packed and unpacked repeated fields with the same Read*Array call; // the two generated cases are the packed and unpacked tags. // TODO(jonskeet): Check that is_packable is equivalent to diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index 3bcb0c90c2ab3..137baae85149a 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -93,13 +93,13 @@ class SourceTreeDescriptorDatabase::SingleFileErrorCollector : filename_(filename), multi_file_error_collector_(multi_file_error_collector), had_errors_(false) {} - ~SingleFileErrorCollector() {} + ~SingleFileErrorCollector() override {} bool had_errors() { return had_errors_; } // implements ErrorCollector --------------------------------------- void AddError(int line, int column, const std::string& message) override { - if (multi_file_error_collector_ != NULL) { + if (multi_file_error_collector_ != nullptr) { multi_file_error_collector_->AddError(filename_, line, column, message); } had_errors_ = true; @@ -134,12 +134,12 @@ SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {} bool SourceTreeDescriptorDatabase::FindFileByName(const std::string& filename, FileDescriptorProto* output) { std::unique_ptr input(source_tree_->Open(filename)); - if (input == NULL) { + if (input == nullptr) { if (fallback_database_ != nullptr && fallback_database_->FindFileByName(filename, output)) { return true; } - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { error_collector_->AddError(filename, -1, 0, source_tree_->GetLastErrorMessage()); } @@ -151,7 +151,7 @@ bool SourceTreeDescriptorDatabase::FindFileByName(const std::string& filename, io::Tokenizer tokenizer(input.get(), &file_error_collector); Parser parser; - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { parser.RecordErrorsTo(&file_error_collector); } if (using_validation_error_collector_) { @@ -187,7 +187,7 @@ void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError( const std::string& filename, const std::string& element_name, const Message* descriptor, ErrorLocation location, const std::string& message) { - if (owner_->error_collector_ == NULL) return; + if (owner_->error_collector_ == nullptr) return; int line, column; if (location == DescriptorPool::ErrorCollector::IMPORT) { @@ -203,7 +203,7 @@ void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddWarning( const std::string& filename, const std::string& element_name, const Message* descriptor, ErrorLocation location, const std::string& message) { - if (owner_->error_collector_ == NULL) return; + if (owner_->error_collector_ == nullptr) return; int line, column; if (location == DescriptorPool::ErrorCollector::IMPORT) { @@ -429,7 +429,7 @@ DiskSourceTree::DiskFileToVirtualFile(const std::string& disk_file, // of verifying that we are not canonicalizing away any non-existent // directories. std::unique_ptr stream(OpenDiskFile(disk_file)); - if (stream == NULL) { + if (stream == nullptr) { return CANNOT_OPEN; } @@ -440,11 +440,11 @@ bool DiskSourceTree::VirtualFileToDiskFile(const std::string& virtual_file, std::string* disk_file) { std::unique_ptr stream( OpenVirtualFile(virtual_file, disk_file)); - return stream != NULL; + return stream != nullptr; } io::ZeroCopyInputStream* DiskSourceTree::Open(const std::string& filename) { - return OpenVirtualFile(filename, NULL); + return OpenVirtualFile(filename, nullptr); } std::string DiskSourceTree::GetLastErrorMessage() { @@ -461,7 +461,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( last_error_message_ = "Backslashes, consecutive slashes, \".\", or \"..\" " "are not allowed in the virtual path"; - return NULL; + return nullptr; } for (const auto& mapping : mappings_) { @@ -469,8 +469,8 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( if (ApplyMapping(virtual_file, mapping.virtual_path, mapping.disk_path, &temp_disk_file)) { io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file); - if (stream != NULL) { - if (disk_file != NULL) { + if (stream != nullptr) { + if (disk_file != nullptr) { *disk_file = temp_disk_file; } return stream; @@ -480,12 +480,12 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( // The file exists but is not readable. last_error_message_ = "Read access is denied for file: " + temp_disk_file; - return NULL; + return nullptr; } } } last_error_message_ = "File not found."; - return NULL; + return nullptr; } io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( @@ -503,7 +503,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( #else if (ret == 0 && S_ISDIR(sb.st_mode)) { last_error_message_ = "Input file is a directory."; - return NULL; + return nullptr; } #endif int file_descriptor; @@ -515,7 +515,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( result->SetCloseOnDelete(true); return result; } else { - return NULL; + return nullptr; } } diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h index 08a49c55277f2..2ed3b3a635348 100644 --- a/src/google/protobuf/compiler/importer.h +++ b/src/google/protobuf/compiler/importer.h @@ -45,6 +45,7 @@ #include #include +// Must be included last. #include namespace google { @@ -85,7 +86,7 @@ class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { // the specified source_tree. SourceTreeDescriptorDatabase(SourceTree* source_tree, DescriptorDatabase* fallback_database); - ~SourceTreeDescriptorDatabase(); + ~SourceTreeDescriptorDatabase() override; // Instructs the SourceTreeDescriptorDatabase to report any parse errors // to the given MultiFileErrorCollector. This should be called before @@ -124,7 +125,7 @@ class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { : public DescriptorPool::ErrorCollector { public: ValidationErrorCollector(SourceTreeDescriptorDatabase* owner); - ~ValidationErrorCollector(); + ~ValidationErrorCollector() override; // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, const std::string& element_name, @@ -241,7 +242,7 @@ class PROTOBUF_EXPORT SourceTree { class PROTOBUF_EXPORT DiskSourceTree : public SourceTree { public: DiskSourceTree(); - ~DiskSourceTree(); + ~DiskSourceTree() override; // Map a path on disk to a location in the SourceTree. The path may be // either a file or a directory. If it is a directory, the entire tree diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc index daa197f460659..d2810ade12852 100644 --- a/src/google/protobuf/compiler/importer_unittest.cc +++ b/src/google/protobuf/compiler/importer_unittest.cc @@ -66,20 +66,20 @@ bool FileExists(const std::string& path) { class MockErrorCollector : public MultiFileErrorCollector { public: MockErrorCollector() {} - ~MockErrorCollector() {} + ~MockErrorCollector() override {} std::string text_; std::string warning_text_; // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, int line, int column, - const std::string& message) { + const std::string& message) override { 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) { + const std::string& message) override { strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n", filename, line, column, message); } @@ -91,23 +91,23 @@ class MockErrorCollector : public MultiFileErrorCollector { class MockSourceTree : public SourceTree { public: MockSourceTree() {} - ~MockSourceTree() {} + ~MockSourceTree() override {} void AddFile(const std::string& name, const char* contents) { files_[name] = contents; } // implements SourceTree ------------------------------------------- - io::ZeroCopyInputStream* Open(const std::string& filename) { + io::ZeroCopyInputStream* Open(const std::string& filename) override { const char* contents = FindPtrOrNull(files_, filename); - if (contents == NULL) { - return NULL; + if (contents == nullptr) { + return nullptr; } else { return new io::ArrayInputStream(contents, strlen(contents)); } } - std::string GetLastErrorMessage() { return "File not found."; } + std::string GetLastErrorMessage() override { return "File not found."; } private: std::unordered_map files_; @@ -139,7 +139,7 @@ TEST_F(ImporterTest, Import) { const FileDescriptor* file = importer_.Import("foo.proto"); EXPECT_EQ("", error_collector_.text_); - ASSERT_TRUE(file != NULL); + ASSERT_TRUE(file != nullptr); ASSERT_EQ(1, file->message_type_count()); EXPECT_EQ("Foo", file->message_type(0)->name()); @@ -168,8 +168,8 @@ TEST_F(ImporterTest, ImportNested) { const FileDescriptor* foo = importer_.Import("foo.proto"); const FileDescriptor* bar = importer_.Import("bar.proto"); EXPECT_EQ("", error_collector_.text_); - ASSERT_TRUE(foo != NULL); - ASSERT_TRUE(bar != NULL); + ASSERT_TRUE(foo != nullptr); + ASSERT_TRUE(bar != nullptr); // Check that foo's dependency is the same object as bar. ASSERT_EQ(1, foo->dependency_count()); @@ -187,7 +187,7 @@ TEST_F(ImporterTest, ImportNested) { TEST_F(ImporterTest, FileNotFound) { // Error: Parsing a file that doesn't exist. - EXPECT_TRUE(importer_.Import("foo.proto") == NULL); + EXPECT_TRUE(importer_.Import("foo.proto") == nullptr); EXPECT_EQ("foo.proto:-1:0: File not found.\n", error_collector_.text_); } @@ -197,7 +197,7 @@ TEST_F(ImporterTest, ImportNotFound) { "syntax = \"proto2\";\n" "import \"bar.proto\";\n"); - EXPECT_TRUE(importer_.Import("foo.proto") == NULL); + EXPECT_TRUE(importer_.Import("foo.proto") == nullptr); EXPECT_EQ( "bar.proto:-1:0: File not found.\n" "foo.proto:1:0: Import \"bar.proto\" was not found or had errors.\n", @@ -214,7 +214,7 @@ TEST_F(ImporterTest, RecursiveImport) { "syntax = \"proto2\";\n" "import \"recursive1.proto\";\n"); - EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL); + EXPECT_TRUE(importer_.Import("recursive1.proto") == nullptr); EXPECT_EQ( "recursive1.proto:2:0: File recursively imports itself: " "recursive1.proto " @@ -262,7 +262,7 @@ TEST_F(ImporterTest, LiteRuntimeImport) { class DiskSourceTreeTest : public testing::Test { protected: - virtual void SetUp() { + void SetUp() override { dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1"); dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2"); @@ -274,7 +274,7 @@ class DiskSourceTreeTest : public testing::Test { } } - virtual void TearDown() { + void TearDown() override { for (int i = 0; i < dirnames_.size(); i++) { if (FileExists(dirnames_[i])) { File::DeleteRecursively(dirnames_[i], NULL, NULL); @@ -294,7 +294,7 @@ class DiskSourceTreeTest : public testing::Test { const char* expected_contents) { std::unique_ptr input(source_tree_.Open(filename)); - ASSERT_FALSE(input == NULL); + ASSERT_FALSE(input == nullptr); // Read all the data from the file. std::string file_contents; @@ -310,7 +310,7 @@ class DiskSourceTreeTest : public testing::Test { void ExpectCannotOpenFile(const std::string& filename, const std::string& error_message) { std::unique_ptr input(source_tree_.Open(filename)); - EXPECT_TRUE(input == NULL); + EXPECT_TRUE(input == nullptr); EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage()); } @@ -537,8 +537,8 @@ TEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) { EXPECT_EQ("not touched", not_touched); // Accept NULL as output parameter. - EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", NULL)); - EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", NULL)); + EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", nullptr)); + EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", nullptr)); } } // namespace diff --git a/src/google/protobuf/compiler/java/java_context.cc b/src/google/protobuf/compiler/java/java_context.cc index fea870f1ca448..19cb6318407f8 100644 --- a/src/google/protobuf/compiler/java/java_context.cc +++ b/src/google/protobuf/compiler/java/java_context.cc @@ -30,11 +30,11 @@ #include +#include +#include #include #include #include -#include -#include #include namespace google { diff --git a/src/google/protobuf/compiler/java/java_doc_comment.cc b/src/google/protobuf/compiler/java/java_doc_comment.cc index 80b79025dfd7d..d0e01845e6293 100644 --- a/src/google/protobuf/compiler/java/java_doc_comment.cc +++ b/src/google/protobuf/compiler/java/java_doc_comment.cc @@ -36,9 +36,9 @@ #include -#include #include #include +#include namespace google { namespace protobuf { @@ -199,7 +199,16 @@ void WriteDeprecatedJavadoc(io::Printer* printer, const FieldDescriptor* field, return; } - printer->Print(" * @deprecated\n"); + std::string startLine = "0"; + SourceLocation location; + if (field->GetSourceLocation(&location)) { + startLine = std::to_string(location.start_line); + } + + printer->Print(" * @deprecated $name$ is deprecated.\n", "name", + field->full_name()); + printer->Print(" * See $file$;l=$line$\n", "file", field->file()->name(), + "line", startLine); } void WriteFieldAccessorDocComment(io::Printer* printer, diff --git a/src/google/protobuf/compiler/java/java_doc_comment.h b/src/google/protobuf/compiler/java/java_doc_comment.h index b7de8776708d4..7f687781fb0c5 100644 --- a/src/google/protobuf/compiler/java/java_doc_comment.h +++ b/src/google/protobuf/compiler/java/java_doc_comment.h @@ -37,6 +37,7 @@ #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index 51032c2742b39..0d9a71b99d43a 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -32,17 +32,18 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include +#include +#include #include #include -#include #include #include #include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 0dad42ada3549..0e6fb44d000a0 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -40,13 +40,13 @@ #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h index 82dbd9e4a6841..abdc18847888e 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.h +++ b/src/google/protobuf/compiler/java/java_enum_field.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { @@ -99,7 +100,7 @@ class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator { ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableEnumOneofFieldGenerator(); + ~ImmutableEnumOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; 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 ca3a2e8803074..27b62ac52308c 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -40,13 +40,13 @@ #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index aa64c97127a55..5d7955c2fe260 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -32,17 +32,18 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include +#include +#include #include #include -#include #include #include #include -#include -#include #include namespace google { diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc index db210fb3e503b..6ebca41d47eb9 100644 --- a/src/google/protobuf/compiler/java/java_extension.cc +++ b/src/google/protobuf/compiler/java/java_extension.cc @@ -34,12 +34,12 @@ #include +#include +#include #include #include #include #include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h index f928a783725d4..318cfa4cc9216 100644 --- a/src/google/protobuf/compiler/java/java_extension.h +++ b/src/google/protobuf/compiler/java/java_extension.h @@ -92,7 +92,7 @@ class ImmutableExtensionGenerator : public ExtensionGenerator { public: explicit ImmutableExtensionGenerator(const FieldDescriptor* descriptor, Context* context); - virtual ~ImmutableExtensionGenerator(); + ~ImmutableExtensionGenerator() override; void Generate(io::Printer* printer) override; int GenerateNonNestedInitializationCode(io::Printer* printer) override; diff --git a/src/google/protobuf/compiler/java/java_extension_lite.cc b/src/google/protobuf/compiler/java/java_extension_lite.cc index 71bf4e23f3cb3..d84ee2754b909 100644 --- a/src/google/protobuf/compiler/java/java_extension_lite.cc +++ b/src/google/protobuf/compiler/java/java_extension_lite.cc @@ -30,12 +30,12 @@ #include +#include +#include #include #include #include #include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_extension_lite.h b/src/google/protobuf/compiler/java/java_extension_lite.h index 76961563a9201..54dc43758e033 100644 --- a/src/google/protobuf/compiler/java/java_extension_lite.h +++ b/src/google/protobuf/compiler/java/java_extension_lite.h @@ -49,7 +49,7 @@ class ImmutableExtensionLiteGenerator : public ExtensionGenerator { public: explicit ImmutableExtensionLiteGenerator(const FieldDescriptor* descriptor, Context* context); - virtual ~ImmutableExtensionLiteGenerator(); + ~ImmutableExtensionLiteGenerator() override; void Generate(io::Printer* printer) override; diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc index 8916d1385ae3d..cd08d60ad8560 100644 --- a/src/google/protobuf/compiler/java/java_field.cc +++ b/src/google/protobuf/compiler/java/java_field.cc @@ -38,6 +38,9 @@ #include #include +#include +#include +#include #include #include #include @@ -50,9 +53,6 @@ #include #include #include -#include -#include -#include namespace google { diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 9dbf81814bb58..7dbf64d81716d 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -37,6 +37,11 @@ #include #include +#include +#include +#include +#include +#include #include #include #include @@ -47,12 +52,7 @@ #include #include #include -#include #include -#include -#include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h index 71ee3e85579c1..79ee6308c5595 100644 --- a/src/google/protobuf/compiler/java/java_file.h +++ b/src/google/protobuf/compiler/java/java_file.h @@ -38,6 +38,7 @@ #include #include #include + #include #include diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc index 29ae2cf9f4c23..2ee08744edc16 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -37,6 +37,8 @@ #include +#include +#include #include #include #include @@ -44,8 +46,6 @@ #include #include #include -#include -#include #include diff --git a/src/google/protobuf/compiler/java/java_generator.h b/src/google/protobuf/compiler/java/java_generator.h index 6315e7c3fedc2..bbc71700c66fd 100644 --- a/src/google/protobuf/compiler/java/java_generator.h +++ b/src/google/protobuf/compiler/java/java_generator.h @@ -40,6 +40,7 @@ #include #include +// Must be included last. #include namespace google { @@ -54,7 +55,7 @@ namespace java { class PROTOC_EXPORT JavaGenerator : public CodeGenerator { public: JavaGenerator(); - ~JavaGenerator(); + ~JavaGenerator() override; // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const std::string& parameter, diff --git a/src/google/protobuf/compiler/java/java_generator_factory.h b/src/google/protobuf/compiler/java/java_generator_factory.h index 831d9dd857112..807bca383a392 100644 --- a/src/google/protobuf/compiler/java/java_generator_factory.h +++ b/src/google/protobuf/compiler/java/java_generator_factory.h @@ -78,7 +78,7 @@ class GeneratorFactory { class ImmutableGeneratorFactory : public GeneratorFactory { public: ImmutableGeneratorFactory(Context* context); - virtual ~ImmutableGeneratorFactory(); + ~ImmutableGeneratorFactory() override; MessageGenerator* NewMessageGenerator( const Descriptor* descriptor) const override; diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index f37ecde7844fc..c66da524e1831 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -41,12 +41,12 @@ #include #include -#include -#include -#include #include #include #include +#include +#include +#include #include // for hash namespace google { @@ -1049,8 +1049,7 @@ int GetExperimentalJavaFieldType(const FieldDescriptor* field) { if (field->is_map()) { if (!SupportUnknownEnumValue(field)) { - const FieldDescriptor* value = - field->message_type()->FindFieldByName("value"); + const FieldDescriptor* value = field->message_type()->map_value(); if (GetJavaType(value) == JAVATYPE_ENUM) { extra_bits |= kMapWithProto2EnumValue; } diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index 28cac6af9ae78..dd947bcd88f84 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -38,10 +38,10 @@ #include #include -#include -#include #include #include +#include +#include namespace google { namespace protobuf { @@ -151,6 +151,21 @@ inline bool IsDescriptorProto(const Descriptor* descriptor) { // fields. std::string GetOneofStoredType(const FieldDescriptor* field); +// We use either the proto1 enums if the enum is generated, otherwise fall back +// to use integers. +enum class Proto1EnumRepresentation { + kEnum, + kInteger, +}; + +// Returns which representation we should use. +inline Proto1EnumRepresentation GetProto1EnumRepresentation( + const EnumDescriptor* descriptor) { + if (descriptor->containing_type() != nullptr) { + return Proto1EnumRepresentation::kEnum; + } + return Proto1EnumRepresentation::kInteger; +} // Whether we should generate multiple java files for messages. inline bool MultipleJavaFiles(const FileDescriptor* descriptor, diff --git a/src/google/protobuf/compiler/java/java_kotlin_generator.cc b/src/google/protobuf/compiler/java/java_kotlin_generator.cc index 8d262a018aff1..aa54bb2cfa058 100644 --- a/src/google/protobuf/compiler/java/java_kotlin_generator.cc +++ b/src/google/protobuf/compiler/java/java_kotlin_generator.cc @@ -30,11 +30,11 @@ #include +#include #include +#include #include #include -#include -#include namespace google { namespace protobuf { @@ -63,11 +63,13 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, if (option.first == "output_list_file") { file_options.output_list_file = option.second; } else if (option.first == "immutable") { + // Note: the option is considered always set regardless of the input. file_options.generate_immutable_code = true; } else if (option.first == "mutable") { *error = "Mutable not supported by Kotlin generator"; return false; } else if (option.first == "shared") { + // Note: the option is considered always set regardless of the input. file_options.generate_shared_code = true; } else if (option.first == "lite") { file_options.enforce_lite = true; @@ -81,23 +83,17 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, } } - // By default we generate immutable code and shared code for immutable API. - if (!file_options.generate_immutable_code && - !file_options.generate_shared_code) { - file_options.generate_immutable_code = true; - file_options.generate_shared_code = true; - } + // We only support generation of immutable code so we do it. + file_options.generate_immutable_code = true; + file_options.generate_shared_code = true; std::vector all_files; std::vector all_annotations; - std::unique_ptr file_generator; - if (file_options.generate_immutable_code) { - file_generator.reset( + std::unique_ptr file_generator( new FileGenerator(file, file_options, /* immutable_api = */ true)); - } - if (!file_generator->Validate(error)) { + if (!file_generator || !file_generator->Validate(error)) { return false; } diff --git a/src/google/protobuf/compiler/java/java_kotlin_generator.h b/src/google/protobuf/compiler/java/java_kotlin_generator.h index 66e32b9e0010d..ccd9688ca06eb 100644 --- a/src/google/protobuf/compiler/java/java_kotlin_generator.h +++ b/src/google/protobuf/compiler/java/java_kotlin_generator.h @@ -36,6 +36,8 @@ #include #include + +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc index 8a89100714113..606d26e93db3f 100644 --- a/src/google/protobuf/compiler/java/java_map_field.cc +++ b/src/google/protobuf/compiler/java/java_map_field.cc @@ -30,11 +30,11 @@ #include +#include #include #include #include #include -#include namespace google { namespace protobuf { @@ -47,14 +47,14 @@ const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("key"); + return message->map_key(); } const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("value"); + return message->map_value(); } std::string TypeName(const FieldDescriptor* field, @@ -99,6 +99,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, const JavaType keyJavaType = GetJavaType(key); const JavaType valueJavaType = GetJavaType(value); + std::string pass_through_nullness = "/* nullable */\n"; + (*variables)["key_type"] = TypeName(key, name_resolver, false); std::string boxed_key_type = TypeName(key, name_resolver, true); (*variables)["boxed_key_type"] = boxed_key_type; @@ -129,6 +131,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + (*variables)["value_enum_type_pass_through_nullness"] = + pass_through_nullness + (*variables)["value_enum_type"]; + if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. (*variables)["unrecognized_value"] = @@ -140,6 +145,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); + + (*variables)["value_type_pass_through_nullness"] = + (IsReferenceType(valueJavaType) ? pass_through_nullness : "") + + (*variables)["value_type"]; + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -218,11 +228,12 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" - " $key_type$ key,\n" - " $value_enum_type$ defaultValue);\n"); + printer->Print(variables_, + "$deprecation$$value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type_pass_through_nullness$ " + " defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -276,9 +287,10 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$value_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue);\n"); + " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -538,9 +550,10 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( variables_, "@java.lang.Override\n" "$deprecation$\n" - "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "public $value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_enum_type$ defaultValue) {\n" + " $value_enum_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" " internalGet$capitalized_name$().getMap();\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 e71116866e2ae..f6245224068ae 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -32,11 +32,11 @@ #include +#include #include #include #include #include -#include namespace google { namespace protobuf { @@ -49,14 +49,14 @@ const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("key"); + return message->map_key(); } const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("value"); + return message->map_value(); } std::string TypeName(const FieldDescriptor* field, @@ -101,6 +101,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, const JavaType keyJavaType = GetJavaType(key); const JavaType valueJavaType = GetJavaType(value); + std::string pass_through_nullness = "/* nullable */\n"; + (*variables)["key_type"] = TypeName(key, name_resolver, false); (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true); (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver); @@ -128,6 +130,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + (*variables)["value_enum_type_pass_through_nullness"] = + pass_through_nullness + (*variables)["value_enum_type"]; + if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. (*variables)["unrecognized_value"] = @@ -139,6 +144,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); + + (*variables)["value_type_pass_through_nullness"] = + (IsReferenceType(valueJavaType) ? pass_through_nullness : "") + + (*variables)["value_type"]; + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -203,11 +213,12 @@ void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" - " $key_type$ key,\n" - " $value_enum_type$ defaultValue);\n"); + printer->Print(variables_, + "$deprecation$$value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type_pass_through_nullness$ " + " defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -261,9 +272,10 @@ void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$value_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue);\n"); + " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -606,9 +618,10 @@ void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers( variables_, "@java.lang.Override\n" "$deprecation$\n" - "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "public $value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_enum_type$ defaultValue) {\n" + " $value_enum_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" " instance.get$capitalized_name$Map();\n" diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 27d1014f69e3a..b2a236f2cb296 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -40,6 +40,11 @@ #include #include +#include +#include +#include +#include +#include #include #include #include @@ -50,11 +55,6 @@ #include #include #include -#include -#include -#include -#include -#include namespace google { namespace protobuf { @@ -67,7 +67,7 @@ using internal::WireFormatLite; namespace { std::string MapValueImmutableClassdName(const Descriptor* descriptor, ClassNameResolver* name_resolver) { - const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + const FieldDescriptor* value_field = descriptor->map_value(); GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } @@ -1273,6 +1273,9 @@ void ImmutableMessageGenerator::GenerateParsingConstructor( printer->Print( "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" " throw e.setUnfinishedMessage(this);\n" + "} catch (com.google.protobuf.UninitializedMessageException e) {\n" + " throw " + "e.asInvalidProtocolBufferException().setUnfinishedMessage(this);\n" "} catch (java.io.IOException e) {\n" " throw new com.google.protobuf.InvalidProtocolBufferException(\n" " e).setUnfinishedMessage(this);\n" @@ -1455,7 +1458,7 @@ void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const { void ImmutableMessageGenerator::GenerateKotlinMembers( io::Printer* printer) const { printer->Print( - "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n" "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " "kotlin.Unit): " "$message$ " @@ -1486,7 +1489,7 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( "kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " - "}._build()\n", + "}._build()\n\n", "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_)); @@ -1495,6 +1498,25 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( ImmutableMessageGenerator(descriptor_->nested_type(i), context_) .GenerateTopLevelKotlinMembers(printer); } + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->has_optional_keyword() && + GetJavaType(field) == JAVATYPE_MESSAGE) { + printer->Print( + "val $full_classname$OrBuilder.$camelcase_name$OrNull: $full_name$?\n" + " get() = if (has$name$()) get$name$() else null\n\n", + "full_classname", name_resolver_->GetClassName(descriptor_, true), + "camelcase_name", context_->GetFieldGeneratorInfo(field)->name, + "full_name", + name_resolver_->GetImmutableClassName(field->message_type()), "name", + context_->GetFieldGeneratorInfo(field)->capitalized_name); + } + } } void ImmutableMessageGenerator::GenerateKotlinExtensions( @@ -1504,7 +1526,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@Suppress(\"UNCHECKED_CAST\")\n" "@kotlin.jvm.JvmSynthetic\n" - "public operator fun get(extension: " + "public operator fun get(extension: " "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" " return if (extension.isRepeated) {\n" " get(extension as com.google.protobuf.ExtensionLite<$message$, " @@ -1520,7 +1542,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( "@kotlin.OptIn" "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" - "public operator fun get(\n" + "public operator fun get(\n" " extension: com.google.protobuf.ExtensionLite<$message$, List>\n" "): com.google.protobuf.kotlin.ExtensionList {\n" " return com.google.protobuf.kotlin.ExtensionList(extension, " @@ -1549,7 +1571,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@kotlin.PublishedApi\n" - "internal fun setExtension(extension: " + "internal fun setExtension(extension: " "com.google.protobuf.ExtensionLite<$message$, T>, " "value: T) {\n" " _builder.setExtension(extension, value)\n" @@ -1592,7 +1614,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.add(value: E) {\n" " _builder.addExtension(this.extension, value)\n" "}\n\n", @@ -1601,7 +1623,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign" "(value: E) {\n" @@ -1611,7 +1633,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.addAll(values: Iterable) {\n" " for (value in values) {\n" " add(value)\n" @@ -1622,7 +1644,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign(values: " "Iterable) {\n" @@ -1632,7 +1654,8 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public operator fun com.google.protobuf.kotlin.ExtensionList " + "com.google.protobuf.kotlin.ExtensionList.set(index: Int, value: " "E) {\n" " _builder.setExtension(this.extension, index, value)\n" diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h index cafc91e68ba8a..cc24d73d351f6 100644 --- a/src/google/protobuf/compiler/java/java_message.h +++ b/src/google/protobuf/compiler/java/java_message.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { @@ -100,7 +101,7 @@ class MessageGenerator { class ImmutableMessageGenerator : public MessageGenerator { public: ImmutableMessageGenerator(const Descriptor* descriptor, Context* context); - virtual ~ImmutableMessageGenerator(); + ~ImmutableMessageGenerator() override; void Generate(io::Printer* printer) override; void GenerateInterface(io::Printer* printer) override; @@ -136,6 +137,7 @@ class ImmutableMessageGenerator : public MessageGenerator { void GenerateParsingConstructor(io::Printer* printer); void GenerateMutableCopy(io::Printer* printer); void GenerateKotlinExtensions(io::Printer* printer) const; + void GenerateKotlinOrNull(io::Printer* printer) const; void GenerateAnyMethods(io::Printer* printer); Context* context_; diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc index 320852b1be975..4d46669a1f247 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/src/google/protobuf/compiler/java/java_message_builder.cc @@ -39,6 +39,11 @@ #include #include +#include +#include +#include +#include +#include #include #include #include @@ -47,11 +52,6 @@ #include #include #include -#include -#include -#include -#include -#include namespace google { namespace protobuf { @@ -61,7 +61,7 @@ namespace java { namespace { std::string MapValueImmutableClassdName(const Descriptor* descriptor, ClassNameResolver* name_resolver) { - const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + const FieldDescriptor* value_field = descriptor->map_value(); GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } diff --git a/src/google/protobuf/compiler/java/java_message_builder.h b/src/google/protobuf/compiler/java/java_message_builder.h index fcd73b3436269..619bf9eca1396 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.h +++ b/src/google/protobuf/compiler/java/java_message_builder.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { 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 7b69a9ab3894e..b8136e3de9bb4 100644 --- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc @@ -39,6 +39,11 @@ #include #include +#include +#include +#include +#include +#include #include #include #include @@ -47,11 +52,6 @@ #include #include #include -#include -#include -#include -#include -#include namespace google { namespace protobuf { 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 3402adf3322bb..03ecbf870b138 100644 --- a/src/google/protobuf/compiler/java/java_message_builder_lite.h +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index 8aae96145fc8f..1705c32d4004e 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -32,17 +32,18 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include +#include +#include +#include #include #include #include -#include #include -#include -#include -#include namespace google { namespace protobuf { @@ -438,6 +439,16 @@ void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" "}\n"); + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageFieldGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + if (descriptor_->has_optional_keyword()) { + printer->Print(variables_, + "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" + " get() = $kt_dsl_builder$.$name$OrNull\n"); + } } void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode( @@ -698,8 +709,9 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "if ($has_oneof_case_message$) {\n" " $name$Builder_.mergeFrom(value);\n" - "}\n" - "$name$Builder_.setMessage(value);\n", + "} else {\n" + " $name$Builder_.setMessage(value);\n" + "}\n", "$set_oneof_case_message$;\n" "return this;\n"); diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h index 8588100b6b969..be1fb205b186b 100644 --- a/src/google/protobuf/compiler/java/java_message_field.h +++ b/src/google/protobuf/compiler/java/java_message_field.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { @@ -61,7 +62,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableMessageFieldGenerator(); + ~ImmutableMessageFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- @@ -102,6 +103,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator); + void GenerateKotlinOrNull(io::Printer* printer) const; }; class ImmutableMessageOneofFieldGenerator @@ -110,7 +112,7 @@ class ImmutableMessageOneofFieldGenerator ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableMessageOneofFieldGenerator(); + ~ImmutableMessageOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; 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 1c4d016d3ca4e..658d105c725f3 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -38,13 +38,13 @@ #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include namespace google { namespace protobuf { @@ -308,6 +308,15 @@ void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" "}\n"); + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + if (descriptor_->has_optional_keyword()) { + printer->Print(variables_, + "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" + " get() = $kt_dsl_builder$.$name$OrNull\n"); + } } void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo( diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.h b/src/google/protobuf/compiler/java/java_message_field_lite.h index 8f81f60dfe185..313a409f7b1ae 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.h +++ b/src/google/protobuf/compiler/java/java_message_field_lite.h @@ -62,7 +62,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { explicit ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutableMessageFieldLiteGenerator(); + ~ImmutableMessageFieldLiteGenerator() override; // implements ImmutableFieldLiteGenerator // ------------------------------------ @@ -85,6 +85,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldLiteGenerator); + void GenerateKotlinOrNull(io::Printer* printer) const; }; class ImmutableMessageOneofFieldLiteGenerator @@ -93,7 +94,7 @@ class ImmutableMessageOneofFieldLiteGenerator ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutableMessageOneofFieldLiteGenerator(); + ~ImmutableMessageOneofFieldLiteGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index c2c278890204f..dd32c261eca8e 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -40,6 +40,11 @@ #include #include +#include +#include +#include +#include +#include #include #include #include @@ -50,11 +55,6 @@ #include #include #include -#include -#include -#include -#include -#include namespace google { namespace protobuf { @@ -779,7 +779,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinDsl( void ImmutableMessageLiteGenerator::GenerateKotlinMembers( io::Printer* printer) const { printer->Print( - "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n" "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " "kotlin.Unit): " "$message$ =\n" @@ -808,7 +808,7 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( "kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " - "}._build()\n", + "}._build()\n\n", "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_)); @@ -817,6 +817,27 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) .GenerateTopLevelKotlinMembers(printer); } + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + // Generate getFieldOrNull getters for all optional message fields. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->has_optional_keyword() && + GetJavaType(field) == JAVATYPE_MESSAGE) { + printer->Print( + "val $full_classname$OrBuilder.$camelcase_name$OrNull: " + "$full_name$?\n" + " get() = if (has$name$()) get$name$() else null\n\n", + "full_classname", name_resolver_->GetClassName(descriptor_, true), + "camelcase_name", context_->GetFieldGeneratorInfo(field)->name, + "full_name", + name_resolver_->GetImmutableClassName(field->message_type()), "name", + context_->GetFieldGeneratorInfo(field)->capitalized_name); + } + } } void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( @@ -826,7 +847,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@Suppress(\"UNCHECKED_CAST\")\n" "@kotlin.jvm.JvmSynthetic\n" - "public operator fun get(extension: " + "public operator fun get(extension: " "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" " return if (extension.isRepeated) {\n" " get(extension as com.google.protobuf.ExtensionLite<$message$, " @@ -842,7 +863,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( "@kotlin.OptIn" "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" - "public operator fun get(\n" + "public operator fun get(\n" " extension: com.google.protobuf.ExtensionLite<$message$, List>\n" "): com.google.protobuf.kotlin.ExtensionList {\n" " return com.google.protobuf.kotlin.ExtensionList(extension, " @@ -871,7 +892,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@kotlin.PublishedApi\n" - "internal fun setExtension(extension: " + "internal fun setExtension(extension: " "com.google.protobuf.ExtensionLite<$message$, T>, " "value: T) {\n" " _builder.setExtension(extension, value)\n" @@ -914,7 +935,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.add(value: E) {\n" " _builder.addExtension(this.extension, value)\n" "}\n\n", @@ -923,7 +944,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign" "(value: E) {\n" @@ -933,7 +954,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.addAll(values: Iterable) {\n" " for (value in values) {\n" " add(value)\n" @@ -944,7 +965,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign(values: " "Iterable) {\n" @@ -954,7 +975,8 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public operator fun com.google.protobuf.kotlin.ExtensionList " + "com.google.protobuf.kotlin.ExtensionList.set(index: Int, value: " "E) {\n" " _builder.setExtension(this.extension, index, value)\n" diff --git a/src/google/protobuf/compiler/java/java_message_lite.h b/src/google/protobuf/compiler/java/java_message_lite.h index adb0df7cc77a1..c0afbc99ec186 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.h +++ b/src/google/protobuf/compiler/java/java_message_lite.h @@ -37,6 +37,7 @@ #include #include + #include #include @@ -48,7 +49,7 @@ namespace java { class ImmutableMessageLiteGenerator : public MessageGenerator { public: ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context); - virtual ~ImmutableMessageLiteGenerator(); + ~ImmutableMessageLiteGenerator() override; void Generate(io::Printer* printer) override; void GenerateInterface(io::Printer* printer) override; @@ -70,6 +71,7 @@ class ImmutableMessageLiteGenerator : public MessageGenerator { void GenerateConstructor(io::Printer* printer); void GenerateDynamicMethodNewBuildMessageInfo(io::Printer* printer); void GenerateKotlinExtensions(io::Printer* printer) const; + void GenerateKotlinOrNull(io::Printer* printer) const; Context* context_; ClassNameResolver* name_resolver_; diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc index 39bf3e2784173..08c009b155292 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -33,10 +33,10 @@ #include #include -#include -#include #include #include +#include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h index a688d49a4210c..eddf23b045afe 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.h +++ b/src/google/protobuf/compiler/java/java_name_resolver.h @@ -123,7 +123,6 @@ class ClassNameResolver { std::string GetDowngradedFileClassName(const FileDescriptor* file); std::string GetDowngradedClassName(const Descriptor* descriptor); - private: // Get the full name of a Java class by prepending the Java package name // or outer class name. std::string GetClassFullName(const std::string& name_without_package, @@ -132,6 +131,8 @@ class ClassNameResolver { std::string GetClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file, bool kotlin); + + private: // Get the Java Class style full name of a message. std::string GetJavaClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable); diff --git a/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/google/protobuf/compiler/java/java_plugin_unittest.cc index 3bdd53bff67e4..56b5fc7bb3a1d 100644 --- a/src/google/protobuf/compiler/java/java_plugin_unittest.cc +++ b/src/google/protobuf/compiler/java/java_plugin_unittest.cc @@ -54,11 +54,10 @@ namespace { class TestGenerator : public CodeGenerator { public: TestGenerator() {} - ~TestGenerator() {} + ~TestGenerator() override {} - 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 { std::string filename = "Test.java"; TryInsert(filename, "outer_class_scope", context); TryInsert(filename, "class_scope:foo.Bar", context); diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index f67f6d39e1f21..3a338eec55144 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -40,13 +40,13 @@ #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h index 1f0eb8c8692ad..2eb1b2325c1fd 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.h +++ b/src/google/protobuf/compiler/java/java_primitive_field.h @@ -37,6 +37,7 @@ #include #include + #include namespace google { @@ -101,7 +102,7 @@ class ImmutablePrimitiveOneofFieldGenerator ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutablePrimitiveOneofFieldGenerator(); + ~ImmutablePrimitiveOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; 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 5441d01a511a4..2da5f0d5ab145 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -40,13 +40,13 @@ #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include namespace google { namespace protobuf { @@ -160,7 +160,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); } else { - (*variables)["set_has_field_bit_message"] = ""; (*variables)["set_has_field_bit_message"] = ""; (*variables)["clear_has_field_bit_message"] = ""; diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/src/google/protobuf/compiler/java/java_primitive_field_lite.h index dfafae3921805..d27743619e688 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.h +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.h @@ -93,7 +93,7 @@ class ImmutablePrimitiveOneofFieldLiteGenerator ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutablePrimitiveOneofFieldLiteGenerator(); + ~ImmutablePrimitiveOneofFieldLiteGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc index e30d155e47eb6..68b915bce3861 100644 --- a/src/google/protobuf/compiler/java/java_service.cc +++ b/src/google/protobuf/compiler/java/java_service.cc @@ -34,12 +34,12 @@ #include +#include +#include #include #include #include #include -#include -#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h index 81db519481341..9cb9021628598 100644 --- a/src/google/protobuf/compiler/java/java_service.h +++ b/src/google/protobuf/compiler/java/java_service.h @@ -78,7 +78,7 @@ class ImmutableServiceGenerator : public ServiceGenerator { public: ImmutableServiceGenerator(const ServiceDescriptor* descriptor, Context* context); - virtual ~ImmutableServiceGenerator(); + ~ImmutableServiceGenerator() override; void Generate(io::Printer* printer) override; diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/src/google/protobuf/compiler/java/java_shared_code_generator.cc index 45943d76226df..e527234fe78df 100644 --- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc @@ -34,15 +34,15 @@ #include -#include -#include -#include #include -#include #include #include #include #include +#include +#include +#include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 28164c7633790..409d5280f2e10 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -41,13 +41,13 @@ #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include namespace google { namespace protobuf { @@ -968,16 +968,14 @@ void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers( // property for List WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); - printer->Print( - variables_, - "public val $kt_name$: " - "com.google.protobuf.kotlin.DslList" - "\n" - " @kotlin.OptIn" - "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" - " get() = com.google.protobuf.kotlin.DslList(\n" - " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" - " )\n"); + printer->Print(variables_, + "$kt_deprecation$public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); // List.add(String) WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, @@ -997,10 +995,11 @@ void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers( printer->Print(variables_, "@kotlin.jvm.JvmSynthetic\n" "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" - "public operator fun com.google.protobuf.kotlin.DslList" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" "." "plusAssign(value: kotlin.String) {\n" - " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + " add(value)\n" "}\n"); // List.addAll(Iterable) @@ -1023,10 +1022,11 @@ void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers( variables_, "@kotlin.jvm.JvmSynthetic\n" "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" - "public operator fun com.google.protobuf.kotlin.DslList" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" "." "plusAssign(values: kotlin.collections.Iterable) {\n" - " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + " addAll(values)\n" "}\n"); // List[Int] = String diff --git a/src/google/protobuf/compiler/java/java_string_field.h b/src/google/protobuf/compiler/java/java_string_field.h index efab5fee4add5..3112887fe43ef 100644 --- a/src/google/protobuf/compiler/java/java_string_field.h +++ b/src/google/protobuf/compiler/java/java_string_field.h @@ -38,6 +38,7 @@ #include #include + #include namespace google { @@ -61,7 +62,7 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableStringFieldGenerator(); + ~ImmutableStringFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- @@ -101,7 +102,7 @@ class ImmutableStringOneofFieldGenerator ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableStringOneofFieldGenerator(); + ~ImmutableStringOneofFieldGenerator() override; private: void GenerateMembers(io::Printer* printer) const override; 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 57cd43677c484..d010634d8a6a1 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -41,13 +41,13 @@ #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include namespace google { namespace protobuf { @@ -755,7 +755,7 @@ void RepeatedImmutableStringFieldLiteGenerator::GenerateKotlinDslMembers( WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); printer->Print( variables_, - "public val $kt_name$: " + "$kt_deprecation$public val $kt_name$: " "com.google.protobuf.kotlin.DslList" "\n" " @kotlin.OptIn" diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index cfd0e037c9036..2cee9da597bd7 100644 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -3625,7 +3625,19 @@ void Generator::GenerateFile(const GeneratorOptions& options, if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { printer->Print("var proto = {};\n\n"); } else { - printer->Print("var global = Function('return this')();\n\n"); + // To get the global object we call a function with .call(null), this will + // set "this" inside the function to the global object. This does not work + // if we are running in strict mode ("use strict"), so we fallback to the + // following things (in order from first to last): + // - window: defined in browsers + // - global: defined in most server side environments like NodeJS + // - self: defined inside Web Workers (WorkerGlobalScope) + // - Function('return this')(): this will work on most platforms, but it + // may be blocked by things like CSP. + // Function('') is almost the same as eval('') + printer->Print( + "var global = (function() { return this || window || global || self " + "|| Function('return this')(); }).call(null);\n\n"); } for (int i = 0; i < file->dependency_count(); i++) { diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index 7cb7a6375cd49..7bddb314ba533 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -34,11 +34,13 @@ #include #include #include +#include #include #include #include #include +// Must be included last. #include namespace google { @@ -75,6 +77,10 @@ int ProtobufMain(int argc, char* argv[]) { python::Generator py_generator; cli.RegisterGenerator("--python_out", "--python_opt", &py_generator, "Generate Python source file."); + // Pyton pyi + python::PyiGenerator pyi_generator; + cli.RegisterGenerator("--pyi_out", &pyi_generator, + "Generate python pyi stub."); // PHP php::Generator php_generator; diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index 1fce1060969ba..53f6118ac6cd8 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -315,7 +315,7 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, io::AnnotationProtoCollector annotation_collector( &annotations); io::Printer printer(output.get(), '$', - annotate ? &annotation_collector : NULL); + annotate ? &annotation_collector : nullptr); printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context)); std::string annotate_suffix = "_annotation"; if (annotate) { diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index 6e101055de72e..45d735a30fc87 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -78,7 +78,7 @@ namespace compiler { class MockCodeGenerator : public CodeGenerator { public: MockCodeGenerator(const std::string& name); - virtual ~MockCodeGenerator(); + ~MockCodeGenerator() override; // Expect (via gTest) that a MockCodeGenerator with the given name was called // with the given parameters by inspecting the output location. diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index a03b8604fca12..713f93ef1b97d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -110,6 +110,9 @@ bool ObjectiveCGenerator::GenerateAll( // - Comments start with "#". // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. // // There is no validation that the prefixes are good prefixes, it is // assumed that they are when you create the file. diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 5f4b7f60fa252..cf926071fca81 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -73,6 +73,14 @@ using ::open; namespace { +bool BoolFromEnvVar(const char* env_var, bool default_value) { + const char* value = getenv(env_var); + if (value) { + return std::string("YES") == ToUpper(value); + } + return default_value; +} + class SimpleLineCollector : public LineConsumer { public: SimpleLineCollector(std::unordered_set* inout_set) @@ -102,9 +110,14 @@ class PrefixModeStorage { bool is_package_exempted(const std::string& package); + // When using a proto package as the prefix, this should be added as the + // prefix in front of it. + const std::string& forced_package_prefix() const { return forced_prefix_; } + private: bool use_package_name_; std::string exception_path_; + std::string forced_prefix_; std::unordered_set exceptions_; }; @@ -112,14 +125,19 @@ PrefixModeStorage::PrefixModeStorage() { // Even thought there are generation options, have an env back door since some // of these helpers could be used in other plugins. - const char* use_package_cstr = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX"); - use_package_name_ = - (use_package_cstr && (std::string("YES") == ToUpper(use_package_cstr))); + use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false); const char* exception_path = getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH"); if (exception_path) { exception_path_ = exception_path; } + + // This one is a not expected to be common, so it doesn't get a generation + // option, just the env var. + const char* prefix = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX_PREFIX"); + if (prefix) { + forced_prefix_ = prefix; + } } bool PrefixModeStorage::is_package_exempted(const std::string& package) { @@ -168,7 +186,9 @@ void SetProtoPackagePrefixExceptionList(const std::string& file_path) { } Options::Options() { - // Default is the value of the env for the package prefixes. + // While there are generator options, also support env variables to help with + // build systems where it isn't as easy to hook in for add the generation + // options when invoking protoc. const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES"); if (file_path) { expected_prefixes_path = file_path; @@ -178,8 +198,9 @@ Options::Options() { expected_prefixes_suppressions = Split(suppressions, ";", true); } - prefixes_must_be_registered = false; - require_prefixes = false; + prefixes_must_be_registered = + BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false); + require_prefixes = BoolFromEnvVar("GPB_OBJC_REQUIRE_PREFIXES", false); } namespace { @@ -352,9 +373,9 @@ bool IsReservedCIdentifier(const std::string& input) { } std::string SanitizeNameForObjC(const std::string& prefix, - const std::string& input, - const std::string& extension, - std::string* out_suffix_added) { + 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 = @@ -510,8 +531,8 @@ std::string FileClassPrefix(const FileDescriptor* file) { return file->options().objc_class_prefix(); } - // If package prefix isn't enabled or no package, done. - if (!g_prefix_mode.use_package_name() || file->package().empty()) { + // If package prefix isn't enabled, done. + if (!g_prefix_mode.use_package_name()) { return ""; } @@ -538,7 +559,7 @@ std::string FileClassPrefix(const FileDescriptor* file) { if (!result.empty()) { result.append("_"); } - return result; + return g_prefix_mode.forced_package_prefix() + result; } std::string FilePath(const FileDescriptor* file) { @@ -1240,6 +1261,11 @@ bool ValidateObjCClassPrefix( const std::string prefix = file->options().objc_class_prefix(); const std::string package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const std::string no_package_prefix("no_package:"); + const std::string lookup_key = + package.empty() ? no_package_prefix + file->name() : 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. @@ -1247,7 +1273,7 @@ bool ValidateObjCClassPrefix( // 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 = - expected_package_prefixes.find(package); + expected_package_prefixes.find(lookup_key); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... if (has_prefix && package_match->second == prefix) { @@ -1256,8 +1282,11 @@ bool ValidateObjCClassPrefix( } else { // ...it didn't match! *out_error = "error: Expected 'option objc_class_prefix = \"" + - package_match->second + "\";' for package '" + package + - "' in '" + file->name() + "'"; + package_match->second + "\";'"; + if (!package.empty()) { + *out_error += " for package '" + package + "'"; + } + *out_error += " in '" + file->name() + "'"; if (has_prefix) { *out_error += "; but found '" + prefix + "' instead"; } @@ -1286,35 +1315,12 @@ bool ValidateObjCClassPrefix( i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; - break; - } - } - - // Check: Warning - If the file does not have a package, check whether the - // prefix was declared is being used by another package or not. This is - // a special case for empty packages. - if (package.empty()) { - // The file does not have a package and ... - if (other_package_for_prefix.empty()) { - // ... no other package has declared that prefix. - 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 (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); - } else { - // ... another package has declared the same prefix. - 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 " - << "to the proto, or reusing one of the packages already using this " - << "prefix in the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); + // Stop on the first real package listing, if it was a no_package file + // specific entry, keep looking to try and find a package one. + if (!HasPrefixString(other_package_for_prefix, no_package_prefix)) { + break; + } } - return true; } // Check: Error - Make sure the prefix wasn't expected for a different @@ -1323,14 +1329,20 @@ bool ValidateObjCClassPrefix( if (!other_package_for_prefix.empty()) { *out_error = "error: Found 'option objc_class_prefix = \"" + prefix + - "\";' in '" + file->name() + - "'; that prefix is already used for 'package " + - other_package_for_prefix + ";'. It can only be reused by listing " + - "it in the expected file (" + - expected_prefixes_path + ")."; + "\";' in '" + file->name() + "'; that prefix is already used for "; + if (HasPrefixString(other_package_for_prefix, no_package_prefix)) { + *out_error += "file '" + + StripPrefixString(other_package_for_prefix, no_package_prefix) + + "'."; + } else { + *out_error += "'package " + other_package_for_prefix + ";'."; + } + *out_error += + " It can only be reused by adding '" + lookup_key + " = " + prefix + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; // Only report first usage of the prefix. } - } // !prefix.empty() + } // !prefix.empty() && have_expected_prefix_file // Check: Warning - Make sure the prefix is is a reasonable value according // to Apple's rules (the checks above implicitly whitelist anything that @@ -1359,17 +1371,18 @@ bool ValidateObjCClassPrefix( if (prefixes_must_be_registered) { *out_error = "error: '" + file->name() + "' has 'option objc_class_prefix = \"" + - prefix + "\";', but it is not registered; add it to the expected " + - "prefixes file (" + expected_prefixes_path + ") for the package '" + - package + "'."; + prefix + "\";', but it is not registered. Add '" + lookup_key + " = " + + (prefix.empty() ? "\"\"" : prefix) + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; } std::cerr << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " consider adding it to the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; + << prefix << "\";' in '" << file->name() << "'; consider adding '" + << lookup_key << " = " << (prefix.empty() ? "\"\"" : prefix) + << "' to the expected prefixes file (" << expected_prefixes_path + << ")." << std::endl; std::cerr.flush(); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index c5f948c84ee16..f4b71ced8e91d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -54,8 +54,8 @@ namespace objectivec { bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix(); void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off); // Get/Set the path to a file to load as exceptions when -// `UseProtoPackageAsDefaultPrefixUseProtoPackageAsDefaultPrefix()` is `true`. -// And empty string means there should be no exceptions loaded. +// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there +// should be no exceptions. std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList(); void PROTOC_EXPORT SetProtoPackagePrefixExceptionList( const std::string& file_path); @@ -263,7 +263,7 @@ class PROTOC_EXPORT TextFormatDecodeData { TextFormatDecodeData(const TextFormatDecodeData&) = delete; TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete; - void AddString(int32 key, const std::string& input_for_decode, + void AddString(int32_t key, const std::string& input_for_decode, const std::string& desired_output); size_t num_entries() const { return entries_.size(); } std::string Data() const; @@ -272,7 +272,7 @@ class PROTOC_EXPORT TextFormatDecodeData { const std::string& desired_output); private: - typedef std::pair DataEntry; + typedef std::pair DataEntry; std::vector entries_; }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc index 3c5eda226596b..7ae6a9275f5a4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc @@ -30,7 +30,6 @@ #include #include -#include #include namespace google { @@ -154,7 +153,7 @@ TEST(ObjCHelper, TextFormatDecodeData_RawStrings) { EXPECT_EQ(4, decode_data.num_entries()); - uint8 expected_data[] = { + uint8_t expected_data[] = { 0x4, 0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0, 0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0, @@ -179,7 +178,7 @@ TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) { EXPECT_EQ(5, decode_data.num_entries()); - uint8 expected_data[] = { + uint8_t expected_data[] = { 0x5, // All as is (00 op) 0x1, 0x0A, 0x0, diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index 746224ff86b24..c1b1f53b148fa 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -153,7 +153,7 @@ void MapFieldGenerator::FinishInitialization(void) { // Use the array_comment support in RepeatedFieldGenerator to output what the // values in the map are. const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) { variables_["array_comment"] = "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n"; @@ -164,7 +164,7 @@ void MapFieldGenerator::DetermineForwardDeclarations( std::set* fwd_decls) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { const std::string& value_storage_type = value_field_generator_->variable("storage_type"); @@ -176,7 +176,7 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const { // Class name is already in "storage_type". const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { fwd_decls->insert(ObjCClassDeclaration( value_field_generator_->variable("storage_type"))); diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 49ddfceb1aa92..860d4a6863ec8 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -46,11 +46,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -180,9 +180,9 @@ bool IsNumberFollowUnderscore(const std::string& name) { // =================================================================== Parser::Parser() - : input_(NULL), - error_collector_(NULL), - source_location_table_(NULL), + : input_(nullptr), + error_collector_(nullptr), + source_location_table_(nullptr), had_errors_(false), require_syntax_identifier_(false), stop_after_syntax_identifier_(false) { @@ -347,7 +347,7 @@ bool Parser::TryConsumeEndOfDeclaration(const char* text, // from last time. leading.swap(upcoming_doc_comments_); - if (location != NULL) { + if (location != nullptr) { upcoming_detached_comments_.swap(detached); location->AttachComments(&leading, &trailing, &detached); } else if (strcmp(text, "}") == 0) { @@ -380,7 +380,7 @@ bool Parser::ConsumeEndOfDeclaration(const char* text, // ------------------------------------------------------------------- void Parser::AddError(int line, int column, const std::string& error) { - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { error_collector_->AddError(line, column, error); } had_errors_ = true; @@ -473,7 +473,7 @@ void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { void Parser::LocationRecorder::RecordLegacyLocation( const Message* descriptor, DescriptorPool::ErrorCollector::ErrorLocation location) { - if (parser_->source_location_table_ != NULL) { + if (parser_->source_location_table_ != nullptr) { parser_->source_location_table_->Add( descriptor, location, location_->span(0), location_->span(1)); } @@ -516,7 +516,7 @@ void Parser::SkipStatement() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -534,7 +534,7 @@ void Parser::SkipRestOfBlock() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration("}", NULL)) { + if (TryConsumeEndOfDeclaration("}", nullptr)) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -628,7 +628,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (LookingAtType(io::Tokenizer::TYPE_START)) { // Advance to first token. - input_->NextWithComments(NULL, &upcoming_detached_comments_, + input_->NextWithComments(nullptr, &upcoming_detached_comments_, &upcoming_doc_comments_); } @@ -644,7 +644,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { return false; } // Store the syntax into the file. - if (file != NULL) file->set_syntax(syntax_identifier_); + if (file != nullptr) file->set_syntax(syntax_identifier_); } else if (!stop_after_syntax_identifier_) { GOOGLE_LOG(WARNING) << "No syntax specified for the proto file: " << file->name() << ". Please use 'syntax = \"proto2\";' " @@ -664,16 +664,16 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (LookingAt("}")) { AddError("Unmatched \"}\"."); - input_->NextWithComments(NULL, &upcoming_detached_comments_, + input_->NextWithComments(nullptr, &upcoming_detached_comments_, &upcoming_doc_comments_); } } } } - input_ = NULL; - source_code_info_ = NULL; - assert(file != NULL); + input_ = nullptr; + source_code_info_ = nullptr; + assert(file != nullptr); source_code_info.Swap(file->mutable_source_code_info()); return !had_errors_; } @@ -706,7 +706,7 @@ bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) { bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, const LocationRecorder& root_location) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("message")) { @@ -862,7 +862,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &message_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in message definition (missing '}')."); return false; @@ -887,7 +887,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, bool Parser::ParseMessageStatement(DescriptorProto* message, const LocationRecorder& message_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("message")) { @@ -1458,7 +1458,7 @@ bool Parser::ParseOption(Message* options, // Create an entry in the uninterpreted_option field. const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->FindFieldByName("uninterpreted_option"); - GOOGLE_CHECK(uninterpreted_option_field != NULL) + GOOGLE_CHECK(uninterpreted_option_field != nullptr) << "No field named \"uninterpreted_option\" in the Options proto."; const Reflection* reflection = options->GetReflection(); @@ -1906,7 +1906,7 @@ bool Parser::ParseExtend(RepeatedPtrField* extensions, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -1970,7 +1970,7 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -2003,7 +2003,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &enum_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in enum definition (missing '}')."); return false; @@ -2022,7 +2022,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, const LocationRecorder& enum_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("option")) { @@ -2120,7 +2120,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &service_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in service definition (missing '}')."); return false; @@ -2139,7 +2139,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, const LocationRecorder& service_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("option")) { @@ -2177,7 +2177,6 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, DescriptorPool::ErrorCollector::OTHER); method->set_client_streaming(true); DO(Consume("stream")); - } LocationRecorder location(method_location, MethodDescriptorProto::kInputTypeFieldNumber); @@ -2198,7 +2197,6 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, DescriptorPool::ErrorCollector::OTHER); DO(Consume("stream")); method->set_server_streaming(true); - } LocationRecorder location(method_location, MethodDescriptorProto::kOutputTypeFieldNumber); @@ -2226,13 +2224,13 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, Message* mutable_options) { // Options! ConsumeEndOfDeclaration("{", &parent_location); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in method options (missing '}')."); return false; } - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore } else { LocationRecorder location(parent_location, optionsFieldNumber); @@ -2396,7 +2394,7 @@ bool SourceLocationTable::Find( int* column) const { const std::pair* result = FindOrNull(location_map_, std::make_pair(descriptor, location)); - if (result == NULL) { + if (result == nullptr) { *line = -1; *column = 0; return false; diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index b5a5df89969b8..f95c419a83aea 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -42,10 +42,10 @@ #include #include -#include #include #include #include +#include // Must be included last. #include @@ -281,9 +281,6 @@ class PROTOBUF_EXPORT Parser { std::vector* detached_comments) const; private: - // Indexes of parent and current location in the parent - // SourceCodeInfo.location repeated field. For top-level elements, - // parent_index_ is -1. Parser* parser_; SourceCodeInfo* source_code_info_; SourceCodeInfo::Location* location_; @@ -434,7 +431,6 @@ class PROTOBUF_EXPORT Parser { const LocationRecorder& method_location, const FileDescriptorProto* containing_file); - // Parse options of a single method or stream. bool ParseMethodOptions(const LocationRecorder& parent_location, const FileDescriptorProto* containing_file, diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 6973bc993dd51..8ddc312405456 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -83,7 +83,7 @@ class MockValidationErrorCollector : public DescriptorPool::ErrorCollector { io::ErrorCollector* wrapped_collector) : source_locations_(source_locations), wrapped_collector_(wrapped_collector) {} - ~MockValidationErrorCollector() {} + ~MockValidationErrorCollector() override {} // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, const std::string& element_name, @@ -173,7 +173,7 @@ class ParserTest : public testing::Test { MockValidationErrorCollector validation_error_collector(source_locations, &error_collector_); EXPECT_TRUE(pool_.BuildFileCollectingErrors( - file, &validation_error_collector) == NULL); + file, &validation_error_collector) == nullptr); EXPECT_EQ(expected_errors, error_collector_.text_); } @@ -194,7 +194,7 @@ TEST_F(ParserTest, StopAfterSyntaxIdentifier) { "syntax = \"foobar\";\n" "this line will not be parsed\n"); parser_->SetStopAfterSyntaxIdentifier(true); - EXPECT_TRUE(parser_->Parse(input_.get(), NULL)); + EXPECT_TRUE(parser_->Parse(input_.get(), nullptr)); EXPECT_EQ("", error_collector_.text_); EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier()); } @@ -204,7 +204,7 @@ TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) { "// blah\n" "this line will not be parsed\n"); parser_->SetStopAfterSyntaxIdentifier(true); - EXPECT_TRUE(parser_->Parse(input_.get(), NULL)); + EXPECT_TRUE(parser_->Parse(input_.get(), nullptr)); EXPECT_EQ("", error_collector_.text_); EXPECT_EQ("", parser_->GetSyntaxIdentifier()); } @@ -214,7 +214,7 @@ TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) { "// blah\n" "syntax = error;\n"); parser_->SetStopAfterSyntaxIdentifier(true); - EXPECT_FALSE(parser_->Parse(input_.get(), NULL)); + EXPECT_FALSE(parser_->Parse(input_.get(), nullptr)); EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_); } @@ -1792,7 +1792,7 @@ TEST_F(ParserValidationErrorTest, PackageNameError) { FileDescriptorProto other_file; other_file.set_name("bar.proto"); other_file.add_message_type()->set_name("foo"); - EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); + EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr); // Now try to define it as a package. ExpectHasValidationErrors( @@ -2071,7 +2071,7 @@ TEST_F(ParserValidationErrorTest, ResolvedUndefinedError) { other_file.set_name("base.proto"); other_file.set_package("base"); other_file.add_message_type()->set_name("bar"); - EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); + EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr); // Define "foo.base" and try "base.bar". // "base.bar" is resolved to "foo.base.bar" which is not defined. @@ -2092,7 +2092,7 @@ TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) { // Build descriptor message in test pool FileDescriptorProto descriptor_proto; DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto); - ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != nullptr); // base2.proto: // package baz @@ -2121,7 +2121,7 @@ TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) { extension->set_type_name("Bar"); extension->set_extendee("google.protobuf.FileOptions"); - EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); + EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr); // qux.proto: // package qux.baz @@ -2228,17 +2228,17 @@ TEST_F(ParseDescriptorDebugTest, TestAllDescriptorTypes) { protobuf_unittest_import::PublicImportMessage::descriptor()->file(); FileDescriptorProto public_import_proto; public_import->CopyTo(&public_import_proto); - ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(public_import_proto) != nullptr); const FileDescriptor* import = protobuf_unittest_import::ImportMessage::descriptor()->file(); FileDescriptorProto import_proto; import->CopyTo(&import_proto); - ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(import_proto) != nullptr); const FileDescriptor* actual = pool_.BuildFile(parsed); parsed.Clear(); - ASSERT_TRUE(actual != NULL) << "Failed to validate:\n" << debug_string; + ASSERT_TRUE(actual != nullptr) << "Failed to validate:\n" << debug_string; actual->CopyTo(&parsed); - ASSERT_TRUE(actual != NULL); + ASSERT_TRUE(actual != nullptr); // The messages might be in different orders, making them hard to compare. // So, sort the messages in the descriptor protos (including nested messages, @@ -2276,14 +2276,14 @@ TEST_F(ParseDescriptorDebugTest, TestCustomOptions) { const FileDescriptor* import = FileDescriptorProto::descriptor()->file(); FileDescriptorProto import_proto; import->CopyTo(&import_proto); - ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(import_proto) != nullptr); 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); + ASSERT_TRUE(actual != nullptr); parsed.Clear(); actual->CopyTo(&parsed); @@ -2365,7 +2365,7 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) { MockValidationErrorCollector collector(source_locations, &error_collector_); const FileDescriptor* descriptor = pool_.BuildFileCollectingErrors(parsed_desc, &collector); - ASSERT_TRUE(descriptor != NULL); + ASSERT_TRUE(descriptor != nullptr); // Ensure that each of the comments appears somewhere in the DebugString(). // We don't test the exact comment placement or formatting, because we do not @@ -2429,7 +2429,7 @@ TEST_F(ParseDescriptorDebugTest, TestMaps) { EXPECT_TRUE(parser_->Parse(input_.get(), &original)); original.set_name("foo.proto"); const FileDescriptor* file = pool_.BuildFile(original); - ASSERT_TRUE(file != NULL); + ASSERT_TRUE(file != nullptr); // Make sure the debug string uses map syntax and does not have the auto // generated entry. @@ -2472,7 +2472,7 @@ bool FollowPath(const Message& root, const int* path_begin, const int* path_end, if (path_begin == path_end) { // Path refers to this whole message. *output_message = &root; - *output_field = NULL; + *output_field = nullptr; *output_index = -1; return true; } @@ -2482,7 +2482,7 @@ bool FollowPath(const Message& root, const int* path_begin, const int* path_end, const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin); - if (field == NULL) { + if (field == nullptr) { ADD_FAILURE() << descriptor->name() << " has no field number: " << *path_begin; return false; @@ -2573,8 +2573,8 @@ class SourceInfoTest : public ParserTest { const SourceCodeInfo& source_info = file_.source_code_info(); for (int i = 0; i < source_info.location_size(); i++) { const SourceCodeInfo::Location& location = source_info.location(i); - const Message* descriptor_proto = NULL; - const FieldDescriptor* field = NULL; + const Message* descriptor_proto = nullptr; + const FieldDescriptor* field = nullptr; int index = 0; if (!FollowPath(file_, location.path().begin(), location.path().end(), &descriptor_proto, &field, &index)) { @@ -2601,8 +2601,8 @@ class SourceInfoTest : public ParserTest { bool HasSpan(char start_marker, char end_marker, const Message& descriptor_proto) { - return HasSpanWithComment(start_marker, end_marker, descriptor_proto, NULL, - -1, NULL, NULL, NULL); + return HasSpanWithComment(start_marker, end_marker, descriptor_proto, + nullptr, -1, nullptr, nullptr, nullptr); } bool HasSpanWithComment(char start_marker, char end_marker, @@ -2610,8 +2610,8 @@ class SourceInfoTest : public ParserTest { const char* expected_leading_comments, const char* expected_trailing_comments, const char* expected_leading_detached_comments) { - return HasSpanWithComment(start_marker, end_marker, descriptor_proto, NULL, - -1, expected_leading_comments, + return HasSpanWithComment(start_marker, end_marker, descriptor_proto, + nullptr, -1, expected_leading_comments, expected_trailing_comments, expected_leading_detached_comments); } @@ -2625,7 +2625,7 @@ class SourceInfoTest : public ParserTest { const Message& descriptor_proto, const std::string& field_name, int index) { return HasSpan(start_marker, end_marker, descriptor_proto, field_name, - index, NULL, NULL, NULL); + index, nullptr, nullptr, nullptr); } bool HasSpan(char start_marker, char end_marker, @@ -2635,7 +2635,7 @@ class SourceInfoTest : public ParserTest { const char* expected_leading_detached_comments) { const FieldDescriptor* field = descriptor_proto.GetDescriptor()->FindFieldByName(field_name); - if (field == NULL) { + if (field == nullptr) { ADD_FAILURE() << descriptor_proto.GetDescriptor()->name() << " has no such field: " << field_name; return false; @@ -2648,8 +2648,8 @@ class SourceInfoTest : public ParserTest { } bool HasSpan(const Message& descriptor_proto) { - return HasSpanWithComment('\0', '\0', descriptor_proto, NULL, -1, NULL, - NULL, NULL); + return HasSpanWithComment('\0', '\0', descriptor_proto, nullptr, -1, + nullptr, nullptr, nullptr); } bool HasSpan(const Message& descriptor_proto, const std::string& field_name) { @@ -2686,21 +2686,21 @@ class SourceInfoTest : public ParserTest { for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) { if (CompareSpans(expected_span, iter->second->span())) { - if (expected_leading_comments == NULL) { + if (expected_leading_comments == nullptr) { EXPECT_FALSE(iter->second->has_leading_comments()); } else { EXPECT_TRUE(iter->second->has_leading_comments()); EXPECT_EQ(expected_leading_comments, iter->second->leading_comments()); } - if (expected_trailing_comments == NULL) { + if (expected_trailing_comments == nullptr) { EXPECT_FALSE(iter->second->has_trailing_comments()); } else { EXPECT_TRUE(iter->second->has_trailing_comments()); EXPECT_EQ(expected_trailing_comments, iter->second->trailing_comments()); } - if (expected_leading_detached_comments == NULL) { + if (expected_leading_detached_comments == nullptr) { EXPECT_EQ(0, iter->second->leading_detached_comments_size()); } else { EXPECT_EQ( @@ -3496,7 +3496,7 @@ TEST_F(SourceInfoTest, DocComments) { const FieldDescriptorProto& bar = foo.field(0); EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, " Foo leading\n line 2\n", - " Foo trailing\n line 2\n", NULL)); + " Foo trailing\n line 2\n", nullptr)); EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n", " bar trailing\n", " detached\n")); @@ -3572,7 +3572,7 @@ TEST_F(SourceInfoTest, DocComments3) { const FieldDescriptorProto& bar = foo.field(0); EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n", - " bar trailing\n", NULL)); + " bar trailing\n", nullptr)); // Ignore these. EXPECT_TRUE(HasSpan(file_)); @@ -3655,7 +3655,7 @@ TEST_F(SourceInfoTest, DocCommentsOneof) { const FieldDescriptorProto& bar_int = foo.field(0); EXPECT_TRUE(HasSpanWithComment('a', 'f', foo, " Foo leading\n", - " Foo trailing\n", NULL)); + " Foo trailing\n", nullptr)); EXPECT_TRUE(HasSpanWithComment('b', 'e', bar, " bar leading\n line 2 ", " bar trailing\n line 2 ", " detached before oneof\n")); diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 05f8acad87530..6b8ee524aaf70 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -83,14 +83,14 @@ struct Options { bool is_descriptor = false; bool aggregate_metadata = false; bool gen_c_wkt = false; - std::set aggregate_metadata_prefixes; + std::set aggregate_metadata_prefixes; }; namespace { // Forward decls. std::string PhpName(const std::string& full_name, const Options& options); -std::string IntToString(int32 value); +std::string IntToString(int32_t value); std::string FilenameToClassname(const std::string& filename); std::string GeneratedMetadataFileName(const FileDescriptor* file, const Options& options); @@ -430,7 +430,7 @@ std::string GeneratedServiceFileName(const ServiceDescriptor* service, return result + ".php"; } -std::string IntToString(int32 value) { +std::string IntToString(int32_t value) { std::ostringstream os; os << value; return os.str(); @@ -741,8 +741,8 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, // Type check. if (field->is_map()) { const Descriptor* map_entry = field->message_type(); - const FieldDescriptor* key = map_entry->FindFieldByName("key"); - const FieldDescriptor* value = map_entry->FindFieldByName("value"); + const FieldDescriptor* key = map_entry->map_key(); + const FieldDescriptor* value = map_entry->map_value(); printer->Print( "$arr = GPBUtil::checkMapField($var, " "\\Google\\Protobuf\\Internal\\GPBType::^key_type^, " @@ -889,9 +889,9 @@ void GenerateMessageToPool(const std::string& name_prefix, const FieldDescriptor* field = message->field(i); if (field->is_map()) { const FieldDescriptor* key = - field->message_type()->FindFieldByName("key"); + field->message_type()->map_key(); const FieldDescriptor* val = - field->message_type()->FindFieldByName("value"); + field->message_type()->map_value(); printer->Print( "->map('^field^', \\Google\\Protobuf\\Internal\\GPBType::^key^, " "\\Google\\Protobuf\\Internal\\GPBType::^value^, ^number^^other^)\n", diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 780996866295f..25ca5f04ddf0c 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -68,7 +68,7 @@ class GeneratorResponseContext : public GeneratorContext { : compiler_version_(compiler_version), response_(response), parsed_files_(parsed_files) {} - virtual ~GeneratorResponseContext() {} + ~GeneratorResponseContext() override {} // implements GeneratorContext -------------------------------------- @@ -117,7 +117,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, DescriptorPool pool; for (int i = 0; i < request.proto_file_size(); i++) { const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); - if (file == NULL) { + if (file == nullptr) { // BuildFile() already wrote an error message. return false; } @@ -126,7 +126,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, std::vector parsed_files; for (int i = 0; i < request.file_to_generate_size(); i++) { parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); - if (parsed_files.back() == NULL) { + if (parsed_files.back() == nullptr) { *error_msg = "protoc asked plugin to generate a file but " "did not provide a descriptor for the file: " + diff --git a/src/google/protobuf/compiler/plugin.h b/src/google/protobuf/compiler/plugin.h index 7d1bf450847e0..611713e2c057b 100644 --- a/src/google/protobuf/compiler/plugin.h +++ b/src/google/protobuf/compiler/plugin.h @@ -64,6 +64,7 @@ #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index e423e851be026..f6be6642427bf 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -16,72 +16,76 @@ #include PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + PROTOBUF_NAMESPACE_OPEN namespace compiler { constexpr Version::Version( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : suffix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , major_(0) , minor_(0) , patch_(0){} struct VersionDefaultTypeInternal { constexpr VersionDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~VersionDefaultTypeInternal() {} union { Version _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT VersionDefaultTypeInternal _Version_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 VersionDefaultTypeInternal _Version_default_instance_; constexpr CodeGeneratorRequest::CodeGeneratorRequest( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : file_to_generate_() , proto_file_() , parameter_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , compiler_version_(nullptr){} struct CodeGeneratorRequestDefaultTypeInternal { constexpr CodeGeneratorRequestDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorRequestDefaultTypeInternal() {} union { CodeGeneratorRequest _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , insertion_point_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , content_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , generated_code_info_(nullptr){} struct CodeGeneratorResponse_FileDefaultTypeInternal { constexpr CodeGeneratorResponse_FileDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponse_FileDefaultTypeInternal() {} union { CodeGeneratorResponse_File _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; constexpr CodeGeneratorResponse::CodeGeneratorResponse( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + ::_pbi::ConstantInitialized) : file_() , error_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) , supported_features_(uint64_t{0u}){} struct CodeGeneratorResponseDefaultTypeInternal { constexpr CodeGeneratorResponseDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponseDefaultTypeInternal() {} union { CodeGeneratorResponse _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_; } // namespace compiler PROTOBUF_NAMESPACE_CLOSE -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4]; -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; +static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4]; +static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]; +static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; const uint32_t TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _has_bits_), @@ -139,18 +143,18 @@ const uint32_t TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offset 1, ~0u, }; -static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, 10, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::Version)}, { 14, 24, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)}, { 28, 38, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, { 42, 51, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, }; -static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_File_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_), +static const ::_pb::Message* const file_default_instances[] = { + &::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_File_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_._instance, }; const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -175,22 +179,24 @@ const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2epro "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] = { +static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, }; -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { - false, false, 773, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 1, 4, - schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, - file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, +static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; +const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { + false, false, 773, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, + "google/protobuf/compiler/plugin.proto", + &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 1, 4, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, + file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, }; -PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() { +PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; } // Force running AddDescriptors() at dynamic initialization time. -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_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::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() { @@ -238,16 +244,13 @@ Version::Version(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version) } Version::Version(const Version& from) : ::PROTOBUF_NAMESPACE_ID::Message(), _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + suffix_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -262,7 +265,7 @@ Version::Version(const Version& from) } inline void Version::SharedCtor() { -suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +suffix_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -274,9 +277,11 @@ ::memset(reinterpret_cast(this) + static_cast( Version::~Version() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Version::SharedDtor() { @@ -284,12 +289,6 @@ inline void Version::SharedDtor() { 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); } @@ -313,12 +312,12 @@ void Version::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Version::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional int32 major = 1; case 1: @@ -351,11 +350,11 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in case 4: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { auto str = _internal_mutable_suffix(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -393,19 +392,19 @@ uint8_t* Version::_InternalSerialize( // optional int32 major = 1; if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_major(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_major(), target); } // optional int32 minor = 2; if (cached_has_bits & 0x00000004u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_minor(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_minor(), target); } // optional int32 patch = 3; if (cached_has_bits & 0x00000008u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_patch(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_patch(), target); } // optional string suffix = 4; @@ -419,7 +418,7 @@ uint8_t* Version::_InternalSerialize( } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -445,17 +444,17 @@ size_t Version::ByteSizeLong() const { // optional int32 major = 1; if (cached_has_bits & 0x00000002u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_major()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_major()); } // optional int32 minor = 2; if (cached_has_bits & 0x00000004u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_minor()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_minor()); } // optional int32 patch = 3; if (cached_has_bits & 0x00000008u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_patch()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_patch()); } } @@ -531,7 +530,7 @@ void Version::InternalSwap(Version* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata Version::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]); } @@ -563,9 +562,6 @@ CodeGeneratorRequest::CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena file_to_generate_(arena), proto_file_(arena) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest) } CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) @@ -574,7 +570,7 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) file_to_generate_(from.file_to_generate_), proto_file_(from.proto_file_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + parameter_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -591,7 +587,7 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) } inline void CodeGeneratorRequest::SharedCtor() { -parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +parameter_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -600,9 +596,11 @@ compiler_version_ = nullptr; CodeGeneratorRequest::~CodeGeneratorRequest() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorRequest::SharedDtor() { @@ -611,12 +609,6 @@ inline void CodeGeneratorRequest::SharedDtor() { 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); } @@ -643,12 +635,12 @@ void CodeGeneratorRequest::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // repeated string file_to_generate = 1; case 1: @@ -657,11 +649,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM do { ptr += 1; auto str = _internal_add_file_to_generate(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); #endif // !NDEBUG - CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); } else @@ -671,11 +663,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_parameter(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -753,22 +745,21 @@ uint8_t* CodeGeneratorRequest::_InternalSerialize( // optional .google.protobuf.compiler.Version compiler_version = 3; if (cached_has_bits & 0x00000002u) { - target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage( - 3, _Internal::compiler_version(this), target, stream); + InternalWriteMessage(3, _Internal::compiler_version(this), + _Internal::compiler_version(this).GetCachedSize(), target, stream); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - for (unsigned int i = 0, - n = static_cast(this->_internal_proto_file_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_proto_file_size()); i < n; i++) { + const auto& repfield = this->_internal_proto_file(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(15, this->_internal_proto_file(i), target, stream); + InternalWriteMessage(15, repfield, repfield.GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -881,7 +872,7 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorRequest::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]); } @@ -918,16 +909,13 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID:: bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) : ::PROTOBUF_NAMESPACE_ID::Message(), _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -935,7 +923,7 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArenaForAllocation()); } - insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + insertion_point_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -943,7 +931,7 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_insertion_point(), GetArenaForAllocation()); } - content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + content_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -960,15 +948,15 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon } inline void CodeGeneratorResponse_File::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +insertion_point_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +content_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -977,9 +965,11 @@ generated_code_info_ = nullptr; CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorResponse_File::SharedDtor() { @@ -990,12 +980,6 @@ inline void CodeGeneratorResponse_File::SharedDtor() { 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); } @@ -1026,22 +1010,22 @@ void CodeGeneratorResponse_File::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1049,11 +1033,11 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_insertion_point(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1061,11 +1045,11 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB case 15: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 122)) { auto str = _internal_mutable_content(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1140,14 +1124,13 @@ uint8_t* CodeGeneratorResponse_File::_InternalSerialize( // 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); + InternalWriteMessage(16, _Internal::generated_code_info(this), + _Internal::generated_code_info(this).GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -1269,7 +1252,7 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]); } @@ -1292,9 +1275,6 @@ CodeGeneratorResponse::CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* are : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), file_(arena) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse) } CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) @@ -1302,7 +1282,7 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) _has_bits_(from._has_bits_), file_(from.file_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + error_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1315,7 +1295,7 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) } inline void CodeGeneratorResponse::SharedCtor() { -error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +error_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1324,9 +1304,11 @@ supported_features_ = uint64_t{0u}; CodeGeneratorResponse::~CodeGeneratorResponse() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorResponse::SharedDtor() { @@ -1334,12 +1316,6 @@ inline void CodeGeneratorResponse::SharedDtor() { 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); } @@ -1360,22 +1336,22 @@ void CodeGeneratorResponse::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional string error = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_error(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1445,19 +1421,19 @@ uint8_t* CodeGeneratorResponse::_InternalSerialize( // 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); + target = ::_pbi::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++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_file_size()); i < n; i++) { + const auto& repfield = this->_internal_file(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(15, this->_internal_file(i), target, stream); + InternalWriteMessage(15, repfield, repfield.GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _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) @@ -1490,7 +1466,7 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { // optional uint64 supported_features = 2; if (cached_has_bits & 0x00000002u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features()); + total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features()); } } @@ -1557,7 +1533,7 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]); } @@ -1566,16 +1542,20 @@ ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse::GetMetadata() const { } // namespace compiler PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::Version* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::Version* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* 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) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(Arena* 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) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(Arena* 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) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(Arena* 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 76c3da1de70ad..204e42afad13e 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -50,14 +49,6 @@ PROTOBUF_NAMESPACE_CLOSE // Internal implementation detail -- do not use these members. 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::AuxiliaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; static const uint32_t offsets[]; }; PROTOC_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; @@ -225,9 +216,6 @@ class PROTOC_EXPORT Version final : protected: explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -433,9 +421,6 @@ class PROTOC_EXPORT CodeGeneratorRequest final : protected: explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -662,9 +647,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : protected: explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -885,9 +867,6 @@ class PROTOC_EXPORT CodeGeneratorResponse final : protected: explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -1141,7 +1120,7 @@ inline std::string* Version::release_suffix() { _has_bits_[0] &= ~0x00000001u; auto* p = suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (suffix_.IsDefault()) { suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1156,7 +1135,7 @@ inline void Version::set_allocated_suffix(std::string* suffix) { suffix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), suffix, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (suffix_.IsDefault()) { suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1289,7 +1268,7 @@ inline std::string* CodeGeneratorRequest::release_parameter() { _has_bits_[0] &= ~0x00000001u; auto* p = parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (parameter_.IsDefault()) { parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1304,7 +1283,7 @@ inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter parameter_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), parameter, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (parameter_.IsDefault()) { parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1489,7 +1468,7 @@ inline std::string* CodeGeneratorResponse_File::release_name() { _has_bits_[0] &= ~0x00000001u; auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (name_.IsDefault()) { name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1504,7 +1483,7 @@ inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) { name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (name_.IsDefault()) { name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1558,7 +1537,7 @@ inline std::string* CodeGeneratorResponse_File::release_insertion_point() { _has_bits_[0] &= ~0x00000002u; auto* p = insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (insertion_point_.IsDefault()) { insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1573,7 +1552,7 @@ inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::strin insertion_point_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), insertion_point, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (insertion_point_.IsDefault()) { insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1627,7 +1606,7 @@ inline std::string* CodeGeneratorResponse_File::release_content() { _has_bits_[0] &= ~0x00000004u; auto* p = content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (content_.IsDefault()) { content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1642,7 +1621,7 @@ inline void CodeGeneratorResponse_File::set_allocated_content(std::string* conte content_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), content, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (content_.IsDefault()) { content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1788,7 +1767,7 @@ inline std::string* CodeGeneratorResponse::release_error() { _has_bits_[0] &= ~0x00000001u; auto* p = error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (error_.IsDefault()) { error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -1803,7 +1782,7 @@ inline void CodeGeneratorResponse::set_allocated_error(std::string* error) { error_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + if (error_.IsDefault()) { error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index 9ad7a33b2e710..7d9e7eae67c7b 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -55,12 +55,14 @@ #include #include #include -#include +#include +#include #include #include #include #include #include +#include namespace google { namespace protobuf { @@ -68,16 +70,6 @@ namespace compiler { namespace python { namespace { - - -// Returns the Python module name expected for a given .proto filename. -std::string ModuleName(const std::string& filename) { - std::string basename = StripProto(filename); - ReplaceCharacters(&basename, "-", '_'); - ReplaceCharacters(&basename, "/", '.'); - return basename + "_pb2"; -} - // Returns the alias we assign to the module of the given .proto filename // when importing. See testPackageInitializationImport in // net/proto2/python/internal/reflection_test.py @@ -92,78 +84,18 @@ std::string ModuleAlias(const std::string& filename) { return module_name; } -// Keywords reserved by the Python language. -const char* const kKeywords[] = { - "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])); - -bool ContainsPythonKeyword(const std::string& module_name) { - std::vector tokens = Split(module_name, "."); - for (int i = 0; i < tokens.size(); ++i) { - if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) { - return true; - } - } - return false; -} - -inline bool IsPythonKeyword(const std::string& name) { - return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd); -} - -std::string ResolveKeyword(const std::string& name) { - if (IsPythonKeyword(name)) { - return "globals()['" + name + "']"; - } - return name; -} - -// Returns the name of all containing types for descriptor, -// in order from outermost to innermost, followed by descriptor's -// own name. Each name is separated by |separator|. -template -std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, - const std::string& separator) { - std::string name = descriptor.name(); - const Descriptor* parent = descriptor.containing_type(); - if (parent != nullptr) { - std::string prefix = NamePrefixedWithNestedTypes(*parent, separator); - if (separator == "." && IsPythonKeyword(name)) { - return "getattr(" + prefix + ", '" + name + "')"; - } else { - return prefix + separator + name; - } - } - if (separator == ".") { - name = ResolveKeyword(name); - } - return name; -} - // Name of the class attribute where we store the Python // descriptor.Descriptor instance for the generated class. // Must stay consistent with the _DESCRIPTOR_KEY constant // in proto2/public/reflection.py. const char kDescriptorKey[] = "DESCRIPTOR"; + // Does the file have top-level enums? inline bool HasTopLevelEnums(const FileDescriptor* file) { return file->enum_type_count() > 0; } -// Should we generate generic services for this file? -inline bool HasGenericServices(const FileDescriptor* file) { - return file->service_count() > 0 && file->options().py_generic_services(); -} - -// Prints the common boilerplate needed at the top of every .py // file output by this generator. void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) { @@ -174,27 +106,16 @@ void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file, "# source: $filename$\n" "\"\"\"Generated protocol buffer code.\"\"\"\n", "filename", file->name()); - if (HasTopLevelEnums(file)) { - printer->Print( - "from google.protobuf.internal import enum_type_wrapper\n"); - } printer->Print( + "from google.protobuf.internal import builder as _builder\n" "from google.protobuf import descriptor as _descriptor\n" "from google.protobuf import descriptor_pool as " "_descriptor_pool\n" - "from google.protobuf import message as _message\n" - "from google.protobuf import reflection as _reflection\n" "from google.protobuf import symbol_database as " "_symbol_database\n"); - if (HasGenericServices(file)) { - printer->Print( - "from google.protobuf import service as _service\n" - "from google.protobuf import service_reflection\n"); - } - printer->Print( - "# @@protoc_insertion_point(imports)\n\n" - "_sym_db = _symbol_database.Default()\n"); + printer->Print("# @@protoc_insertion_point(imports)\n\n"); + printer->Print("_sym_db = _symbol_database.Default()\n"); printer->Print("\n\n"); } @@ -309,6 +230,11 @@ bool Generator::Generate(const FileDescriptor* file, for (int i = 0; i < options.size(); i++) { if (options[i].first == "cpp_generated_lib_linked") { cpp_generated_lib_linked = true; + } else if (options[i].first == "pyi_out") { + python::PyiGenerator pyi_generator; + if (!pyi_generator.Generate(file, "", context, error)) { + return false; + } } else { *error = "Unknown generator option: " + options[i].first; return false; @@ -324,11 +250,8 @@ bool Generator::Generate(const FileDescriptor* file, // to have any mutable members. Then it is implicitly thread-safe. MutexLock lock(&mutex_); file_ = file; - std::string module_name = ModuleName(file->name()); - std::string filename = module_name; - ReplaceCharacters(&filename, ".", '/'); - filename += ".py"; + std::string filename = GetFileName(file, ".py"); pure_python_workable_ = !cpp_generated_lib_linked; if (HasPrefixString(file->name(), "google/protobuf/")) { pure_python_workable_ = true; @@ -349,15 +272,13 @@ bool Generator::Generate(const FileDescriptor* file, PrintImports(); } PrintFileDescriptor(); - PrintTopLevelEnums(); - PrintTopLevelExtensions(); if (pure_python_workable_) { if (GeneratingDescriptorProto()) { printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n"); printer_->Indent(); // Create enums before message descriptors - PrintAllNestedEnumsInFile(StripPrintDescriptor::kCreate); - PrintMessageDescriptors(StripPrintDescriptor::kCreate); + PrintAllNestedEnumsInFile(); + PrintMessageDescriptors(); FixForeignFieldsInDescriptors(); printer_->Outdent(); printer_->Print("else:\n"); @@ -365,16 +286,18 @@ bool Generator::Generate(const FileDescriptor* file, } // Find the message descriptors first and then use the message // descriptor to find enums. - PrintMessageDescriptors(StripPrintDescriptor::kFind); - PrintAllNestedEnumsInFile(StripPrintDescriptor::kFind); + printer_->Print( + "_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())\n"); if (GeneratingDescriptorProto()) { printer_->Outdent(); } } - PrintMessages(); + std::string module_name = ModuleName(file->name()); + printer_->Print( + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, '$module_name$', " + "globals())\n", + "module_name", module_name); if (pure_python_workable_) { - PrintServiceDescriptors(); - printer.Print("if _descriptor._USE_C_DESCRIPTORS == False:\n"); printer_->Indent(); @@ -395,7 +318,9 @@ bool Generator::Generate(const FileDescriptor* file, printer_->Outdent(); } if (HasGenericServices(file)) { - PrintServices(); + printer_->Print( + "_builder.BuildServices(DESCRIPTOR, '$module_name$', globals())\n", + "module_name", module_name); } printer.Print("# @@protoc_insertion_point(module_scope)\n"); @@ -403,7 +328,6 @@ bool Generator::Generate(const FileDescriptor* file, return !printer.failed(); } - // Prints Python imports for all modules imported by |file|. void Generator::PrintImports() const { for (int i = 0; i < file_->dependency_count(); ++i) { @@ -516,47 +440,17 @@ void Generator::PrintFileDescriptor() const { printer_->Print("\n"); } -// Prints descriptors and module-level constants for all top-level -// enums defined in |file|. -void Generator::PrintTopLevelEnums() const { - std::vector > top_level_enum_values; - for (int i = 0; i < file_->enum_type_count(); ++i) { - const EnumDescriptor& enum_descriptor = *file_->enum_type(i); - PrintFindEnum(enum_descriptor); - printer_->Print( - "$name$ = " - "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)", - "name", ResolveKeyword(enum_descriptor.name()), "descriptor_name", - ModuleLevelDescriptorName(enum_descriptor)); - printer_->Print("\n"); - - for (int j = 0; j < enum_descriptor.value_count(); ++j) { - const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j); - top_level_enum_values.push_back( - std::make_pair(value_descriptor.name(), value_descriptor.number())); - } - } - - for (int i = 0; i < top_level_enum_values.size(); ++i) { - printer_->Print("$name$ = $value$\n", "name", - ResolveKeyword(top_level_enum_values[i].first), "value", - StrCat(top_level_enum_values[i].second)); - } - printer_->Print("\n"); -} - // Prints all enums contained in all message types in |file|. -void Generator::PrintAllNestedEnumsInFile( - StripPrintDescriptor print_mode) const { +void Generator::PrintAllNestedEnumsInFile() const { for (int i = 0; i < file_->message_type_count(); ++i) { - PrintNestedEnums(*file_->message_type(i), print_mode); + PrintNestedEnums(*file_->message_type(i)); } } // Prints a Python statement assigning the appropriate module-level // enum name to a Python EnumDescriptor object equivalent to // enum_descriptor. -void Generator::PrintCreateEnum(const EnumDescriptor& enum_descriptor) const { +void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { std::map m; std::string module_level_descriptor_name = ModuleLevelDescriptorName(enum_descriptor); @@ -600,68 +494,23 @@ void Generator::PrintCreateEnum(const EnumDescriptor& enum_descriptor) const { printer_->Print("\n"); } -void Generator::PrintFindEnum(const EnumDescriptor& enum_descriptor) const { - std::map m; - m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor); - m["name"] = enum_descriptor.name(); - m["file"] = kDescriptorKey; - if (enum_descriptor.containing_type()) { - m["containing_type"] = - ModuleLevelDescriptorName(*enum_descriptor.containing_type()); - printer_->Print(m, - "$descriptor_name$ = " - "$containing_type$.enum_types_by_name['$name$']\n"); - } else { - printer_->Print( - m, "$descriptor_name$ = $file$.enum_types_by_name['$name$']\n"); - } -} - // Recursively prints enums in nested types within descriptor, then // prints enums contained at the top level in descriptor. -void Generator::PrintNestedEnums(const Descriptor& descriptor, - StripPrintDescriptor print_mode) const { +void Generator::PrintNestedEnums(const Descriptor& descriptor) const { for (int i = 0; i < descriptor.nested_type_count(); ++i) { - PrintNestedEnums(*descriptor.nested_type(i), print_mode); + PrintNestedEnums(*descriptor.nested_type(i)); } for (int i = 0; i < descriptor.enum_type_count(); ++i) { - if (print_mode == StripPrintDescriptor::kCreate) { - PrintCreateEnum(*descriptor.enum_type(i)); - } else { - PrintFindEnum(*descriptor.enum_type(i)); - } + PrintEnum(*descriptor.enum_type(i)); } } -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"; - ToUpper(&constant_name); - printer_->Print("$constant_name$ = $number$\n", "constant_name", - constant_name, "number", - StrCat(extension_field.number())); - printer_->Print( - "$resolved_name$ = " - "$file$.extensions_by_name['$name$']\n", - "resolved_name", ResolveKeyword(extension_field.name()), "file", - kDescriptorKey, "name", extension_field.name()); - } - printer_->Print("\n"); -} - // Prints Python equivalents of all Descriptors in |file|. -void Generator::PrintMessageDescriptors(StripPrintDescriptor print_mode) const { - if (print_mode == StripPrintDescriptor::kCreate) { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintCreateDescriptor(*file_->message_type(i)); - printer_->Print("\n"); - } - } else { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintFindDescriptor(*file_->message_type(i)); - } +void Generator::PrintMessageDescriptors() const { + for (int i = 0; i < file_->message_type_count(); ++i) { + PrintDescriptor(*file_->message_type(i)); + printer_->Print("\n"); } } @@ -730,14 +579,13 @@ void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { // to a Python Descriptor object for message_descriptor. // // Mutually recursive with PrintNestedDescriptors(). -void Generator::PrintCreateDescriptor( - const Descriptor& message_descriptor) const { +void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { std::map m; m["name"] = message_descriptor.name(); m["full_name"] = message_descriptor.full_name(); m["file"] = kDescriptorKey; - PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kCreate); + PrintNestedDescriptors(message_descriptor); printer_->Print("\n"); printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", @@ -823,41 +671,14 @@ void Generator::PrintCreateDescriptor( printer_->Print(")\n"); } -void Generator::PrintFindDescriptor( - const Descriptor& message_descriptor) const { - std::map m; - m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); - m["name"] = message_descriptor.name(); - - if (message_descriptor.containing_type()) { - m["containing_type"] = - ModuleLevelDescriptorName(*message_descriptor.containing_type()); - printer_->Print(m, - "$descriptor_name$ = " - "$containing_type$.nested_types_by_name['$name$']\n"); - } else { - m["file"] = kDescriptorKey; - printer_->Print( - m, "$descriptor_name$ = $file$.message_types_by_name['$name$']\n"); - } - - PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kFind); -} - // Prints Python Descriptor objects for all nested types contained in // message_descriptor. // // Mutually recursive with PrintDescriptor(). -void Generator::PrintNestedDescriptors(const Descriptor& containing_descriptor, - StripPrintDescriptor print_mode) const { - if (print_mode == StripPrintDescriptor::kCreate) { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintCreateDescriptor(*containing_descriptor.nested_type(i)); - } - } else { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintFindDescriptor(*containing_descriptor.nested_type(i)); - } +void Generator::PrintNestedDescriptors( + const Descriptor& containing_descriptor) const { + for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { + PrintDescriptor(*containing_descriptor.nested_type(i)); } } diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index 3b4c1323bdd2f..a77cf33803cf8 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -40,6 +40,7 @@ #include #include +// Must be included last. #include namespace google { @@ -59,8 +60,6 @@ class Printer; namespace compiler { namespace python { -enum class StripPrintDescriptor { kCreate, kFind }; - // CodeGenerator implementation for generated Python protocol buffer classes. // If you create your own protocol compiler binary and you want it to support // Python output, you can do so by registering an instance of this @@ -68,7 +67,7 @@ enum class StripPrintDescriptor { kCreate, kFind }; class PROTOC_EXPORT Generator : public CodeGenerator { public: Generator(); - virtual ~Generator(); + ~Generator() override; // CodeGenerator methods. bool Generate(const FileDescriptor* file, const std::string& parameter, @@ -80,14 +79,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { private: void PrintImports() const; void PrintFileDescriptor() const; - void PrintTopLevelEnums() const; - void PrintAllNestedEnumsInFile(StripPrintDescriptor print_mode) const; - void PrintNestedEnums(const Descriptor& descriptor, - StripPrintDescriptor print_mode) const; - void PrintCreateEnum(const EnumDescriptor& enum_descriptor) const; - void PrintFindEnum(const EnumDescriptor& enum_descriptor) const; - - void PrintTopLevelExtensions() const; + void PrintAllNestedEnumsInFile() const; + void PrintNestedEnums(const Descriptor& descriptor) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; void PrintFieldDescriptor(const FieldDescriptor& field, bool is_extension) const; @@ -97,11 +91,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const; void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; - void PrintMessageDescriptors(StripPrintDescriptor print_mode) const; - void PrintCreateDescriptor(const Descriptor& message_descriptor) const; - void PrintFindDescriptor(const Descriptor& message_descriptor) const; - void PrintNestedDescriptors(const Descriptor& containing_descriptor, - StripPrintDescriptor print_mode) const; + void PrintMessageDescriptors() const; + void PrintDescriptor(const Descriptor& message_descriptor) const; + void PrintNestedDescriptors(const Descriptor& containing_descriptor) const; void PrintMessages() const; void PrintMessage(const Descriptor& message_descriptor, diff --git a/src/google/protobuf/compiler/python/python_helpers.cc b/src/google/protobuf/compiler/python/python_helpers.cc new file mode 100644 index 0000000000000..eae236f8f756a --- /dev/null +++ b/src/google/protobuf/compiler/python/python_helpers.cc @@ -0,0 +1,131 @@ +// 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 + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +// Returns the Python module name expected for a given .proto filename. +std::string ModuleName(const std::string& filename) { + std::string basename = StripProto(filename); + ReplaceCharacters(&basename, "-", '_'); + ReplaceCharacters(&basename, "/", '.'); + return basename + "_pb2"; +} + +std::string StrippedModuleName(const std::string& filename) { + std::string module_name = ModuleName(filename); + return module_name; +} + +// Keywords reserved by the Python language. +const char* const kKeywords[] = { + "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])); + +bool ContainsPythonKeyword(const std::string& module_name) { + std::vector tokens = Split(module_name, "."); + for (int i = 0; i < static_cast(tokens.size()); ++i) { + if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) { + return true; + } + } + return false; +} + +bool IsPythonKeyword(const std::string& name) { + return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd); +} + +std::string ResolveKeyword(const std::string& name) { + if (IsPythonKeyword(name)) { + return "globals()['" + name + "']"; + } + return name; +} + +std::string GetFileName(const FileDescriptor* file_des, + const std::string& suffix) { + std::string module_name = ModuleName(file_des->name()); + std::string filename = module_name; + ReplaceCharacters(&filename, ".", '/'); + filename += suffix; + return filename; +} + +bool HasGenericServices(const FileDescriptor* file) { + return file->service_count() > 0 && file->options().py_generic_services(); +} + +template +std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, + const std::string& separator) { + std::string name = descriptor.name(); + const Descriptor* parent = descriptor.containing_type(); + if (parent != nullptr) { + std::string prefix = NamePrefixedWithNestedTypes(*parent, separator); + if (separator == "." && IsPythonKeyword(name)) { + return "getattr(" + prefix + ", '" + name + "')"; + } else { + return prefix + separator + name; + } + } + if (separator == ".") { + name = ResolveKeyword(name); + } + return name; +} + +template std::string NamePrefixedWithNestedTypes( + const Descriptor& descriptor, const std::string& separator); +template std::string NamePrefixedWithNestedTypes( + const EnumDescriptor& descriptor, const std::string& separator); + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/python/python_helpers.h b/src/google/protobuf/compiler/python/python_helpers.h new file mode 100644 index 0000000000000..a68ceb1969dd6 --- /dev/null +++ b/src/google/protobuf/compiler/python/python_helpers.h @@ -0,0 +1,62 @@ +// 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_COMPILER_PYTHON_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ + +#include + +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + + +std::string ModuleName(const std::string& filename); +std::string StrippedModuleName(const std::string& filename); +bool ContainsPythonKeyword(const std::string& module_name); +bool IsPythonKeyword(const std::string& name); +std::string ResolveKeyword(const std::string& name); +std::string GetFileName(const FileDescriptor* file_des, + const std::string& suffix); +bool HasGenericServices(const FileDescriptor* file); + +template +std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, + const std::string& separator); + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc index 76ceef32a0af5..bc92b2319bfdc 100644 --- a/src/google/protobuf/compiler/python/python_plugin_unittest.cc +++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc @@ -55,11 +55,10 @@ namespace { class TestGenerator : public CodeGenerator { public: TestGenerator() {} - ~TestGenerator() {} + ~TestGenerator() override {} - 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 { TryInsert("test_pb2.py", "imports", context); TryInsert("test_pb2.py", "module_scope", context); TryInsert("test_pb2.py", "class_scope:foo.Bar", context); @@ -77,37 +76,6 @@ class TestGenerator : public CodeGenerator { } }; -// This test verifies that all the expected insertion points exist. It does -// not verify that they are correctly-placed; that would require actually -// compiling the output which is a bit more than I care to do for this test. -TEST(PythonPluginTest, PluginTest) { - GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto", - "syntax = \"proto2\";\n" - "package foo;\n" - "message Bar {\n" - " message Baz {}\n" - "}\n", - true)); - - compiler::CommandLineInterface cli; - cli.SetInputsAreProtoPathRelative(true); - - python::Generator python_generator; - TestGenerator test_generator; - cli.RegisterGenerator("--python_out", &python_generator, ""); - cli.RegisterGenerator("--test_out", &test_generator, ""); - - std::string proto_path = "-I" + TestTempDir(); - std::string python_out = "--python_out=" + TestTempDir(); - std::string test_out = "--test_out=" + TestTempDir(); - - const char* argv[] = {"protoc", proto_path.c_str(), python_out.c_str(), - test_out.c_str(), "test.proto"}; - - EXPECT_EQ(0, cli.Run(5, argv)); -} - -// This test verifies that the generated Python output uses regular imports (as // opposed to importlib) in the usual case where the .proto file paths do not // not contain any Python keywords. TEST(PythonPluginTest, ImportTest) { diff --git a/src/google/protobuf/compiler/python/python_pyi_generator.cc b/src/google/protobuf/compiler/python/python_pyi_generator.cc new file mode 100644 index 0000000000000..d78d76669e134 --- /dev/null +++ b/src/google/protobuf/compiler/python/python_pyi_generator.cc @@ -0,0 +1,558 @@ +// 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 + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +template +struct SortByName { + bool operator()(const DescriptorT* l, const DescriptorT* r) const { + return l->name() < r->name(); + } +}; + +PyiGenerator::PyiGenerator() : file_(nullptr) {} + +PyiGenerator::~PyiGenerator() {} + +void PyiGenerator::PrintItemMap( + const std::map& item_map) const { + for (const auto& entry : item_map) { + printer_->Print("$key$: $value$\n", "key", entry.first, "value", + entry.second); + } +} + +template +std::string PyiGenerator::ModuleLevelName(const DescriptorT& descriptor) const { + std::string name = NamePrefixedWithNestedTypes(descriptor, "."); + if (descriptor.file() != file_) { + std::string module_name = ModuleName(descriptor.file()->name()); + std::vector tokens = Split(module_name, "."); + name = "_" + tokens.back() + "." + name; + } + return name; +} + +struct ImportModules { + bool has_repeated = false; // _containers + bool has_iterable = false; // typing.Iterable + bool has_messages = false; // _message + bool has_enums = false; // _enum_type_wrapper + bool has_extendable = false; // _python_message + bool has_mapping = false; // typing.Mapping + bool has_optional = false; // typing.Optional + bool has_union = false; // typing.Uion +}; + +// Checks what modules should be imported for this message +// descriptor. +void CheckImportModules(const Descriptor* descriptor, + ImportModules* import_modules) { + if (descriptor->extension_range_count() > 0) { + import_modules->has_extendable = true; + } + if (descriptor->enum_type_count() > 0) { + import_modules->has_enums = true; + } + for (int i = 0; i < descriptor->field_count(); ++i) { + const FieldDescriptor* field = descriptor->field(i); + if (IsPythonKeyword(field->name())) { + continue; + } + import_modules->has_optional = true; + if (field->is_repeated()) { + import_modules->has_repeated = true; + } + if (field->is_map()) { + import_modules->has_mapping = true; + const FieldDescriptor* value_des = field->message_type()->field(1); + if (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + value_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + import_modules->has_union = true; + } + } else { + if (field->is_repeated()) { + import_modules->has_iterable = true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + import_modules->has_union = true; + import_modules->has_mapping = true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + import_modules->has_union = true; + } + } + } + for (int i = 0; i < descriptor->nested_type_count(); ++i) { + CheckImportModules(descriptor->nested_type(i), import_modules); + } +} + +void PyiGenerator::PrintImports( + std::map* item_map) const { + // Prints imported dependent _pb2 files. + for (int i = 0; i < file_->dependency_count(); ++i) { + const std::string& filename = file_->dependency(i)->name(); + std::string module_name = StrippedModuleName(filename); + size_t last_dot_pos = module_name.rfind('.'); + std::string import_statement; + if (last_dot_pos == std::string::npos) { + import_statement = "import " + module_name; + } else { + import_statement = "from " + module_name.substr(0, last_dot_pos) + + " import " + module_name.substr(last_dot_pos + 1); + module_name = module_name.substr(last_dot_pos + 1); + } + printer_->Print("$statement$ as _$module_name$\n", "statement", + import_statement, "module_name", module_name); + } + + // Checks what modules should be imported. + ImportModules import_modules; + if (file_->message_type_count() > 0) { + import_modules.has_messages = true; + } + if (file_->enum_type_count() > 0) { + import_modules.has_enums = true; + } + for (int i = 0; i < file_->message_type_count(); i++) { + CheckImportModules(file_->message_type(i), &import_modules); + } + + // Prints modules (e.g. _containers, _messages, typing) that are + // required in the proto file. + if (import_modules.has_repeated) { + printer_->Print( + "from google.protobuf.internal import containers as " + "_containers\n"); + } + if (import_modules.has_enums) { + printer_->Print( + "from google.protobuf.internal import enum_type_wrapper" + " as _enum_type_wrapper\n"); + } + if (import_modules.has_extendable) { + printer_->Print( + "from google.protobuf.internal import python_message" + " as _python_message\n"); + } + printer_->Print( + "from google.protobuf import" + " descriptor as _descriptor\n"); + if (import_modules.has_messages) { + printer_->Print( + "from google.protobuf import message as _message\n"); + } + if (HasGenericServices(file_)) { + printer_->Print( + "from google.protobuf import service as" + " _service\n"); + } + printer_->Print("from typing import "); + printer_->Print("ClassVar"); + if (import_modules.has_iterable) { + printer_->Print(", Iterable"); + } + if (import_modules.has_mapping) { + printer_->Print(", Mapping"); + } + if (import_modules.has_optional) { + printer_->Print(", Optional"); + } + if (file_->service_count() > 0) { + printer_->Print(", Text"); + } + if (import_modules.has_union) { + printer_->Print(", Union"); + } + printer_->Print("\n\n"); + + // Public imports + for (int i = 0; i < file_->public_dependency_count(); ++i) { + const FileDescriptor* public_dep = file_->public_dependency(i); + std::string module_name = StrippedModuleName(public_dep->name()); + // Top level messages in public imports + for (int i = 0; i < public_dep->message_type_count(); ++i) { + printer_->Print("from $module$ import $message_class$\n", "module", + module_name, "message_class", + public_dep->message_type(i)->name()); + } + // Top level enums for public imports + for (int i = 0; i < public_dep->enum_type_count(); ++i) { + printer_->Print("from $module$ import $enum_class$\n", "module", + module_name, "enum_class", + public_dep->enum_type(i)->name()); + } + // Enum values for public imports + for (int i = 0; i < public_dep->enum_type_count(); ++i) { + const EnumDescriptor* enum_descriptor = public_dep->enum_type(i); + for (int j = 0; j < enum_descriptor->value_count(); ++j) { + (*item_map)[enum_descriptor->value(j)->name()] = + ModuleLevelName(*enum_descriptor); + } + } + // Top level extensions for public imports + AddExtensions(*public_dep, item_map); + } +} + +void PyiGenerator::PrintEnum(const EnumDescriptor& enum_descriptor) const { + std::string enum_name = enum_descriptor.name(); + printer_->Print( + "class $enum_name$(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):\n" + " __slots__ = []\n", + "enum_name", enum_name); +} + +// Adds enum value to item map which will be ordered and printed later. +void PyiGenerator::AddEnumValue( + const EnumDescriptor& enum_descriptor, + std::map* item_map) const { + // enum values + std::string module_enum_name = ModuleLevelName(enum_descriptor); + for (int j = 0; j < enum_descriptor.value_count(); ++j) { + const EnumValueDescriptor* value_descriptor = enum_descriptor.value(j); + (*item_map)[value_descriptor->name()] = module_enum_name; + } +} + +// Prints top level enums +void PyiGenerator::PrintTopLevelEnums() const { + for (int i = 0; i < file_->enum_type_count(); ++i) { + printer_->Print("\n"); + PrintEnum(*file_->enum_type(i)); + } +} + +// Add top level extensions to item_map which will be ordered and +// printed later. +template +void PyiGenerator::AddExtensions( + const DescriptorT& descriptor, + std::map* item_map) const { + for (int i = 0; i < descriptor.extension_count(); ++i) { + const FieldDescriptor* extension_field = descriptor.extension(i); + std::string constant_name = extension_field->name() + "_FIELD_NUMBER"; + ToUpper(&constant_name); + (*item_map)[constant_name] = "ClassVar[int]"; + (*item_map)[extension_field->name()] = "_descriptor.FieldDescriptor"; + } +} + +// Returns the string format of a field's cpp_type +std::string PyiGenerator::GetFieldType(const FieldDescriptor& field_des) const { + switch (field_des.cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + return "int"; + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + return "float"; + case FieldDescriptor::CPPTYPE_BOOL: + return "bool"; + case FieldDescriptor::CPPTYPE_ENUM: + return ModuleLevelName(*field_des.enum_type()); + case FieldDescriptor::CPPTYPE_STRING: + if (field_des.type() == FieldDescriptor::TYPE_STRING) { + return "str"; + } else { + return "bytes"; + } + case FieldDescriptor::CPPTYPE_MESSAGE: + return ModuleLevelName(*field_des.message_type()); + default: + GOOGLE_LOG(FATAL) << "Unsuppoted field type."; + } + return ""; +} + +void PyiGenerator::PrintMessage(const Descriptor& message_descriptor, + bool is_nested) const { + if (!is_nested) { + printer_->Print("\n"); + } + std::string class_name = message_descriptor.name(); + printer_->Print("class $class_name$(_message.Message):\n", "class_name", + class_name); + printer_->Indent(); + printer_->Indent(); + + std::vector fields; + fields.reserve(message_descriptor.field_count()); + for (int i = 0; i < message_descriptor.field_count(); ++i) { + fields.push_back(message_descriptor.field(i)); + } + std::sort(fields.begin(), fields.end(), SortByName()); + + // Prints slots + printer_->Print("__slots__ = [", "class_name", class_name); + bool first_item = true; + for (const auto& field_des : fields) { + if (IsPythonKeyword(field_des->name())) { + continue; + } + if (first_item) { + first_item = false; + } else { + printer_->Print(", "); + } + printer_->Print("\"$field_name$\"", "field_name", field_des->name()); + } + printer_->Print("]\n"); + + std::map item_map; + // Prints Extensions for extendable messages + if (message_descriptor.extension_range_count() > 0) { + item_map["Extensions"] = "_python_message._ExtensionDict"; + } + + // Prints nested enums + std::vector nested_enums; + nested_enums.reserve(message_descriptor.enum_type_count()); + for (int i = 0; i < message_descriptor.enum_type_count(); ++i) { + nested_enums.push_back(message_descriptor.enum_type(i)); + } + std::sort(nested_enums.begin(), nested_enums.end(), + SortByName()); + + for (const auto& entry : nested_enums) { + PrintEnum(*entry); + // Adds enum value to item_map which will be ordered and printed later + AddEnumValue(*entry, &item_map); + } + + // Prints nested messages + std::vector nested_messages; + nested_messages.reserve(message_descriptor.nested_type_count()); + for (int i = 0; i < message_descriptor.nested_type_count(); ++i) { + nested_messages.push_back(message_descriptor.nested_type(i)); + } + std::sort(nested_messages.begin(), nested_messages.end(), + SortByName()); + + for (const auto& entry : nested_messages) { + PrintMessage(*entry, true); + } + + // Adds extensions to item_map which will be ordered and printed later + AddExtensions(message_descriptor, &item_map); + + // Adds field number and field descriptor to item_map + for (int i = 0; i < message_descriptor.field_count(); ++i) { + const FieldDescriptor& field_des = *message_descriptor.field(i); + item_map[ToUpper(field_des.name()) + "_FIELD_NUMBER"] = + "ClassVar[int]"; + if (IsPythonKeyword(field_des.name())) { + continue; + } + std::string field_type = ""; + if (field_des.is_map()) { + const FieldDescriptor* key_des = field_des.message_type()->field(0); + const FieldDescriptor* value_des = field_des.message_type()->field(1); + field_type = (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + ? "_containers.MessageMap[" + : "_containers.ScalarMap["); + field_type += GetFieldType(*key_des); + field_type += ", "; + field_type += GetFieldType(*value_des); + } else { + if (field_des.is_repeated()) { + field_type = (field_des.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + ? "_containers.RepeatedCompositeFieldContainer[" + : "_containers.RepeatedScalarFieldContainer["); + } + field_type += GetFieldType(field_des); + } + + if (field_des.is_repeated()) { + field_type += "]"; + } + item_map[field_des.name()] = field_type; + } + + // Prints all items in item_map + PrintItemMap(item_map); + + // Prints __init__ + printer_->Print("def __init__(self"); + bool has_key_words = false; + bool is_first = true; + for (int i = 0; i < message_descriptor.field_count(); ++i) { + const FieldDescriptor* field_des = message_descriptor.field(i); + if (IsPythonKeyword(field_des->name())) { + has_key_words = true; + continue; + } + std::string field_name = field_des->name(); + if (is_first && field_name == "self") { + // See b/144146793 for an example of real code that generates a (self, + // self) method signature. Since repeating a parameter name is illegal in + // Python, we rename the duplicate self. + field_name = "self_"; + } + is_first = false; + printer_->Print(", $field_name$: ", "field_name", field_name); + if (field_des->is_repeated() || + field_des->cpp_type() != FieldDescriptor::CPPTYPE_BOOL) { + printer_->Print("Optional["); + } + if (field_des->is_map()) { + const Descriptor* map_entry = field_des->message_type(); + printer_->Print("Mapping[$key_type$, $value_type$]", "key_type", + GetFieldType(*map_entry->field(0)), "value_type", + GetFieldType(*map_entry->field(1))); + } else { + if (field_des->is_repeated()) { + printer_->Print("Iterable["); + } + if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer_->Print("Union[$type_name$, Mapping]", "type_name", + GetFieldType(*field_des)); + } else { + if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer_->Print("Union[$type_name$, str]", "type_name", + ModuleLevelName(*field_des->enum_type())); + } else { + printer_->Print("$type_name$", "type_name", GetFieldType(*field_des)); + } + } + if (field_des->is_repeated()) { + printer_->Print("]"); + } + } + if (field_des->is_repeated() || + field_des->cpp_type() != FieldDescriptor::CPPTYPE_BOOL) { + printer_->Print("]"); + } + printer_->Print(" = ..."); + } + if (has_key_words) { + printer_->Print(", **kwargs"); + } + printer_->Print(") -> None: ...\n"); + + printer_->Outdent(); + printer_->Outdent(); +} + +void PyiGenerator::PrintMessages() const { + // Order the descriptors by name to have same output with proto_to_pyi.py + std::vector messages; + messages.reserve(file_->message_type_count()); + for (int i = 0; i < file_->message_type_count(); ++i) { + messages.push_back(file_->message_type(i)); + } + std::sort(messages.begin(), messages.end(), SortByName()); + + for (const auto& entry : messages) { + PrintMessage(*entry, false); + } +} + +void PyiGenerator::PrintServices() const { + std::vector services; + services.reserve(file_->service_count()); + for (int i = 0; i < file_->service_count(); ++i) { + services.push_back(file_->service(i)); + } + std::sort(services.begin(), services.end(), SortByName()); + + // Prints $Service$ and $Service$_Stub classes + for (const auto& entry : services) { + printer_->Print("\n"); + printer_->Print( + "class $service_name$(_service.service): ...\n\n" + "class $service_name$_Stub($service_name$): ...\n", + "service_name", entry->name()); + } +} + +bool PyiGenerator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* context, + std::string* error) const { + MutexLock lock(&mutex_); + // Calculate file name. + file_ = file; + // proto_to_pyi.py may set the output file name directly. To replace + // proto_to_pyi.py in google3, protoc also accept --pyi_out to set + // the output file name. + std::string filename = + parameter.empty() ? GetFileName(file, ".pyi") : parameter; + + std::unique_ptr output(context->Open(filename)); + GOOGLE_CHECK(output.get()); + io::Printer printer(output.get(), '$'); + printer_ = &printer; + + // item map will store "DESCRIPTOR", top level extensions, top level enum + // values. The items will be sorted and printed later. + std::map item_map; + + // Adds "DESCRIPTOR" into item_map. + item_map["DESCRIPTOR"] = "_descriptor.FileDescriptor"; + PrintImports(&item_map); + // Adds top level enum values to item_map. + for (int i = 0; i < file_->enum_type_count(); ++i) { + AddEnumValue(*file_->enum_type(i), &item_map); + } + // Adds top level extensions to item_map. + AddExtensions(*file_, &item_map); + // Prints item map + PrintItemMap(item_map); + + PrintMessages(); + PrintTopLevelEnums(); + if (HasGenericServices(file)) { + PrintServices(); + } + return true; +} + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/python/python_pyi_generator.h b/src/google/protobuf/compiler/python/python_pyi_generator.h new file mode 100644 index 0000000000000..5d382be1be095 --- /dev/null +++ b/src/google/protobuf/compiler/python/python_pyi_generator.h @@ -0,0 +1,104 @@ +// 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: jieluo@google.com (Jie Luo) +// +// Generates Python stub (.pyi) for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ + +#include +#include + +#include +#include + +// Must be included last. +#include + +namespace google { +namespace protobuf { +class Descriptor; +class EnumDescriptor; +class FieldDescriptor; +class MethodDescriptor; +class ServiceDescriptor; + +namespace io { +class Printer; +} + +namespace compiler { +namespace python { + +class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenerator { + public: + PyiGenerator(); + ~PyiGenerator() override; + + // CodeGenerator methods. + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + + private: + void PrintImports(std::map* item_map) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; + void AddEnumValue(const EnumDescriptor& enum_descriptor, + std::map* item_map) const; + void PrintTopLevelEnums() const; + template + void AddExtensions(const DescriptorT& descriptor, + std::map* item_map) const; + void PrintMessages() const; + void PrintMessage(const Descriptor& message_descriptor, bool is_nested) const; + void PrintServices() const; + void PrintItemMap(const std::map& item_map) const; + std::string GetFieldType(const FieldDescriptor& field_des) const; + template + std::string ModuleLevelName(const DescriptorT& descriptor) const; + + // Very coarse-grained lock to ensure that Generate() is reentrant. + // Guards file_ and printer_. + mutable Mutex mutex_; + mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PyiGenerator); +}; + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb index 4cf4866cfa383..256ac7c153a3f 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb @@ -1,9 +1,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ruby_generated_code.proto -require 'ruby_generated_code_proto2_import_pb' require 'google/protobuf' +require 'ruby_generated_code_proto2_import_pb' + Google::Protobuf::DescriptorPool.generated_pool.build do add_file("ruby_generated_code.proto", :syntax => :proto3) do add_message "A.B.C.TestMessage" do diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb index e331e9b2b3eb3..44d31969eca4f 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb @@ -1,9 +1,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ruby_generated_code_proto2.proto -require 'ruby_generated_code_proto2_import_pb' require 'google/protobuf' +require 'ruby_generated_code_proto2_import_pb' + Google::Protobuf::DescriptorPool.generated_pool.build do add_file("ruby_generated_code_proto2.proto", :syntax => :proto2) do add_message "A.B.C.TestMessage" do diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index c1a5c67d2ac23..2bda45935188f 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -421,7 +421,7 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { // -> A.B.C if (package_name.find("::") != std::string::npos) { need_change_to_module = false; - } else { + } else if (package_name.find(".") != std::string::npos) { GOOGLE_LOG(WARNING) << "ruby_package option should be in the form of:" << " 'A::B::C' and not 'A.B.C'"; } @@ -467,8 +467,6 @@ void EndPackageModules(int levels, io::Printer* printer) { bool GenerateDslDescriptor(const FileDescriptor* file, io::Printer* printer, std::string* error) { - printer->Print( - "require 'google/protobuf'\n\n"); printer->Print("Google::Protobuf::DescriptorPool.generated_pool.build do\n"); printer->Indent(); printer->Print("add_file(\"$filename$\", :syntax => :$syntax$) do\n", @@ -509,8 +507,13 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, "\n", "filename", file->name()); - for (int i = 0; i < file->dependency_count(); i++) { - printer->Print("require '$name$'\n", "name", GetRequireName(file->dependency(i)->name())); + printer->Print("require 'google/protobuf'\n\n"); + + if (file->dependency_count() != 0) { + for (int i = 0; i < file->dependency_count(); i++) { + printer->Print("require '$name$'\n", "name", GetRequireName(file->dependency(i)->name())); + } + printer->Print("\n"); } // TODO: Remove this when ruby supports extensions for proto2 syntax. diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index 040b6c981cb29..c3ce1d368469c 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -57,7 +57,7 @@ std::string FindRubyTestDir() { // Some day, we may integrate build systems between protoc and the language // extensions to the point where we can do this test in a more automated way. -void RubyTest(string proto_file, string import_proto_file = "") { +void RubyTest(std::string proto_file, std::string import_proto_file = "") { std::string ruby_tests = FindRubyTestDir(); google::protobuf::compiler::CommandLineInterface cli; diff --git a/src/google/protobuf/compiler/scc.h b/src/google/protobuf/compiler/scc.h index a1394602f78c2..7b95689d7ac6e 100644 --- a/src/google/protobuf/compiler/scc.h +++ b/src/google/protobuf/compiler/scc.h @@ -37,6 +37,7 @@ #include #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc index 7e59cd7d8d26c..f79d127fc51e0 100644 --- a/src/google/protobuf/compiler/subprocess.cc +++ b/src/google/protobuf/compiler/subprocess.cc @@ -55,7 +55,7 @@ namespace compiler { namespace { char* portable_strdup(const char* s) { char* ns = (char*)malloc(strlen(s) + 1); - if (ns != NULL) { + if (ns != nullptr) { strcpy(ns, s); } return ns; @@ -309,7 +309,7 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { GOOGLE_CHECK(pipe(stdin_pipe) != -1); GOOGLE_CHECK(pipe(stdout_pipe) != -1); - char* argv[2] = {portable_strdup(program.c_str()), NULL}; + char* argv[2] = {portable_strdup(program.c_str()), nullptr}; child_pid_ = fork(); if (child_pid_ == -1) { @@ -386,7 +386,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, FD_SET(child_stdin_, &write_fds); } - if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) { + if (select(max_fd + 1, &read_fds, &write_fds, nullptr, nullptr) < 0) { if (errno == EINTR) { // Interrupted by signal. Try again. continue; diff --git a/src/google/protobuf/compiler/subprocess.h b/src/google/protobuf/compiler/subprocess.h index c1ddaae531ded..5cb784d467bd5 100644 --- a/src/google/protobuf/compiler/subprocess.h +++ b/src/google/protobuf/compiler/subprocess.h @@ -46,6 +46,7 @@ #include +// Must be included last. #include namespace google { diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index c8ce218a981d1..a2552f67ec8c3 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -50,21 +51,21 @@ #include #include #include +#include #include #include -#include #include #include #include +#include +#include #include #include #include +#include +#include #include #include -#include -#include -#include -#include #include #include #include @@ -72,11 +73,443 @@ #undef PACKAGE // autoheader #defines this. :( +// Must be included last. #include namespace google { namespace protobuf { +namespace { +const int kPackageLimit = 100; + +// Note: I distrust ctype.h due to locales. +char ToUpper(char ch) { + return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch; +} + +char ToLower(char ch) { + return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch; +} + +std::string ToCamelCase(const std::string& input, bool lower_first) { + bool capitalize_next = !lower_first; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(ToUpper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + // Lower-case the first letter. + if (lower_first && !result.empty()) { + result[0] = ToLower(result[0]); + } + + return result; +} + +std::string ToJsonName(const std::string& input) { + bool capitalize_next = false; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(ToUpper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + return result; +} + +// Backport of fold expressions for the comma operator to C++11. +// Usage: Fold({expr...}); +// Guaranteed to evaluate left-to-right +struct ExpressionEater { + template + ExpressionEater(T&&) {} // NOLINT +}; +void Fold(std::initializer_list) {} + +constexpr size_t RoundUp(size_t n) { return (n + 7) & ~7; } + +template +constexpr int FindTypeIndex() { + return -1; +} + +template +constexpr int FindTypeIndex() { + return std::is_same::value ? 0 : FindTypeIndex() + 1; +} + +// A type to value map, where the possible keys as specified in `Keys...`. +// The values for key `K` is `ValueT` +template