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/.gitignore b/.gitignore index b9d795ce4cd45..4fe3edde37aa4 100644 --- a/.gitignore +++ b/.gitignore @@ -215,5 +215,14 @@ _build/ .idea *.iml +# Eclipse +**/.settings +**/.project +**/.classpath + # BenchmarkDotNet BenchmarkDotNet.Artifacts/ + +# Clangd uses these common ephemeral files +.cache +compile_commands.json diff --git a/BUILD b/BUILD index 1690d421984ea..887e5e3845f21 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,9 +28,7 @@ ZLIB_DEPS = ["@zlib//:zlib"] ################################################################################ MSVC_COPTS = [ - "/wd4018", # -Wno-sign-compare "/wd4065", # switch statement contains 'default' but no 'case' labels - "/wd4146", # unary minus operator applied to unsigned type, result still unsigned "/wd4244", # 'conversion' conversion from 'type1' to 'type2', possible loss of data "/wd4251", # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' "/wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data @@ -46,7 +46,6 @@ COPTS = select({ ":msvc": MSVC_COPTS, "//conditions:default": [ "-DHAVE_ZLIB", - "-Wmissing-field-initializers", "-Woverloaded-virtual", "-Wno-sign-compare", ], @@ -147,6 +146,7 @@ load( "adapt_proto_library", "cc_proto_library", "internal_copied_filegroup", + "internal_gen_kt_protos", "internal_gen_well_known_protos_java", "internal_protobuf_py_tests", "py_proto_library", @@ -161,7 +161,6 @@ cc_library( "src/google/protobuf/arenastring.cc", "src/google/protobuf/extension_set.cc", "src/google/protobuf/generated_enum_util.cc", - "src/google/protobuf/generated_message_table_driven_lite.cc", "src/google/protobuf/generated_message_tctable_lite.cc", "src/google/protobuf/generated_message_util.cc", "src/google/protobuf/implicit_weak_message.cc", @@ -223,7 +222,6 @@ cc_library( "src/google/protobuf/field_mask.pb.cc", "src/google/protobuf/generated_message_bases.cc", "src/google/protobuf/generated_message_reflection.cc", - "src/google/protobuf/generated_message_table_driven.cc", "src/google/protobuf/generated_message_tctable_full.cc", "src/google/protobuf/io/gzip_stream.cc", "src/google/protobuf/io/printer.cc", @@ -499,6 +497,8 @@ cc_library( "src/google/protobuf/compiler/plugin.cc", "src/google/protobuf/compiler/plugin.pb.cc", "src/google/protobuf/compiler/python/python_generator.cc", + "src/google/protobuf/compiler/python/python_helpers.cc", + "src/google/protobuf/compiler/python/python_pyi_generator.cc", "src/google/protobuf/compiler/ruby/ruby_generator.cc", "src/google/protobuf/compiler/subprocess.cc", "src/google/protobuf/compiler/zip_writer.cc", @@ -518,6 +518,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 ################################################################################ @@ -590,6 +654,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", @@ -826,6 +892,23 @@ internal_gen_well_known_protos_java( deps = [proto + "_proto" for proto in LITE_WELL_KNOWN_PROTO_MAP.keys()], ) +internal_gen_kt_protos( + name = "gen_well_known_protos_kotlin", + visibility = [ + "//java:__subpackages__", + ], + deps = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], +) + +internal_gen_kt_protos( + name = "gen_well_known_protos_kotlinlite", + visibility = [ + "//java:__subpackages__", + ], + lite = True, + deps = [proto + "_proto" for proto in LITE_WELL_KNOWN_PROTO_MAP.keys()], +) + alias( name = "protobuf_java", actual = "//java/core", @@ -1116,7 +1199,7 @@ proto_library( name = "generated_protos_proto", srcs = [ "src/google/protobuf/unittest_import_public.proto", - "unittest_gen.proto", + "unittest_gen_import.proto", ], ) @@ -1124,7 +1207,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", @@ -1254,6 +1337,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 = [ @@ -1347,3 +1443,63 @@ filegroup( srcs = glob(["**/*.bzl"]), visibility = ["//visibility:public"], ) + +# Kotlin proto rules + +proto_library( + name = "kt_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", + ], + strip_import_prefix = "src", +) + +internal_gen_kt_protos( + name = "gen_kotlin_unittest_lite", + deps = [":kt_unittest_lite"], + lite = True, + visibility = ["//java:__subpackages__"], +) + +proto_library( + name = "kt_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", + ], + strip_import_prefix = "src", +) + +internal_gen_kt_protos( + name = "gen_kotlin_unittest", + deps = [":kt_unittest"], + visibility = ["//java:__subpackages__"], +) + +proto_library( + name = "kt_proto3_unittest", + srcs = [ + "src/google/protobuf/unittest_proto3.proto", + "src/google/protobuf/unittest_import.proto", + "src/google/protobuf/unittest_import_public.proto", + ], + strip_import_prefix = "src", +) + +internal_gen_kt_protos( + name = "gen_kotlin_proto3_unittest_lite", + deps = [":kt_proto3_unittest"], + lite = True, + visibility = ["//java:__subpackages__"], +) + +internal_gen_kt_protos( + name = "gen_kotlin_proto3_unittest", + deps = [":kt_proto3_unittest"], + visibility = ["//java:__subpackages__"], +) diff --git a/CHANGES.txt b/CHANGES.txt index b3c43613f18e8..349f81785046a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,133 @@ +2022-03-04 version 3.20.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Dropped Ruby 2.3 and 2.4 support for CI and releases. (#9311) + * Added Ruby 3.1 support for CI and releases (#9566). + * Message.decode/encode: Add recursion_limit option (#9218/#9486) + * Allocate with xrealloc()/xfree() so message allocation is visible to the + Ruby GC. In certain tests this leads to much lower memory usage due to more + frequent GC runs (#9586). + * Fix conversion of singleton classes in Ruby (#9342) + * Suppress warning for intentional circular require (#9556) + * 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. + + Java + * Revert "Standardize on Array copyOf" (#9400) + * Resolve more java field accessor name conflicts (#8198) + * Don't support map fields in DynamicMessage.Builder.{getFieldBuilder,getRepeatedFieldBuilder} + * Fix parseFrom to only throw InvalidProtocolBufferException + * InvalidProtocolBufferException now allows arbitrary wrapped Exception types. + * Fix bug in `FieldSet.Builder.mergeFrom` + * Flush CodedOutputStream also flushes underlying OutputStream + * When oneof case is the same and the field type is Message, merge the + subfield. (previously it was replaced.)’ + * Add @CheckReturnValue to some protobuf types + * Report original exceptions when parsing JSON + * Add more info to @deprecated javadoc for set/get/has methods + * Fix initialization bug in doc comment line numbers + * Fix comments for message set wire format. + + Kotlin + * Add test scope to kotlin-test for protobuf-kotlin-lite (#9518) + * Add orNull extensions for optional message fields. + * Add orNull extensions to all proto3 message fields. + + Python + * Dropped support for Python < 3.7 (#9480) + * Protoc is now able to generate python stubs (.pyi) with --pyi_out + * Pin multibuild scripts to get manylinux1 wheels back (#9216) + * Fix type annotations of some Duration and Timestamp methods. + * Repeated field containers are now generic in field types and could be used + in type annotations. + * Protobuf python generated codes are simplified. Descriptors and message + classes' definitions are now dynamic created in internal/builder.py. + Insertion Points for messages classes are discarded. + * has_presence is added for FieldDescriptor in python + * Loosen indexing type requirements to allow valid __index__() implementations + rather than only PyLongObjects. + * Fix the deepcopy bug caused by not copying message_listener. + * Added python JSON parse recursion limit (default 100) + * Path info is added for python JSON parse errors + * Pure python repeated scalar fields will not able to pickle. Convert to list + first. + * Timestamp.ToDatetime() now accepts an optional tzinfo parameter. If + specified, the function returns a timezone-aware datetime in the given time + zone. If omitted or None, the function returns a timezone-naive UTC datetime + (as previously). + * Adds client_streaming and server_streaming fields to MethodDescriptor. + * Add "ensure_ascii" parameter to json_format.MessageToJson. This allows smaller + JSON serializations with UTF-8 or other non-ASCII encodings. + * Added experimental support for directly assigning numpy scalars and array. + * Improve the calculation of public_dependencies in DescriptorPool. + + Compiler + * Migrate IsDefault(const std::string*) and UnsafeSetDefault(const std::string*) + * Implement strong qualified tags for TaggedPtr + * Rework allocations to power-of-two byte sizes. + * Migrate IsDefault(const std::string*) and UnsafeSetDefault(const std::string*) + * Implement strong qualified tags for TaggedPtr + * Make TaggedPtr Set...() calls explicitly spell out the content type. + * Check for parsing error before verifying UTF8. + * Enforce a maximum message nesting limit of 32 in the descriptor builder to + guard against stack overflows + * Fixed bugs in operators for RepeatedPtrIterator + * Assert a maximum map alignment for allocated values + * Fix proto1 group extension protodb parsing error + * Do not log/report the same descriptor symbol multiple times if it contains + more than one invalid character. + * Add UnknownFieldSet::SerializeToString and SerializeToCodedStream. + * Remove explicit default pointers and deprecated API from protocol compiler + + Arenas + * Change Repeated*Field to reuse memory when using arenas. + * Implements pbarenaz for profiling proto arenas + * Introduce CreateString() and CreateArenaString() for cleaner semantics + * Fix unreferenced parameter for MSVC builds + * Add UnsafeSetAllocated to be used for one-of string fields. + * Make Arena::AllocateAligned() a public function. + * Determine if ArenaDtor related code generation is necessary in one place. + * Implement on demand register ArenaDtor for InlinedStringField + + C++ + * Enable testing via CTest (#8737) + * Add option to use external GTest in CMake (#8736) + * CMake: Set correct sonames for libprotobuf-lite.so and libprotoc.so (#8635) (#9529) + * Add cmake option `protobuf_INSTALL` to not install files (#7123) + * CMake: Allow custom plugin options e.g. to generate mocks (#9105) + * CMake: Use linker version scripts (#9545) + * Manually *struct Cord fields to work better with arenas. + * Manually destruct map fields. + * Generate narrower code + * Fix https://github.com/protocolbuffers/protobuf/issues/9378 by removing + shadowed _cached_size_ field + * Remove GetPointer() and explicit nullptr defaults. + * Add proto_h flag for speeding up large builds + * Add missing overload for reference wrapped fields. + * Add MergedDescriptorDatabase::FindAllFileNames() + * RepeatedField now defines an iterator type instead of using a pointer. + * Remove obsolete macros GOOGLE_PROTOBUF_HAS_ONEOF and GOOGLE_PROTOBUF_HAS_ARENAS. + + PHP + * Fix: add missing reserved classnames (#9458) + * PHP 8.1 compatibility (#9370) + + C# + * Fix trim warnings (#9182) + * Fixes NullReferenceException when accessing FieldDescriptor.IsPacked (#9430) + * Add ToProto() method to all descriptor classes (#9426) + * Add an option to preserve proto names in JsonFormatter (#6307) + + Objective-C + * Add prefix_to_proto_package_mappings_path option. (#9498) + * Rename `proto_package_to_prefix_mappings_path` to `package_to_prefix_mappings_path`. (#9552) + * Add a generation option to control use of forward declarations in headers. (#9568) + 2022-01-28 version 3.19.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) Python @@ -10,7 +140,7 @@ 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 @@ -20,6 +150,22 @@ 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) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b8d97fc23d85b..c2da98f2c6c9d 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -100,3 +100,8 @@ Patch contributors: Andrew Paprocki * Fixed minor IBM xlC compiler build issues * Added atomicops for AIX (POWER) + Nipunn Koorapati + * Provide a type alias field ValueType on EnumTypeWrapper + * Match service argument names to abstract interface + + diff --git a/Makefile.am b/Makefile.am index 41d4061a98e66..c6787cc0554ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,6 +54,7 @@ csharp_EXTRA_DIST= \ csharp/CHANGES.txt \ csharp/Google.Protobuf.Tools.targets \ csharp/Google.Protobuf.Tools.nuspec \ + csharp/NuGet.Config \ csharp/README.md \ csharp/build_packages.bat \ csharp/build_tools.sh \ @@ -181,10 +182,14 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/Collections/ProtobufEqualityComparers.cs \ csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs \ csharp/src/Google.Protobuf/Collections/RepeatedField.cs \ + csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs \ + csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs \ csharp/src/Google.Protobuf/Compatibility/MethodInfoExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs \ + csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs \ csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \ + csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs \ csharp/src/Google.Protobuf/Extension.cs \ csharp/src/Google.Protobuf/ExtensionRegistry.cs \ csharp/src/Google.Protobuf/ExtensionSet.cs \ @@ -303,6 +308,7 @@ java_EXTRA_DIST= java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java \ java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \ java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java \ + java/core/src/main/java/com/google/protobuf/CompileTimeConstant.java \ java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java \ java/core/src/main/java/com/google/protobuf/Descriptors.java \ java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java \ @@ -326,6 +332,7 @@ java_EXTRA_DIST= java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java \ java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java \ java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java \ + java/core/src/main/java/com/google/protobuf/InlineMe.java \ java/core/src/main/java/com/google/protobuf/IntArrayList.java \ java/core/src/main/java/com/google/protobuf/Internal.java \ java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \ @@ -437,9 +444,9 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java \ java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java \ java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java \ - java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \ java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java \ java/core/src/test/java/com/google/protobuf/IntArrayListTest.java \ + java/core/src/test/java/com/google/protobuf/InvalidProtocolBufferExceptionTest.java \ java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java \ java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \ java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java \ @@ -464,15 +471,12 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2LiteSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2MessageFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto2MessageLiteFactory.java \ java/core/src/test/java/com/google/protobuf/Proto2SchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java \ java/core/src/test/java/com/google/protobuf/Proto3LiteSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto3MessageFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto3MessageLiteFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto3SchemaTest.java \ java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java \ java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java \ @@ -496,7 +500,6 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java \ java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \ java/core/src/test/java/com/google/protobuf/Utf8Test.java \ - java/core/src/test/java/com/google/protobuf/Utf8Utils.java \ java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java \ java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java \ java/core/src/test/java/com/google/protobuf/WireFormatTest.java \ @@ -505,6 +508,7 @@ java_EXTRA_DIST= java/core/src/test/proto/com/google/protobuf/any_test.proto \ java/core/src/test/proto/com/google/protobuf/cached_field_size_test.proto \ java/core/src/test/proto/com/google/protobuf/deprecated_file.proto \ + java/core/src/test/proto/com/google/protobuf/dynamic_message_test.proto \ java/core/src/test/proto/com/google/protobuf/field_presence_test.proto \ java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto \ java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto \ @@ -513,7 +517,6 @@ java_EXTRA_DIST= java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto \ java/core/src/test/proto/com/google/protobuf/map_lite_test.proto \ java/core/src/test/proto/com/google/protobuf/map_test.proto \ - java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto\ java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto \ java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto \ java/core/src/test/proto/com/google/protobuf/nested_extension.proto \ @@ -536,19 +539,22 @@ java_EXTRA_DIST= java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \ java/internal/BUILD \ java/internal/testing.bzl \ + java/kotlin/BUILD \ java/kotlin/generate-sources-build.xml \ java/kotlin/generate-test-sources-build.xml \ java/kotlin/pom.xml \ + java/kotlin/pom_template.xml \ + java/kotlin/src/main/kotlin/com/google/protobuf/Anies.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/ByteStrings.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslMap.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslProxy.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt \ - java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt\ java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt\ java/kotlin/src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt \ + java/kotlin/src/test/kotlin/com/google/protobuf/AniesTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt \ @@ -560,11 +566,14 @@ java_EXTRA_DIST= java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto3.proto \ java/kotlin/src/test/proto/com/google/protobuf/example_extensible_message.proto \ java/kotlin/src/test/proto/com/google/protobuf/multiple_files_proto3.proto \ + java/kotlin-lite/BUILD \ java/kotlin-lite/generate-sources-build.xml \ java/kotlin-lite/generate-test-sources-build.xml \ java/kotlin-lite/lite.awk \ java/kotlin-lite/pom.xml \ + java/kotlin-lite/pom_template.xml \ java/kotlin-lite/process-lite-sources-build.xml \ + java/kotlin-lite/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt\ java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt\ java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt \ java/lite.md \ @@ -576,7 +585,6 @@ java_EXTRA_DIST= java/lite/pom_template.xml \ java/lite/process-lite-sources-build.xml \ java/lite/src/test/java/com/google/protobuf/LiteTest.java \ - java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java \ java/BUILD \ java/pom.xml \ java/util/BUILD \ @@ -589,10 +597,12 @@ java_EXTRA_DIST= java/util/src/main/java/com/google/protobuf/util/Structs.java \ java/util/src/main/java/com/google/protobuf/util/Timestamps.java \ java/util/src/main/java/com/google/protobuf/util/Values.java \ + java/util/src/test/java/com/google/protobuf/util/DurationsTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \ java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \ java/util/src/test/java/com/google/protobuf/util/StructsTest.java \ + java/util/src/test/java/com/google/protobuf/util/TimestampsTest.java \ java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \ java/util/src/test/proto/com/google/protobuf/util/json_test.proto @@ -1012,6 +1022,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 \ @@ -1026,7 +1037,10 @@ python_EXTRA_DIST= \ python/google/protobuf/internal/factory_test2.proto \ python/google/protobuf/internal/file_options_test.proto \ python/google/protobuf/internal/generator_test.py \ + python/google/protobuf/internal/import_test.py \ python/google/protobuf/internal/import_test_package/__init__.py \ + python/google/protobuf/internal/import_test_package/import_public.proto \ + python/google/protobuf/internal/import_test_package/import_public_nested.proto \ python/google/protobuf/internal/import_test_package/inner.proto \ python/google/protobuf/internal/import_test_package/outer.proto \ python/google/protobuf/internal/json_format_test.py \ @@ -1372,65 +1386,68 @@ js_EXTRA_DIST= \ all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST) -EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ - autogen.sh \ - generate_descriptor_proto.sh \ - README.md \ - LICENSE \ - CONTRIBUTORS.txt \ - CHANGES.txt \ - update_file_lists.sh \ - BUILD \ - WORKSPACE \ - cmake/CMakeLists.txt \ - cmake/README.md \ - cmake/conformance.cmake \ - cmake/examples.cmake \ - cmake/extract_includes.bat.in \ - cmake/install.cmake \ - cmake/libprotobuf.cmake \ - cmake/libprotobuf-lite.cmake \ - cmake/libprotoc.cmake \ - cmake/protobuf-config-version.cmake.in \ - cmake/protobuf-config.cmake.in \ - cmake/protobuf-lite.pc.cmake \ - cmake/protobuf-module.cmake.in \ - cmake/protobuf-options.cmake \ - cmake/protobuf.pc.cmake \ - cmake/protoc.cmake \ - cmake/tests.cmake \ - cmake/version.rc.in \ - compiler_config_setting.bzl \ - build_files_updated_unittest.sh \ - cc_proto_blacklist_test.bzl \ - editors/README.txt \ - editors/proto.vim \ - editors/protobuf-mode.el \ - examples/AddPerson.java \ - examples/BUILD \ - examples/CMakeLists.txt \ - examples/ListPeople.java \ - examples/Makefile \ - examples/README.md \ - examples/WORKSPACE \ - examples/add_person.cc \ - examples/add_person.dart \ - examples/add_person.go \ - examples/add_person.py \ - examples/add_person_test.go \ - examples/addressbook.proto \ - examples/list_people.cc \ - examples/list_people.dart \ - examples/list_people.go \ - examples/list_people.py \ - examples/list_people_test.go \ - examples/pubspec.yaml \ - maven_install.json \ - protobuf.bzl \ - protobuf_deps.bzl \ - protobuf_version.bzl \ - third_party/zlib.BUILD \ - util/python/BUILD \ +EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ + autogen.sh \ + generate_descriptor_proto.sh \ + README.md \ + LICENSE \ + CONTRIBUTORS.txt \ + CHANGES.txt \ + update_file_lists.sh \ + BUILD \ + WORKSPACE \ + cmake/CMakeLists.txt \ + cmake/README.md \ + cmake/conformance.cmake \ + cmake/examples.cmake \ + cmake/extract_includes.bat.in \ + cmake/install.cmake \ + cmake/libprotobuf.cmake \ + cmake/libprotobuf-lite.cmake \ + cmake/libprotoc.cmake \ + cmake/protobuf-config-version.cmake.in \ + cmake/protobuf-config.cmake.in \ + cmake/protobuf-lite.pc.cmake \ + cmake/protobuf-module.cmake.in \ + cmake/protobuf-options.cmake \ + cmake/protobuf.pc.cmake \ + cmake/protoc.cmake \ + cmake/tests.cmake \ + cmake/version.rc.in \ + compiler_config_setting.bzl \ + build_files_updated_unittest.sh \ + cc_proto_blacklist_test.bzl \ + editors/README.txt \ + editors/proto.vim \ + editors/protobuf-mode.el \ + examples/AddPerson.java \ + examples/BUILD \ + examples/CMakeLists.txt \ + examples/ListPeople.java \ + examples/Makefile \ + examples/README.md \ + examples/WORKSPACE \ + examples/add_person.cc \ + examples/add_person.dart \ + examples/add_person.py \ + examples/addressbook.proto \ + examples/go/cmd/add_person/add_person.go \ + examples/go/cmd/add_person/add_person_test.go \ + examples/go/cmd/list_people/list_people.go \ + examples/go/cmd/list_people/list_people_test.go \ + examples/go/go.sum \ + examples/go/go.mod \ + examples/list_people.cc \ + examples/list_people.dart \ + examples/list_people.py \ + examples/pubspec.yaml \ + maven_install.json \ + protobuf.bzl \ + protobuf_deps.bzl \ + protobuf_release.bzl \ + protobuf_version.bzl \ + third_party/zlib.BUILD \ + util/python/BUILD \ internal.bzl diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec index 1c557a04dfc72..9cf983dc00cc7 100644 --- a/Protobuf-C++.podspec +++ b/Protobuf-C++.podspec @@ -1,9 +1,9 @@ Pod::Spec.new do |s| s.name = 'Protobuf-C++' - s.version = '3.19.4' + s.version = '3.20.0-rc2' s.summary = 'Protocol Buffers v3 runtime library for C++.' s.homepage = 'https://github.com/google/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/Protobuf.podspec b/Protobuf.podspec index c70b2ef68c897..ed9df24640f15 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.19.4' + s.version = '3.20.0-rc2' 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 e500967fe4ed7..36df3f33714cf 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -56,3 +56,13 @@ pinned_maven_install() load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() + +load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") +rules_pkg_dependencies() + +# For `kt_jvm_library` +load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories") +kotlin_repositories() + +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..13a8843d2e85f 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 @@ -87,7 +87,17 @@ To run all the benchmark dataset: ### Java: +First build the Java binary in the usual way with Maven: + +``` +$ cd java +$ mvn install +``` + +Assuming that completes successfully, + ``` +$ cd ../benchmarks $ make java ``` diff --git a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java index a4402481b0a07..97c7376cd904d 100644 --- a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java +++ b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java @@ -1,38 +1,27 @@ - package com.google.protobuf; import com.google.caliper.BeforeExperiment; -import com.google.caliper.AfterExperiment; import com.google.caliper.Benchmark; import com.google.caliper.Param; -import com.google.caliper.api.VmOptions; -import com.google.protobuf.ByteString; -import com.google.protobuf.CodedOutputStream; -import com.google.protobuf.ExtensionRegistry; -import com.google.protobuf.Message; import com.google.protobuf.benchmarks.Benchmarks.BenchmarkDataset; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileWriter; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List; -// Caliper set CICompilerCount to 1 for making sure compilation doesn't run in parallel with itself, -// This makes TieredCompilation not working. We just disable TieredCompilation by default. In master -// branch this has been disabled by default in caliper: -// https://github.com/google/caliper/blob/master/caliper-runner/src/main/java/com/google/caliper/runner/target/Jvm.java#L38:14 -// But this haven't been added into most recent release. -@VmOptions("-XX:-TieredCompilation") +/** + * Basic benchmarks for Java protobuf parsing. + */ public class ProtoCaliperBenchmark { public enum BenchmarkMessageType { GOOGLE_MESSAGE1_PROTO3 { - @Override ExtensionRegistry getExtensionRegistry() { return ExtensionRegistry.newInstance(); } + @Override + ExtensionRegistry getExtensionRegistry() { + return ExtensionRegistry.newInstance(); + } @Override Message getDefaultInstance() { return com.google.protobuf.benchmarks.BenchmarkMessage1Proto3.GoogleMessage1 @@ -40,7 +29,9 @@ Message getDefaultInstance() { } }, GOOGLE_MESSAGE1_PROTO2 { - @Override ExtensionRegistry getExtensionRegistry() { return ExtensionRegistry.newInstance(); } + @Override ExtensionRegistry getExtensionRegistry() { + return ExtensionRegistry.newInstance(); + } @Override Message getDefaultInstance() { return com.google.protobuf.benchmarks.BenchmarkMessage1Proto2.GoogleMessage1 @@ -48,7 +39,10 @@ Message getDefaultInstance() { } }, GOOGLE_MESSAGE2 { - @Override ExtensionRegistry getExtensionRegistry() { return ExtensionRegistry.newInstance(); } + @Override + ExtensionRegistry getExtensionRegistry() { + return ExtensionRegistry.newInstance(); + } @Override Message getDefaultInstance() { return com.google.protobuf.benchmarks.BenchmarkMessage2.GoogleMessage2.getDefaultInstance(); diff --git a/benchmarks/python/python_benchmark_messages.cc b/benchmarks/python/python_benchmark_messages.cc index ef7e8a2e95aa3..f6ddcf318554b 100644 --- a/benchmarks/python/python_benchmark_messages.cc +++ b/benchmarks/python/python_benchmark_messages.cc @@ -18,8 +18,7 @@ static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, NULL}; extern "C" { -PyMODINIT_FUNC -PyInit_libbenchmark_messages() { +PyMODINIT_FUNC PyInit_libbenchmark_messages() { benchmarks::BenchmarkDataset().descriptor(); benchmarks::proto3::GoogleMessage1().descriptor(); benchmarks::proto2::GoogleMessage1().descriptor(); diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 51e8478f6e211..ac92442a1e870 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,5 +1,5 @@ # Minimum CMake required -cmake_minimum_required(VERSION 3.1.3) +cmake_minimum_required(VERSION 3.5) if(protobuf_VERBOSE) message(STATUS "Protocol Buffers Configuring...") @@ -41,6 +41,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES Intel) endif() # Options +option(protobuf_INSTALL "Install protobuf binaries and files" ON) if(WITH_PROTOC) set(protobuf_PROTOC_EXE ${WITH_PROTOC} CACHE FILEPATH "Protocol Buffer Compiler executable" FORCE) endif() @@ -126,6 +127,30 @@ if (protobuf_DISABLE_RTTI) add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1) endif() +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map +"{ + global: + main; + local: + *; +};") +# CheckLinkerFlag module available in CMake >=3.18. +if(${CMAKE_VERSION} VERSION_GREATER 3.18 OR ${CMAKE_VERSION} VERSION_EQUAL 3.18) + include(CheckLinkerFlag) + check_linker_flag(CXX -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map protobuf_HAVE_LD_VERSION_SCRIPT) +else() + include(CheckCXXSourceCompiles) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map) + check_cxx_source_compiles(" + int main() { + return 0; + } + " protobuf_HAVE_LD_VERSION_SCRIPT) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endif() +file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map) + find_package(Threads REQUIRED) set(_protobuf_FIND_ZLIB) @@ -181,8 +206,12 @@ else (protobuf_BUILD_SHARED_LIBS) # Prior to CMake 3.15, the MSVC runtime library was pushed into the same flags # making programmatic control difficult. Prefer the functionality in newer # CMake versions when available. - if(CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) + if(${CMAKE_VERSION} VERSION_GREATER 3.15 OR ${CMAKE_VERSION} VERSION_EQUAL 3.15) + if (protobuf_MSVC_STATIC_RUNTIME) + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>DLL) + endif() else() # In case we are building static libraries, link also the runtime library statically # so that MSVCR*.DLL is not required at runtime. @@ -210,9 +239,7 @@ if (MSVC) add_definitions(/utf-8) # MSVC warning suppressions add_definitions( - /wd4018 # 'expression' : signed/unsigned mismatch /wd4065 # switch statement contains 'default' but no 'case' labels - /wd4146 # unary minus operator applied to unsigned type, result still unsigned /wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data /wd4251 # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' /wd4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data @@ -294,6 +321,7 @@ if (protobuf_BUILD_TESTS OR protobuf_BUILD_CONFORMANCE OR protobuf_BUILD_EXAMPLE endif () if (protobuf_BUILD_TESTS) + enable_testing() include(tests.cmake) endif (protobuf_BUILD_TESTS) @@ -301,7 +329,9 @@ if (protobuf_BUILD_CONFORMANCE) include(conformance.cmake) endif (protobuf_BUILD_CONFORMANCE) -include(install.cmake) +if (protobuf_INSTALL) + include(install.cmake) +endif (protobuf_INSTALL) if (protobuf_BUILD_EXAMPLES) include(examples.cmake) diff --git a/cmake/README.md b/cmake/README.md index 89d00c1b6f4f7..3fee4a04148df 100644 --- a/cmake/README.md +++ b/cmake/README.md @@ -36,6 +36,10 @@ If *git* command is not available from *Command Prompt*, add it to system *PATH* C:\Path\to>set PATH=%PATH%;C:\Program Files\Git\cmd +Optionally, you will want to download [ninja](https://ninja-build.org/) and add it to your *PATH* variable. + + C:\Path\to>set PATH=%PATH%;C:\tools\ninja + Good. Now you are ready to continue. Getting Sources @@ -52,29 +56,25 @@ download `protobuf-all-[VERSION].tar.gz`. Or you can use git to clone from protobuf git repository. - C:\Path\to> git clone -b [release_tag] https://github.com/protocolbuffers/protobuf.git + C:\Path\to> mkdir src & cd src + C:\Path\to\src> git clone -b [release_tag] https://github.com/protocolbuffers/protobuf.git Where *[release_tag]* is a git tag like *v3.0.0-beta-1* or a branch name like *master* if you want to get the latest code. Go to the project folder: - C:\Path\to>cd protobuf - C:\Path\to\protobuf> + C:\Path\to\src> cd protobuf + C:\Path\to\src\protobuf> Remember to update any submodules if you are using git clone (you can skip this step if you are using a release .tar.gz or .zip package): ```console -C:\Path\to> git submodule update --init --recursive +C:\Path\to\src\protobuf> git submodule update --init --recursive ``` -Now go to *cmake* folder in protobuf sources: - - C:\Path\to\protobuf>cd cmake - C:\Path\to\protobuf\cmake> - -Good. Now you are ready to *CMake* configuration. +Good. Now you are ready for *CMake* configuration. CMake Configuration =================== @@ -82,71 +82,119 @@ CMake Configuration *CMake* supports a lot of different [generators](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html) for various native build systems. -We are only interested in -[Makefile](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#makefile-generators) -and -[Visual Studio](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) -generators. -We will use shadow building to separate the temporary files from the protobuf source code. +Of most interest to Windows programmers are the following: + +* [Makefile](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#makefile-generators). + This generates NMake Makefiles for Visual Studio. These work, but they are rather slow. + +* [Visual Studio](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) + This generates a Visual Studio solution for the project. + +* [Ninja](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#ninja-generator) + This uses the external tool [Ninja](https://ninja-build.org/) to build. It is the fastest solution available. + +Note that as of Visual Studio 2015, Visual Studio includes +[support for opening directly CMake-based projects](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio). + +It is considered good practice not to build CMake projects in the source tree but in a separate folder. Create a temporary *build* folder and change your working directory to it: - C:\Path\to\protobuf\cmake>mkdir build & cd build - C:\Path\to\protobuf\cmake\build> + mkdir C:\Path\to\build\protobuf + cd C:\Path\to\build\protobuf + C:\Path\to\build\protobuf> -The *Makefile* generator can build the project in only one configuration, so you need to build +The *Makefile* and *Ninja* generators can build the project in only one configuration, so you need to build a separate folder for each configuration. -To start using a *Release* configuration: +To start using a *Release* configuration via the *NMmake* generator: - C:\Path\to\protobuf\cmake\build>mkdir release & cd release - C:\Path\to\protobuf\cmake\build\release>cmake -G "NMake Makefiles" ^ + C:\Path\to\build\protobuf>mkdir release & cd release + C:\Path\to\build\protobuf\release>cmake -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Release ^ - -DCMAKE_INSTALL_PREFIX=../../../../install ^ - ../.. + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + C:\Path\to\src\protobuf -It will generate *nmake* *Makefile* in current directory. +It will generate a *NMake* *Makefile* in the current directory. -To use *Debug* configuration: +To use *Debug* configuration using *Ninja*: - C:\Path\to\protobuf\cmake\build>mkdir debug & cd debug - C:\Path\to\protobuf\cmake\build\debug>cmake -G "NMake Makefiles" ^ + C:\Path\to\build\protobuf>mkdir debug & cd debug + C:\Path\to\build\protobuf\debug>cmake -G "Ninja" ^ -DCMAKE_BUILD_TYPE=Debug ^ - -DCMAKE_INSTALL_PREFIX=../../../../install ^ - ../.. + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + C:\Path\to\src\protobuf -It will generate *nmake* *Makefile* in current directory. +It will generate *Ninja* build scripts in current directory. -To create *Visual Studio* solution file: +The *Visual Studio* generator is multi-configuration: it will generate a single *.sln* file that can be used for both *Debug* and *Release*: - C:\Path\to\protobuf\cmake\build>mkdir solution & cd solution - C:\Path\to\protobuf\cmake\build\solution>cmake -G "Visual Studio 16 2019" ^ - -DCMAKE_INSTALL_PREFIX=../../../../install ^ - ../.. + C:\Path\to\build\protobuf>mkdir solution & cd solution + C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + C:\Path\to\src\protobuf It will generate *Visual Studio* solution file *protobuf.sln* in current directory. -If the *gmock* directory does not exist, and you do not want to build protobuf unit tests, -you need to add *cmake* command argument `-Dprotobuf_BUILD_TESTS=OFF` to disable testing. +Unit Tests +---------- + +Unit tests are being built along with the rest of protobuf. The unit tests require Google Mock (now a part of Google Test). + +A copy of [Google Test](https://github.com/google/googletest) is included as a Git submodule in the `third-party/googletest` folder. +(You do need to initialize the Git submodules as explained above.) + +Alternately, you may want to use protobuf in a larger set-up, you may want to use that standard CMake approach where +you build and install a shared copy of Google Test. + +After you've built and installed your Google Test copy, you need add the following definition to your *cmake* command line +during the configuration step: `-Dprotobuf_USE_EXTERNAL_GTEST=ON`. +This will cause the standard CMake `find_package(GTest REQUIRED)` to be used. -To make a *Visual Studio* file for Visual Studio 16 2019, create the *Visual Studio* -solution file above and edit the CMakeCache file. +[find_package](https://cmake.org/cmake/help/latest/command/find_package.html) will search in a default location, +which on Windows is *C:\Program Files*. This is most likely not what you want. You will want instead to search for +Google Test in your project's root directory (i.e. the same directory you've passed to `CMAKE_INSTALL_PREFIX` when +building Google Test). For this, you need to set the `CMAKE_PREFIX_PATH` CMake variable. (There are other ways in CMake, +see the [manual](https://cmake.org/cmake/help/latest/command/find_package.html) for details.) - C:Path\to\protobuf\cmake\build\solution\CMakeCache +For example: -Then create the *Visual Studio* solution file again + C:\Path\to\build\protobuf>mkdir solution & cd solution + C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + -DCMAKE_PREFIX_PATH=C:\Path\to\my_big_project ^ + -Dprotobuf_USE_EXTERNAL_GTEST=ON ^ + C:\Path\to\src\protobuf + +In most cases, `CMAKE_PREFIX_PATH` and `CMAKE_INSTALL_PREFIX` will point to the same directory. + +To disable testing completely, you need to add the following argument to you *cmake* command line: `-Dprotobuf_BUILD_TESTS=OFF`. + +For example: + + C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + -Dprotobuf_BUILD_TESTS=OFF ^ + C:\Path\to\src\protobuf Compiling ========= -To compile protobuf: +The standard way to compile a *CMake* project is `cmake --build `. + + +Note that if your generator supports multiple configurations, you will probably want to specify which one to build: - C:\Path\to\protobuf\cmake\build\release>nmake + cmake --build C:\Path\to\build\protobuf\solution --config Release + +You can also run directly the build tool you've configured: + + C:\Path\to\build\protobuf\release>nmake or - C:\Path\to\protobuf\cmake\build\debug>nmake + C:\Path\to\build\protobuf\debug>ninja And wait for the compilation to finish. @@ -164,11 +212,15 @@ Testing To run unit-tests, first you must compile protobuf as described above. Then run: - C:\Path\to\protobuf\cmake\build\release>nmake check + C:\Path\to\protobuf\cmake\build\release>ctest --progress --output-on-failure + +You can also build the `check` target (not idiomatic CMake usage, though): + + C:\Path\to\protobuf\cmake\build\release>cmake --build . --target check or - C:\Path\to\protobuf\cmake\build\debug>nmake check + C:\Path\to\build\protobuf\release>ninja check You can also build project *check* from Visual Studio solution. Yes, it may sound strange, but it works. @@ -183,9 +235,9 @@ You should see output similar to: [==========] 1546 tests from 165 test cases ran. (2529 ms total) [ PASSED ] 1546 tests. -To run specific tests: +To run specific tests, you need to pass some command line arguments to the test program itself: - C:\Path\to\protobuf>cmake\build\release\tests.exe --gtest_filter=AnyTest* + C:\Path\to\build\protobuf\release>tests.exe --gtest_filter=AnyTest* Running main() from gmock_main.cc Note: Google Test filter = AnyTest* [==========] Running 3 tests from 1 test case. @@ -210,13 +262,17 @@ If all tests are passed, safely continue. Installing ========== -To install protobuf to the specified *install* folder: +To install protobuf to the *install* folder you've specified in the configuration step, you need to build the `install` target: + + cmake --build C:\Path\to\build\protobuf\solution --config Release --target install + +Or if you prefer: - C:\Path\to\protobuf\cmake\build\release>nmake install + C:\Path\to\build\protobuf\release>nmake install or - C:\Path\to\protobuf\cmake\build\debug>nmake install + C:\Path\to\build\protobuf\debug>ninja install You can also build project *INSTALL* from Visual Studio solution. It sounds not so strange and it works. @@ -280,16 +336,16 @@ You can also compile it from source by yourself. Getting sources: - C:\Path\to>git clone -b v1.2.8 https://github.com/madler/zlib.git - C:\Path\to>cd zlib + C:\Path\to\src>git clone -b v1.2.8 https://github.com/madler/zlib.git + C:\Path\to\src>cd zlib Compiling and Installing: - C:\Path\to\zlib>mkdir build & cd build - C:\Path\to\zlib\build>mkdir release & cd release - C:\Path\to\zlib\build\release>cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ^ - -DCMAKE_INSTALL_PREFIX=../../../install ../.. - C:\Path\to\zlib\build\release>nmake & nmake install + C:\Path\to\src\zlib>mkdir C:\Path\to\build\zlib & cd C:\Path\to\build\zlib + C:\Path\to\build\zlib>mkdir release & cd release + C:\Path\to\build\zlib\release>cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install C:\Path\to\src\zlib + C:\Path\to\src\zlib\build\release>cmake --build . --target install You can make *debug* version or use *Visual Studio* generator also as before for the protobuf project. @@ -308,8 +364,8 @@ the headers or the .lib file in the right directory. If you already have ZLIB library and headers at some other location on your system then alternatively you can define following configuration flags to locate them: - -DZLIB_INCLUDE_DIR= - -DZLIB_LIB= + -DZLIB_INCLUDE_DIR= + -DZLIB_LIB= Build and testing protobuf as usual. @@ -320,8 +376,6 @@ The following warnings have been disabled while building the protobuf libraries and compiler. You may have to disable some of them in your own project as well, or live with them. -* C4018 - 'expression' : signed/unsigned mismatch -* C4146 - unary minus operator applied to unsigned type, result still unsigned * C4244 - Conversion from 'type1' to 'type2', possible loss of data. * C4251 - 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 605c5f966ba30..8e910e99ed574 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -19,6 +19,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h" include\goo copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h" include\google\protobuf\arena.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena_impl.h" include\google\protobuf\arena_impl.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h" include\google\protobuf\arenastring.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenaz_sampler.h" include\google\protobuf\arenaz_sampler.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h" include\google\protobuf\compiler\command_line_interface.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_file.h" include\google\protobuf\compiler\cpp\cpp_file.h @@ -41,6 +42,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 @@ -57,11 +60,8 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflec copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_bases.h" include\google\protobuf\generated_message_bases.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven_lite.h" include\google\protobuf\generated_message_table_driven_lite.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_decl.h" include\google\protobuf\generated_message_tctable_decl.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_impl.h" include\google\protobuf\generated_message_tctable_impl.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_impl.inc" include\google\protobuf\generated_message_tctable_impl.inc copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index f36a7acf6c04e..93760994ea22d 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 @@ -95,21 +93,31 @@ endif() add_library(libprotobuf-lite ${protobuf_SHARED_OR_STATIC} ${libprotobuf_lite_files} ${libprotobuf_lite_includes} ${libprotobuf_lite_rc_files}) -target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT}) +if(protobuf_HAVE_LD_VERSION_SCRIPT) + if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13) + target_link_options(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_source_dir}/src/libprotobuf-lite.map) + elseif(protobuf_BUILD_SHARED_LIBS) + target_link_libraries(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_source_dir}/src/libprotobuf-lite.map) + endif() + set_target_properties(libprotobuf-lite PROPERTIES + LINK_DEPENDS ${protobuf_source_dir}/src/libprotobuf-lite.map) +endif() +target_link_libraries(libprotobuf-lite PRIVATE ${CMAKE_THREAD_LIBS_INIT}) if(protobuf_LINK_LIBATOMIC) - target_link_libraries(libprotobuf-lite atomic) + target_link_libraries(libprotobuf-lite PRIVATE atomic) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") - target_link_libraries(libprotobuf-lite log) + target_link_libraries(libprotobuf-lite PRIVATE log) endif() target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src) -if(MSVC AND protobuf_BUILD_SHARED_LIBS) +if(protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf-lite PUBLIC PROTOBUF_USE_DLLS PRIVATE LIBPROTOBUF_EXPORTS) endif() set_target_properties(libprotobuf-lite PROPERTIES VERSION ${protobuf_VERSION} + SOVERSION 31 OUTPUT_NAME ${LIB_PREFIX}protobuf-lite DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") add_library(protobuf::libprotobuf-lite ALIAS libprotobuf-lite) diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index 668b8c27847e7..448baea0a7789 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -14,13 +14,13 @@ 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 ${protobuf_source_dir}/src/google/protobuf/io/tokenizer.cc ${protobuf_source_dir}/src/google/protobuf/map_field.cc ${protobuf_source_dir}/src/google/protobuf/message.cc + ${protobuf_source_dir}/src/google/protobuf/reflection_internal.h ${protobuf_source_dir}/src/google/protobuf/reflection_ops.cc ${protobuf_source_dir}/src/google/protobuf/service.cc ${protobuf_source_dir}/src/google/protobuf/source_context.pb.cc @@ -107,24 +107,34 @@ endif() add_library(libprotobuf ${protobuf_SHARED_OR_STATIC} ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes} ${libprotobuf_rc_files}) -target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT}) +if(protobuf_HAVE_LD_VERSION_SCRIPT) + if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13) + target_link_options(libprotobuf PRIVATE -Wl,--version-script=${protobuf_source_dir}/src/libprotobuf.map) + elseif(protobuf_BUILD_SHARED_LIBS) + target_link_libraries(libprotobuf PRIVATE -Wl,--version-script=${protobuf_source_dir}/src/libprotobuf.map) + endif() + set_target_properties(libprotobuf PROPERTIES + LINK_DEPENDS ${protobuf_source_dir}/src/libprotobuf.map) +endif() +target_link_libraries(libprotobuf PRIVATE ${CMAKE_THREAD_LIBS_INIT}) if(protobuf_WITH_ZLIB) - target_link_libraries(libprotobuf ${ZLIB_LIBRARIES}) + target_link_libraries(libprotobuf PRIVATE ${ZLIB_LIBRARIES}) endif() if(protobuf_LINK_LIBATOMIC) - target_link_libraries(libprotobuf atomic) + target_link_libraries(libprotobuf PRIVATE atomic) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") - target_link_libraries(libprotobuf log) + target_link_libraries(libprotobuf PRIVATE log) endif() target_include_directories(libprotobuf PUBLIC ${protobuf_source_dir}/src) -if(MSVC AND protobuf_BUILD_SHARED_LIBS) +if(protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf PUBLIC PROTOBUF_USE_DLLS PRIVATE LIBPROTOBUF_EXPORTS) endif() set_target_properties(libprotobuf PROPERTIES VERSION ${protobuf_VERSION} + SOVERSION 31 OUTPUT_NAME ${LIB_PREFIX}protobuf DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") add_library(protobuf::libprotobuf ALIAS libprotobuf) diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 6f043316b9865..92dff13215bdb 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -36,6 +36,7 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field_lite.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_lite.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension.cc @@ -64,24 +65,38 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types_embed.cc ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_extension.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_field.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_file.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_file.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_map_field.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message_field.h + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_oneof.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc ${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 + ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.h ) set(libprotoc_headers @@ -95,18 +110,16 @@ set(libprotoc_headers ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator.h ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_names.h ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_options.h - ${protobuf_source_dir}/src/google/protobuf/compiler/importer.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_kotlin_generator.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_names.h ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_generator.h ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers.h - ${protobuf_source_dir}/src/google/protobuf/compiler/parser.h ${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/plugin.pb.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 ) @@ -118,8 +131,17 @@ endif() add_library(libprotoc ${protobuf_SHARED_OR_STATIC} ${libprotoc_files} ${libprotoc_headers} ${libprotoc_rc_files}) -target_link_libraries(libprotoc libprotobuf) -if(MSVC AND protobuf_BUILD_SHARED_LIBS) +if(protobuf_HAVE_LD_VERSION_SCRIPT) + if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13) + target_link_options(libprotoc PRIVATE -Wl,--version-script=${protobuf_source_dir}/src/libprotoc.map) + elseif(protobuf_BUILD_SHARED_LIBS) + target_link_libraries(libprotoc PRIVATE -Wl,--version-script=${protobuf_source_dir}/src/libprotoc.map) + endif() + set_target_properties(libprotoc PROPERTIES + LINK_DEPENDS ${protobuf_source_dir}/src/libprotoc.map) +endif() +target_link_libraries(libprotoc PRIVATE libprotobuf) +if(protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotoc PUBLIC PROTOBUF_USE_DLLS PRIVATE LIBPROTOC_EXPORTS) @@ -127,6 +149,7 @@ endif() set_target_properties(libprotoc PROPERTIES COMPILE_DEFINITIONS LIBPROTOC_EXPORTS VERSION ${protobuf_VERSION} + SOVERSION 31 OUTPUT_NAME ${LIB_PREFIX}protoc DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") add_library(protobuf::libprotoc ALIAS libprotoc) diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in index 9197625dc25b0..b4332099c90c7 100644 --- a/cmake/protobuf-config.cmake.in +++ b/cmake/protobuf-config.cmake.in @@ -11,7 +11,7 @@ function(protobuf_generate) include(CMakeParseArguments) set(_options APPEND_PATH) - set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN) + set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS) if(COMMAND target_sources) list(APPEND _singleargs TARGET) endif() @@ -39,9 +39,18 @@ function(protobuf_generate) endif() if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp) - set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:") + set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}") endif() - + + foreach(_option ${_dll_export_decl} ${protobuf_generate_PLUGIN_OPTIONS}) + # append comma - not using CMake lists and string replacement as users + # might have semicolons in options + if(_plugin_options) + set( _plugin_options "${_plugin_options},") + endif() + set(_plugin_options "${_plugin_options}${_option}") + endforeach() + if(protobuf_generate_PLUGIN) set(_plugin "--plugin=${protobuf_generate_PLUGIN}") endif() @@ -127,12 +136,20 @@ function(protobuf_generate) endforeach() list(APPEND _generated_srcs_all ${_generated_srcs}) + set(_comment "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}") + if(protobuf_generate_PROTOC_OPTIONS) + set(_comment "${_comment}, protoc-options: ${protobuf_generate_PROTOC_OPTIONS}") + endif() + if(_plugin_options) + set(_comment "${_comment}, plugin-options: ${_plugin_options}") + endif() + add_custom_command( OUTPUT ${_generated_srcs} - COMMAND protobuf::protoc - ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} + COMMAND protobuf::protoc + ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} DEPENDS ${_abs_file} protobuf::protoc - COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}. Custom options: ${protobuf_generate_PROTOC_OPTIONS}" + COMMENT ${_comment} VERBATIM ) endforeach() diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in index 09b9d29c22123..0bb05e38fad86 100644 --- a/cmake/protobuf-module.cmake.in +++ b/cmake/protobuf-module.cmake.in @@ -94,7 +94,7 @@ function(_protobuf_find_libraries name filename) elseif(${name}_LIBRARY) # Honor cache entry used by CMake 3.5 and lower. set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE) - else() + elseif(TARGET protobuf::lib${filename}) get_target_property(${name}_LIBRARY_RELEASE protobuf::lib${filename} LOCATION_RELEASE) get_target_property(${name}_LIBRARY_RELWITHDEBINFO protobuf::lib${filename} @@ -134,23 +134,25 @@ get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) # Set the protoc Executable -get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_RELEASE) -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") +if(NOT Protobuf_PROTOC_EXECUTABLE AND TARGET protobuf::protoc) get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_RELWITHDEBINFO) -endif() -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_MINSIZEREL) -endif() -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_DEBUG) -endif() -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_NOCONFIG) + IMPORTED_LOCATION_RELEASE) + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_RELWITHDEBINFO) + endif() + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_MINSIZEREL) + endif() + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_DEBUG) + endif() + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_NOCONFIG) + endif() endif() # Version info variable diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 529685856ec01..0b0e1bed8c53c 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -1,32 +1,41 @@ -if (NOT EXISTS "${PROJECT_SOURCE_DIR}/../third_party/googletest/CMakeLists.txt") - message(FATAL_ERROR - "Cannot find third_party/googletest directory that's needed to " - "build tests. If you use git, make sure you have cloned submodules:\n" - " git submodule update --init --recursive\n" - "If instead you want to skip tests, run cmake with:\n" - " cmake -Dprotobuf_BUILD_TESTS=OFF\n") -endif() +option(protobuf_USE_EXTERNAL_GTEST "Use external Google Test (i.e. not the one in third_party/googletest)" OFF) option(protobuf_ABSOLUTE_TEST_PLUGIN_PATH "Using absolute test_plugin path in tests" ON) mark_as_advanced(protobuf_ABSOLUTE_TEST_PLUGIN_PATH) -set(googlemock_source_dir "${protobuf_source_dir}/third_party/googletest/googlemock") -set(googletest_source_dir "${protobuf_source_dir}/third_party/googletest/googletest") -include_directories( - ${googlemock_source_dir} - ${googletest_source_dir} - ${googletest_source_dir}/include - ${googlemock_source_dir}/include -) +if (protobuf_USE_EXTERNAL_GTEST) + find_package(GTest REQUIRED) +else() + if (NOT EXISTS "${PROJECT_SOURCE_DIR}/../third_party/googletest/CMakeLists.txt") + message(FATAL_ERROR + "Cannot find third_party/googletest directory that's needed to " + "build tests. If you use git, make sure you have cloned submodules:\n" + " git submodule update --init --recursive\n" + "If instead you want to skip tests, run cmake with:\n" + " cmake -Dprotobuf_BUILD_TESTS=OFF\n") + endif() -add_library(gmock STATIC - "${googlemock_source_dir}/src/gmock-all.cc" - "${googletest_source_dir}/src/gtest-all.cc" -) -target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT}) -add_library(gmock_main STATIC "${googlemock_source_dir}/src/gmock_main.cc") -target_link_libraries(gmock_main gmock) + set(googlemock_source_dir "${protobuf_source_dir}/third_party/googletest/googlemock") + set(googletest_source_dir "${protobuf_source_dir}/third_party/googletest/googletest") + include_directories( + ${googlemock_source_dir} + ${googletest_source_dir} + ${googletest_source_dir}/include + ${googlemock_source_dir}/include + ) + + add_library(gmock STATIC + "${googlemock_source_dir}/src/gmock-all.cc" + "${googletest_source_dir}/src/gtest-all.cc" + ) + target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT}) + add_library(gmock_main STATIC "${googlemock_source_dir}/src/gmock_main.cc") + target_link_libraries(gmock_main gmock) + + add_library(GTest::gmock ALIAS gmock) + add_library(GTest::gmock_main ALIAS gmock_main) +endif() set(lite_test_protos google/protobuf/map_lite_unittest.proto @@ -119,10 +128,10 @@ set(common_lite_test_files set(common_test_files ${common_lite_test_files} + ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc ${protobuf_source_dir}/src/google/protobuf/map_test_util.inc ${protobuf_source_dir}/src/google/protobuf/reflection_tester.cc ${protobuf_source_dir}/src/google/protobuf/test_util.cc - ${protobuf_source_dir}/src/google/protobuf/test_util.inc ${protobuf_source_dir}/src/google/protobuf/testing/file.cc ${protobuf_source_dir}/src/google/protobuf/testing/googletest.cc ) @@ -131,7 +140,9 @@ 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 ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc @@ -144,7 +155,6 @@ set(tests_files ${protobuf_source_dir}/src/google/protobuf/compiler/importer_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_plugin_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/parser_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_plugin_unittest.cc @@ -155,6 +165,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 @@ -222,7 +233,12 @@ if(MINGW) endif() add_executable(tests ${tests_files} ${common_test_files} ${tests_proto_files} ${lite_test_proto_files}) -target_link_libraries(tests libprotoc libprotobuf gmock_main) +if (MSVC) + target_compile_options(tests PRIVATE + /wd4146 # unary minus operator applied to unsigned type, result still unsigned + ) +endif() +target_link_libraries(tests libprotoc libprotobuf GTest::gmock_main) set(test_plugin_files ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc @@ -232,21 +248,25 @@ set(test_plugin_files ) add_executable(test_plugin ${test_plugin_files}) -target_link_libraries(test_plugin libprotoc libprotobuf gmock) +target_link_libraries(test_plugin libprotoc libprotobuf GTest::gmock) set(lite_test_files ${protobuf_source_dir}/src/google/protobuf/lite_unittest.cc ) add_executable(lite-test ${lite_test_files} ${common_lite_test_files} ${lite_test_proto_files}) -target_link_libraries(lite-test libprotobuf-lite gmock_main) +target_link_libraries(lite-test libprotobuf-lite GTest::gmock_main) set(lite_arena_test_files ${protobuf_source_dir}/src/google/protobuf/lite_arena_unittest.cc ) add_executable(lite-arena-test ${lite_arena_test_files} ${common_lite_test_files} ${lite_test_proto_files}) -target_link_libraries(lite-arena-test libprotobuf-lite gmock_main) +target_link_libraries(lite-arena-test libprotobuf-lite GTest::gmock_main) add_custom_target(check COMMAND tests DEPENDS tests test_plugin WORKING_DIRECTORY ${protobuf_source_dir}) + +add_test(NAME check + COMMAND tests + WORKING_DIRECTORY "${protobuf_source_dir}") diff --git a/configure.ac b/configure.ac index 4c774b0beab39..c5db5b005abfe 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.59) # In the SVN trunk, the version should always be the next anticipated release # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # the size of one file name in the dist tarfile over the 99-char limit.) -AC_INIT([Protocol Buffers],[3.19.4],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[3.20.0-rc-2],[protobuf@googlegroups.com],[protobuf]) AM_MAINTAINER_MODE([enable]) @@ -80,7 +80,7 @@ AC_LANG([C++]) ACX_USE_SYSTEM_EXTENSIONS m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc -AC_PROG_OBJC +AS_CASE([$target_os], [darwin*], [AC_PROG_OBJC], [AM_CONDITIONAL([am__fastdepOBJC], [false])]) # test_util.cc takes forever to compile with GCC and optimization turned on. AC_MSG_CHECKING([C++ compiler flags...]) 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/Makefile.am b/conformance/Makefile.am index ac6f9e1b2beb7..940c0a2668a59 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -316,7 +316,7 @@ conformance-java-lite: javac_middleman_lite conformance-csharp: $(other_language_protoc_outputs) @echo "Writing shortcut script conformance-csharp..." @echo '#! /bin/sh' > conformance-csharp - @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp2.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp + @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp3.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp @chmod +x conformance-csharp conformance-php: diff --git a/conformance/conformance_nodejs.js b/conformance/conformance_nodejs.js index 95da893f71b46..275fac4613b27 100755 --- a/conformance/conformance_nodejs.js +++ b/conformance/conformance_nodejs.js @@ -41,11 +41,17 @@ function doTest(request) { var response = new conformance.ConformanceResponse(); try { - if (request.getRequestedOutputFormat() === conformance.WireFormat.JSON) { + if (request.getRequestedOutputFormat() == conformance.WireFormat.JSON) { response.setSkipped("JSON not supported."); return response; } + if (request.getRequestedOutputFormat() == + conformance.WireFormat.TEXT_FORMAT) { + response.setSkipped('Text format is not supported as output format.'); + return response; + } + switch (request.getPayloadCase()) { case conformance.ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD: { if (request.getMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3") { @@ -67,7 +73,7 @@ function doTest(request) { } else { throw "Protobuf request doesn\'t have specific payload type"; } - } + } break; case conformance.ConformanceRequest.PayloadCase.JSON_PAYLOAD: response.setSkipped("JSON not supported."); diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 07b4150670678..2c856f58741d9 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -350,7 +350,17 @@ bool ConformanceTestSuite::CheckSetEmpty( StringAppendF(&output_, "\n"); if (!write_to_file.empty()) { - std::ofstream os(write_to_file); + std::string full_filename; + const std::string* filename = &write_to_file; + if (!output_dir_.empty()) { + full_filename = output_dir_; + if (*output_dir_.rbegin() != '/') { + full_filename.push_back('/'); + } + full_filename += write_to_file; + filename = &full_filename; + } + std::ofstream os(*filename); if (os) { for (std::set::const_iterator iter = set_to_check.begin(); iter != set_to_check.end(); ++iter) { @@ -358,7 +368,7 @@ bool ConformanceTestSuite::CheckSetEmpty( } } else { StringAppendF(&output_, "Failed to open file: %s\n", - write_to_file.c_str()); + filename->c_str()); } } diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 76bd1bc3f1c99..286159837a126 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -174,6 +174,11 @@ class ConformanceTestSuite { failure_list_flag_name_ = failure_list_flag_name; } + // Sets the path of the output directory. + void SetOutputDir(const char* output_dir) { + output_dir_ = output_dir; + } + // Run all the conformance tests against the given test runner. // Test output will be stored in "output". // @@ -296,6 +301,7 @@ class ConformanceTestSuite { bool verbose_; bool enforce_recommended_; std::string output_; + std::string output_dir_; std::string failure_list_flag_name_; std::string failure_list_filename_; diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc index 1572ac03b5f49..2aac35c5cffdf 100644 --- a/conformance/conformance_test_runner.cc +++ b/conformance/conformance_test_runner.cc @@ -141,6 +141,9 @@ void UsageError() { " strictly conforming to protobuf\n"); fprintf(stderr, " spec.\n"); + fprintf(stderr, + " --output_dir Directory to write\n" + " output files.\n"); exit(1); } @@ -162,7 +165,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; @@ -208,6 +211,9 @@ int ForkPipeRunner::Run( suite->SetVerbose(true); } else if (strcmp(argv[arg], "--enforce_recommended") == 0) { suite->SetEnforceRecommended(true); + } else if (strcmp(argv[arg], "--output_dir") == 0) { + if (++arg == argc) UsageError(); + suite->SetOutputDir(argv[arg]); } else if (argv[arg][0] == '-') { bool recognized_flag = false; for (ConformanceTestSuite* suite : suites) { diff --git a/conformance/failure_list_js.txt b/conformance/failure_list_js.txt index e69de29bb2d1d..b7d36b6dd04a9 100644 --- a/conformance/failure_list_js.txt +++ b/conformance/failure_list_js.txt @@ -0,0 +1,162 @@ +Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput +Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput +Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput +Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput +Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput +Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput +Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 098d79d09cb7e..3a3785a4390e1 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.19.4 + 3.20.0-rc2 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/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs index 5e72525fc96f7..234155975aa6b 100644 --- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs +++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs @@ -716,6 +716,25 @@ public void TestSlowPathAvoidance() } } + [Test] + public void MaximumFieldNumber() + { + MemoryStream ms = new MemoryStream(); + CodedOutputStream output = new CodedOutputStream(ms); + + int fieldNumber = 0x1FFFFFFF; + uint tag = WireFormat.MakeTag(fieldNumber, WireFormat.WireType.LengthDelimited); + output.WriteRawVarint32(tag); + output.WriteString("field 1"); + output.Flush(); + ms.Position = 0; + + CodedInputStream input = new CodedInputStream(ms); + + Assert.AreEqual(tag, input.ReadTag()); + Assert.AreEqual(fieldNumber, WireFormat.GetTagFieldNumber(tag)); + } + [Test] public void Tag0Throws() { 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/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/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs index 1a650933efd43..51fa5e01d6bd3 100644 --- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs @@ -1,698 +1,705 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using Google.Protobuf.TestProtos; -using NUnit.Framework; -using UnitTest.Issues.TestProtos; -using Google.Protobuf.WellKnownTypes; -using Google.Protobuf.Reflection; - -using static Google.Protobuf.JsonParserTest; // For WrapInQuotes -using System.IO; -using Google.Protobuf.Collections; -using ProtobufUnittest; - -namespace Google.Protobuf -{ - /// - /// Tests for the JSON formatter. Note that in these tests, double quotes are replaced with apostrophes - /// for the sake of readability (embedding \" everywhere is painful). See the AssertJson method for details. - /// - public class JsonFormatterTest - { - [Test] - public void DefaultValues_WhenOmitted() - { - var formatter = JsonFormatter.Default; - - AssertJson("{ }", formatter.Format(new ForeignMessage())); - AssertJson("{ }", formatter.Format(new TestAllTypes())); - AssertJson("{ }", formatter.Format(new TestMap())); - } - - [Test] - public void DefaultValues_WhenIncluded() - { - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - AssertJson("{ 'c': 0 }", formatter.Format(new ForeignMessage())); - } - - [Test] - public void EnumAllowAlias() - { - var message = new TestEnumAllowAlias - { - Value = TestEnumWithDupValue.Foo2, - }; - var actualText = JsonFormatter.Default.Format(message); - var expectedText = "{ 'value': 'FOO1' }"; - AssertJson(expectedText, actualText); - } - - [Test] - public void EnumAsInt() - { - var message = new TestAllTypes - { - SingleForeignEnum = ForeignEnum.ForeignBar, - RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo } - }; - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatEnumsAsIntegers(true)); - var actualText = formatter.Format(message); - var expectedText = "{ " + - "'singleForeignEnum': 5, " + - "'repeatedForeignEnum': [ 6, 100, 4 ]" + - " }"; - AssertJson(expectedText, actualText); - } - - [Test] - public void AllSingleFields() - { - var message = new TestAllTypes - { - SingleBool = true, - SingleBytes = ByteString.CopyFrom(1, 2, 3, 4), - SingleDouble = 23.5, - SingleFixed32 = 23, - SingleFixed64 = 1234567890123, - SingleFloat = 12.25f, - SingleForeignEnum = ForeignEnum.ForeignBar, - SingleForeignMessage = new ForeignMessage { C = 10 }, - SingleImportEnum = ImportEnum.ImportBaz, - SingleImportMessage = new ImportMessage { D = 20 }, - SingleInt32 = 100, - SingleInt64 = 3210987654321, - SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo, - SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 }, - SinglePublicImportMessage = new PublicImportMessage { E = 54 }, - SingleSfixed32 = -123, - SingleSfixed64 = -12345678901234, - SingleSint32 = -456, - SingleSint64 = -12345678901235, - SingleString = "test\twith\ttabs", - SingleUint32 = uint.MaxValue, - SingleUint64 = ulong.MaxValue, - }; - var actualText = JsonFormatter.Default.Format(message); - - // Fields in numeric order - var expectedText = "{ " + - "'singleInt32': 100, " + - "'singleInt64': '3210987654321', " + - "'singleUint32': 4294967295, " + - "'singleUint64': '18446744073709551615', " + - "'singleSint32': -456, " + - "'singleSint64': '-12345678901235', " + - "'singleFixed32': 23, " + - "'singleFixed64': '1234567890123', " + - "'singleSfixed32': -123, " + - "'singleSfixed64': '-12345678901234', " + - "'singleFloat': 12.25, " + - "'singleDouble': 23.5, " + - "'singleBool': true, " + - "'singleString': 'test\\twith\\ttabs', " + - "'singleBytes': 'AQIDBA==', " + - "'singleNestedMessage': { 'bb': 35 }, " + - "'singleForeignMessage': { 'c': 10 }, " + - "'singleImportMessage': { 'd': 20 }, " + - "'singleNestedEnum': 'FOO', " + - "'singleForeignEnum': 'FOREIGN_BAR', " + - "'singleImportEnum': 'IMPORT_BAZ', " + - "'singlePublicImportMessage': { 'e': 54 }" + - " }"; - AssertJson(expectedText, actualText); - } - - [Test] - public void WithFormatDefaultValues_DoesNotAffectMessageFields() - { - var message = new TestAllTypes(); - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - var json = formatter.Format(message); - Assert.IsFalse(json.Contains("\"singleNestedMessage\"")); - Assert.IsFalse(json.Contains("\"singleForeignMessage\"")); - Assert.IsFalse(json.Contains("\"singleImportMessage\"")); - } - - [Test] - public void WithFormatDefaultValues_DoesNotAffectProto3OptionalFields() - { - var message = new TestProto3Optional(); - message.OptionalInt32 = 0; - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - var json = formatter.Format(message); - // The non-optional proto3 fields are formatted, as is the optional-but-specified field. - AssertJson("{ 'optionalInt32': 0, 'singularInt32': 0, 'singularInt64': '0' }", json); - } - - [Test] - public void WithFormatDefaultValues_DoesNotAffectProto2Fields() - { - var message = new TestProtos.Proto2.ForeignMessage(); - message.C = 0; - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - var json = formatter.Format(message); - // The specified field is formatted, but the non-specified field (d) is not. - AssertJson("{ 'c': 0 }", json); - } - - [Test] - public void WithFormatDefaultValues_DoesNotAffectOneofFields() - { - var message = new TestOneof(); - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - var json = formatter.Format(message); - AssertJson("{ }", json); - } - - [Test] - public void RepeatedField() - { - AssertJson("{ 'repeatedInt32': [ 1, 2, 3, 4, 5 ] }", - JsonFormatter.Default.Format(new TestAllTypes { RepeatedInt32 = { 1, 2, 3, 4, 5 } })); - } - - [Test] - public void MapField_StringString() - { - AssertJson("{ 'mapStringString': { 'with spaces': 'bar', 'a': 'b' } }", - JsonFormatter.Default.Format(new TestMap { MapStringString = { { "with spaces", "bar" }, { "a", "b" } } })); - } - - [Test] - public void MapField_Int32Int32() - { - // The keys are quoted, but the values aren't. - AssertJson("{ 'mapInt32Int32': { '0': 1, '2': 3 } }", - JsonFormatter.Default.Format(new TestMap { MapInt32Int32 = { { 0, 1 }, { 2, 3 } } })); - } - - [Test] - public void MapField_BoolBool() - { - // The keys are quoted, but the values aren't. - AssertJson("{ 'mapBoolBool': { 'false': true, 'true': false } }", - JsonFormatter.Default.Format(new TestMap { MapBoolBool = { { false, true }, { true, false } } })); - } - - [Test] - public void NullValueOutsideStruct() - { - var message = new NullValueOutsideStruct { NullValue = NullValue.NullValue }; - AssertJson("{ 'nullValue': null }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void NullValueNotInOneof() - { - var message = new NullValueNotInOneof(); - AssertJson("{ }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void NullValueNotInOneof_FormatDefaults() - { - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - var message = new NullValueNotInOneof(); - AssertJson("{ 'nullValue': null }", formatter.Format(message)); - } - - [TestCase(1.0, "1")] - [TestCase(double.NaN, "'NaN'")] - [TestCase(double.PositiveInfinity, "'Infinity'")] - [TestCase(double.NegativeInfinity, "'-Infinity'")] - public void DoubleRepresentations(double value, string expectedValueText) - { - var message = new TestAllTypes { SingleDouble = value }; - string actualText = JsonFormatter.Default.Format(message); - string expectedText = "{ 'singleDouble': " + expectedValueText + " }"; - AssertJson(expectedText, actualText); - } - - [Test] - public void UnknownEnumValueNumeric_SingleField() - { - var message = new TestAllTypes { SingleForeignEnum = (ForeignEnum) 100 }; - AssertJson("{ 'singleForeignEnum': 100 }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void UnknownEnumValueNumeric_RepeatedField() - { - var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo } }; - AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 100, 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void UnknownEnumValueNumeric_MapField() - { - var message = new TestMap { MapInt32Enum = { { 1, MapEnum.Foo }, { 2, (MapEnum) 100 }, { 3, MapEnum.Bar } } }; - AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '2': 100, '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void UnknownEnumValue_RepeatedField_AllEntriesUnknown() - { - var message = new TestAllTypes { RepeatedForeignEnum = { (ForeignEnum) 200, (ForeignEnum) 100 } }; - AssertJson("{ 'repeatedForeignEnum': [ 200, 100 ] }", JsonFormatter.Default.Format(message)); - } - - [Test] - [TestCase("a\u17b4b", "a\\u17b4b")] // Explicit - [TestCase("a\u0601b", "a\\u0601b")] // Ranged - [TestCase("a\u0605b", "a\u0605b")] // Passthrough (note lack of double backslash...) - public void SimpleNonAscii(string text, string encoded) - { - var message = new TestAllTypes { SingleString = text }; - AssertJson("{ 'singleString': '" + encoded + "' }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void SurrogatePairEscaping() - { - var message = new TestAllTypes { SingleString = "a\uD801\uDC01b" }; - AssertJson("{ 'singleString': 'a\\ud801\\udc01b' }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void InvalidSurrogatePairsFail() - { - // Note: don't use TestCase for these, as the strings can't be reliably represented - // See http://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a-string/ - - // Lone low surrogate - var message = new TestAllTypes { SingleString = "a\uDC01b" }; - Assert.Throws(() => JsonFormatter.Default.Format(message)); - - // Lone high surrogate - message = new TestAllTypes { SingleString = "a\uD801b" }; - Assert.Throws(() => JsonFormatter.Default.Format(message)); - } - - [Test] - [TestCase("foo_bar", "fooBar")] - [TestCase("bananaBanana", "bananaBanana")] - [TestCase("BANANABanana", "BANANABanana")] - [TestCase("simple", "simple")] - [TestCase("ACTION_AND_ADVENTURE", "ACTIONANDADVENTURE")] - [TestCase("action_and_adventure", "actionAndAdventure")] - [TestCase("kFoo", "kFoo")] - [TestCase("HTTPServer", "HTTPServer")] - [TestCase("CLIENT", "CLIENT")] - public void ToJsonName(string original, string expected) - { - Assert.AreEqual(expected, JsonFormatter.ToJsonName(original)); - } - - [Test] - [TestCase(null, "{ }")] - [TestCase("x", "{ 'fooString': 'x' }")] - [TestCase("", "{ 'fooString': '' }")] - public void Oneof(string fooStringValue, string expectedJson) - { - var message = new TestOneof(); - if (fooStringValue != null) - { - message.FooString = fooStringValue; - } - - // We should get the same result both with and without "format default values". - var formatter = JsonFormatter.Default; - AssertJson(expectedJson, formatter.Format(message)); - formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - AssertJson(expectedJson, formatter.Format(message)); - } - - [Test] - public void WrapperFormatting_Single() - { - // Just a few examples, handling both classes and value types, and - // default vs non-default values - var message = new TestWellKnownTypes - { - Int64Field = 10, - Int32Field = 0, - BytesField = ByteString.FromBase64("ABCD"), - StringField = "" - }; - var expectedJson = "{ 'int64Field': '10', 'int32Field': 0, 'stringField': '', 'bytesField': 'ABCD' }"; - AssertJson(expectedJson, JsonFormatter.Default.Format(message)); - } - - [Test] - public void WrapperFormatting_Message() - { - Assert.AreEqual("\"\"", JsonFormatter.Default.Format(new StringValue())); - Assert.AreEqual("0", JsonFormatter.Default.Format(new Int32Value())); - } - - [Test] - public void WrapperFormatting_FormatDefaultValuesDoesNotFormatNull() - { - // The actual JSON here is very large because there are lots of fields. Just test a couple of them. - var message = new TestWellKnownTypes { Int32Field = 10 }; - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - var actualJson = formatter.Format(message); - // This *used* to include "int64Field": null, but that was a bug. - // WithDefaultValues should not affect message fields, including wrapper types. - Assert.IsFalse(actualJson.Contains("\"int64Field\": null")); - Assert.IsTrue(actualJson.Contains("\"int32Field\": 10")); - } - - [Test] - public void OutputIsInNumericFieldOrder_NoDefaults() - { - var formatter = JsonFormatter.Default; - var message = new TestJsonFieldOrdering { PlainString = "p1", PlainInt32 = 2 }; - AssertJson("{ 'plainString': 'p1', 'plainInt32': 2 }", formatter.Format(message)); - message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" }; - AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message)); - message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" }; - AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message)); - } - - [Test] - public void OutputIsInNumericFieldOrder_WithDefaults() - { - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); - var message = new TestJsonFieldOrdering(); - AssertJson("{ 'plainString': '', 'plainInt32': 0 }", formatter.Format(message)); - message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" }; - AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message)); - message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" }; - AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message)); - } - - [Test] - [TestCase("1970-01-01T00:00:00Z", 0)] - [TestCase("1970-01-01T00:00:00.000000001Z", 1)] - [TestCase("1970-01-01T00:00:00.000000010Z", 10)] - [TestCase("1970-01-01T00:00:00.000000100Z", 100)] - [TestCase("1970-01-01T00:00:00.000001Z", 1000)] - [TestCase("1970-01-01T00:00:00.000010Z", 10000)] - [TestCase("1970-01-01T00:00:00.000100Z", 100000)] - [TestCase("1970-01-01T00:00:00.001Z", 1000000)] - [TestCase("1970-01-01T00:00:00.010Z", 10000000)] - [TestCase("1970-01-01T00:00:00.100Z", 100000000)] - [TestCase("1970-01-01T00:00:00.120Z", 120000000)] - [TestCase("1970-01-01T00:00:00.123Z", 123000000)] - [TestCase("1970-01-01T00:00:00.123400Z", 123400000)] - [TestCase("1970-01-01T00:00:00.123450Z", 123450000)] - [TestCase("1970-01-01T00:00:00.123456Z", 123456000)] - [TestCase("1970-01-01T00:00:00.123456700Z", 123456700)] - [TestCase("1970-01-01T00:00:00.123456780Z", 123456780)] - [TestCase("1970-01-01T00:00:00.123456789Z", 123456789)] - public void TimestampStandalone(string expected, int nanos) - { - Assert.AreEqual(WrapInQuotes(expected), new Timestamp { Nanos = nanos }.ToString()); - } - - [Test] - public void TimestampStandalone_FromDateTime() - { - // One before and one after the Unix epoch, more easily represented via DateTime. - Assert.AreEqual("\"1673-06-19T12:34:56Z\"", - new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp().ToString()); - Assert.AreEqual("\"2015-07-31T10:29:34Z\"", - new DateTime(2015, 7, 31, 10, 29, 34, DateTimeKind.Utc).ToTimestamp().ToString()); - } - - [Test] - [TestCase(-1, -1)] // Would be valid as duration - [TestCase(1, Timestamp.MaxNanos + 1)] - [TestCase(Timestamp.UnixSecondsAtBclMaxValue + 1, 0)] - [TestCase(Timestamp.UnixSecondsAtBclMinValue - 1, 0)] - public void TimestampStandalone_NonNormalized(long seconds, int nanoseconds) - { - var timestamp = new Timestamp { Seconds = seconds, Nanos = nanoseconds }; - Assert.Throws(() => JsonFormatter.Default.Format(timestamp)); - } - - [Test] - public void TimestampField() - { - var message = new TestWellKnownTypes { TimestampField = new Timestamp() }; - AssertJson("{ 'timestampField': '1970-01-01T00:00:00Z' }", JsonFormatter.Default.Format(message)); - } - - [Test] - [TestCase(0, 0, "0s")] - [TestCase(1, 0, "1s")] - [TestCase(-1, 0, "-1s")] - [TestCase(0, 1, "0.000000001s")] - [TestCase(0, 10, "0.000000010s")] - [TestCase(0, 100, "0.000000100s")] - [TestCase(0, 1000, "0.000001s")] - [TestCase(0, 10000, "0.000010s")] - [TestCase(0, 100000, "0.000100s")] - [TestCase(0, 1000000, "0.001s")] - [TestCase(0, 10000000, "0.010s")] - [TestCase(0, 100000000, "0.100s")] - [TestCase(0, 120000000, "0.120s")] - [TestCase(0, 123000000, "0.123s")] - [TestCase(0, 123400000, "0.123400s")] - [TestCase(0, 123450000, "0.123450s")] - [TestCase(0, 123456000, "0.123456s")] - [TestCase(0, 123456700, "0.123456700s")] - [TestCase(0, 123456780, "0.123456780s")] - [TestCase(0, 123456789, "0.123456789s")] - [TestCase(0, -100000000, "-0.100s")] - [TestCase(1, 100000000, "1.100s")] - [TestCase(-1, -100000000, "-1.100s")] - public void DurationStandalone(long seconds, int nanoseconds, string expected) - { - var json = JsonFormatter.Default.Format(new Duration { Seconds = seconds, Nanos = nanoseconds }); - Assert.AreEqual(WrapInQuotes(expected), json); - } - - [Test] - [TestCase(1, 2123456789)] - [TestCase(1, -100000000)] - public void DurationStandalone_NonNormalized(long seconds, int nanoseconds) - { - var duration = new Duration { Seconds = seconds, Nanos = nanoseconds }; - Assert.Throws(() => JsonFormatter.Default.Format(duration)); - } - - [Test] - public void DurationField() - { - var message = new TestWellKnownTypes { DurationField = new Duration() }; - AssertJson("{ 'durationField': '0s' }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void StructSample() - { - var message = new Struct - { - Fields = - { - { "a", Value.ForNull() }, - { "b", Value.ForBool(false) }, - { "c", Value.ForNumber(10.5) }, - { "d", Value.ForString("text") }, - { "e", Value.ForList(Value.ForString("t1"), Value.ForNumber(5)) }, - { "f", Value.ForStruct(new Struct { Fields = { { "nested", Value.ForString("value") } } }) } - } - }; - AssertJson("{ 'a': null, 'b': false, 'c': 10.5, 'd': 'text', 'e': [ 't1', 5 ], 'f': { 'nested': 'value' } }", message.ToString()); - } - - [Test] - [TestCase("foo__bar")] - [TestCase("foo_3_ar")] - [TestCase("fooBar")] - public void FieldMaskInvalid(string input) - { - var mask = new FieldMask { Paths = { input } }; - Assert.Throws(() => JsonFormatter.Default.Format(mask)); - } - - [Test] - public void FieldMaskStandalone() - { - var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } }; - Assert.AreEqual("\",single,withUnderscore,nested.field.name,nested..doubleDot\"", fieldMask.ToString()); - - // Invalid, but we shouldn't create broken JSON... - fieldMask = new FieldMask { Paths = { "x\\y" } }; - Assert.AreEqual(@"""x\\y""", fieldMask.ToString()); - } - - [Test] - public void FieldMaskField() - { - var message = new TestWellKnownTypes { FieldMaskField = new FieldMask { Paths = { "user.display_name", "photo" } } }; - AssertJson("{ 'fieldMaskField': 'user.displayName,photo' }", JsonFormatter.Default.Format(message)); - } - - // SourceContext is an example of a well-known type with no special JSON handling - [Test] - public void SourceContextStandalone() - { - var message = new SourceContext { FileName = "foo.proto" }; - AssertJson("{ 'fileName': 'foo.proto' }", JsonFormatter.Default.Format(message)); - } - - [Test] - public void AnyWellKnownType() - { - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(Timestamp.Descriptor))); - var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp(); - var any = Any.Pack(timestamp); - AssertJson("{ '@type': 'type.googleapis.com/google.protobuf.Timestamp', 'value': '1673-06-19T12:34:56Z' }", formatter.Format(any)); - } - - [Test] - public void AnyMessageType() - { - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(TestAllTypes.Descriptor))); - var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } }; - var any = Any.Pack(message); - AssertJson("{ '@type': 'type.googleapis.com/protobuf_unittest3.TestAllTypes', 'singleInt32': 10, 'singleNestedMessage': { 'bb': 20 } }", formatter.Format(any)); - } - - [Test] - public void AnyMessageType_CustomPrefix() - { - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(TestAllTypes.Descriptor))); - var message = new TestAllTypes { SingleInt32 = 10 }; - var any = Any.Pack(message, "foo.bar/baz"); - AssertJson("{ '@type': 'foo.bar/baz/protobuf_unittest3.TestAllTypes', 'singleInt32': 10 }", formatter.Format(any)); - } - - [Test] - public void AnyNested() - { - var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor); - var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(registry)); - - // Nest an Any as the value of an Any. - var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 }; - var nestedMessage = Any.Pack(doubleNestedMessage); - var message = new TestWellKnownTypes { AnyField = Any.Pack(nestedMessage) }; - AssertJson("{ 'anyField': { '@type': 'type.googleapis.com/google.protobuf.Any', 'value': { '@type': 'type.googleapis.com/protobuf_unittest3.TestAllTypes', 'singleInt32': 20 } } }", - formatter.Format(message)); - } - - [Test] - public void AnyUnknownType() - { - // The default type registry doesn't have any types in it. - var message = new TestAllTypes(); - var any = Any.Pack(message); - Assert.Throws(() => JsonFormatter.Default.Format(any)); - } - - [Test] - [TestCase(typeof(BoolValue), true, "true")] - [TestCase(typeof(Int32Value), 32, "32")] - [TestCase(typeof(Int64Value), 32L, "\"32\"")] - [TestCase(typeof(UInt32Value), 32U, "32")] - [TestCase(typeof(UInt64Value), 32UL, "\"32\"")] - [TestCase(typeof(StringValue), "foo", "\"foo\"")] - [TestCase(typeof(FloatValue), 1.5f, "1.5")] - [TestCase(typeof(DoubleValue), 1.5d, "1.5")] - public void Wrappers_Standalone(System.Type wrapperType, object value, string expectedJson) - { - IMessage populated = (IMessage)Activator.CreateInstance(wrapperType); - populated.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.SetValue(populated, value); - Assert.AreEqual(expectedJson, JsonFormatter.Default.Format(populated)); - } - - // Sanity tests for WriteValue. Not particularly comprehensive, as it's all covered above already, - // as FormatMessage uses WriteValue. - - [TestCase(null, "null")] - [TestCase(1, "1")] - [TestCase(1L, "'1'")] - [TestCase(0.5f, "0.5")] - [TestCase(0.5d, "0.5")] - [TestCase("text", "'text'")] - [TestCase("x\ny", @"'x\ny'")] - [TestCase(ForeignEnum.ForeignBar, "'FOREIGN_BAR'")] - public void WriteValue_Constant(object value, string expectedJson) - { - AssertWriteValue(value, expectedJson); - } - - [Test] - public void WriteValue_Timestamp() - { - var value = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp(); - AssertWriteValue(value, "'1673-06-19T12:34:56Z'"); - } - - [Test] - public void WriteValue_Message() - { - var value = new TestAllTypes { SingleInt32 = 100, SingleInt64 = 3210987654321L }; - AssertWriteValue(value, "{ 'singleInt32': 100, 'singleInt64': '3210987654321' }"); - } - - [Test] - public void WriteValue_List() - { - var value = new RepeatedField { 1, 2, 3 }; - AssertWriteValue(value, "[ 1, 2, 3 ]"); - } - - [Test] - public void Proto2_DefaultValuesWritten() - { - var value = new ProtobufTestMessages.Proto2.TestAllTypesProto2() { FieldName13 = 0 }; - AssertWriteValue(value, "{ 'FieldName13': 0 }"); - } - - private static void AssertWriteValue(object value, string expectedJson) - { - var writer = new StringWriter(); - JsonFormatter.Default.WriteValue(writer, value); - string actual = writer.ToString(); - AssertJson(expectedJson, actual); - } - - /// - /// Checks that the actual JSON is the same as the expected JSON - but after replacing - /// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier - /// to read. - /// - private static void AssertJson(string expectedJsonWithApostrophes, string actualJson) - { - var expectedJson = expectedJsonWithApostrophes.Replace("'", "\""); - Assert.AreEqual(expectedJson, actualJson); - } - } -} +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using Google.Protobuf.TestProtos; +using NUnit.Framework; +using UnitTest.Issues.TestProtos; +using Google.Protobuf.WellKnownTypes; +using Google.Protobuf.Reflection; + +using static Google.Protobuf.JsonParserTest; // For WrapInQuotes +using System.IO; +using Google.Protobuf.Collections; +using ProtobufUnittest; + +namespace Google.Protobuf +{ + /// + /// Tests for the JSON formatter. Note that in these tests, double quotes are replaced with apostrophes + /// for the sake of readability (embedding \" everywhere is painful). See the AssertJson method for details. + /// + public class JsonFormatterTest + { + [Test] + public void DefaultValues_WhenOmitted() + { + var formatter = JsonFormatter.Default; + + AssertJson("{ }", formatter.Format(new ForeignMessage())); + AssertJson("{ }", formatter.Format(new TestAllTypes())); + AssertJson("{ }", formatter.Format(new TestMap())); + } + + [Test] + public void DefaultValues_WhenIncluded() + { + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + AssertJson("{ 'c': 0 }", formatter.Format(new ForeignMessage())); + } + + [Test] + public void EnumAllowAlias() + { + var message = new TestEnumAllowAlias + { + Value = TestEnumWithDupValue.Foo2, + }; + var actualText = JsonFormatter.Default.Format(message); + var expectedText = "{ 'value': 'FOO1' }"; + AssertJson(expectedText, actualText); + } + + [Test] + public void EnumAsInt() + { + var message = new TestAllTypes + { + SingleForeignEnum = ForeignEnum.ForeignBar, + RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo } + }; + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatEnumsAsIntegers(true)); + var actualText = formatter.Format(message); + var expectedText = "{ " + + "'singleForeignEnum': 5, " + + "'repeatedForeignEnum': [ 6, 100, 4 ]" + + " }"; + AssertJson(expectedText, actualText); + } + + [Test] + public void AllSingleFields() + { + var message = new TestAllTypes + { + SingleBool = true, + SingleBytes = ByteString.CopyFrom(1, 2, 3, 4), + SingleDouble = 23.5, + SingleFixed32 = 23, + SingleFixed64 = 1234567890123, + SingleFloat = 12.25f, + SingleForeignEnum = ForeignEnum.ForeignBar, + SingleForeignMessage = new ForeignMessage { C = 10 }, + SingleImportEnum = ImportEnum.ImportBaz, + SingleImportMessage = new ImportMessage { D = 20 }, + SingleInt32 = 100, + SingleInt64 = 3210987654321, + SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo, + SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 }, + SinglePublicImportMessage = new PublicImportMessage { E = 54 }, + SingleSfixed32 = -123, + SingleSfixed64 = -12345678901234, + SingleSint32 = -456, + SingleSint64 = -12345678901235, + SingleString = "test\twith\ttabs", + SingleUint32 = uint.MaxValue, + SingleUint64 = ulong.MaxValue, + }; + var actualText = JsonFormatter.Default.Format(message); + + // Fields in numeric order + var expectedText = "{ " + + "'singleInt32': 100, " + + "'singleInt64': '3210987654321', " + + "'singleUint32': 4294967295, " + + "'singleUint64': '18446744073709551615', " + + "'singleSint32': -456, " + + "'singleSint64': '-12345678901235', " + + "'singleFixed32': 23, " + + "'singleFixed64': '1234567890123', " + + "'singleSfixed32': -123, " + + "'singleSfixed64': '-12345678901234', " + + "'singleFloat': 12.25, " + + "'singleDouble': 23.5, " + + "'singleBool': true, " + + "'singleString': 'test\\twith\\ttabs', " + + "'singleBytes': 'AQIDBA==', " + + "'singleNestedMessage': { 'bb': 35 }, " + + "'singleForeignMessage': { 'c': 10 }, " + + "'singleImportMessage': { 'd': 20 }, " + + "'singleNestedEnum': 'FOO', " + + "'singleForeignEnum': 'FOREIGN_BAR', " + + "'singleImportEnum': 'IMPORT_BAZ', " + + "'singlePublicImportMessage': { 'e': 54 }" + + " }"; + AssertJson(expectedText, actualText); + } + + [Test] + public void WithFormatDefaultValues_DoesNotAffectMessageFields() + { + var message = new TestAllTypes(); + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + Assert.IsFalse(json.Contains("\"singleNestedMessage\"")); + Assert.IsFalse(json.Contains("\"singleForeignMessage\"")); + Assert.IsFalse(json.Contains("\"singleImportMessage\"")); + } + + [Test] + public void WithFormatDefaultValues_DoesNotAffectProto3OptionalFields() + { + var message = new TestProto3Optional(); + message.OptionalInt32 = 0; + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + // The non-optional proto3 fields are formatted, as is the optional-but-specified field. + AssertJson("{ 'optionalInt32': 0, 'singularInt32': 0, 'singularInt64': '0' }", json); + } + + [Test] + public void WithFormatDefaultValues_DoesNotAffectProto2Fields() + { + var message = new TestProtos.Proto2.ForeignMessage(); + message.C = 0; + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + // The specified field is formatted, but the non-specified field (d) is not. + AssertJson("{ 'c': 0 }", json); + } + + [Test] + public void WithFormatDefaultValues_DoesNotAffectOneofFields() + { + var message = new TestOneof(); + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + AssertJson("{ }", json); + } + + [Test] + public void RepeatedField() + { + AssertJson("{ 'repeatedInt32': [ 1, 2, 3, 4, 5 ] }", + JsonFormatter.Default.Format(new TestAllTypes { RepeatedInt32 = { 1, 2, 3, 4, 5 } })); + } + + [Test] + public void MapField_StringString() + { + AssertJson("{ 'mapStringString': { 'with spaces': 'bar', 'a': 'b' } }", + JsonFormatter.Default.Format(new TestMap { MapStringString = { { "with spaces", "bar" }, { "a", "b" } } })); + } + + [Test] + public void MapField_Int32Int32() + { + // The keys are quoted, but the values aren't. + AssertJson("{ 'mapInt32Int32': { '0': 1, '2': 3 } }", + JsonFormatter.Default.Format(new TestMap { MapInt32Int32 = { { 0, 1 }, { 2, 3 } } })); + } + + [Test] + public void MapField_BoolBool() + { + // The keys are quoted, but the values aren't. + AssertJson("{ 'mapBoolBool': { 'false': true, 'true': false } }", + JsonFormatter.Default.Format(new TestMap { MapBoolBool = { { false, true }, { true, false } } })); + } + + [Test] + public void NullValueOutsideStruct() + { + var message = new NullValueOutsideStruct { NullValue = NullValue.NullValue }; + AssertJson("{ 'nullValue': null }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void NullValueNotInOneof() + { + var message = new NullValueNotInOneof(); + AssertJson("{ }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void NullValueNotInOneof_FormatDefaults() + { + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var message = new NullValueNotInOneof(); + AssertJson("{ 'nullValue': null }", formatter.Format(message)); + } + + [TestCase(1.0, "1")] + [TestCase(double.NaN, "'NaN'")] + [TestCase(double.PositiveInfinity, "'Infinity'")] + [TestCase(double.NegativeInfinity, "'-Infinity'")] + public void DoubleRepresentations(double value, string expectedValueText) + { + var message = new TestAllTypes { SingleDouble = value }; + string actualText = JsonFormatter.Default.Format(message); + string expectedText = "{ 'singleDouble': " + expectedValueText + " }"; + AssertJson(expectedText, actualText); + } + + [Test] + public void UnknownEnumValueNumeric_SingleField() + { + var message = new TestAllTypes { SingleForeignEnum = (ForeignEnum) 100 }; + AssertJson("{ 'singleForeignEnum': 100 }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void UnknownEnumValueNumeric_RepeatedField() + { + var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo } }; + AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 100, 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void UnknownEnumValueNumeric_MapField() + { + var message = new TestMap { MapInt32Enum = { { 1, MapEnum.Foo }, { 2, (MapEnum) 100 }, { 3, MapEnum.Bar } } }; + AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '2': 100, '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void UnknownEnumValue_RepeatedField_AllEntriesUnknown() + { + var message = new TestAllTypes { RepeatedForeignEnum = { (ForeignEnum) 200, (ForeignEnum) 100 } }; + AssertJson("{ 'repeatedForeignEnum': [ 200, 100 ] }", JsonFormatter.Default.Format(message)); + } + + [Test] + [TestCase("a\u17b4b", "a\\u17b4b")] // Explicit + [TestCase("a\u0601b", "a\\u0601b")] // Ranged + [TestCase("a\u0605b", "a\u0605b")] // Passthrough (note lack of double backslash...) + public void SimpleNonAscii(string text, string encoded) + { + var message = new TestAllTypes { SingleString = text }; + AssertJson("{ 'singleString': '" + encoded + "' }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void SurrogatePairEscaping() + { + var message = new TestAllTypes { SingleString = "a\uD801\uDC01b" }; + AssertJson("{ 'singleString': 'a\\ud801\\udc01b' }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void InvalidSurrogatePairsFail() + { + // Note: don't use TestCase for these, as the strings can't be reliably represented + // See http://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a-string/ + + // Lone low surrogate + var message = new TestAllTypes { SingleString = "a\uDC01b" }; + Assert.Throws(() => JsonFormatter.Default.Format(message)); + + // Lone high surrogate + message = new TestAllTypes { SingleString = "a\uD801b" }; + Assert.Throws(() => JsonFormatter.Default.Format(message)); + } + + [Test] + [TestCase("foo_bar", "fooBar")] + [TestCase("bananaBanana", "bananaBanana")] + [TestCase("BANANABanana", "BANANABanana")] + [TestCase("simple", "simple")] + [TestCase("ACTION_AND_ADVENTURE", "ACTIONANDADVENTURE")] + [TestCase("action_and_adventure", "actionAndAdventure")] + [TestCase("kFoo", "kFoo")] + [TestCase("HTTPServer", "HTTPServer")] + [TestCase("CLIENT", "CLIENT")] + public void ToJsonName(string original, string expected) + { + Assert.AreEqual(expected, JsonFormatter.ToJsonName(original)); + } + + [Test] + [TestCase(null, "{ }")] + [TestCase("x", "{ 'fooString': 'x' }")] + [TestCase("", "{ 'fooString': '' }")] + public void Oneof(string fooStringValue, string expectedJson) + { + var message = new TestOneof(); + if (fooStringValue != null) + { + message.FooString = fooStringValue; + } + + // We should get the same result both with and without "format default values". + var formatter = JsonFormatter.Default; + AssertJson(expectedJson, formatter.Format(message)); + formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + AssertJson(expectedJson, formatter.Format(message)); + } + + [Test] + public void WrapperFormatting_Single() + { + // Just a few examples, handling both classes and value types, and + // default vs non-default values + var message = new TestWellKnownTypes + { + Int64Field = 10, + Int32Field = 0, + BytesField = ByteString.FromBase64("ABCD"), + StringField = "" + }; + var expectedJson = "{ 'int64Field': '10', 'int32Field': 0, 'stringField': '', 'bytesField': 'ABCD' }"; + AssertJson(expectedJson, JsonFormatter.Default.Format(message)); + } + + [Test] + public void WrapperFormatting_Message() + { + Assert.AreEqual("\"\"", JsonFormatter.Default.Format(new StringValue())); + Assert.AreEqual("0", JsonFormatter.Default.Format(new Int32Value())); + } + + [Test] + public void WrapperFormatting_FormatDefaultValuesDoesNotFormatNull() + { + // The actual JSON here is very large because there are lots of fields. Just test a couple of them. + var message = new TestWellKnownTypes { Int32Field = 10 }; + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var actualJson = formatter.Format(message); + // This *used* to include "int64Field": null, but that was a bug. + // WithDefaultValues should not affect message fields, including wrapper types. + Assert.IsFalse(actualJson.Contains("\"int64Field\": null")); + Assert.IsTrue(actualJson.Contains("\"int32Field\": 10")); + } + + [Test] + public void OutputIsInNumericFieldOrder_NoDefaults() + { + var formatter = JsonFormatter.Default; + var message = new TestJsonFieldOrdering { PlainString = "p1", PlainInt32 = 2 }; + AssertJson("{ 'plainString': 'p1', 'plainInt32': 2 }", formatter.Format(message)); + message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" }; + AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message)); + message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" }; + AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message)); + } + + [Test] + public void OutputIsInNumericFieldOrder_WithDefaults() + { + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var message = new TestJsonFieldOrdering(); + AssertJson("{ 'plainString': '', 'plainInt32': 0 }", formatter.Format(message)); + message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" }; + AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message)); + message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" }; + AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message)); + } + + [Test] + [TestCase("1970-01-01T00:00:00Z", 0)] + [TestCase("1970-01-01T00:00:00.000000001Z", 1)] + [TestCase("1970-01-01T00:00:00.000000010Z", 10)] + [TestCase("1970-01-01T00:00:00.000000100Z", 100)] + [TestCase("1970-01-01T00:00:00.000001Z", 1000)] + [TestCase("1970-01-01T00:00:00.000010Z", 10000)] + [TestCase("1970-01-01T00:00:00.000100Z", 100000)] + [TestCase("1970-01-01T00:00:00.001Z", 1000000)] + [TestCase("1970-01-01T00:00:00.010Z", 10000000)] + [TestCase("1970-01-01T00:00:00.100Z", 100000000)] + [TestCase("1970-01-01T00:00:00.120Z", 120000000)] + [TestCase("1970-01-01T00:00:00.123Z", 123000000)] + [TestCase("1970-01-01T00:00:00.123400Z", 123400000)] + [TestCase("1970-01-01T00:00:00.123450Z", 123450000)] + [TestCase("1970-01-01T00:00:00.123456Z", 123456000)] + [TestCase("1970-01-01T00:00:00.123456700Z", 123456700)] + [TestCase("1970-01-01T00:00:00.123456780Z", 123456780)] + [TestCase("1970-01-01T00:00:00.123456789Z", 123456789)] + public void TimestampStandalone(string expected, int nanos) + { + Assert.AreEqual(WrapInQuotes(expected), new Timestamp { Nanos = nanos }.ToString()); + } + + [Test] + public void TimestampStandalone_FromDateTime() + { + // One before and one after the Unix epoch, more easily represented via DateTime. + Assert.AreEqual("\"1673-06-19T12:34:56Z\"", + new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp().ToString()); + Assert.AreEqual("\"2015-07-31T10:29:34Z\"", + new DateTime(2015, 7, 31, 10, 29, 34, DateTimeKind.Utc).ToTimestamp().ToString()); + } + + [Test] + [TestCase(-1, -1)] // Would be valid as duration + [TestCase(1, Timestamp.MaxNanos + 1)] + [TestCase(Timestamp.UnixSecondsAtBclMaxValue + 1, 0)] + [TestCase(Timestamp.UnixSecondsAtBclMinValue - 1, 0)] + public void TimestampStandalone_NonNormalized(long seconds, int nanoseconds) + { + var timestamp = new Timestamp { Seconds = seconds, Nanos = nanoseconds }; + Assert.Throws(() => JsonFormatter.Default.Format(timestamp)); + } + + [Test] + public void TimestampField() + { + var message = new TestWellKnownTypes { TimestampField = new Timestamp() }; + AssertJson("{ 'timestampField': '1970-01-01T00:00:00Z' }", JsonFormatter.Default.Format(message)); + } + + [Test] + [TestCase(0, 0, "0s")] + [TestCase(1, 0, "1s")] + [TestCase(-1, 0, "-1s")] + [TestCase(0, 1, "0.000000001s")] + [TestCase(0, 10, "0.000000010s")] + [TestCase(0, 100, "0.000000100s")] + [TestCase(0, 1000, "0.000001s")] + [TestCase(0, 10000, "0.000010s")] + [TestCase(0, 100000, "0.000100s")] + [TestCase(0, 1000000, "0.001s")] + [TestCase(0, 10000000, "0.010s")] + [TestCase(0, 100000000, "0.100s")] + [TestCase(0, 120000000, "0.120s")] + [TestCase(0, 123000000, "0.123s")] + [TestCase(0, 123400000, "0.123400s")] + [TestCase(0, 123450000, "0.123450s")] + [TestCase(0, 123456000, "0.123456s")] + [TestCase(0, 123456700, "0.123456700s")] + [TestCase(0, 123456780, "0.123456780s")] + [TestCase(0, 123456789, "0.123456789s")] + [TestCase(0, -100000000, "-0.100s")] + [TestCase(1, 100000000, "1.100s")] + [TestCase(-1, -100000000, "-1.100s")] + public void DurationStandalone(long seconds, int nanoseconds, string expected) + { + var json = JsonFormatter.Default.Format(new Duration { Seconds = seconds, Nanos = nanoseconds }); + Assert.AreEqual(WrapInQuotes(expected), json); + } + + [Test] + [TestCase(1, 2123456789)] + [TestCase(1, -100000000)] + public void DurationStandalone_NonNormalized(long seconds, int nanoseconds) + { + var duration = new Duration { Seconds = seconds, Nanos = nanoseconds }; + Assert.Throws(() => JsonFormatter.Default.Format(duration)); + } + + [Test] + public void DurationField() + { + var message = new TestWellKnownTypes { DurationField = new Duration() }; + AssertJson("{ 'durationField': '0s' }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void StructSample() + { + var message = new Struct + { + Fields = + { + { "a", Value.ForNull() }, + { "b", Value.ForBool(false) }, + { "c", Value.ForNumber(10.5) }, + { "d", Value.ForString("text") }, + { "e", Value.ForList(Value.ForString("t1"), Value.ForNumber(5)) }, + { "f", Value.ForStruct(new Struct { Fields = { { "nested", Value.ForString("value") } } }) } + } + }; + AssertJson("{ 'a': null, 'b': false, 'c': 10.5, 'd': 'text', 'e': [ 't1', 5 ], 'f': { 'nested': 'value' } }", message.ToString()); + } + + [Test] + [TestCase("foo__bar")] + [TestCase("foo_3_ar")] + [TestCase("fooBar")] + public void FieldMaskInvalid(string input) + { + var mask = new FieldMask { Paths = { input } }; + Assert.Throws(() => JsonFormatter.Default.Format(mask)); + } + + [Test] + public void FieldMaskStandalone() + { + var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } }; + Assert.AreEqual("\",single,withUnderscore,nested.field.name,nested..doubleDot\"", fieldMask.ToString()); + + // Invalid, but we shouldn't create broken JSON... + fieldMask = new FieldMask { Paths = { "x\\y" } }; + Assert.AreEqual(@"""x\\y""", fieldMask.ToString()); + } + + [Test] + public void FieldMaskField() + { + var message = new TestWellKnownTypes { FieldMaskField = new FieldMask { Paths = { "user.display_name", "photo" } } }; + AssertJson("{ 'fieldMaskField': 'user.displayName,photo' }", JsonFormatter.Default.Format(message)); + } + + // SourceContext is an example of a well-known type with no special JSON handling + [Test] + public void SourceContextStandalone() + { + var message = new SourceContext { FileName = "foo.proto" }; + AssertJson("{ 'fileName': 'foo.proto' }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void AnyWellKnownType() + { + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(Timestamp.Descriptor))); + var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp(); + var any = Any.Pack(timestamp); + AssertJson("{ '@type': 'type.googleapis.com/google.protobuf.Timestamp', 'value': '1673-06-19T12:34:56Z' }", formatter.Format(any)); + } + + [Test] + public void AnyMessageType() + { + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(TestAllTypes.Descriptor))); + var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } }; + var any = Any.Pack(message); + AssertJson("{ '@type': 'type.googleapis.com/protobuf_unittest3.TestAllTypes', 'singleInt32': 10, 'singleNestedMessage': { 'bb': 20 } }", formatter.Format(any)); + } + + [Test] + public void AnyMessageType_CustomPrefix() + { + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(TestAllTypes.Descriptor))); + var message = new TestAllTypes { SingleInt32 = 10 }; + var any = Any.Pack(message, "foo.bar/baz"); + AssertJson("{ '@type': 'foo.bar/baz/protobuf_unittest3.TestAllTypes', 'singleInt32': 10 }", formatter.Format(any)); + } + + [Test] + public void AnyNested() + { + var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor); + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(registry)); + + // Nest an Any as the value of an Any. + var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 }; + var nestedMessage = Any.Pack(doubleNestedMessage); + var message = new TestWellKnownTypes { AnyField = Any.Pack(nestedMessage) }; + AssertJson("{ 'anyField': { '@type': 'type.googleapis.com/google.protobuf.Any', 'value': { '@type': 'type.googleapis.com/protobuf_unittest3.TestAllTypes', 'singleInt32': 20 } } }", + formatter.Format(message)); + } + + [Test] + public void AnyUnknownType() + { + // The default type registry doesn't have any types in it. + var message = new TestAllTypes(); + var any = Any.Pack(message); + Assert.Throws(() => JsonFormatter.Default.Format(any)); + } + + [Test] + [TestCase(typeof(BoolValue), true, "true")] + [TestCase(typeof(Int32Value), 32, "32")] + [TestCase(typeof(Int64Value), 32L, "\"32\"")] + [TestCase(typeof(UInt32Value), 32U, "32")] + [TestCase(typeof(UInt64Value), 32UL, "\"32\"")] + [TestCase(typeof(StringValue), "foo", "\"foo\"")] + [TestCase(typeof(FloatValue), 1.5f, "1.5")] + [TestCase(typeof(DoubleValue), 1.5d, "1.5")] + public void Wrappers_Standalone(System.Type wrapperType, object value, string expectedJson) + { + IMessage populated = (IMessage)Activator.CreateInstance(wrapperType); + populated.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.SetValue(populated, value); + Assert.AreEqual(expectedJson, JsonFormatter.Default.Format(populated)); + } + + // Sanity tests for WriteValue. Not particularly comprehensive, as it's all covered above already, + // as FormatMessage uses WriteValue. + + [TestCase(null, "null")] + [TestCase(1, "1")] + [TestCase(1L, "'1'")] + [TestCase(0.5f, "0.5")] + [TestCase(0.5d, "0.5")] + [TestCase("text", "'text'")] + [TestCase("x\ny", @"'x\ny'")] + [TestCase(ForeignEnum.ForeignBar, "'FOREIGN_BAR'")] + public void WriteValue_Constant(object value, string expectedJson) + { + AssertWriteValue(value, expectedJson); + } + + [Test] + public void WriteValue_Timestamp() + { + var value = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp(); + AssertWriteValue(value, "'1673-06-19T12:34:56Z'"); + } + + [Test] + public void WriteValue_Message() + { + var value = new TestAllTypes { SingleInt32 = 100, SingleInt64 = 3210987654321L }; + AssertWriteValue(value, "{ 'singleInt32': 100, 'singleInt64': '3210987654321' }"); + } + + [Test] + public void WriteValue_Message_PreserveNames() + { + var value = new TestAllTypes { SingleInt32 = 100, SingleInt64 = 3210987654321L }; + AssertWriteValue(value, "{ 'single_int32': 100, 'single_int64': '3210987654321' }", JsonFormatter.Settings.Default.WithPreserveProtoFieldNames(true)); + } + + [Test] + public void WriteValue_List() + { + var value = new RepeatedField { 1, 2, 3 }; + AssertWriteValue(value, "[ 1, 2, 3 ]"); + } + + [Test] + public void Proto2_DefaultValuesWritten() + { + var value = new ProtobufTestMessages.Proto2.TestAllTypesProto2() { FieldName13 = 0 }; + AssertWriteValue(value, "{ 'FieldName13': 0 }"); + } + + private static void AssertWriteValue(object value, string expectedJson, JsonFormatter.Settings settings = null) + { + var writer = new StringWriter(); + new JsonFormatter(settings ?? JsonFormatter.Settings.Default).WriteValue(writer, value); + string actual = writer.ToString(); + AssertJson(expectedJson, actual); + } + + /// + /// Checks that the actual JSON is the same as the expected JSON - but after replacing + /// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier + /// to read. + /// + private static void AssertJson(string expectedJsonWithApostrophes, string actualJson) + { + var expectedJson = expectedJsonWithApostrophes.Replace("'", "\""); + Assert.AreEqual(expectedJson, actualJson); + } + } +} 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/UnknownFieldSetTest.cs b/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs index 15debc1b6c8e4..f3e5af2056961 100644 --- a/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs +++ b/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs @@ -138,6 +138,29 @@ public void TestClone(IMessage message) Assert.AreEqual(message.ToByteArray(), otherEmptyMessage.ToByteArray()); } + [Test] + public void TestClone_LengthDelimited() + { + var unknownVarintField = new UnknownField(); + unknownVarintField.AddVarint(99); + + var unknownLengthDelimitedField1 = new UnknownField(); + unknownLengthDelimitedField1.AddLengthDelimited(ByteString.CopyFromUtf8("some data")); + + var unknownLengthDelimitedField2 = new UnknownField(); + unknownLengthDelimitedField2.AddLengthDelimited(ByteString.CopyFromUtf8("some more data")); + + var destUnknownFieldSet = new UnknownFieldSet(); + destUnknownFieldSet.AddOrReplaceField(997, unknownVarintField); + destUnknownFieldSet.AddOrReplaceField(999, unknownLengthDelimitedField1); + destUnknownFieldSet.AddOrReplaceField(999, unknownLengthDelimitedField2); + + var clone = UnknownFieldSet.Clone(destUnknownFieldSet); + + Assert.IsTrue(clone.HasField(997)); + Assert.IsTrue(clone.HasField(999)); + } + [Test] [TestCaseSource(typeof(Data), "Messages")] public void TestDiscardUnknownFields(IMessage message) diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index f1f44f1c54670..ab60703568c98 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 010e4b4272718..9f8897a02c9c7 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -4,7 +4,7 @@ C# runtime library for Protocol Buffers - Google's data interchange format. Copyright 2015, Google Inc. Google Protocol Buffers - 3.19.4 + 3.20.0-rc2 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..db7dc5c809bcf 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 { @@ -232,7 +233,14 @@ private bool WriteMessageFields(TextWriter writer, IMessage message, bool assume writer.Write(PropertySeparator); } - WriteString(writer, accessor.Descriptor.JsonName); + if (settings.PreserveProtoFieldNames) + { + WriteString(writer, accessor.Descriptor.Name); + } + else + { + WriteString(writer, accessor.Descriptor.JsonName); + } writer.Write(NameValueSeparator); WriteValue(writer, value); @@ -815,6 +823,11 @@ static Settings() /// public bool FormatEnumsAsIntegers { get; } + /// + /// Whether to use the original proto field names as defined in the .proto file. Defaults to false. + /// + public bool PreserveProtoFieldNames { get; } + /// /// Creates a new object with the specified formatting of default values @@ -831,7 +844,7 @@ public Settings(bool formatDefaultValues) : this(formatDefaultValues, TypeRegist /// /// true if default values (0, empty strings etc) should be formatted; false otherwise. /// The to use when formatting messages. - public Settings(bool formatDefaultValues, TypeRegistry typeRegistry) : this(formatDefaultValues, typeRegistry, false) + public Settings(bool formatDefaultValues, TypeRegistry typeRegistry) : this(formatDefaultValues, typeRegistry, false, false) { } @@ -841,32 +854,41 @@ public Settings(bool formatDefaultValues, TypeRegistry typeRegistry) : this(form /// true if default values (0, empty strings etc) should be formatted; false otherwise. /// The to use when formatting messages. TypeRegistry.Empty will be used if it is null. /// true to format the enums as integers; false to format enums as enum names. + /// true to preserve proto field names; false to convert them to lowerCamelCase. private Settings(bool formatDefaultValues, TypeRegistry typeRegistry, - bool formatEnumsAsIntegers) + bool formatEnumsAsIntegers, + bool preserveProtoFieldNames) { FormatDefaultValues = formatDefaultValues; TypeRegistry = typeRegistry ?? TypeRegistry.Empty; FormatEnumsAsIntegers = formatEnumsAsIntegers; + PreserveProtoFieldNames = preserveProtoFieldNames; } /// /// Creates a new object with the specified formatting of default values and the current settings. /// /// true if default values (0, empty strings etc) should be formatted; false otherwise. - public Settings WithFormatDefaultValues(bool formatDefaultValues) => new Settings(formatDefaultValues, TypeRegistry, FormatEnumsAsIntegers); + public Settings WithFormatDefaultValues(bool formatDefaultValues) => new Settings(formatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames); /// /// Creates a new object with the specified type registry and the current settings. /// /// The to use when formatting messages. - public Settings WithTypeRegistry(TypeRegistry typeRegistry) => new Settings(FormatDefaultValues, typeRegistry, FormatEnumsAsIntegers); + public Settings WithTypeRegistry(TypeRegistry typeRegistry) => new Settings(FormatDefaultValues, typeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames); /// /// Creates a new object with the specified enums formatting option and the current settings. /// /// true to format the enums as integers; false to format enums as enum names. - public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) => new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers); + public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) => new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers, PreserveProtoFieldNames); + + /// + /// Creates a new object with the specified field name formatting option and the current settings. + /// + /// true to preserve proto field names; false to convert them to lowerCamelCase. + public Settings WithPreserveProtoFieldNames(bool preserveProtoFieldNames) => new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, preserveProtoFieldNames); } // Effectively a cache of mapping from enum values to the original name as specified in the proto file, @@ -879,6 +901,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 +922,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 +937,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/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..cd4d0958dbe3c 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; @@ -10101,8 +10164,8 @@ public Location Clone() { /// location. /// /// Each element is a field number or an index. They form a path from - /// the root FileDescriptorProto to the place where the definition. For - /// example, this path: + /// the root FileDescriptorProto to the place where the definition occurs. + /// For example, this path: /// [ 4, 3, 2, 7, 1 ] /// refers to: /// file.message_type(3) // 4, 3 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 0ba16cf96f205..84ad49d276380 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs @@ -91,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. /// @@ -239,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; } } } @@ -452,7 +461,7 @@ private IFieldAccessor CreateAccessor() } 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/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs index 7b5019a8acd02..13066da3fedce 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs @@ -65,7 +65,7 @@ static AnyReflection() { /// foo = any.unpack(Foo.class); /// } /// - /// Example 3: Pack and unpack a message in Python. + /// Example 3: Pack and unpack a message in Python. /// /// foo = Foo(...) /// any = Any() @@ -75,7 +75,7 @@ static AnyReflection() { /// any.Unpack(foo) /// ... /// - /// Example 4: Pack and unpack a message in Go + /// Example 4: Pack and unpack a message in Go /// /// foo := &pb.Foo{...} /// any, err := anypb.New(foo) @@ -95,7 +95,7 @@ static AnyReflection() { /// name "y.z". /// /// JSON - /// ==== + /// /// The JSON representation of an `Any` value uses the regular /// representation of the deserialized, embedded message, with an /// additional field `@type` which contains the type URL. Example: 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/csharp/src/Google.Protobuf/WireFormat.cs b/csharp/src/Google.Protobuf/WireFormat.cs index 68f0f4a1f5209..201fd16e0d025 100644 --- a/csharp/src/Google.Protobuf/WireFormat.cs +++ b/csharp/src/Google.Protobuf/WireFormat.cs @@ -90,7 +90,7 @@ public static WireType GetTagWireType(uint tag) /// public static int GetTagFieldNumber(uint tag) { - return (int) tag >> TagTypeBits; + return (int) (tag >> TagTypeBits); } /// diff --git a/docs/options.md b/docs/options.md index 159951ac3c3eb..dbb3563af6cdf 100644 --- a/docs/options.md +++ b/docs/options.md @@ -292,3 +292,15 @@ 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 + +1. Embedded Proto + * Website: https://EmbeddedProto.com + * Extension: 1141 diff --git a/docs/third_party.md b/docs/third_party.md index 645ada81f4e4f..f09cff2fcbfe2 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,29 +71,28 @@ 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 @@ -101,15 +100,16 @@ These are projects we know about implementing Protocol Buffers for other program * 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 @@ -130,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) @@ -159,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) @@ -201,3 +201,4 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [intellij-protolint: A protobuf linter for JetBrains IDEs](https://github.com/yoheimuta/intellij-protolint) * [vim-protolint: A protobuf linter for Vim](https://github.com/yoheimuta/vim-protolint) * [super-linter: Protocol Buffer lint as GitHub Action](https://github.com/github/super-linter) +* [protoc-gen-fieldmask - A plugin to generate static type fieldmask paths](https://github.com/idodod/protoc-gen-fieldmask) diff --git a/editors/protobuf-mode.el b/editors/protobuf-mode.el index bbb82b7f4bda7..e97b95cf38a38 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 -(define-derived-mode protobuf-mode prog-mode "Protobuf" +(define-derived-mode protobuf-mode prog-mode "Protocol-Buffers" "Major mode for editing Protocol Buffers description language. The hook `c-mode-common-hook' is run with no argument at mode @@ -201,26 +201,17 @@ initialization, then `protobuf-mode-hook'. Key bindings: \\{protobuf-mode-map}" - (interactive) - (kill-all-local-variables) - (set-syntax-table protobuf-mode-syntax-table) - (setq major-mode 'protobuf-mode - mode-name "Protocol-Buffers" - local-abbrev-table protobuf-mode-abbrev-table - abbrev-mode t) - (use-local-map protobuf-mode-map) + :after-hook (c-update-modeline) + (setq abbrev-mode t) (c-initialize-cc-mode t) - (if (fboundp 'c-make-emacs-variables-local) - (c-make-emacs-variables-local)) (c-init-language-vars protobuf-mode) (c-common-init 'protobuf-mode) (easy-menu-add protobuf-menu) - (c-run-mode-hooks 'c-mode-common-hook 'protobuf-mode-hook) - (c-update-modeline) (setq imenu-generic-expression '(("Message" "^[[:space:]]*message[[:space:]]+\\([[:alnum:]]+\\)" 1) ("Enum" "^[[:space:]]*enum[[:space:]]+\\([[:alnum:]]+\\)" 1) - ("Service" "^[[:space:]]*service[[:space:]]+\\([[:alnum:]]+\\)" 1)))) + ("Service" "^[[:space:]]*service[[:space:]]+\\([[:alnum:]]+\\)" 1))) + (c-run-mode-hooks 'c-mode-common-hook)) (provide 'protobuf-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..4a1cdc2c0f5d1 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", ], @@ -11,6 +13,8 @@ filegroup( name = "release", srcs = [ "//java/core:release", # contains lite. + "//java/kotlin:release", + "//java/kotlin-lite:release", "//java/util:release", ] -) \ No newline at end of file +) diff --git a/java/README.md b/java/README.md index 0170b9d77269f..637235aaa432b 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.19.4 + 3.20.0-rc-2 ``` @@ -37,7 +37,7 @@ protobuf-java-util package: com.google.protobuf protobuf-java-util - 3.19.4 + 3.20.0-rc-2 ``` @@ -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.19.4' + implementation 'com.google.protobuf:protobuf-java:3.20.0-rc-2' ``` 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 c818a142dd580..7af3c7b177ee6 100644 --- a/java/bom/pom.xml +++ b/java/bom/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-bom - 3.19.4 + 3.20.0-rc-2 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 419eafb58a6f5..011fb1c7e16c2 100644 --- a/java/core/BUILD +++ b/java/core/BUILD @@ -27,6 +27,7 @@ LITE_SRCS = [ "src/main/java/com/google/protobuf/CodedInputStreamReader.java", "src/main/java/com/google/protobuf/CodedOutputStream.java", "src/main/java/com/google/protobuf/CodedOutputStreamWriter.java", + "src/main/java/com/google/protobuf/CompileTimeConstant.java", "src/main/java/com/google/protobuf/DoubleArrayList.java", "src/main/java/com/google/protobuf/ExperimentalApi.java", "src/main/java/com/google/protobuf/ExtensionLite.java", @@ -41,6 +42,7 @@ LITE_SRCS = [ "src/main/java/com/google/protobuf/FloatArrayList.java", "src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java", "src/main/java/com/google/protobuf/GeneratedMessageLite.java", + "src/main/java/com/google/protobuf/InlineMe.java", "src/main/java/com/google/protobuf/IntArrayList.java", "src/main/java/com/google/protobuf/Internal.java", "src/main/java/com/google/protobuf/InvalidProtocolBufferException.java", @@ -176,6 +178,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( @@ -216,6 +233,7 @@ java_library( "@maven//:com_google_guava_guava", "@maven//:junit_junit", ], + visibility = ["//java:__subpackages__"], ) test_suite( @@ -263,7 +281,7 @@ junit_tests( "@maven//:com_google_guava_guava", "@maven//:com_google_truth_truth", "@maven//:junit_junit", - "@maven//:org_easymock_easymock", + "@maven//:org_mockito_mockito_core", ], ) @@ -319,6 +337,7 @@ java_library( ], visibility = [ "//java/lite:__pkg__", + "//java/kotlin-lite:__pkg__", ], deps = [ ":generic_test_protos_java_proto_lite", @@ -389,6 +408,6 @@ junit_tests( ":test_util_lite", "@maven//:com_google_truth_truth", "@maven//:junit_junit", - "@maven//:org_easymock_easymock", + "@maven//:org_mockito_mockito_core", ], ) diff --git a/java/core/generate-test-sources-build.xml b/java/core/generate-test-sources-build.xml index 71a88d07b33b3..bad6f19c6162f 100644 --- a/java/core/generate-test-sources-build.xml +++ b/java/core/generate-test-sources-build.xml @@ -4,6 +4,7 @@ + @@ -22,6 +23,7 @@ + @@ -30,7 +32,6 @@ - diff --git a/java/core/pom.xml b/java/core/pom.xml index ce068ee684037..7ee824037de42 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.19.4 + 3.20.0-rc-2 protobuf-java @@ -23,8 +23,8 @@ test - org.easymock - easymock + org.mockito + mockito-core test 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..0fc88ae450fa0 100644 --- a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java +++ b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java @@ -43,15 +43,17 @@ * IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when * crossing protobuf public API boundaries. */ +@CheckReturnValue final class ArrayDecoders { + + private ArrayDecoders() { + } + /** * A helper used to return multiple values in a Java function. Java doesn't natively support * returning multiple values in a function. Creating a new Object to hold the return values will * be too expensive. Instead, we pass a Registers instance to functions that want to return * multiple values and let the function set the return value in this Registers instance instead. - * - *

TODO(xiaofeng): This could be merged into CodedInputStream or CodedInputStreamReader which - * is already being passed through all the parsing routines. */ static final class Registers { public int int1; @@ -548,7 +550,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..480f85fd6d2a5 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). @@ -268,22 +305,20 @@ public int compare(ByteString former, ByteString latter) { ByteIterator latterBytes = latter.iterator(); while (formerBytes.hasNext() && latterBytes.hasNext()) { - // Note: This code was copied from com.google.common.primitives.UnsignedBytes#compare, - // as Guava libraries cannot be used in the {@code com.google.protobuf} package. int result = - Integer.compare(toInt(formerBytes.nextByte()), toInt(latterBytes.nextByte())); + Integer.valueOf(toInt(formerBytes.nextByte())) + .compareTo(toInt(latterBytes.nextByte())); if (result != 0) { return result; } } - - return Integer.compare(former.size(), latter.size()); + return Integer.valueOf(former.size()).compareTo(Integer.valueOf(latter.size())); } }; /** - * 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 +381,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/DescriptorMessageInfoFactory.java b/java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java index 7975136596a85..6090985e181e5 100644 --- a/java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java +++ b/java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java @@ -61,8 +61,32 @@ final class DescriptorMessageInfoFactory implements MessageInfoFactory { private static final String GET_DEFAULT_INSTANCE_METHOD_NAME = "getDefaultInstance"; private static final DescriptorMessageInfoFactory instance = new DescriptorMessageInfoFactory(); + + /** + * Names that should be avoided (in UpperCamelCase format). Using them causes the compiler to + * generate accessors whose names collide with methods defined in base classes. + * + *

Keep this list in sync with kForbiddenWordList in + * src/google/protobuf/compiler/java/java_helpers.cc + */ private static final Set specialFieldNames = - new HashSet<>(Arrays.asList("cached_size", "serialized_size", "class")); + new HashSet<>( + Arrays.asList( + // java.lang.Object: + "Class", + // com.google.protobuf.MessageLiteOrBuilder: + "DefaultInstanceForType", + // com.google.protobuf.MessageLite: + "ParserForType", + "SerializedSize", + // com.google.protobuf.MessageOrBuilder: + "AllFields", + "DescriptorForType", + "InitializationErrorString", + // TODO(b/219045204): re-enable + // "UnknownFields", + // obsolete. kept for backwards compatibility of generated code + "CachedSize")); // Disallow construction - it's a singleton. private DescriptorMessageInfoFactory() {} @@ -125,6 +149,8 @@ private static MessageInfo convert(Class messageType, Descriptor messageDescr * *

This class is thread-safe. */ + //

The code is adapted from the C++ implementation: + // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/compiler/java/java_helpers.h static class IsInitializedCheckAnalyzer { private final Map resultCache = @@ -593,21 +619,104 @@ static String getFieldName(FieldDescriptor fd) { String name = (fd.getType() == FieldDescriptor.Type.GROUP) ? fd.getMessageType().getName() : fd.getName(); - String suffix = specialFieldNames.contains(name) ? "__" : "_"; - return snakeCaseToCamelCase(name) + suffix; + + // convert to UpperCamelCase for comparison to the specialFieldNames + // (which are in UpperCamelCase) + String upperCamelCaseName = snakeCaseToUpperCamelCase(name); + + // Append underscores to match the behavior of the protoc java compiler + final String suffix; + if (specialFieldNames.contains(upperCamelCaseName)) { + // For proto field names that match the specialFieldNames, + // the protoc java compiler appends "__" to the java field name + // to prevent the field's accessor method names from clashing with other methods. + // For example: + // proto field name = "class" + // java field name = "class__" + // accessor method name = "getClass_()" (so that it does not clash with + // Object.getClass()) + suffix = "__"; + } else { + // For other proto field names, + // the protoc java compiler appends "_" to the java field name + // to prevent field names from clashing with java keywords. + // For example: + // proto field name = "int" + // java field name = "int_" (so that it does not clash with int keyword) + // accessor method name = "getInt()" + suffix = "_"; + } + return snakeCaseToLowerCamelCase(name) + suffix; } private static String getCachedSizeFieldName(FieldDescriptor fd) { - return snakeCaseToCamelCase(fd.getName()) + "MemoizedSerializedSize"; + return snakeCaseToLowerCamelCase(fd.getName()) + "MemoizedSerializedSize"; + } + + /** + * Converts a snake case string into lower camel case. + * + *

Some examples: + * + *

+   *     snakeCaseToLowerCamelCase("foo_bar") => "fooBar"
+   *     snakeCaseToLowerCamelCase("foo") => "foo"
+   * 
+ * + * @param snakeCase the string in snake case to convert + * @return the string converted to camel case, with a lowercase first character + */ + private static String snakeCaseToLowerCamelCase(String snakeCase) { + return snakeCaseToCamelCase(snakeCase, false); } /** - * This method must match exactly with the corresponding function in protocol compiler. See: - * https://github.com/google/protobuf/blob/v3.0.0/src/google/protobuf/compiler/java/java_helpers.cc#L153 + * Converts a snake case string into upper camel case. + * + *

Some examples: + * + *

+   *     snakeCaseToUpperCamelCase("foo_bar") => "FooBar"
+   *     snakeCaseToUpperCamelCase("foo") => "Foo"
+   * 
+ * + * @param snakeCase the string in snake case to convert + * @return the string converted to camel case, with an uppercase first character + */ + private static String snakeCaseToUpperCamelCase(String snakeCase) { + return snakeCaseToCamelCase(snakeCase, true); + } + + /** + * Converts a snake case string into camel case. + * + *

For better readability, prefer calling either {@link #snakeCaseToLowerCamelCase(String)} or + * {@link #snakeCaseToUpperCamelCase(String)}. + * + *

Some examples: + * + *

+   *     snakeCaseToCamelCase("foo_bar", false) => "fooBar"
+   *     snakeCaseToCamelCase("foo_bar", true) => "FooBar"
+   *     snakeCaseToCamelCase("foo", false) => "foo"
+   *     snakeCaseToCamelCase("foo", true) => "Foo"
+   *     snakeCaseToCamelCase("Foo", false) => "foo"
+   *     snakeCaseToCamelCase("fooBar", false) => "fooBar"
+   * 
+ * + *

This implementation of this method must exactly match the corresponding function in the + * protocol compiler. Specifically, the {@code UnderscoresToCamelCase} function in {@code + * src/google/protobuf/compiler/java/java_helpers.cc}. + * + * @param snakeCase the string in snake case to convert + * @param capFirst true if the first letter of the returned string should be uppercase. false if + * the first letter of the returned string should be lowercase. + * @return the string converted to camel case, with an uppercase or lowercase first character + * depending on if {@code capFirst} is true or false, respectively */ - private static String snakeCaseToCamelCase(String snakeCase) { + private static String snakeCaseToCamelCase(String snakeCase, boolean capFirst) { StringBuilder sb = new StringBuilder(snakeCase.length() + 1); - boolean capNext = false; + boolean capNext = capFirst; for (int ctr = 0; ctr < snakeCase.length(); ctr++) { char next = snakeCase.charAt(ctr); if (next == '_') { @@ -653,7 +762,7 @@ private static Class getTypeForRepeatedMessageField(Class messageType, Fie /** Constructs the name of the get method for the given field in the proto. */ private static String getterForField(String snakeCase) { - String camelCase = snakeCaseToCamelCase(snakeCase); + String camelCase = snakeCaseToLowerCamelCase(snakeCase); StringBuilder builder = new StringBuilder("get"); // Capitalize the first character in the field name. builder.append(Character.toUpperCase(camelCase.charAt(0))); @@ -679,7 +788,7 @@ OneofInfo getOneof(Class messageType, OneofDescriptor desc) { } private static OneofInfo newInfo(Class messageType, OneofDescriptor desc) { - String camelCase = snakeCaseToCamelCase(desc.getName()); + String camelCase = snakeCaseToLowerCamelCase(desc.getName()); String valueFieldName = camelCase + "_"; String caseFieldName = camelCase + "Case_"; 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..99d088ae7aa40 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(); @@ -1941,7 +1941,7 @@ public static final class EnumValueDescriptor extends GenericDescriptor new Comparator() { @Override public int compare(EnumValueDescriptor o1, EnumValueDescriptor o2) { - return Integer.compare(o1.getNumber(), o2.getNumber()); + return Integer.valueOf(o1.getNumber()).compareTo(o2.getNumber()); } }; @@ -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 8d1136036836f..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) { @@ -1114,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 { @@ -1169,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(); } @@ -1194,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<>(); @@ -1262,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(); @@ -1271,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..20da4d8036454 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -692,7 +692,7 @@ private void mergeMessageSetExtensionFromCoded // The wire format for MessageSet is: // message MessageSet { // repeated group Item = 1 { - // required int32 typeId = 2; + // required uint32 typeId = 2; // required bytes message = 3; // } // } @@ -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..b6bbcb160d3fd 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; } @@ -256,7 +259,9 @@ public static int hashEnumList(List list) { /** Helper method for implementing {@link Message#equals(Object)} for bytes field. */ public static boolean equals(List a, List b) { - if (a.size() != b.size()) return false; + if (a.size() != b.size()) { + return false; + } for (int i = 0; i < a.size(); ++i) { if (!Arrays.equals(a.get(i), b.get(i))) { return false; @@ -450,7 +455,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 +553,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..7f36e098308b9 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,23 @@ 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(Exception e) { + super(e.getMessage(), e); + } + + public InvalidProtocolBufferException(String description, Exception e) { + super(description, e); + } + public InvalidProtocolBufferException(IOException e) { super(e.getMessage(), e); } - public InvalidProtocolBufferException(final String description, IOException e) { + public InvalidProtocolBufferException(String description, IOException 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/MessageReflection.java b/java/core/src/main/java/com/google/protobuf/MessageReflection.java index 6741e1cb9cdf1..b7f5d52d4a5c3 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageReflection.java +++ b/java/core/src/main/java/com/google/protobuf/MessageReflection.java @@ -882,7 +882,7 @@ private static void mergeMessageSetExtensionFromCodedStream( // The wire format for MessageSet is: // message MessageSet { // repeated group Item = 1 { - // required int32 typeId = 2; + // required uint32 typeId = 2; // required bytes message = 3; // } // } 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..8525dda8e709b 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, @@ -300,7 +300,7 @@ boolean parseMessageSetItemOrUnknownField( // The wire format for MessageSet is: // message MessageSet { // repeated group Item = 1 { - // required int32 typeId = 2; + // required uint32 typeId = 2; // required bytes message = 3; // } // } 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..b32a8b59a4f45 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -30,8 +30,6 @@ package com.google.protobuf; -import static java.nio.charset.StandardCharsets.UTF_8; - import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -51,7 +49,7 @@ /** * Provide text parsing and formatting support for proto2 instances. The implementation largely - * follows google/protobuf/text_format.cc. + * follows text_format.cc. * * @author wenboz@google.com Wenbo Zhu * @author kenton@google.com Kenton Varda @@ -61,6 +59,8 @@ private TextFormat() {} private static final Logger logger = Logger.getLogger(TextFormat.class.getName()); + private static final String DEBUG_STRING_SILENT_MARKER = "\t "; + /** * Outputs a textual representation of the Protocol Message supplied into the parameter output. @@ -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); @@ -491,11 +506,11 @@ public int compareTo(MapEntryAdapter b) { } switch (fieldType) { case BOOLEAN: - return Boolean.compare((boolean) getKey(), (boolean) b.getKey()); + return Boolean.valueOf((boolean) getKey()).compareTo((boolean) b.getKey()); case LONG: - return Long.compare((long) getKey(), (long) b.getKey()); + return Long.valueOf((long) getKey()).compareTo((long) b.getKey()); case INT: - return Integer.compare((int) getKey(), (int) b.getKey()); + return Integer.valueOf((int) getKey()).compareTo((int) b.getKey()); case STRING: String aString = (String) getKey(); String bString = (String) b.getKey(); @@ -932,6 +947,14 @@ private static final class Tokenizer { Pattern.compile("-?inf(inity)?f?", Pattern.CASE_INSENSITIVE); private static final Pattern FLOAT_NAN = Pattern.compile("nanf?", Pattern.CASE_INSENSITIVE); + /** + * {@link containsSilentMarkerAfterCurrentToken} indicates if there is a silent marker after the + * current token. This value is moved to {@link containsSilentMarkerAfterPrevToken} every time + * the next token is parsed. + */ + private boolean containsSilentMarkerAfterCurrentToken = false; + private boolean containsSilentMarkerAfterPrevToken = false; + /** Construct a tokenizer that parses tokens from the given text. */ private Tokenizer(final CharSequence text) { this.text = text; @@ -956,6 +979,14 @@ int getColumn() { return column; } + boolean getContainsSilentMarkerAfterCurrentToken() { + return containsSilentMarkerAfterCurrentToken; + } + + boolean getContainsSilentMarkerAfterPrevToken() { + return containsSilentMarkerAfterPrevToken; + } + /** Are we at the end of the input? */ public boolean atEnd() { return currentToken.length() == 0; @@ -1521,6 +1552,19 @@ public static T parse( * control the parser behavior. */ public static class Parser { + private int debugStringSilentMarker; + + /** + * A valid silent marker appears between a field name and its value. If there is a ":" in + * between, the silent marker will only appear after the colon. This is called after a field + * name is parsed, and before the ":" if it exists. If the current token is ":", then + * containsSilentMarkerAfterCurrentToken indicates if there is a valid silent marker. Otherwise, + * the current token is part of the field value, so the silent marker is indicated by + * containsSilentMarkerAfterPrevToken. + */ + private void detectSilentMarker(Tokenizer tokenizer) { + } + /** * Determines if repeated values for non-repeated fields and oneofs are permitted. For example, * given required/optional field "foo" and a oneof containing "baz" and "qux": @@ -1877,6 +1921,7 @@ private void mergeField( // start with "{" or "<" which indicates the beginning of a message body. // If there is no ":" or there is a "{" or "<" after ":", this field has // to be a message or the input is ill-formed. + detectSilentMarker(tokenizer); if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("{") && !tokenizer.lookingAt("<")) { skipFieldValue(tokenizer); } else { @@ -1887,6 +1932,7 @@ private void mergeField( // Handle potential ':'. if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + detectSilentMarker(tokenizer); tokenizer.tryConsume(":"); // optional if (parseTreeBuilder != null) { TextFormatParseInfoTree.Builder childParseTreeBuilder = @@ -1910,6 +1956,7 @@ private void mergeField( unknownFields); } } else { + detectSilentMarker(tokenizer); tokenizer.consume(":"); // required consumeFieldValues( tokenizer, @@ -2171,6 +2218,7 @@ private void mergeAnyFieldValue( throw tokenizer.parseExceptionPreviousToken("Expected a valid type URL."); } } + detectSilentMarker(tokenizer); tokenizer.tryConsume(":"); final String anyEndToken; if (tokenizer.tryConsume("<")) { @@ -2207,7 +2255,7 @@ private void mergeAnyFieldValue( } /** Skips the next field including the field's name and value. */ - private static void skipField(Tokenizer tokenizer) throws ParseException { + private void skipField(Tokenizer tokenizer) throws ParseException { if (tokenizer.tryConsume("[")) { // Extension name. do { @@ -2224,6 +2272,7 @@ private static void skipField(Tokenizer tokenizer) throws ParseException { // start with "{" or "<" which indicates the beginning of a message body. // If there is no ":" or there is a "{" or "<" after ":", this field has // to be a message or the input is ill-formed. + detectSilentMarker(tokenizer); if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("<") && !tokenizer.lookingAt("{")) { skipFieldValue(tokenizer); } else { @@ -2239,7 +2288,7 @@ private static void skipField(Tokenizer tokenizer) throws ParseException { /** * Skips the whole body of a message including the beginning delimiter and the ending delimiter. */ - private static void skipFieldMessage(Tokenizer tokenizer) throws ParseException { + private void skipFieldMessage(Tokenizer tokenizer) throws ParseException { final String delimiter; if (tokenizer.tryConsume("<")) { delimiter = ">"; @@ -2254,7 +2303,7 @@ private static void skipFieldMessage(Tokenizer tokenizer) throws ParseException } /** Skips a field value. */ - private static void skipFieldValue(Tokenizer tokenizer) throws ParseException { + private void skipFieldValue(Tokenizer tokenizer) throws ParseException { if (tokenizer.tryConsumeString()) { while (tokenizer.tryConsumeString()) {} return; @@ -2294,7 +2343,7 @@ public static String escapeBytes(byte[] input) { * Un-escape a byte sequence as escaped using {@link #escapeBytes(ByteString)}. Two-digit hex * escapes (starting with "\x") are also recognized. */ - public static ByteString unescapeBytes(final CharSequence charString) + public static ByteString unescapeBytes(CharSequence charString) throws InvalidEscapeSequenceException { // First convert the Java character sequence to UTF-8 bytes. ByteString input = ByteString.copyFromUtf8(charString.toString()); @@ -2393,11 +2442,12 @@ && isHex(input.byteAt(i + 3))) { | digitValue(input.byteAt(i + 1)) << 8 | digitValue(input.byteAt(i + 2)) << 4 | digitValue(input.byteAt(i + 3))); - if (Character.isSurrogate(ch)) { + + if (ch >= Character.MIN_SURROGATE && ch <= Character.MAX_SURROGATE) { throw new InvalidEscapeSequenceException( "Invalid escape sequence: '\\u' refers to a surrogate"); } - byte[] chUtf8 = Character.toString(ch).getBytes(UTF_8); + byte[] chUtf8 = Character.toString(ch).getBytes(Internal.UTF_8); System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); pos += chUtf8.length; i += 3; @@ -2430,9 +2480,10 @@ && isHex(input.byteAt(i + 3))) { + "' is not a valid code point value"); } Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(codepoint); - if (unicodeBlock.equals(Character.UnicodeBlock.LOW_SURROGATES) + if (unicodeBlock != null + && (unicodeBlock.equals(Character.UnicodeBlock.LOW_SURROGATES) || unicodeBlock.equals(Character.UnicodeBlock.HIGH_SURROGATES) - || unicodeBlock.equals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES)) { + || unicodeBlock.equals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES))) { throw new InvalidEscapeSequenceException( "Invalid escape sequence: '\\U" + input.substring(i, i + 8).toStringUtf8() @@ -2440,7 +2491,7 @@ && isHex(input.byteAt(i + 3))) { } int[] codepoints = new int[1]; codepoints[0] = codepoint; - byte[] chUtf8 = new String(codepoints, 0, 1).getBytes(UTF_8); + byte[] chUtf8 = new String(codepoints, 0, 1).getBytes(Internal.UTF_8); System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); pos += chUtf8.length; i += 7; diff --git a/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java b/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java index 2501ec936c631..4e3eb765e0b2e 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java @@ -30,7 +30,24 @@ package com.google.protobuf; -/** Provide text format escaping support for proto2 instances. */ +/** + * Provide text format escaping of proto instances. These ASCII characters are escaped: + * + * ASCII #7 (bell) --> \a + * ASCII #8 (backspace) --> \b + * ASCII #9 (horizontal tab) --> \t + * ASCII #10 (linefeed) --> \n + * ASCII #11 (vertical tab) --> \v + * ASCII #13 (carriage return) --> \r + * ASCII #12 (formfeed) --> \f + * ASCII #34 (apostrophe) --> \' + * ASCII #39 (straight double quote) --> \" + * ASCII #92 (backslash) --> \\ + * + * Other printable ASCII characters between 32 and 127 inclusive are output as is, unescaped. + * Other ASCII characters less than 32 and all Unicode characters 128 or greater are + * first encoded as UTF-8, then each byte is escaped individually as a 3-digit octal escape. + */ final class TextFormatEscaper { private TextFormatEscaper() {} @@ -41,17 +58,13 @@ private interface ByteSequence { } /** - * Escapes bytes in the format used in protocol buffer text format, which is the same as the - * format used for C string literals. All bytes that are not printable 7-bit ASCII characters are - * escaped, as well as backslash, single-quote, and double-quote characters. Characters for which - * no defined short-hand escape sequence is defined will be escaped using 3-digit octal sequences. + * Backslash escapes bytes in the format used in protocol buffer text format. */ - static String escapeBytes(final ByteSequence input) { + static String escapeBytes(ByteSequence input) { final StringBuilder builder = new StringBuilder(input.size()); for (int i = 0; i < input.size(); i++) { - final byte b = input.byteAt(i); + byte b = input.byteAt(i); switch (b) { - // Java does not recognize \a or \v, apparently. case 0x07: builder.append("\\a"); break; @@ -100,10 +113,7 @@ static String escapeBytes(final ByteSequence input) { } /** - * Escapes bytes in the format used in protocol buffer text format, which is the same as the - * format used for C string literals. All bytes that are not printable 7-bit ASCII characters are - * escaped, as well as backslash, single-quote, and double-quote characters. Characters for which - * no defined short-hand escape sequence is defined will be escaped using 3-digit octal sequences. + * Backslash escapes bytes in the format used in protocol buffer text format. */ static String escapeBytes(final ByteString input) { return escapeBytes( @@ -137,16 +147,14 @@ public byte byteAt(int offset) { } /** - * Like {@link #escapeBytes(ByteString)}, but escapes a text string. Non-ASCII characters are - * first encoded as UTF-8, then each byte is escaped individually as a 3-digit octal escape. Yes, - * it's weird. + * Like {@link #escapeBytes(ByteString)}, but escapes a text string. */ - static String escapeText(final String input) { + static String escapeText(String input) { return escapeBytes(ByteString.copyFromUtf8(input)); } /** Escape double quotes and backslashes in a String for unicode output of a message. */ - static String escapeDoubleQuotesAndBackslashes(final String input) { + static String escapeDoubleQuotesAndBackslashes(String input) { return input.replace("\\", "\\\\").replace("\"", "\\\""); } } 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/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..3130a31557492 100644 --- a/java/core/src/main/java/com/google/protobuf/Utf8.java +++ b/java/core/src/main/java/com/google/protobuf/Utf8.java @@ -64,9 +64,9 @@ * Well Formed UTF-8 Byte Sequences. * *

This class supports decoding of partial byte sequences, so that the bytes in a complete UTF-8 - * byte sequences can be stored in multiple segments. Methods typically return {@link #MALFORMED} if - * the partial byte sequence is definitely not well-formed, {@link #COMPLETE} if it is well-formed - * in the absence of additional input, or if the byte sequence apparently terminated in the middle + * byte sequence can be stored in multiple segments. Methods typically return {@link #MALFORMED} if + * the partial byte sequence is definitely not well-formed; {@link #COMPLETE} if it is well-formed + * in the absence of additional input; or, if the byte sequence apparently terminated in the middle * of a character, an opaque integer "state" value containing enough information to decode the * character when passed to a subsequent invocation of a partial decoding method. * @@ -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..ef27323f482da 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(); @@ -766,6 +764,7 @@ private static void assertEqualBytes(OutputType outputType, byte[] a, byte[] b) * Writes the given value using writeRawVarint32() and writeRawVarint64() and checks that the * result matches the given bytes. */ + @SuppressWarnings("UnnecessaryLongToIntConversion") // Intentionally tests 32-bit int values. private static void assertWriteVarint(byte[] data, long value) throws Exception { for (OutputType outputType : OutputType.values()) { // Only test 32-bit write if the value fits into an int. 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/ServiceTest.java b/java/core/src/test/java/com/google/protobuf/ServiceTest.java index 33ce537a4aaff..eccdf1c14c06b 100644 --- a/java/core/src/test/java/com/google/protobuf/ServiceTest.java +++ b/java/core/src/test/java/com/google/protobuf/ServiceTest.java @@ -32,6 +32,8 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; @@ -46,145 +48,124 @@ import protobuf_unittest.no_generic_services_test.UnittestNoGenericServices; import java.util.HashSet; import java.util.Set; -import org.easymock.EasyMock; -import org.easymock.IArgumentMatcher; -import org.easymock.IMocksControl; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.InOrder; +import org.mockito.Mockito; -/** Tests services and stubs. */ @RunWith(JUnit4.class) public class ServiceTest { - private IMocksControl control; - private RpcController mockController; - private final Descriptors.MethodDescriptor fooDescriptor = TestService.getDescriptor().getMethods().get(0); private final Descriptors.MethodDescriptor barDescriptor = TestService.getDescriptor().getMethods().get(1); - - @Before - public void setUp() throws Exception { - control = EasyMock.createStrictControl(); - mockController = control.createMock(RpcController.class); - } - - // ================================================================= + private static final FooRequest FOO_REQUEST = FooRequest.getDefaultInstance(); + private static final BarRequest BAR_REQUEST = BarRequest.getDefaultInstance(); + private static final RpcController MOCK_RPC_CONTROLLER = Mockito.mock(RpcController.class); + private static final FooResponse FOO_RESPONSE = FooResponse.getDefaultInstance(); + private static final BarResponse BAR_RESPONSE = BarResponse.getDefaultInstance(); + private static final MessageWithNoOuter MESSAGE_WITH_NO_OUTER = + MessageWithNoOuter.getDefaultInstance(); /** Tests Service.callMethod(). */ @Test + @SuppressWarnings({"unchecked", "rawtypes"}) public void testCallMethod() throws Exception { - FooRequest fooRequest = FooRequest.newBuilder().build(); - BarRequest barRequest = BarRequest.newBuilder().build(); - MockCallback fooCallback = new MockCallback(); - MockCallback barCallback = new MockCallback(); - TestService mockService = EasyMock.createMock(TestService.class); - - mockService.foo( - EasyMock.same(mockController), - EasyMock.same(fooRequest), - this.wrapsCallback(fooCallback)); - mockService.bar( - EasyMock.same(mockController), - EasyMock.same(barRequest), - this.wrapsCallback(barCallback)); - control.replay(); - - mockService.callMethod( - fooDescriptor, mockController, - fooRequest, fooCallback); - mockService.callMethod( - barDescriptor, mockController, - barRequest, barCallback); - control.verify(); + TestService mockService = Mockito.mock(TestService.class); + RpcCallback mockFooRpcCallback = Mockito.mock(RpcCallback.class); + RpcCallback mockBarRpcCallback = Mockito.mock(RpcCallback.class); + InOrder order = Mockito.inOrder(mockService); + + mockService.callMethod(fooDescriptor, MOCK_RPC_CONTROLLER, FOO_REQUEST, mockFooRpcCallback); + mockService.callMethod(barDescriptor, MOCK_RPC_CONTROLLER, BAR_REQUEST, mockBarRpcCallback); + order + .verify(mockService) + .foo( + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(FOO_REQUEST), + Mockito.same(mockFooRpcCallback)); + order + .verify(mockService) + .bar( + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(BAR_REQUEST), + Mockito.same(mockBarRpcCallback)); } /** Tests Service.get{Request,Response}Prototype(). */ @Test public void testGetPrototype() throws Exception { - TestService mockService = EasyMock.createMock(TestService.class); - - assertThat(mockService.getRequestPrototype(fooDescriptor)) - .isSameInstanceAs(FooRequest.getDefaultInstance()); - assertThat(mockService.getResponsePrototype(fooDescriptor)) - .isSameInstanceAs(FooResponse.getDefaultInstance()); - assertThat(mockService.getRequestPrototype(barDescriptor)) - .isSameInstanceAs(BarRequest.getDefaultInstance()); - assertThat(mockService.getResponsePrototype(barDescriptor)) - .isSameInstanceAs(BarResponse.getDefaultInstance()); + Descriptors.MethodDescriptor fooDescriptor = TestService.getDescriptor().getMethods().get(0); + Descriptors.MethodDescriptor barDescriptor = TestService.getDescriptor().getMethods().get(1); + TestService mockService = Mockito.mock(TestService.class); + + assertThat(mockService.getRequestPrototype(fooDescriptor)).isSameInstanceAs(FOO_REQUEST); + assertThat(mockService.getResponsePrototype(fooDescriptor)).isSameInstanceAs(FOO_RESPONSE); + assertThat(mockService.getRequestPrototype(barDescriptor)).isSameInstanceAs(BAR_REQUEST); + assertThat(mockService.getResponsePrototype(barDescriptor)).isSameInstanceAs(BAR_RESPONSE); } /** Tests generated stubs. */ @Test + @SuppressWarnings({"unchecked", "rawtypes"}) public void testStub() throws Exception { - FooRequest fooRequest = FooRequest.newBuilder().build(); - BarRequest barRequest = BarRequest.newBuilder().build(); - MockCallback fooCallback = new MockCallback(); - MockCallback barCallback = new MockCallback(); - RpcChannel mockChannel = control.createMock(RpcChannel.class); - TestService stub = TestService.newStub(mockChannel); - - mockChannel.callMethod( - EasyMock.same(fooDescriptor), - EasyMock.same(mockController), - EasyMock.same(fooRequest), - EasyMock.same(FooResponse.getDefaultInstance()), - this.wrapsCallback(fooCallback)); - mockChannel.callMethod( - EasyMock.same(barDescriptor), - EasyMock.same(mockController), - EasyMock.same(barRequest), - EasyMock.same(BarResponse.getDefaultInstance()), - this.wrapsCallback(barCallback)); - control.replay(); - - stub.foo(mockController, fooRequest, fooCallback); - stub.bar(mockController, barRequest, barCallback); - control.verify(); + RpcCallback mockFooRpcCallback = Mockito.mock(RpcCallback.class); + RpcCallback mockBarRpcCallback = Mockito.mock(RpcCallback.class); + RpcChannel mockRpcChannel = Mockito.mock(RpcChannel.class); + InOrder order = Mockito.inOrder(mockRpcChannel); + TestService stub = TestService.newStub(mockRpcChannel); + + stub.foo(MOCK_RPC_CONTROLLER, FOO_REQUEST, mockFooRpcCallback); + stub.bar(MOCK_RPC_CONTROLLER, BAR_REQUEST, mockBarRpcCallback); + + order + .verify(mockRpcChannel) + .callMethod( + Mockito.same(fooDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(FOO_REQUEST), + Mockito.same(FOO_RESPONSE), + Mockito.any(RpcCallback.class)); + order + .verify(mockRpcChannel) + .callMethod( + Mockito.same(barDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(BAR_REQUEST), + Mockito.same(BAR_RESPONSE), + Mockito.any(RpcCallback.class)); } /** Tests generated blocking stubs. */ @Test public void testBlockingStub() throws Exception { - FooRequest fooRequest = FooRequest.newBuilder().build(); - BarRequest barRequest = BarRequest.newBuilder().build(); - BlockingRpcChannel mockChannel = control.createMock(BlockingRpcChannel.class); - TestService.BlockingInterface stub = TestService.newBlockingStub(mockChannel); - - FooResponse fooResponse = FooResponse.newBuilder().build(); - BarResponse barResponse = BarResponse.newBuilder().build(); - - EasyMock.expect( - mockChannel.callBlockingMethod( - EasyMock.same(fooDescriptor), - EasyMock.same(mockController), - EasyMock.same(fooRequest), - EasyMock.same(FooResponse.getDefaultInstance()))) - .andReturn(fooResponse); - EasyMock.expect( - mockChannel.callBlockingMethod( - EasyMock.same(barDescriptor), - EasyMock.same(mockController), - EasyMock.same(barRequest), - EasyMock.same(BarResponse.getDefaultInstance()))) - .andReturn(barResponse); - control.replay(); - - assertThat(fooResponse).isSameInstanceAs(stub.foo(mockController, fooRequest)); - assertThat(barResponse).isSameInstanceAs(stub.bar(mockController, barRequest)); - control.verify(); + BlockingRpcChannel mockBlockingRpcChannel = Mockito.mock(BlockingRpcChannel.class); + TestService.BlockingInterface stub = TestService.newBlockingStub(mockBlockingRpcChannel); + + when(mockBlockingRpcChannel.callBlockingMethod( + Mockito.same(fooDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(FOO_REQUEST), + Mockito.same(FOO_RESPONSE))) + .thenReturn(FOO_RESPONSE); + when(mockBlockingRpcChannel.callBlockingMethod( + Mockito.same(barDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(BAR_REQUEST), + Mockito.same(BAR_RESPONSE))) + .thenReturn(BAR_RESPONSE); + + assertThat(FOO_RESPONSE).isSameInstanceAs(stub.foo(MOCK_RPC_CONTROLLER, FOO_REQUEST)); + assertThat(BAR_RESPONSE).isSameInstanceAs(stub.bar(MOCK_RPC_CONTROLLER, BAR_REQUEST)); } @Test public void testNewReflectiveService() { - ServiceWithNoOuter.Interface impl = control.createMock(ServiceWithNoOuter.Interface.class); - RpcController controller = control.createMock(RpcController.class); + ServiceWithNoOuter.Interface impl = Mockito.mock(ServiceWithNoOuter.Interface.class); Service service = ServiceWithNoOuter.newReflectiveService(impl); MethodDescriptor fooMethod = ServiceWithNoOuter.getDescriptor().findMethodByName("Foo"); - MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance(); RpcCallback callback = new RpcCallback() { @Override @@ -195,36 +176,30 @@ public void run(Message parameter) { }; RpcCallback specializedCallback = RpcUtil.specializeCallback(callback); - impl.foo(EasyMock.same(controller), EasyMock.same(request), EasyMock.same(specializedCallback)); - EasyMock.expectLastCall(); - - control.replay(); - - service.callMethod(fooMethod, controller, request, callback); - - control.verify(); + service.callMethod(fooMethod, MOCK_RPC_CONTROLLER, MESSAGE_WITH_NO_OUTER, callback); + verify(impl) + .foo( + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(MESSAGE_WITH_NO_OUTER), + Mockito.same(specializedCallback)); } @Test public void testNewReflectiveBlockingService() throws ServiceException { ServiceWithNoOuter.BlockingInterface impl = - control.createMock(ServiceWithNoOuter.BlockingInterface.class); - RpcController controller = control.createMock(RpcController.class); + Mockito.mock(ServiceWithNoOuter.BlockingInterface.class); + BlockingService service = ServiceWithNoOuter.newReflectiveBlockingService(impl); MethodDescriptor fooMethod = ServiceWithNoOuter.getDescriptor().findMethodByName("Foo"); - MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance(); TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance(); - EasyMock.expect(impl.foo(EasyMock.same(controller), EasyMock.same(request))) - .andReturn(expectedResponse); - - control.replay(); - Message response = service.callBlockingMethod(fooMethod, controller, request); + when(impl.foo(Mockito.same(MOCK_RPC_CONTROLLER), Mockito.same(MESSAGE_WITH_NO_OUTER))) + .thenReturn(expectedResponse); + Message response = + service.callBlockingMethod(fooMethod, MOCK_RPC_CONTROLLER, MESSAGE_WITH_NO_OUTER); assertThat(response).isEqualTo(expectedResponse); - - control.verify(); } @Test @@ -243,7 +218,7 @@ public void testNoGenericServices() throws Exception { "protobuf_unittest.no_generic_services_test.UnittestNoGenericServices"; Class outerClass = Class.forName(outerName); - Set innerClassNames = new HashSet(); + Set innerClassNames = new HashSet<>(); for (Class innerClass : outerClass.getClasses()) { String fullName = innerClass.getName(); // Figure out the unqualified name of the inner class. @@ -279,57 +254,4 @@ public void testNoGenericServices() throws Exception { // ================================================================= - - /** - * wrapsCallback() is an EasyMock argument predicate. wrapsCallback(c) matches a callback if - * calling that callback causes c to be called. In other words, c wraps the given callback. - */ - private RpcCallback wrapsCallback(MockCallback callback) { - EasyMock.reportMatcher(new WrapsCallback(callback)); - return null; - } - - /** The parameter to wrapsCallback() must be a MockCallback. */ - private static class MockCallback implements RpcCallback { - private boolean called = false; - - public boolean isCalled() { - return called; - } - - public void reset() { - called = false; - } - - @Override - public void run(T message) { - called = true; - } - } - - /** Implementation of the wrapsCallback() argument matcher. */ - private static class WrapsCallback implements IArgumentMatcher { - private MockCallback callback; - - public WrapsCallback(MockCallback callback) { - this.callback = callback; - } - - @Override - public boolean matches(Object actual) { - if (!(actual instanceof RpcCallback)) { - return false; - } - RpcCallback actualCallback = (RpcCallback) actual; - - callback.reset(); - actualCallback.run(null); - return callback.isCalled(); - } - - @Override - public void appendTo(StringBuffer buffer) { - buffer.append("wrapsCallback(mockCallback)"); - } - } } diff --git a/java/core/src/test/java/com/google/protobuf/TestSchemas.java b/java/core/src/test/java/com/google/protobuf/TestSchemas.java index ab0ced4cdc7b8..639583d4999d6 100644 --- a/java/core/src/test/java/com/google/protobuf/TestSchemas.java +++ b/java/core/src/test/java/com/google/protobuf/TestSchemas.java @@ -41,6 +41,10 @@ /** Schemas to support testing. */ public class TestSchemas { + + private TestSchemas() { + } + public static final Schema genericProto2Schema = new ManifestSchemaFactory().createSchema(Proto2Message.class); public static final Schema genericProto3Schema = 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..cde17768309b1 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 { @@ -172,6 +170,13 @@ public void testPrintMessage() throws Exception { assertThat(javaText).isEqualTo(ALL_FIELDS_SET_TEXT); } + @Test + // https://github.com/protocolbuffers/protobuf/issues/9447 + public void testCharacterNotInUnicodeBlock() throws TextFormat.InvalidEscapeSequenceException { + ByteString actual = TextFormat.unescapeBytes("\\U000358da"); + assertThat(actual.size()).isEqualTo(4); + } + /** Print TestAllTypes as Builder and compare with golden file. */ @Test public void testPrintMessageBuilder() throws Exception { @@ -1826,4 +1831,5 @@ public void testPreservesFloatingPointNegative0() throws Exception { assertThat(TextFormat.printer().printToString(message)) .isEqualTo("optional_float: -0.0\noptional_double: -0.0\n"); } + } 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/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..88ea5e3caeb73 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 @@ -32,21 +32,77 @@ // This file tests that various identifiers work as field and type names even // though the same identifiers are used internally by the java code generator. +// LINT: LEGACY_NAMES 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 option java_package = "com.google.protobuf"; option java_outer_classname = "TestBadIdentifiersProto"; -message TestMessage { - optional string cached_size = 1; - optional string serialized_size = 2; - optional string class = 3; +// Message with field names using underscores that conflict with accessors in +// the base message class in java. See kForbiddenWordList in +// src/google/protobuf/compiler/java/java_helpers.cc +message ForbiddenWordsUnderscoreMessage { + // java.lang.Object + optional bool class = 1; + // com.google.protobuf.MessageLiteOrBuilder + optional bool default_instance_for_type = 2; + // com.google.protobuf.MessageLite + optional bool parser_for_type = 3; + optional bool serialized_size = 4; + // com.google.protobuf.MessageOrBuilder + optional bool all_fields = 5; + optional bool descriptor_for_type = 6; + optional bool initialization_error_string = 7; + // TODO(b/219045204): re-enable + // optional bool unknown_fields = 8; + // obsolete. kept for backwards compatibility of generated code + optional bool cached_size = 9; +} + +// Message with field names using leading underscores that conflict with +// accessors in the base message class in java. See kForbiddenWordList in +// src/google/protobuf/compiler/java/java_helpers.cc +message ForbiddenWordsLeadingUnderscoreMessage { + // java.lang.Object + optional bool _class = 1; + // com.google.protobuf.MessageLiteOrBuilder + optional bool _default_instance_for_type = 2; + // com.google.protobuf.MessageLite + optional bool _parser_for_type = 3; + optional bool _serialized_size = 4; + // com.google.protobuf.MessageOrBuilder + optional bool _all_fields = 5; + optional bool _descriptor_for_type = 6; + optional bool _initialization_error_string = 7; + // TODO(b/219045204): re-enable + // optional bool _unknown_fields = 8; + // obsolete. kept for backwards compatibility of generated code + optional bool _cached_size = 9; +} + +// Message with field names in camel case that conflict with accessors in the +// base message class in java. See kForbiddenWordList in +// src/google/protobuf/compiler/java/java_helpers.cc +message ForbiddenWordsCamelMessage { + // java.lang.Object + optional bool class = 1; + // com.google.protobuf.MessageLiteOrBuilder + optional bool defaultInstanceForType = 2; + // com.google.protobuf.MessageLite + optional bool serializedSize = 3; + optional bool parserForType = 4; + // com.google.protobuf.MessageOrBuilder: + optional bool initializationErrorString = 5; + optional bool descriptorForType = 6; + optional bool allFields = 7; + // TODO(b/219045204): re-enable + // optional bool unknownFields = 8; + // obsolete. kept for backwards compatibility of generated code + optional bool cachedSize = 9; } message Descriptor { @@ -84,7 +140,7 @@ message Deprecated { optional int32 field1 = 1 [deprecated = true]; optional TestEnum field2 = 2 [deprecated = true]; - optional TestMessage field3 = 3 [deprecated = true]; + optional ForbiddenWordsUnderscoreMessage field3 = 3 [deprecated = true]; } message Override { @@ -117,7 +173,8 @@ message Double { } service TestConflictingMethodNames { - rpc Override(TestMessage) returns (TestMessage); + rpc Override(ForbiddenWordsUnderscoreMessage) + returns (ForbiddenWordsUnderscoreMessage); } message TestConflictingFieldNames { @@ -125,24 +182,24 @@ message TestConflictingFieldNames { UNKNOWN = 0; FOO = 1; } - message TestMessage {} + message ForbiddenWordsUnderscoreMessage {} repeated int32 int32_field = 1; repeated TestEnum enum_field = 2; repeated string string_field = 3; repeated bytes bytes_field = 4; - repeated TestMessage message_field = 5; + repeated ForbiddenWordsUnderscoreMessage message_field = 5; optional int32 int32_field_count = 11; optional TestEnum enum_field_count = 12; optional string string_field_count = 13; optional bytes bytes_field_count = 14; - optional TestMessage message_field_count = 15; + optional ForbiddenWordsUnderscoreMessage message_field_count = 15; - repeated int32 Int32Field = 21; // NO_PROTO3 - repeated TestEnum EnumField = 22; // NO_PROTO3 - repeated string StringField = 23; // NO_PROTO3 - repeated bytes BytesField = 24; // NO_PROTO3 - repeated TestMessage MessageField = 25; // NO_PROTO3 + repeated int32 Int32Field = 21; // NO_PROTO3 + repeated TestEnum EnumField = 22; // NO_PROTO3 + repeated string StringField = 23; // NO_PROTO3 + repeated bytes BytesField = 24; // NO_PROTO3 + repeated ForbiddenWordsUnderscoreMessage MessageField = 25; // NO_PROTO3 // This field conflicts with "int32_field" as they both generate // the method getInt32FieldList(). diff --git a/java/kotlin-lite/BUILD b/java/kotlin-lite/BUILD new file mode 100644 index 0000000000000..fd0c103166c62 --- /dev/null +++ b/java/kotlin-lite/BUILD @@ -0,0 +1,185 @@ +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_lite_proto_library") +load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export") +load("//:protobuf_version.bzl", "PROTOBUF_VERSION") +load("//:protobuf.bzl", "internal_gen_kt_protos") + +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"], +) + +kt_jvm_library( + name = "well_known_protos_kotlin_lite", + srcs = [ + "//:gen_well_known_protos_kotlinlite", + ], + deps = [ + "//java/lite", + "//java/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/kotlin:shared_runtime", + ], +) + +kt_jvm_export( + name = "kotlin-lite_mvn", + maven_coordinates = "com.google.protobuf:protobuf-kotlin-lite:%s" % PROTOBUF_VERSION, + pom_template = "//java/kotlin-lite:pom_template.xml", + resources = ["//:well_known_protos"], + runtime_deps = [ + ":lite_extensions", + ":well_known_protos_kotlin_lite", + "//java/kotlin:bytestring_lib", + "//java/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/kotlin:shared_runtime", + ], + deploy_env = [ + "@com_github_jetbrains_kotlin//:kotlin-stdlib", + "//java/lite", + ], +) + +filegroup( + name = "release", + srcs = [ + ":kotlin-lite_mvn-docs", + ":kotlin-lite_mvn-maven-source", + ":kotlin-lite_mvn-pom", + ":kotlin-lite_mvn-project", + ], + visibility = ["//java:__pkg__"], +) + +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"], +) + +internal_gen_kt_protos( + name = "gen_evil_names_proto2_lite", + deps = ["//java/kotlin:evil_names_proto2"], + lite = True, +) + +java_lite_proto_library( + name = "evil_names_proto3_java_proto_lite", + deps = ["//java/kotlin:evil_names_proto3"], +) + +internal_gen_kt_protos( + name = "gen_evil_names_proto3_lite", + deps = ["//java/kotlin:evil_names_proto3"], + lite = True, +) + +java_lite_proto_library( + name = "multiple_files_proto3_java_proto_lite", + deps = ["//java/kotlin:multiple_files_proto3"], +) + +internal_gen_kt_protos( + name = "gen_kotlin_proto3_java_multiple_files_lite", + deps = ["//java/kotlin:multiple_files_proto3"], +) + +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 = ["//java/kotlin:src/test/kotlin/com/google/protobuf/Proto3Test.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.Proto3Test", +) 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 977959b504556..9f6d4aa8d3532 100644 --- a/java/kotlin-lite/pom.xml +++ b/java/kotlin-lite/pom.xml @@ -4,14 +4,14 @@ com.google.protobuf protobuf-parent - 3.19.4 + 3.20.0-rc-2 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. @@ -31,8 +31,8 @@ test - org.easymock - easymock + org.mockito + mockito-core test @@ -59,6 +59,7 @@ org.jetbrains.kotlin kotlin-test ${kotlin.version} + test @@ -94,7 +95,6 @@ DslList.kt DslMap.kt DslProxy.kt - ExtendableMessageLiteExtensions.kt ExtensionList.kt OnlyForUseByGeneratedProtoCode.kt ProtoDslMarker.kt @@ -119,14 +119,6 @@ TestUtilLite.java - - ${basedir}/../kotlin/src/test/kotlin/com/google/protobuf - - ExtendableMessageExtensionsTest.kt - Proto2Test.kt - ProtoUtil.java - - @@ -223,8 +215,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/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt b/java/kotlin-lite/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt similarity index 100% rename from java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt rename to java/kotlin-lite/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt 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..1da4de535cd90 --- /dev/null +++ b/java/kotlin/BUILD @@ -0,0 +1,296 @@ +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_proto_library") +load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export") +load("@rules_proto//proto:defs.bzl", "proto_library") +load("//:protobuf_version.bzl", "PROTOBUF_VERSION") +load("//:protobuf.bzl", "internal_gen_kt_protos") + +exports_files([ + "src/test/kotlin/com/google/protobuf/Proto3Test.kt", +]) + +# 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"], + visibility = ["//java:__subpackages__"], +) + +kt_jvm_library( + name = "full_extensions", + srcs = [ + "src/main/kotlin/com/google/protobuf/Anies.kt", + "src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt", + ], + deps = ["//java/core"], +) + +kt_jvm_export( + name = "kotlin_mvn", + maven_coordinates = "com.google.protobuf:protobuf-kotlin:%s" % PROTOBUF_VERSION, + pom_template = "//java/kotlin:pom_template.xml", + resources = ["//:well_known_protos"], + runtime_deps = [ + ":bytestring_lib", + ":full_extensions", + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + ":shared_runtime", + ":well_known_protos_kotlin", + ], + deploy_env = [ + "@com_github_jetbrains_kotlin//:kotlin-stdlib", + "//java/core", + ], +) + +filegroup( + name = "release", + srcs = [ + ":kotlin_mvn-docs", + ":kotlin_mvn-maven-source", + ":kotlin_mvn-pom", + ":kotlin_mvn-project", + ], + visibility = ["//java:__pkg__"], +) + +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/AniesTest.kt", + "src/test/kotlin/com/google/protobuf/ExtendableMessageExtensionsTest.kt", + ], + deps = [ + ":example_extensible_message_java_proto", + ":full_extensions", + "//java/core:core", + ":kotlin_unittest", + ":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__"], +) + +java_proto_library( + name = "evil_names_proto2_java_proto", + deps = [":evil_names_proto2"], +) + +internal_gen_kt_protos( + name = "gen_evil_names_proto2", + deps = [":evil_names_proto2"], +) + +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_proto3_java_proto", + deps = [":evil_names_proto3"], +) + +internal_gen_kt_protos( + name = "gen_evil_names_proto3", + 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"], +) + +internal_gen_kt_protos( + name = "gen_kotlin_proto3_java_multiple_files", + deps = [":multiple_files_proto3"], +) + +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", + ":well_known_protos_kotlin", + "//: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", +) + +kt_jvm_library( + name = "well_known_protos_kotlin", + srcs = [ + "//:gen_well_known_protos_kotlin", + ], + deps = [ + "//java/core", + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + ":shared_runtime", + ], +) diff --git a/java/kotlin/generate-sources-build.xml b/java/kotlin/generate-sources-build.xml index 6963f3717f576..b78bc0ba7a421 100644 --- a/java/kotlin/generate-sources-build.xml +++ b/java/kotlin/generate-sources-build.xml @@ -3,6 +3,7 @@ + diff --git a/java/kotlin/pom.xml b/java/kotlin/pom.xml index 286af32f7b3dd..baa4fe43f0835 100644 --- a/java/kotlin/pom.xml +++ b/java/kotlin/pom.xml @@ -4,14 +4,14 @@ com.google.protobuf protobuf-parent - 3.19.4 + 3.20.0-rc-2 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. @@ -30,8 +30,8 @@ test - org.easymock - easymock + org.mockito + mockito-core test 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/main/kotlin/com/google/protobuf/Anies.kt b/java/kotlin/src/main/kotlin/com/google/protobuf/Anies.kt new file mode 100644 index 0000000000000..64ac019ba3ee3 --- /dev/null +++ b/java/kotlin/src/main/kotlin/com/google/protobuf/Anies.kt @@ -0,0 +1,45 @@ +// 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.kotlin + +import com.google.protobuf.Any as ProtoAny +import com.google.protobuf.Message + +/** Returns `true` if this [com.google.protobuf.Any] contains a message of type `T`. */ +inline fun ProtoAny.isA(): Boolean = this.`is`(T::class.java) + +/** + * Returns the message of type `T` encoded in this [com.google.protobuf.Any]. + * + * @throws InvalidProtocolBufferException if this [com.google.protobuf.Any] does not contain a `T` + * message. + */ +inline fun ProtoAny.unpack(): T = unpack(T::class.java) diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/AniesTest.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/AniesTest.kt new file mode 100644 index 0000000000000..808c644a9026f --- /dev/null +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/AniesTest.kt @@ -0,0 +1,70 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf.kotlin + +import com.google.common.truth.Truth.assertThat +import com.google.protobuf.Any as ProtoAny +import com.google.protobuf.InvalidProtocolBufferException +import protobuf_unittest.UnittestProto.BoolMessage +import protobuf_unittest.UnittestProto.Int32Message +import protobuf_unittest.int32Message +import kotlin.test.assertFailsWith +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +/** Tests for extension methods on [ProtoAny]. */ +@RunWith(JUnit4::class) +class AniesTest { + companion object { + val anAny = ProtoAny.pack(int32Message { data = 5 }) + } + + @Test + fun isA_Positive() { + assertThat(anAny.isA()).isTrue() + } + + @Test + fun isA_Negative() { + assertThat(anAny.isA()).isFalse() + } + + @Test + fun unpackValid() { + assertThat(anAny.unpack().data).isEqualTo(5) + } + + @Test + fun unpackInvalid() { + assertFailsWith { anAny.unpack() } + } +} diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt index 99c8c9808fe18..e944d385aab6d 100644 --- a/java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt @@ -33,6 +33,7 @@ package com.google.protobuf.kotlin import com.google.common.truth.Truth.assertThat import com.google.protobuf.ByteString import java.lang.IndexOutOfBoundsException +import java.nio.Buffer import java.nio.ByteBuffer import kotlin.test.assertFailsWith import org.junit.Test @@ -90,8 +91,8 @@ class ByteStringsTest { @Test fun byteBufferToByteStringRespectsPositionAndLimit() { val buffer = ByteBuffer.wrap("abc".toByteArray(Charsets.UTF_8)) - buffer.position(1) - buffer.limit(2) + (buffer as java.nio.Buffer).position(1) + (buffer as java.nio.Buffer).limit(2) assertThat(buffer.toByteString()).isEqualTo(ByteString.copyFromUtf8("b")) } } 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..d6d0ab5218207 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,8 @@ import proto3_unittest.UnittestProto3.TestAllTypes import proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum import proto3_unittest.UnittestProto3.TestEmptyMessage import proto3_unittest.copy +import proto3_unittest.optionalForeignMessageOrNull +import proto3_unittest.optionalNestedMessageOrNull import proto3_unittest.testAllTypes import proto3_unittest.testEmptyMessage import org.junit.Test @@ -86,66 +88,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 +151,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 +331,25 @@ 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 }) + + // No optional keyword, OrNull should still be generated + assertThat(someNestedMessage.optionalForeignMessageOrNull).isEqualTo(null) } } diff --git a/java/lite.md b/java/lite.md index 755a1a69f27c5..0795540538cfd 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.19.4 + 3.20.0-rc-2 ``` diff --git a/java/lite/BUILD b/java/lite/BUILD index 17e9667e6ac7d..fac19f609ccd5 100644 --- a/java/lite/BUILD +++ b/java/lite/BUILD @@ -24,6 +24,19 @@ 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( diff --git a/java/lite/generate-test-sources-build.xml b/java/lite/generate-test-sources-build.xml index 65e62ce4fba7d..8123efb3f1368 100644 --- a/java/lite/generate-test-sources-build.xml +++ b/java/lite/generate-test-sources-build.xml @@ -5,6 +5,7 @@ + @@ -29,7 +30,6 @@ - diff --git a/java/lite/pom.xml b/java/lite/pom.xml index 901ae6767a3c7..f04b77fbe66ef 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.19.4 + 3.20.0-rc-2 protobuf-javalite @@ -23,8 +23,8 @@ test - org.easymock - easymock + org.mockito + mockito-core test @@ -105,6 +105,7 @@ CodedInputStreamReader.java CodedOutputStream.java CodedOutputStreamWriter.java + CompileTimeConstant.java DoubleArrayList.java ExperimentalApi.java ExtensionLite.java @@ -119,6 +120,7 @@ FloatArrayList.java GeneratedMessageInfoFactory.java GeneratedMessageLite.java + InlineMe.java IntArrayList.java Internal.java InvalidProtocolBufferException.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 a6161214a866c..7b868fce07292 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.19.4 + 3.20.0-rc-2 pom Protocol Buffers [Parent] @@ -41,7 +41,7 @@ - 3-Clause BSD License + BSD-3-Clause https://opensource.org/licenses/BSD-3-Clause repo @@ -79,9 +79,9 @@ test - org.easymock - easymock - 3.2 + org.mockito + mockito-core + 4.3.1 test @@ -160,29 +160,43 @@ maven-antrun-plugin 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 ee6ddeaf19337..753fabb7120ad 100644 --- a/java/util/BUILD +++ b/java/util/BUILD @@ -12,7 +12,6 @@ java_library( visibility = ["//visibility:public"], deps = [ "//java/core", - "//java/lite", "@maven//:com_google_code_findbugs_jsr305", "@maven//:com_google_code_gson_gson", "@maven//:com_google_errorprone_error_prone_annotations", @@ -28,6 +27,7 @@ java_export( pom_template = "pom_template.xml", visibility = ["//java:__pkg__"], runtime_deps = [":util"], + deploy_env = ["//java/core"], ) filegroup( @@ -68,6 +68,7 @@ junit_tests( ":util", "//java/core", "//java/core:generic_test_protos_java_proto", + "@maven//:com_google_code_gson_gson", "@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 2c5e2926cabeb..51ad1a63e1c9e 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.19.4 + 3.20.0-rc-2 protobuf-java-util @@ -45,15 +45,15 @@ com.google.code.gson gson - 2.8.6 + 2.8.9 junit junit - org.easymock - easymock + org.mockito + mockito-core test @@ -117,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..a2d18bc776ea2 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,18 +1314,16 @@ 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) { throw (IOException) e.getCause(); } else { - throw new InvalidProtocolBufferException(e.getMessage()); + throw new InvalidProtocolBufferException(e.getMessage(), e); } - } catch (Exception e) { + } catch (RuntimeException e) { // We convert all exceptions from JSON parsing to our own exceptions. - throw new InvalidProtocolBufferException(e.getMessage()); + throw new InvalidProtocolBufferException(e.getMessage(), e); } } @@ -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; } } @@ -1895,7 +1901,7 @@ private String parseString(JsonElement json) { return json.getAsString(); } - private ByteString parseBytes(JsonElement json) throws InvalidProtocolBufferException { + private ByteString parseBytes(JsonElement json) { try { return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString())); } catch (IllegalArgumentException e) { @@ -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..216969082c8c4 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 @@ -34,6 +34,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import com.google.common.collect.ImmutableSet; +import com.google.gson.JsonSyntaxException; import com.google.protobuf.Any; import com.google.protobuf.BoolValue; import com.google.protobuf.ByteString; @@ -79,17 +80,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 +356,94 @@ public void testParserAcceptFloatingPointValueForIntegerField() throws Exception assertThat(builder.getRepeatedInt64(i)).isEqualTo(expectedValues[i]); assertThat(builder.getRepeatedUint64(i)).isEqualTo(expectedValues[i]); } + } + + @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); + } + } + + @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(); + } + } - // 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 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(); + } } - private void assertRejects(String name, String value) { + @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 +911,7 @@ public void testTimestampMergeError() throws Exception { assertThat(e) .hasMessageThat() .isEqualTo("Failed to parse timestamp: " + incorrectTimestampString); + assertThat(e).hasCauseThat().isNotNull(); } } @@ -857,6 +936,7 @@ public void testDurationMergeError() throws Exception { assertThat(e) .hasMessageThat() .isEqualTo("Failed to parse duration: " + incorrectDurationString); + assertThat(e).hasCauseThat().isNotNull(); } } @@ -973,8 +1053,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 = @@ -1037,7 +1118,7 @@ public void testAnyFields() throws Exception { + " \"value\": \"12345\"\n" + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(UInt64Value.newBuilder().setValue(12345).build()); + anyMessage = Any.pack(UInt64Value.of(12345)); assertThat(printer.print(anyMessage)) .isEqualTo( "{\n" @@ -1045,7 +1126,7 @@ public void testAnyFields() throws Exception { + " \"value\": \"12345\"\n" + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(FloatValue.newBuilder().setValue(12345).build()); + anyMessage = Any.pack(FloatValue.of(12345)); assertThat(printer.print(anyMessage)) .isEqualTo( "{\n" @@ -1053,7 +1134,7 @@ public void testAnyFields() throws Exception { + " \"value\": 12345.0\n" + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(DoubleValue.newBuilder().setValue(12345).build()); + anyMessage = Any.pack(DoubleValue.of(12345)); assertThat(printer.print(anyMessage)) .isEqualTo( "{\n" @@ -1260,7 +1341,7 @@ public void testParserUnexpectedTypeUrl() throws Exception { } } - @Test + @Test public void testParserRejectTrailingComma() throws Exception { try { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -1270,25 +1351,27 @@ public void testParserRejectTrailingComma() throws Exception { // Expected. } - // TODO(xiaofeng): GSON allows trailing comma in arrays even after I set - // the JsonReader to non-lenient mode. If we want to enforce strict JSON - // compliance, we might want to switch to a different JSON parser or - // implement one by ourselves. - // try { - // TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - // JsonFormat.merge( - // "{\n" - // + " \"repeatedInt32\": [12345,]\n" - // + "}", builder); - // fail("Exception is expected."); - // } catch (IOException e) { - // // Expected. - // } + try { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + mergeFromJson( + "{\n" + + " \"repeatedInt32\": [12345,]\n" + + "}", builder); + assertWithMessage("IOException expected.").fail(); + } catch (IOException e) { + // Expected. + } } @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 @@ -1779,7 +1862,7 @@ public void testRecursionLimit() throws Exception { // Test that we are not leaking out JSON exceptions. @Test - public void testJsonException() throws Exception { + public void testJsonException_forwardsIOException() throws Exception { InputStream throwingInputStream = new InputStream() { @Override @@ -1797,7 +1880,10 @@ public int read() throws IOException { } catch (IOException e) { assertThat(e).hasMessageThat().isEqualTo("12345"); } + } + @Test + public void testJsonException_forwardsJsonException() throws Exception { Reader invalidJsonReader = new StringReader("{ xxx - yyy }"); // When the JSON parser throws parser exceptions, JsonFormat should turn // that into InvalidProtocolBufferException. @@ -1806,7 +1892,7 @@ public int read() throws IOException { JsonFormat.parser().merge(invalidJsonReader, builder); assertWithMessage("Exception is expected.").fail(); } catch (InvalidProtocolBufferException e) { - // Expected. + assertThat(e.getCause()).isInstanceOf(JsonSyntaxException.class); } } 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 2025d9a3d2b8a..29a871359177f 100644 --- a/js/commonjs/export.js +++ b/js/commonjs/export.js @@ -15,7 +15,7 @@ goog.require('jspb.ExtensionFieldInfo'); goog.require('jspb.Message'); goog.require('jspb.Map'); -if ( typeof exports === 'object' ) { +if (typeof exports === 'object') { exports.Map = jspb.Map; exports.Message = jspb.Message; exports.BinaryReader = jspb.BinaryReader; @@ -23,7 +23,8 @@ if ( typeof exports === 'object' ) { exports.ExtensionFieldInfo = jspb.ExtensionFieldInfo; exports.ExtensionFieldBinaryInfo = jspb.ExtensionFieldBinaryInfo; - // These are used by generated code but should not be used directly by clients. + // 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}; 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/js/package.json b/js/package.json index f7e8a3f1f4659..8d347fa3dc38e 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "google-protobuf", - "version": "3.19.4", + "version": "3.20.0-rc.2", "description": "Protocol Buffers for JavaScript", "main": "google-protobuf.js", "files": [ 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/benchmark/build.sh b/kokoro/linux/benchmark/build.sh index dee7c47ac7467..f470989394845 100755 --- a/kokoro/linux/benchmark/build.sh +++ b/kokoro/linux/benchmark/build.sh @@ -1,18 +1,18 @@ #!/bin/bash # +# This is the top-level script we give to Kokoro as the entry point for +# running the "pull request" project: +# +# This script selects a specific Dockerfile (for building a Docker image) and +# a script to run inside that image. Then we delegate to the general +# build_and_run_docker.sh script. + # Change to repo root cd $(dirname $0)/../../.. -set -ex - -# Install openJDK 11 (required by the java benchmarks) -sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 78BD65473CB3BD13 -sudo add-apt-repository ppa:openjdk-r/ppa -sudo apt-get update -sudo apt-get install -y openjdk-11-jdk-headless - -# use java 11 -sudo update-java-alternatives --set /usr/lib/jvm/java-1.11.0-openjdk-amd64 -java -version - -./tests.sh benchmark +export DOCKERHUB_ORGANIZATION=protobuftesting +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/java_stretch +export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh +export OUTPUT_DIR=testoutput +export TEST_SET="benchmark" +./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/benchmark/run.sh b/kokoro/linux/benchmark/run.sh index acd8737077343..963f7796ab4b3 100755 --- a/kokoro/linux/benchmark/run.sh +++ b/kokoro/linux/benchmark/run.sh @@ -23,7 +23,7 @@ popd ./configure CXXFLAGS="-fPIC -O2" make -j8 pushd python -virtualenv -p python3 env +python3 -m venv env source env/bin/activate python3 setup.py build --cpp_implementation pip3 install --install-option="--cpp_implementation" . 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/java_stretch/Dockerfile b/kokoro/linux/dockerfile/test/java_stretch/Dockerfile index b9f562a2b498c..8eeb6a2d1cdf7 100644 --- a/kokoro/linux/dockerfile/test/java_stretch/Dockerfile +++ b/kokoro/linux/dockerfile/test/java_stretch/Dockerfile @@ -1,4 +1,7 @@ -FROM debian:stretch +# Despite the name of this image, we are no longer on stretch. +# We should consider renaming this image, and/or evaluating what +# software versions we actually need. +FROM debian:bullseye # Install dependencies. We start with the basic ones required to build protoc # and the C++ build @@ -8,6 +11,7 @@ RUN apt-get update && apt-get install -y \ build-essential \ bzip2 \ ccache \ + cmake \ curl \ gcc \ git \ @@ -18,13 +22,17 @@ RUN apt-get update && apt-get install -y \ libtool \ make \ parallel \ + pkg-config \ time \ wget \ # Java dependencies maven \ - openjdk-8-jdk \ + openjdk-11-jdk \ + # Required for the gtest build. + python2 \ # Python dependencies + python3-dev \ python3-setuptools \ python3-pip \ - virtualenv \ + python3-venv \ && apt-get clean diff --git a/kokoro/linux/dockerfile/test/php80/Dockerfile b/kokoro/linux/dockerfile/test/php80/Dockerfile index 8093eae16c1ce..5b382d0a10120 100644 --- a/kokoro/linux/dockerfile/test/php80/Dockerfile +++ b/kokoro/linux/dockerfile/test/php80/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:jessie +FROM debian:stretch # Install dependencies. We start with the basic ones require to build protoc # and the C++ build @@ -29,7 +29,7 @@ RUN apt-get update && apt-get install -y \ # Install php dependencies RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ - php5 \ + php \ libcurl4-openssl-dev \ libgmp-dev \ libgmp3-dev \ @@ -90,6 +90,34 @@ RUN wget -O phpunit https://phar.phpunit.de/phpunit-9.phar \ && cp phpunit /usr/local/php-8.0/bin \ && mv phpunit /usr/local/php-8.0-zts/bin +# php 8.1 +RUN cd php-src \ + && git checkout php-8.1.2 \ + && ./buildconf --force +RUN cd php-src \ + && ./configure \ + --enable-bcmath \ + --enable-mbstring \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + --prefix=/usr/local/php-8.1 \ + && make \ + && make install \ + && make clean +RUN cd php-src \ + && ./configure \ + --enable-bcmath \ + --enable-mbstring \ + --enable-maintainer-zts \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + --prefix=/usr/local/php-8.1-zts \ + && make \ + && make install \ + && make clean + # Install php dependencies RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ valgrind \ diff --git a/kokoro/linux/dockerfile/test/python35/Dockerfile b/kokoro/linux/dockerfile/test/python35/Dockerfile deleted file mode 100644 index 50ee184536190..0000000000000 --- a/kokoro/linux/dockerfile/test/python35/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -FROM python:3.5-buster - -# Install dependencies. We start with the basic ones require to build protoc -# and the C++ build -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - ccache \ - curl \ - gcc \ - git \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - parallel \ - time \ - wget \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Install Python libraries. -RUN python -m pip install --no-cache-dir --upgrade \ - pip \ - setuptools \ - tox \ - wheel diff --git a/kokoro/linux/dockerfile/test/python36/Dockerfile b/kokoro/linux/dockerfile/test/python36/Dockerfile deleted file mode 100644 index 742503e5a4174..0000000000000 --- a/kokoro/linux/dockerfile/test/python36/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -FROM python:3.6-buster - -# Install dependencies. We start with the basic ones require to build protoc -# and the C++ build -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - ccache \ - curl \ - gcc \ - git \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - parallel \ - time \ - wget \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Install Python libraries. -RUN python -m pip install --no-cache-dir --upgrade \ - pip \ - setuptools \ - tox \ - wheel diff --git a/kokoro/linux/dockerfile/test/ruby/Dockerfile b/kokoro/linux/dockerfile/test/ruby/Dockerfile index 836287090ac71..914cd4b4b9074 100644 --- a/kokoro/linux/dockerfile/test/ruby/Dockerfile +++ b/kokoro/linux/dockerfile/test/ruby/Dockerfile @@ -35,8 +35,9 @@ RUN /bin/bash -l -c "rvm install 2.5.1" RUN /bin/bash -l -c "rvm install 2.6.0" RUN /bin/bash -l -c "rvm install 2.7.0" RUN /bin/bash -l -c "rvm install 3.0.0" -RUN /bin/bash -l -c "rvm install jruby-9.2.19.0" -RUN /bin/bash -l -c "rvm install jruby-9.3.0.0" +RUN /bin/bash -l -c "rvm install 3.1.0" +RUN /bin/bash -l -c "rvm install jruby-9.2.20.1" +RUN /bin/bash -l -c "rvm install jruby-9.3.3.0" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" diff --git a/kokoro/linux/python27/build.sh b/kokoro/linux/python27/build.sh deleted file mode 100755 index 41531a15efe88..0000000000000 --- a/kokoro/linux/python27/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "pull request" project: -# -# This script selects a specific Dockerfile (for building a Docker image) and -# a script to run inside that image. Then we delegate to the general -# build_and_run_docker.sh script. - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python27 -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="python27" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python27/presubmit.cfg b/kokoro/linux/python27/presubmit.cfg deleted file mode 100644 index dd98469a6fb60..0000000000000 --- a/kokoro/linux/python27/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python27/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python27_cpp/build.sh b/kokoro/linux/python27_cpp/build.sh deleted file mode 100755 index 1a972ee9f2611..0000000000000 --- a/kokoro/linux/python27_cpp/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "pull request" project: -# -# This script selects a specific Dockerfile (for building a Docker image) and -# a script to run inside that image. Then we delegate to the general -# build_and_run_docker.sh script. - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python27 -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="python27_cpp" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python27_cpp/continuous.cfg b/kokoro/linux/python27_cpp/continuous.cfg deleted file mode 100644 index ace22d0077174..0000000000000 --- a/kokoro/linux/python27_cpp/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python27_cpp/presubmit.cfg b/kokoro/linux/python27_cpp/presubmit.cfg deleted file mode 100644 index ace22d0077174..0000000000000 --- a/kokoro/linux/python27_cpp/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python35/continuous.cfg b/kokoro/linux/python35/continuous.cfg deleted file mode 100644 index 2b3e12cbb0cde..0000000000000 --- a/kokoro/linux/python35/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python35/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python35/presubmit.cfg b/kokoro/linux/python35/presubmit.cfg deleted file mode 100644 index 2b3e12cbb0cde..0000000000000 --- a/kokoro/linux/python35/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python35/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python35_cpp/build.sh b/kokoro/linux/python35_cpp/build.sh deleted file mode 100755 index 4d0dbd4986b29..0000000000000 --- a/kokoro/linux/python35_cpp/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "pull request" project: -# -# This script selects a specific Dockerfile (for building a Docker image) and -# a script to run inside that image. Then we delegate to the general -# build_and_run_docker.sh script. - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python35 -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="python35_cpp" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python35_cpp/continuous.cfg b/kokoro/linux/python35_cpp/continuous.cfg deleted file mode 100644 index ad5cc8657adc7..0000000000000 --- a/kokoro/linux/python35_cpp/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python35_cpp/presubmit.cfg b/kokoro/linux/python35_cpp/presubmit.cfg deleted file mode 100644 index ad5cc8657adc7..0000000000000 --- a/kokoro/linux/python35_cpp/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python36/build.sh b/kokoro/linux/python36/build.sh deleted file mode 100755 index a483efc3027f1..0000000000000 --- a/kokoro/linux/python36/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "pull request" project: -# -# This script selects a specific Dockerfile (for building a Docker image) and -# a script to run inside that image. Then we delegate to the general -# build_and_run_docker.sh script. - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python36 -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="python36" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python36/continuous.cfg b/kokoro/linux/python36/continuous.cfg deleted file mode 100644 index ee7f4888f8c76..0000000000000 --- a/kokoro/linux/python36/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python36/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python36_cpp/build.sh b/kokoro/linux/python36_cpp/build.sh deleted file mode 100755 index eb71bda92c48c..0000000000000 --- a/kokoro/linux/python36_cpp/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "pull request" project: -# -# This script selects a specific Dockerfile (for building a Docker image) and -# a script to run inside that image. Then we delegate to the general -# build_and_run_docker.sh script. - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python36 -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="python36_cpp" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python36_cpp/continuous.cfg b/kokoro/linux/python36_cpp/continuous.cfg deleted file mode 100644 index df9e7144943a8..0000000000000 --- a/kokoro/linux/python36_cpp/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python36_cpp/presubmit.cfg b/kokoro/linux/python36_cpp/presubmit.cfg deleted file mode 100644 index df9e7144943a8..0000000000000 --- a/kokoro/linux/python36_cpp/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python35/build.sh b/kokoro/linux/ruby31/build.sh old mode 100755 new mode 100644 similarity index 86% rename from kokoro/linux/python35/build.sh rename to kokoro/linux/ruby31/build.sh index 66ea03f0367ab..c22bdae2efd68 --- a/kokoro/linux/python35/build.sh +++ b/kokoro/linux/ruby31/build.sh @@ -11,8 +11,8 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python35 +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/ruby export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput -export TEST_SET="python35" +export TEST_SET="ruby31" ./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python27/continuous.cfg b/kokoro/linux/ruby31/continuous.cfg similarity index 76% rename from kokoro/linux/python27/continuous.cfg rename to kokoro/linux/ruby31/continuous.cfg index dd98469a6fb60..0477912b8cacc 100644 --- a/kokoro/linux/python27/continuous.cfg +++ b/kokoro/linux/ruby31/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/python27/build.sh" +build_file: "protobuf/kokoro/linux/ruby31/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36/presubmit.cfg b/kokoro/linux/ruby31/presubmit.cfg similarity index 76% rename from kokoro/linux/python36/presubmit.cfg rename to kokoro/linux/ruby31/presubmit.cfg index ee7f4888f8c76..0477912b8cacc 100644 --- a/kokoro/linux/python36/presubmit.cfg +++ b/kokoro/linux/ruby31/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/python36/build.sh" +build_file: "protobuf/kokoro/linux/ruby31/build.sh" timeout_mins: 120 action { diff --git a/kokoro/macos/prepare_build_macos_rc b/kokoro/macos/prepare_build_macos_rc index c0017b64ac822..8e0a87edbbf87 100755 --- a/kokoro/macos/prepare_build_macos_rc +++ b/kokoro/macos/prepare_build_macos_rc @@ -36,5 +36,5 @@ if [[ "${KOKORO_INSTALL_RVM:-}" == "yes" ]] ; then # 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 + curl -sSL https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer | bash -s master --ruby fi diff --git a/kokoro/macos/ruby31/build.sh b/kokoro/macos/ruby31/build.sh new file mode 100644 index 0000000000000..1b5a5a5a60eb6 --- /dev/null +++ b/kokoro/macos/ruby31/build.sh @@ -0,0 +1,12 @@ +#!/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 ruby31 diff --git a/kokoro/macos/ruby31/continuous.cfg b/kokoro/macos/ruby31/continuous.cfg new file mode 100644 index 0000000000000..19e16b3eaf5c7 --- /dev/null +++ b/kokoro/macos/ruby31/continuous.cfg @@ -0,0 +1,5 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/macos/ruby31/build.sh" +timeout_mins: 1440 diff --git a/kokoro/macos/ruby31/presubmit.cfg b/kokoro/macos/ruby31/presubmit.cfg new file mode 100644 index 0000000000000..19e16b3eaf5c7 --- /dev/null +++ b/kokoro/macos/ruby31/presubmit.cfg @@ -0,0 +1,5 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/macos/ruby31/build.sh" +timeout_mins: 1440 diff --git a/kokoro/release/python/linux/build_artifacts.sh b/kokoro/release/python/linux/build_artifacts.sh index 31da562814410..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,13 +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_artifact_version 3.10 +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_artifact_version 3.10 +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 75644539fa057..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 diff --git a/kokoro/release/python/windows/build_artifacts.bat b/kokoro/release/python/windows/build_artifacts.bat index ac466a901d3c2..121283a438248 100644 --- a/kokoro/release/python/windows/build_artifacts.bat +++ b/kokoro/release/python/windows/build_artifacts.bat @@ -14,6 +14,15 @@ 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 @@ -31,16 +40,6 @@ mkdir %ARTIFACT_DIR% REM Build wheel -SET PYTHON=C:\python36_32bit -SET PYTHON_VERSION=3.6 -SET PYTHON_ARCH=32 -CALL build_single_artifact.bat || goto :error - -SET PYTHON=C:\python36 -SET PYTHON_VERSION=3.6 -SET PYTHON_ARCH=64 -CALL build_single_artifact.bat || goto :error - SET PYTHON=C:\python37_32bit SET PYTHON_VERSION=3.7 SET PYTHON_ARCH=32 diff --git a/kokoro/release/python/windows/build_single_artifact.bat b/kokoro/release/python/windows/build_single_artifact.bat index 8d3cd0c9d8ee9..af2d265263a7e 100644 --- a/kokoro/release/python/windows/build_single_artifact.bat +++ b/kokoro/release/python/windows/build_single_artifact.bat @@ -1,11 +1,5 @@ setlocal -if %PYTHON%==C:\python36_32bit set generator=Visual Studio 14 -if %PYTHON%==C:\python36_32bit set vcplatform=Win32 - -if %PYTHON%==C:\python36 set generator=Visual Studio 14 Win64 -if %PYTHON%==C:\python36 set vcplatform=x64 - if %PYTHON%==C:\python37_32bit set generator=Visual Studio 14 if %PYTHON%==C:\python37_32bit set vcplatform=Win32 diff --git a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh index 98270d138338b..c3fcd3c584b17 100755 --- a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh +++ b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh @@ -3,12 +3,25 @@ set -ex set +ex # rvm script is very verbose and exits with errorcode + +curl -sSL https://rvm.io/mpapis.asc | gpg --import - +curl -sSL https://rvm.io/pkuczynski.asc | gpg --import - + +# 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 master --ruby + source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 rvm use 2.5.0 gem install rake-compiler --no-document gem install bundler --no-document +time rvm install 3.1.0 +rvm use 3.1.0 +gem install rake-compiler --no-document +gem install bundler --no-document time rvm install 2.7.0 rvm use 2.7.0 --default gem install rake-compiler --no-document @@ -20,6 +33,8 @@ set -ex rm -rf ~/.rake-compiler CROSS_RUBY=$(mktemp tmpfile.XXXXXXXX) +CROSS_RUBY31=$(mktemp tmpfile.XXXXXXXX) + curl https://raw.githubusercontent.com/rake-compiler/rake-compiler/72184e51779b6a3b9b8580b036a052fdc3181ced/tasks/bin/cross-ruby.rake > "$CROSS_RUBY" @@ -52,8 +67,33 @@ patch "$CROSS_RUBY" << EOF end EOF +cp $CROSS_RUBY $CROSS_RUBY31 + +patch "$CROSS_RUBY31" << EOF +--- cross-ruby.rake 2022-03-04 11:49:52.000000000 +0000 ++++ patched 2022-03-04 11:58:22.000000000 +0000 +@@ -114,6 +114,7 @@ + '--enable-static', + '--disable-shared', + '--disable-install-doc', ++ '--with-coroutine=ucontext', + '--without-gmp', + '--with-ext=', + 'LDFLAGS=-pipe', +EOF + MAKE="make -j8" +set +x # rvm commands are very verbose +rvm use 3.1.0 +set -x +ruby --version | grep 'ruby 3.1.0' +for v in 3.1.0 ; do + ccache -c + rake -f "$CROSS_RUBY31" cross-ruby VERSION="$v" HOST=x86_64-darwin MAKE="$MAKE" + rake -f "$CROSS_RUBY31" cross-ruby VERSION="$v" HOST=aarch64-darwin MAKE="$MAKE" +done + set +x # rvm commands are very verbose rvm use 2.7.0 set -x diff --git a/maven_install.json b/maven_install.json index 6168aa4af246e..808e0130d8f6f 100644 --- a/maven_install.json +++ b/maven_install.json @@ -1,25 +1,13 @@ { "dependency_tree": { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": 1907885757, - "__RESOLVED_ARTIFACTS_HASH": 375457873, + "__INPUT_ARTIFACTS_HASH": -1867950668, + "__RESOLVED_ARTIFACTS_HASH": 1254982283, "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": [ - { - "coord": "cglib:cglib-nodep:2.2.2", - "dependencies": [], - "directDependencies": [], - "file": "v1/https/repo1.maven.org/maven2/cglib/cglib-nodep/2.2.2/cglib-nodep-2.2.2.jar", - "mirror_urls": [ - "https://repo1.maven.org/maven2/cglib/cglib-nodep/2.2.2/cglib-nodep-2.2.2.jar", - "https://repo.maven.apache.org/maven2/cglib/cglib-nodep/2.2.2/cglib-nodep-2.2.2.jar" - ], - "sha256": "e78c7792e59554ed8a23d18a12e3a0d2f7a244217ecf89621477f63aec074f15", - "url": "https://repo1.maven.org/maven2/cglib/cglib-nodep/2.2.2/cglib-nodep-2.2.2.jar" - }, { "coord": "com.google.auto.value:auto-value-annotations:1.7.4", "dependencies": [], @@ -45,16 +33,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", @@ -81,21 +69,50 @@ "url": "https://repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" }, { - "coord": "com.google.guava:guava:30.1.1-jre", + "coord": "com.google.guava:guava-testlib:30.1.1-jre", "dependencies": [ + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.5.1", + "com.google.guava:failureaccess:1.0.1", + "com.google.guava:guava:30.1.1-jre", "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", "com.google.j2objc:j2objc-annotations:1.3", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.9.1", + "org.hamcrest:hamcrest-core:1.3" + ], + "directDependencies": [ "com.google.code.findbugs:jsr305:3.0.2", - "com.google.guava:failureaccess:1.0.1", "com.google.errorprone:error_prone_annotations:2.5.1", + "com.google.guava:guava:30.1.1-jre", + "com.google.j2objc:j2objc-annotations:1.3", + "junit:junit:4.13.2", "org.checkerframework:checker-qual:3.9.1" ], - "directDependencies": [ + "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": [ + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.5.1", + "com.google.guava:failureaccess:1.0.1", "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", "com.google.j2objc:j2objc-annotations:1.3", + "org.checkerframework:checker-qual:3.9.1" + ], + "directDependencies": [ "com.google.code.findbugs:jsr305:3.0.2", - "com.google.guava:failureaccess:1.0.1", "com.google.errorprone:error_prone_annotations:2.5.1", + "com.google.guava:failureaccess:1.0.1", + "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", + "com.google.j2objc:j2objc-annotations:1.3", "org.checkerframework:checker-qual:3.9.1" ], "file": "v1/https/repo1.maven.org/maven2/com/google/guava/guava/30.1.1-jre/guava-30.1.1-jre.jar", @@ -133,21 +150,20 @@ { "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", - "org.checkerframework:checker-qual:3.9.1" + "com.google.guava:guava:30.1.1-jre", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.9.1", + "org.ow2.asm:asm:9.0" ], "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", - "org.checkerframework:checker-qual:3.9.1" + "com.google.guava:guava:30.1.1-jre", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.9.1", + "org.ow2.asm:asm:9.0" ], "file": "v1/https/repo1.maven.org/maven2/com/google/truth/truth/1.1.2/truth-1.1.2.jar", "mirror_urls": [ @@ -158,20 +174,44 @@ "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.2/junit-4.13.2.jar", + "https://repo.maven.apache.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar" + ], + "sha256": "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", + "url": "https://repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar" + }, + { + "coord": "net.bytebuddy:byte-buddy-agent:1.12.7", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar", + "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar" + ], + "sha256": "73d84bb6e8e8980e674d796a29063f510ceb527c6f8c912a08a13e236be05c71", + "url": "https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar" + }, + { + "coord": "net.bytebuddy:byte-buddy:1.12.7", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.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/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.jar", + "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.jar" ], - "sha256": "c30719db974d6452793fe191b3638a5777005485bae145924044530ffa5f6122", - "url": "https://repo1.maven.org/maven2/junit/junit/4.13.1/junit-4.13.1.jar" + "sha256": "d2e46555699e70361b5471a7e142f9c67855bba6907a285177ebd8ad973775d8", + "url": "https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.jar" }, { "coord": "org.checkerframework:checker-qual:3.9.1", @@ -185,24 +225,6 @@ "sha256": "ab0468b1ba35bb2ae45f61a60dc4960bd887660ab8f05113a662a7e675eae776", "url": "https://repo1.maven.org/maven2/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar" }, - { - "coord": "org.easymock:easymock:3.2", - "dependencies": [ - "cglib:cglib-nodep:2.2.2", - "org.objenesis:objenesis:1.3" - ], - "directDependencies": [ - "cglib:cglib-nodep:2.2.2", - "org.objenesis:objenesis:1.3" - ], - "file": "v1/https/repo1.maven.org/maven2/org/easymock/easymock/3.2/easymock-3.2.jar", - "mirror_urls": [ - "https://repo1.maven.org/maven2/org/easymock/easymock/3.2/easymock-3.2.jar", - "https://repo.maven.apache.org/maven2/org/easymock/easymock/3.2/easymock-3.2.jar" - ], - "sha256": "b3dd1cf5019f942d8cc2afad0aa6aef4b21532446fe90a6b68d567e3389763dd", - "url": "https://repo1.maven.org/maven2/org/easymock/easymock/3.2/easymock-3.2.jar" - }, { "coord": "org.hamcrest:hamcrest-core:1.3", "dependencies": [], @@ -216,16 +238,36 @@ "url": "https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" }, { - "coord": "org.objenesis:objenesis:1.3", + "coord": "org.mockito:mockito-core:4.3.1", + "dependencies": [ + "net.bytebuddy:byte-buddy-agent:1.12.7", + "net.bytebuddy:byte-buddy:1.12.7", + "org.objenesis:objenesis:3.2" + ], + "directDependencies": [ + "net.bytebuddy:byte-buddy-agent:1.12.7", + "net.bytebuddy:byte-buddy:1.12.7", + "org.objenesis:objenesis:3.2" + ], + "file": "v1/https/repo1.maven.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar", + "https://repo.maven.apache.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar" + ], + "sha256": "148de2c6928365db29443ca12d35c930d9f481172b934fdd801d1cb1409ea83a", + "url": "https://repo1.maven.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar" + }, + { + "coord": "org.objenesis:objenesis:3.2", "dependencies": [], "directDependencies": [], - "file": "v1/https/repo1.maven.org/maven2/org/objenesis/objenesis/1.3/objenesis-1.3.jar", + "file": "v1/https/repo1.maven.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar", "mirror_urls": [ - "https://repo1.maven.org/maven2/org/objenesis/objenesis/1.3/objenesis-1.3.jar", - "https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.3/objenesis-1.3.jar" + "https://repo1.maven.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar", + "https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar" ], - "sha256": "dd4ef3d3091063a4fec578cbb2bbe6c1f921c00091ba2993dcd9afd25ff9444a", - "url": "https://repo1.maven.org/maven2/org/objenesis/objenesis/1.3/objenesis-1.3.jar" + "sha256": "03d960bd5aef03c653eb000413ada15eb77cdd2b8e4448886edf5692805e35f3", + "url": "https://repo1.maven.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar" }, { "coord": "org.ow2.asm:asm:9.0", diff --git a/objectivec/GPBAny.pbobjc.h b/objectivec/GPBAny.pbobjc.h index 21b7dcf4afb4c..7fb4129b139e1 100644 --- a/objectivec/GPBAny.pbobjc.h +++ b/objectivec/GPBAny.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. @@ -81,7 +69,7 @@ typedef GPB_ENUM(GPBAny_FieldNumber) { * foo = any.unpack(Foo.class); * } * - * Example 3: Pack and unpack a message in Python. + * Example 3: Pack and unpack a message in Python. * * foo = Foo(...) * any = Any() @@ -91,7 +79,7 @@ typedef GPB_ENUM(GPBAny_FieldNumber) { * any.Unpack(foo) * ... * - * Example 4: Pack and unpack a message in Go + * Example 4: Pack and unpack a message in Go * * foo := &pb.Foo{...} * any, err := anypb.New(foo) @@ -112,7 +100,7 @@ typedef GPB_ENUM(GPBAny_FieldNumber) { * * * JSON - * ==== + * * The JSON representation of an `Any` value uses the regular * representation of the deserialized, embedded message, with an * additional field `\@type` which contains the type URL. Example: diff --git a/objectivec/GPBAny.pbobjc.m b/objectivec/GPBAny.pbobjc.m index a5143f15dc3ca..7632c8c279b45 100644 --- a/objectivec/GPBAny.pbobjc.m +++ b/objectivec/GPBAny.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBAny.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBAny.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBApi.pbobjc.h b/objectivec/GPBApi.pbobjc.h index 5d55ebf39921a..871e90885a619 100644 --- a/objectivec/GPBApi.pbobjc.h +++ b/objectivec/GPBApi.pbobjc.h @@ -1,21 +1,11 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" +#import "GPBSourceContext.pbobjc.h" +#import "GPBType.pbobjc.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. @@ -33,9 +23,6 @@ CF_EXTERN_C_BEGIN @class GPBMethod; @class GPBMixin; -@class GPBOption; -@class GPBSourceContext; -GPB_ENUM_FWD_DECLARE(GPBSyntax); NS_ASSUME_NONNULL_BEGIN diff --git a/objectivec/GPBApi.pbobjc.m b/objectivec/GPBApi.pbobjc.m index 5915ce1122628..7f86a087ffd86 100644 --- a/objectivec/GPBApi.pbobjc.m +++ b/objectivec/GPBApi.pbobjc.m @@ -1,27 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBApi.pbobjc.h" - #import "GPBSourceContext.pbobjc.h" - #import "GPBType.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBApi.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBDuration.pbobjc.h b/objectivec/GPBDuration.pbobjc.h index 88527f520d3c3..d6236b07f34dc 100644 --- a/objectivec/GPBDuration.pbobjc.h +++ b/objectivec/GPBDuration.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBDuration.pbobjc.m b/objectivec/GPBDuration.pbobjc.m index d3cc7e31ca3f4..11ba5e5f7b336 100644 --- a/objectivec/GPBDuration.pbobjc.m +++ b/objectivec/GPBDuration.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBDuration.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBDuration.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBEmpty.pbobjc.h b/objectivec/GPBEmpty.pbobjc.h index 45600ead863a1..8a31c04ff511d 100644 --- a/objectivec/GPBEmpty.pbobjc.h +++ b/objectivec/GPBEmpty.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBEmpty.pbobjc.m b/objectivec/GPBEmpty.pbobjc.m index df3e398170afb..8aefddb5b46ac 100644 --- a/objectivec/GPBEmpty.pbobjc.m +++ b/objectivec/GPBEmpty.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBEmpty.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBEmpty.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBFieldMask.pbobjc.h b/objectivec/GPBFieldMask.pbobjc.h index 3028b775dcd6d..c4667b44db26e 100644 --- a/objectivec/GPBFieldMask.pbobjc.h +++ b/objectivec/GPBFieldMask.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBFieldMask.pbobjc.m b/objectivec/GPBFieldMask.pbobjc.m index 3605f89d80578..ab25d3f9b1eac 100644 --- a/objectivec/GPBFieldMask.pbobjc.m +++ b/objectivec/GPBFieldMask.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBFieldMask.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBFieldMask.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBProtocolBuffers.h b/objectivec/GPBProtocolBuffers.h index c5df916396987..619c08228bb67 100644 --- a/objectivec/GPBProtocolBuffers.h +++ b/objectivec/GPBProtocolBuffers.h @@ -44,33 +44,14 @@ #import "GPBWellKnownTypes.h" #import "GPBWireFormat.h" -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - // Well-known proto types -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import - #import - #import - #import - #import - #import - #import - #import -#else - #import "GPBAny.pbobjc.h" - #import "GPBApi.pbobjc.h" - #import "GPBDuration.pbobjc.h" - #import "GPBEmpty.pbobjc.h" - #import "GPBFieldMask.pbobjc.h" - #import "GPBSourceContext.pbobjc.h" - #import "GPBStruct.pbobjc.h" - #import "GPBTimestamp.pbobjc.h" - #import "GPBType.pbobjc.h" - #import "GPBWrappers.pbobjc.h" -#endif +#import "GPBAny.pbobjc.h" +#import "GPBApi.pbobjc.h" +#import "GPBDuration.pbobjc.h" +#import "GPBEmpty.pbobjc.h" +#import "GPBFieldMask.pbobjc.h" +#import "GPBSourceContext.pbobjc.h" +#import "GPBStruct.pbobjc.h" +#import "GPBTimestamp.pbobjc.h" +#import "GPBType.pbobjc.h" +#import "GPBWrappers.pbobjc.h" diff --git a/objectivec/GPBSourceContext.pbobjc.h b/objectivec/GPBSourceContext.pbobjc.h index 7a103362b5658..b17fec0b788c5 100644 --- a/objectivec/GPBSourceContext.pbobjc.h +++ b/objectivec/GPBSourceContext.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBSourceContext.pbobjc.m b/objectivec/GPBSourceContext.pbobjc.m index b3e6fa759ce48..376d4421de2d7 100644 --- a/objectivec/GPBSourceContext.pbobjc.m +++ b/objectivec/GPBSourceContext.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBSourceContext.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBSourceContext.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBStruct.pbobjc.h b/objectivec/GPBStruct.pbobjc.h index abdd6c82be379..dd6ab28f0e81f 100644 --- a/objectivec/GPBStruct.pbobjc.h +++ b/objectivec/GPBStruct.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBStruct.pbobjc.m b/objectivec/GPBStruct.pbobjc.m index 554046a9fe50f..726cfb860ea70 100644 --- a/objectivec/GPBStruct.pbobjc.m +++ b/objectivec/GPBStruct.pbobjc.m @@ -1,25 +1,11 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBStruct.pbobjc.h" #import -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBStruct.pbobjc.h" -#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBTimestamp.pbobjc.h b/objectivec/GPBTimestamp.pbobjc.h index a328afc7c93d4..8203383bdd985 100644 --- a/objectivec/GPBTimestamp.pbobjc.h +++ b/objectivec/GPBTimestamp.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBTimestamp.pbobjc.m b/objectivec/GPBTimestamp.pbobjc.m index 736a75d19f9d0..72d348f42a6bc 100644 --- a/objectivec/GPBTimestamp.pbobjc.m +++ b/objectivec/GPBTimestamp.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBTimestamp.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBTimestamp.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBType.pbobjc.h b/objectivec/GPBType.pbobjc.h index 747e15d455dc7..b0230501cf3ce 100644 --- a/objectivec/GPBType.pbobjc.h +++ b/objectivec/GPBType.pbobjc.h @@ -1,21 +1,11 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/type.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" +#import "GPBAny.pbobjc.h" +#import "GPBSourceContext.pbobjc.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. @@ -31,11 +21,9 @@ CF_EXTERN_C_BEGIN -@class GPBAny; @class GPBEnumValue; @class GPBField; @class GPBOption; -@class GPBSourceContext; NS_ASSUME_NONNULL_BEGIN diff --git a/objectivec/GPBType.pbobjc.m b/objectivec/GPBType.pbobjc.m index 70dae31c68a06..f5fc1efececbd 100644 --- a/objectivec/GPBType.pbobjc.m +++ b/objectivec/GPBType.pbobjc.m @@ -1,29 +1,11 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/type.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBType.pbobjc.h" #import -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBType.pbobjc.h" - #import "GPBAny.pbobjc.h" - #import "GPBSourceContext.pbobjc.h" -#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBWellKnownTypes.h b/objectivec/GPBWellKnownTypes.h index 784ba9ff99e85..80d9db00e91fe 100644 --- a/objectivec/GPBWellKnownTypes.h +++ b/objectivec/GPBWellKnownTypes.h @@ -30,21 +30,9 @@ #import -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBAny.pbobjc.h" - #import "GPBDuration.pbobjc.h" - #import "GPBTimestamp.pbobjc.h" -#endif +#import "GPBAny.pbobjc.h" +#import "GPBDuration.pbobjc.h" +#import "GPBTimestamp.pbobjc.h" NS_ASSUME_NONNULL_BEGIN diff --git a/objectivec/GPBWrappers.pbobjc.h b/objectivec/GPBWrappers.pbobjc.h index 713bafc89b025..e6741ae120c40 100644 --- a/objectivec/GPBWrappers.pbobjc.h +++ b/objectivec/GPBWrappers.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/wrappers.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBWrappers.pbobjc.m b/objectivec/GPBWrappers.pbobjc.m index 32201d4d8305a..b02a0716e2361 100644 --- a/objectivec/GPBWrappers.pbobjc.m +++ b/objectivec/GPBWrappers.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/wrappers.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBWrappers.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBWrappers.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/README.md b/objectivec/README.md index 9aedb219f5262..a0fcd19307455 100644 --- a/objectivec/README.md +++ b/objectivec/README.md @@ -133,12 +133,12 @@ This options allow you to provide a custom prefix for all the symbols generated from a proto file (classes (from message), enums, the Root for extension support). -If not set, the generation option `use_package_as_prefix` (documented below) -controls what is used instead. Since Objective C uses a global namespace for all -of its classes, there can be collisions. `use_package_as_prefix=yes` should -avoid collisions since proto package are used to scope/name things in other -languages, but this option can be used to get shorter names instead. Convention -is to base the explicit prefix on the proto package. +If not set, the generation options `package_to_prefix_mappings_path` and +`use_package_as_prefix` (documented below) controls what is used instead. Since +Objective C uses a global namespace for all of its classes, there can be collisions. +`use_package_as_prefix=yes` should avoid collisions since proto package are used to +scope/name things in other languages, but this option can be used to get shorter +names instead. Convention is to base the explicit prefix on the proto package. Objective C Generator `protoc` Options -------------------------------------- @@ -182,6 +182,24 @@ supported keys are: having to add the runtime directory to the header search path since the generate `#import` will be more complete. + * `package_to_prefix_mappings_path`: The `value` used for this key is a + path to a file containing a list of proto packages and prefixes. + The generator will use this to locate which ObjC class prefix to use when + generating sources _unless_ the `objc_class_prefix` file option is set. + This option can be useful if multiple apps consume a common set of + proto files but wish to use a different prefix for the generated sources + between them. This option takes precedent over the `use_package_as_prefix` + option. + + The format of the file is: + * An entry is a line of "package=prefix". + * 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. + * `use_package_as_prefix` and `proto_package_prefix_exceptions_path`: The `value` for `use_package_as_prefix` can be `yes` or `no`, and indicates if a prefix should be derived from the proto package for all the symbols @@ -200,6 +218,21 @@ supported keys are: helps prepare folks before they end up using a lot of protos and getting a lot of collisions. + * `headers_use_forward_declarations`: The `value` for this can be `yes` or + `no`, and indicates if the generated headers use forward declarations for + Message and Enum types from other .proto files or if the files should be + imported into the generated header instead. + + By using forward declarations, less code is likely to recompile when the + files do change, but Swift generally doesn't like forward declarations and + will fail to include properties when the concrete definition of the type is + known at import time. If your proto usages span modules, this can be a + problem. + + `headers_use_forward_declarations` currently defaults to `yes` (existing + behavior), but in a future release, that default may change to provide + better Swift support by default. + Contributing ------------ diff --git a/php/ext/google/protobuf/arena.c b/php/ext/google/protobuf/arena.c index 035dfcad760f2..bc639ba53e87d 100644 --- a/php/ext/google/protobuf/arena.c +++ b/php/ext/google/protobuf/arena.c @@ -38,7 +38,7 @@ typedef struct Arena { zend_object std; - upb_arena* arena; + upb_Arena* arena; } Arena; zend_class_entry *Arena_class_entry; @@ -50,14 +50,14 @@ static zend_object* Arena_Create(zend_class_entry *class_type) { Arena *intern = emalloc(sizeof(Arena)); zend_object_std_init(&intern->std, class_type); intern->std.handlers = &Arena_object_handlers; - intern->arena = upb_arena_new(); + intern->arena = upb_Arena_New(); // Skip object_properties_init(), we don't allow derived classes. return &intern->std; } static void Arena_Free(zend_object* obj) { Arena* intern = (Arena*)obj; - upb_arena_free(intern->arena); + upb_Arena_Free(intern->arena); zend_object_std_dtor(&intern->std); } @@ -67,7 +67,7 @@ void Arena_Init(zval* val) { ZVAL_OBJ(val, Arena_Create(Arena_class_entry)); } -upb_arena *Arena_Get(zval *val) { +upb_Arena *Arena_Get(zval *val) { Arena *a = (Arena*)Z_OBJ_P(val); return a->arena; } diff --git a/php/ext/google/protobuf/arena.h b/php/ext/google/protobuf/arena.h index 67e165d37d35c..00895fcd51515 100644 --- a/php/ext/google/protobuf/arena.h +++ b/php/ext/google/protobuf/arena.h @@ -38,10 +38,10 @@ // Registers the PHP Arena class. void Arena_ModuleInit(); -// Creates and returns a new arena object that wraps a new upb_arena*. +// Creates and returns a new arena object that wraps a new upb_Arena*. void Arena_Init(zval *val); -// Gets the underlying upb_arena from this arena object. -upb_arena *Arena_Get(zval *arena); +// Gets the underlying upb_Arena from this arena object. +upb_Arena *Arena_Get(zval *arena); #endif // PHP_PROTOBUF_ARENA_H_ diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 2c9a7108b9d48..72c7809674c6b 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -54,7 +54,7 @@ static void RepeatedFieldIter_make(zval *val, zval *repeated_field); typedef struct { zend_object std; zval arena; - upb_array *array; + upb_Array *array; TypeInfo type; } RepeatedField; @@ -120,14 +120,14 @@ static int RepeatedField_compare_objects(zval *rf1, zval *rf2) { */ static zend_object *RepeatedField_clone_obj(PROTO_VAL *object) { RepeatedField* intern = PROTO_VAL_P(object); - upb_arena *arena = Arena_Get(&intern->arena); - upb_array *clone = upb_array_new(arena, intern->type.type); - size_t n = upb_array_size(intern->array); + upb_Arena *arena = Arena_Get(&intern->arena); + upb_Array *clone = upb_Array_New(arena, intern->type.type); + size_t n = upb_Array_Size(intern->array); size_t i; for (i = 0; i < n; i++) { - upb_msgval msgval = upb_array_get(intern->array, i); - upb_array_append(clone, msgval, arena); + upb_MessageValue msgval = upb_Array_Get(intern->array, i); + upb_Array_Append(clone, msgval, arena); } zval ret; @@ -149,7 +149,7 @@ static zval *RepeatedField_GetPropertyPtrPtr(PROTO_VAL *object, // These are documented in the header file. -void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, TypeInfo type, +void RepeatedField_GetPhpWrapper(zval *val, upb_Array *arr, TypeInfo type, zval *arena) { if (!arr) { ZVAL_NULL(val); @@ -169,15 +169,15 @@ void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, TypeInfo type, } } -upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, - upb_arena *arena) { +upb_Array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, + upb_Arena *arena) { if (Z_ISREF_P(val)) { ZVAL_DEREF(val); } if (Z_TYPE_P(val) == IS_ARRAY) { - // Auto-construct, eg. [1, 2, 3] -> upb_array([1, 2, 3]). - upb_array *arr = upb_array_new(arena, type.type); + // Auto-construct, eg. [1, 2, 3] -> upb_Array([1, 2, 3]). + upb_Array *arr = upb_Array_New(arena, type.type); HashTable *table = HASH_OF(val); HashPosition pos; @@ -185,7 +185,7 @@ upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, while (true) { zval *zv = zend_hash_get_current_data_ex(table, &pos); - upb_msgval val; + upb_MessageValue val; if (!zv) return arr; @@ -193,12 +193,12 @@ upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, return NULL; } - upb_array_append(arr, val, arena); + upb_Array_Append(arr, val, arena); zend_hash_move_forward_ex(table, &pos); } } else if (Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == RepeatedField_class_entry) { - // Unwrap existing RepeatedField object to get the upb_array* inside. + // Unwrap existing RepeatedField object to get the upb_Array* inside. RepeatedField *intern = (RepeatedField*)Z_OBJ_P(val); if (!TypeInfo_Eq(intern->type, type)) { @@ -206,7 +206,7 @@ upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, "Wrong type for this repeated field."); } - upb_arena_fuse(arena, Arena_Get(&intern->arena)); + upb_Arena_Fuse(arena, Arena_Get(&intern->arena)); return intern->array; } else { php_error_docref(NULL, E_USER_ERROR, "Must be a repeated field"); @@ -214,19 +214,19 @@ upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, } } -bool ArrayEq(const upb_array *a1, const upb_array *a2, TypeInfo type) { +bool ArrayEq(const upb_Array *a1, const upb_Array *a2, TypeInfo type) { size_t i; size_t n; if ((a1 == NULL) != (a2 == NULL)) return false; if (a1 == NULL) return true; - n = upb_array_size(a1); - if (n != upb_array_size(a2)) return false; + n = upb_Array_Size(a1); + if (n != upb_Array_Size(a2)) return false; for (i = 0; i < n; i++) { - upb_msgval val1 = upb_array_get(a1, i); - upb_msgval val2 = upb_array_get(a2, i); + upb_MessageValue val1 = upb_Array_Get(a1, i); + upb_MessageValue val2 = upb_Array_Get(a2, i); if (!ValueEq(val1, val2, type)) return false; } @@ -245,7 +245,7 @@ bool ArrayEq(const upb_array *a1, const upb_array *a2, TypeInfo type) { */ PHP_METHOD(RepeatedField, __construct) { RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); + upb_Arena *arena = Arena_Get(&intern->arena); zend_long type; zend_class_entry* klass = NULL; @@ -256,13 +256,13 @@ PHP_METHOD(RepeatedField, __construct) { intern->type.type = pbphp_dtype_to_type(type); intern->type.desc = Descriptor_GetFromClassEntry(klass); - if (intern->type.type == UPB_TYPE_MESSAGE && klass == NULL) { + if (intern->type.type == kUpb_CType_Message && klass == NULL) { php_error_docref(NULL, E_USER_ERROR, "Message/enum type must have concrete class."); return; } - intern->array = upb_array_new(arena, intern->type.type); + intern->array = upb_Array_New(arena, intern->type.type); ObjCache_Add(intern->array, &intern->std); } @@ -274,20 +274,20 @@ PHP_METHOD(RepeatedField, __construct) { */ PHP_METHOD(RepeatedField, append) { RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); + upb_Arena *arena = Arena_Get(&intern->arena); zval *php_val; - upb_msgval msgval; + upb_MessageValue msgval; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &php_val) != SUCCESS || !Convert_PhpToUpb(php_val, &msgval, intern->type, arena)) { return; } - upb_array_append(intern->array, msgval, arena); + upb_Array_Append(intern->array, msgval, arena); } /** - * RepeatedField::offsetExists() + * RepeatedField::offsetExists(): bool * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -305,11 +305,11 @@ PHP_METHOD(RepeatedField, offsetExists) { return; } - RETURN_BOOL(index >= 0 && index < upb_array_size(intern->array)); + RETURN_BOOL(index >= 0 && index < upb_Array_Size(intern->array)); } /** - * RepeatedField::offsetGet() + * RepeatedField::offsetGet(): mixed * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -323,25 +323,25 @@ PHP_METHOD(RepeatedField, offsetExists) { PHP_METHOD(RepeatedField, offsetGet) { RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); zend_long index; - upb_msgval msgval; + upb_MessageValue msgval; zval ret; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { return; } - if (index < 0 || index >= upb_array_size(intern->array)) { + if (index < 0 || index >= upb_Array_Size(intern->array)) { zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); return; } - msgval = upb_array_get(intern->array, index); + msgval = upb_Array_Get(intern->array, index); Convert_UpbToPhp(msgval, &ret, intern->type, &intern->arena); RETURN_COPY_VALUE(&ret); } /** - * RepeatedField::offsetSet() + * RepeatedField::offsetSet(): void * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -356,11 +356,11 @@ PHP_METHOD(RepeatedField, offsetGet) { */ PHP_METHOD(RepeatedField, offsetSet) { RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); - size_t size = upb_array_size(intern->array); + upb_Arena *arena = Arena_Get(&intern->arena); + size_t size = upb_Array_Size(intern->array); zval *offset, *val; int64_t index; - upb_msgval msgval; + upb_MessageValue msgval; if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &offset, &val) != SUCCESS) { return; @@ -379,14 +379,14 @@ PHP_METHOD(RepeatedField, offsetSet) { if (index > size) { zend_error(E_USER_ERROR, "Element at index %ld doesn't exist.\n", index); } else if (index == size) { - upb_array_append(intern->array, msgval, Arena_Get(&intern->arena)); + upb_Array_Append(intern->array, msgval, Arena_Get(&intern->arena)); } else { - upb_array_set(intern->array, index, msgval); + upb_Array_Set(intern->array, index, msgval); } } /** - * RepeatedField::offsetUnset() + * RepeatedField::offsetUnset(): void * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -399,7 +399,7 @@ PHP_METHOD(RepeatedField, offsetSet) { PHP_METHOD(RepeatedField, offsetUnset) { RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); zend_long index; - zend_long size = upb_array_size(intern->array); + zend_long size = upb_Array_Size(intern->array); // Only the element at the end of the array can be removed. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) != SUCCESS) { @@ -412,11 +412,11 @@ PHP_METHOD(RepeatedField, offsetUnset) { return; } - upb_array_resize(intern->array, size - 1, Arena_Get(&intern->arena)); + upb_Array_Resize(intern->array, size - 1, Arena_Get(&intern->arena)); } /** - * RepeatedField::count() + * RepeatedField::count(): int * * Implements the Countable interface. Invoked when PHP code calls: * @@ -432,11 +432,11 @@ PHP_METHOD(RepeatedField, count) { return; } - RETURN_LONG(upb_array_size(intern->array)); + RETURN_LONG(upb_Array_Size(intern->array)); } /** - * RepeatedField::getIterator() + * RepeatedField::getIterator(): Traversable * * Implements the IteratorAggregate interface. Invoked when PHP code calls: * @@ -459,24 +459,38 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 1) ZEND_ARG_INFO(0, newval) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetExists, 0, 0, _IS_BOOL, 0) ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_offsetGet, 0, 0, IS_MIXED, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetSet, 0, 2, IS_VOID, 0) ZEND_ARG_INFO(0, index) ZEND_ARG_INFO(0, newval) ZEND_END_ARG_INFO() +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetUnset, 0, 0, IS_VOID, 0) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_count, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_getIterator, 0, 0, Traversable, 0) +ZEND_END_ARG_INFO() + static zend_function_entry repeated_field_methods[] = { - PHP_ME(RepeatedField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, append, arginfo_append, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, count, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, getIterator, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, append, arginfo_append, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetExists, arginfo_offsetExists, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetUnset, arginfo_offsetUnset, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, count, arginfo_count, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, getIterator, arginfo_getIterator, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -550,7 +564,7 @@ static void RepeatedFieldIter_make(zval *val, zval *repeated_field) { */ /** - * RepeatedFieldIter::rewind() + * RepeatedFieldIter::rewind(): void * * Implements the Iterator interface. Sets the iterator to the first element. */ @@ -560,30 +574,30 @@ PHP_METHOD(RepeatedFieldIter, rewind) { } /** - * RepeatedFieldIter::current() + * RepeatedFieldIter::current(): mixed * * Implements the Iterator interface. Returns the current value. */ PHP_METHOD(RepeatedFieldIter, current) { RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis()); RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field); - upb_array *array = field->array; + upb_Array *array = field->array; zend_long index = intern->position; - upb_msgval msgval; + upb_MessageValue msgval; zval ret; - if (index < 0 || index >= upb_array_size(array)) { + if (index < 0 || index >= upb_Array_Size(array)) { zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); } - msgval = upb_array_get(array, index); + msgval = upb_Array_Get(array, index); Convert_UpbToPhp(msgval, &ret, field->type, &field->arena); RETURN_COPY_VALUE(&ret); } /** - * RepeatedFieldIter::key() + * RepeatedFieldIter::key(): mixed * * Implements the Iterator interface. Returns the current key. */ @@ -593,7 +607,7 @@ PHP_METHOD(RepeatedFieldIter, key) { } /** - * RepeatedFieldIter::next() + * RepeatedFieldIter::next(): void * * Implements the Iterator interface. Advances to the next element. */ @@ -603,22 +617,37 @@ PHP_METHOD(RepeatedFieldIter, next) { } /** - * RepeatedFieldIter::valid() + * RepeatedFieldIter::valid(): bool * * Implements the Iterator interface. Returns true if this is a valid element. */ PHP_METHOD(RepeatedFieldIter, valid) { RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis()); RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field); - RETURN_BOOL(intern->position < upb_array_size(field->array)); + RETURN_BOOL(intern->position < upb_Array_Size(field->array)); } +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_current, 0, 0, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_key, 0, 0, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_next, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_valid, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rewind, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + static zend_function_entry repeated_field_iter_methods[] = { - PHP_ME(RepeatedFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, rewind, arginfo_rewind, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, current, arginfo_current, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, key, arginfo_key, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, next, arginfo_next, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, valid, arginfo_valid, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/php/ext/google/protobuf/array.h b/php/ext/google/protobuf/array.h index 031effa711233..a6691e7d4508a 100644 --- a/php/ext/google/protobuf/array.h +++ b/php/ext/google/protobuf/array.h @@ -39,29 +39,29 @@ // Registers PHP classes for RepeatedField. void Array_ModuleInit(); -// Gets a upb_array* for the PHP object |val|: +// Gets a upb_Array* for the PHP object |val|: // * If |val| is a RepeatedField object, we first check its type and verify // that that the elements have the correct type for |type|. If so, we return -// the wrapped upb_array*. We also make sure that this array's arena is fused -// to |arena|, so the returned upb_array is guaranteed to live as long as +// the wrapped upb_Array*. We also make sure that this array's arena is fused +// to |arena|, so the returned upb_Array is guaranteed to live as long as // |arena|. -// * If |val| is a PHP Array, we attempt to create a new upb_array using +// * If |val| is a PHP Array, we attempt to create a new upb_Array using // |arena| and add all of the PHP elements to it. // // If an error occurs, we raise a PHP error and return NULL. -upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, - upb_arena *arena); +upb_Array *RepeatedField_GetUpbArray(zval *val, TypeInfo type, + upb_Arena *arena); -// Creates a PHP RepeatedField object for the given upb_array* and |type| and +// Creates a PHP RepeatedField object for the given upb_Array* and |type| and // returns it in |val|. The PHP object will keep a reference to this |arena| to // ensure the underlying array data stays alive. // // If |arr| is NULL, this will return a PHP null object. -void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, TypeInfo type, +void RepeatedField_GetPhpWrapper(zval *val, upb_Array *arr, TypeInfo type, zval *arena); // Returns true if the given arrays are equal. Both arrays must be of this -// |type| and, if the type is |UPB_TYPE_MESSAGE|, must have the same |m|. -bool ArrayEq(const upb_array *a1, const upb_array *a2, TypeInfo type); +// |type| and, if the type is |kUpb_CType_Message|, must have the same |m|. +bool ArrayEq(const upb_Array *a1, const upb_Array *a2, TypeInfo type); #endif // PHP_PROTOBUF_ARRAY_H_ diff --git a/php/ext/google/protobuf/config.m4 b/php/ext/google/protobuf/config.m4 index c09c03af0a5b7..74cae3c7ef8da 100644 --- a/php/ext/google/protobuf/config.m4 +++ b/php/ext/google/protobuf/config.m4 @@ -4,7 +4,7 @@ if test "$PHP_PROTOBUF" != "no"; then PHP_NEW_EXTENSION( protobuf, - arena.c array.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c, + arena.c array.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c third_party/utf8_range/naive.c third_party/utf8_range/range2-neon.c third_party/utf8_range/range2-sse.c, $ext_shared, , -std=gnu99) fi diff --git a/php/ext/google/protobuf/convert.c b/php/ext/google/protobuf/convert.c index a1ed2c8a3fecf..bedbcca367fc8 100644 --- a/php/ext/google/protobuf/convert.c +++ b/php/ext/google/protobuf/convert.c @@ -153,30 +153,30 @@ static zend_function_entry util_methods[] = { // Conversion functions used from C // ----------------------------------------------------------------------------- -upb_fieldtype_t pbphp_dtype_to_type(upb_descriptortype_t type) { +upb_CType pbphp_dtype_to_type(upb_FieldType type) { switch (type) { #define CASE(descriptor_type, type) \ - case UPB_DESCRIPTOR_TYPE_##descriptor_type: \ - return UPB_TYPE_##type; - - CASE(FLOAT, FLOAT); - CASE(DOUBLE, DOUBLE); - CASE(BOOL, BOOL); - CASE(STRING, STRING); - CASE(BYTES, BYTES); - CASE(MESSAGE, MESSAGE); - CASE(GROUP, MESSAGE); - CASE(ENUM, ENUM); - CASE(INT32, INT32); - CASE(INT64, INT64); - CASE(UINT32, UINT32); - CASE(UINT64, UINT64); - CASE(SINT32, INT32); - CASE(SINT64, INT64); - CASE(FIXED32, UINT32); - CASE(FIXED64, UINT64); - CASE(SFIXED32, INT32); - CASE(SFIXED64, INT64); + case kUpb_FieldType_##descriptor_type: \ + return kUpb_CType_##type; + + CASE(Float, Float); + CASE(Double, Double); + CASE(Bool, Bool); + CASE(String, String); + CASE(Bytes, Bytes); + CASE(Message, Message); + CASE(Group, Message); + CASE(Enum, Enum); + CASE(Int32, Int32); + CASE(Int64, Int64); + CASE(UInt32, Int32); + CASE(UInt64, UInt64); + CASE(SInt32, Int32); + CASE(SInt64, Int64); + CASE(Fixed32, UInt32); + CASE(Fixed64, UInt64); + CASE(SFixed32, Int32); + CASE(SFixed64, Int64); #undef CASE @@ -353,8 +353,8 @@ static bool to_string(zval* from) { } } -bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, TypeInfo type, - upb_arena *arena) { +bool Convert_PhpToUpb(zval *php_val, upb_MessageValue *upb_val, TypeInfo type, + upb_Arena *arena) { int64_t i64; if (Z_ISREF_P(php_val)) { @@ -362,37 +362,37 @@ bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, TypeInfo type, } switch (type.type) { - case UPB_TYPE_INT64: + case kUpb_CType_Int64: return Convert_PhpToInt64(php_val, &upb_val->int64_val); - case UPB_TYPE_INT32: - case UPB_TYPE_ENUM: + case kUpb_CType_Int32: + case kUpb_CType_Enum: if (!Convert_PhpToInt64(php_val, &i64)) { return false; } upb_val->int32_val = i64; return true; - case UPB_TYPE_UINT64: + case kUpb_CType_UInt64: if (!Convert_PhpToInt64(php_val, &i64)) { return false; } upb_val->uint64_val = i64; return true; - case UPB_TYPE_UINT32: + case kUpb_CType_UInt32: if (!Convert_PhpToInt64(php_val, &i64)) { return false; } upb_val->uint32_val = i64; return true; - case UPB_TYPE_DOUBLE: + case kUpb_CType_Double: return to_double(php_val, &upb_val->double_val); - case UPB_TYPE_FLOAT: + case kUpb_CType_Float: if (!to_double(php_val, &upb_val->double_val)) return false; upb_val->float_val = upb_val->double_val; return true; - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return to_bool(php_val, &upb_val->bool_val); - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { + case kUpb_CType_String: + case kUpb_CType_Bytes: { char *ptr; size_t size; @@ -401,30 +401,30 @@ bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, TypeInfo type, size = Z_STRLEN_P(php_val); // If arena is NULL we reference the input zval. - // The resulting upb_strview will only be value while the zval is alive. + // The resulting upb_StringView will only be value while the zval is alive. if (arena) { - ptr = upb_arena_malloc(arena, size); + ptr = upb_Arena_Malloc(arena, size); memcpy(ptr, Z_STRVAL_P(php_val), size); } else { ptr = Z_STRVAL_P(php_val); } - upb_val->str_val = upb_strview_make(ptr, size); + upb_val->str_val = upb_StringView_FromDataAndSize(ptr, size); return true; } - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: PBPHP_ASSERT(type.desc); return Message_GetUpbMessage(php_val, type.desc, arena, - (upb_msg **)&upb_val->msg_val); + (upb_Message **)&upb_val->msg_val); } return false; } -void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, TypeInfo type, +void Convert_UpbToPhp(upb_MessageValue upb_val, zval *php_val, TypeInfo type, zval *arena) { switch (type.type) { - case UPB_TYPE_INT64: + case kUpb_CType_Int64: #if SIZEOF_ZEND_LONG == 8 ZVAL_LONG(php_val, upb_val.int64_val); #else @@ -435,7 +435,7 @@ void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, TypeInfo type, } #endif break; - case UPB_TYPE_UINT64: + case kUpb_CType_UInt64: #if SIZEOF_ZEND_LONG == 8 ZVAL_LONG(php_val, upb_val.uint64_val); #else @@ -446,51 +446,70 @@ void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, TypeInfo type, } #endif break; - case UPB_TYPE_INT32: - case UPB_TYPE_ENUM: + case kUpb_CType_Int32: + case kUpb_CType_Enum: ZVAL_LONG(php_val, upb_val.int32_val); break; - case UPB_TYPE_UINT32: { + case kUpb_CType_UInt32: { // Sign-extend for consistency between 32/64-bit builds. zend_long val = (int32_t)upb_val.uint32_val; ZVAL_LONG(php_val, val); break; } - case UPB_TYPE_DOUBLE: + case kUpb_CType_Double: ZVAL_DOUBLE(php_val, upb_val.double_val); break; - case UPB_TYPE_FLOAT: + case kUpb_CType_Float: ZVAL_DOUBLE(php_val, upb_val.float_val); break; - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: ZVAL_BOOL(php_val, upb_val.bool_val); break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - upb_strview str = upb_val.str_val; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView str = upb_val.str_val; ZVAL_NEW_STR(php_val, zend_string_init(str.data, str.size, 0)); break; } - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: PBPHP_ASSERT(type.desc); - Message_GetPhpWrapper(php_val, type.desc, (upb_msg *)upb_val.msg_val, + Message_GetPhpWrapper(php_val, type.desc, (upb_Message *)upb_val.msg_val, arena); break; } } -bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val, TypeInfo type, - upb_arena *arena) { - const upb_msgdef *subm = type.desc ? type.desc->msgdef : NULL; - if (subm && upb_msgdef_iswrapper(subm) && Z_TYPE_P(val) != IS_OBJECT) { +// Check if the field is a well known wrapper type +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; + } +} + +bool Convert_PhpToUpbAutoWrap(zval *val, upb_MessageValue *upb_val, TypeInfo type, + upb_Arena *arena) { + const upb_MessageDef *subm = type.desc ? type.desc->msgdef : NULL; + if (subm && IsWrapper(subm) && Z_TYPE_P(val) != IS_OBJECT) { // Assigning a scalar to a wrapper-typed value. We will automatically wrap // the value, so the user doesn't need to create a FooWrapper(['value': X]) // message manually. - upb_msg *wrapper = upb_msg_new(subm, arena); - const upb_fielddef *val_f = upb_msgdef_itof(subm, 1); - upb_msgval msgval; + upb_Message *wrapper = upb_Message_New(subm, arena); + const upb_FieldDef *val_f = upb_MessageDef_FindFieldByNumber(subm, 1); + upb_MessageValue msgval; if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(val_f), arena)) return false; - upb_msg_set(wrapper, val_f, msgval, arena); + upb_Message_Set(wrapper, val_f, msgval, arena); upb_val->msg_val = wrapper; return true; } else { diff --git a/php/ext/google/protobuf/convert.h b/php/ext/google/protobuf/convert.h index 96cfc34fd0091..5f3cc077034fa 100644 --- a/php/ext/google/protobuf/convert.h +++ b/php/ext/google/protobuf/convert.h @@ -36,18 +36,18 @@ #include "php-upb.h" #include "def.h" -upb_fieldtype_t pbphp_dtype_to_type(upb_descriptortype_t type); +upb_CType pbphp_dtype_to_type(upb_FieldType type); // Converts |php_val| to an int64_t. Returns false if the value cannot be // converted. bool Convert_PhpToInt64(const zval *php_val, int64_t *i64); -// Converts |php_val| to a upb_msgval according to |type|. If type is -// UPB_TYPE_MESSAGE, then |desc| must be the Descriptor for this message type. +// Converts |php_val| to a upb_MessageValue according to |type|. If type is +// kUpb_CType_Message, then |desc| must be the Descriptor for this message type. // If type is string, message, or bytes, then |arena| will be used to copy // string data or fuse this arena to the given message's arena. -bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, TypeInfo type, - upb_arena *arena); +bool Convert_PhpToUpb(zval *php_val, upb_MessageValue *upb_val, TypeInfo type, + upb_Arena *arena); // Similar to Convert_PhpToUpb, but supports automatically wrapping the wrapper // types if a primitive is specified: @@ -56,15 +56,15 @@ bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, TypeInfo type, // // We currently allow this implicit conversion in initializers, but not for // assignment. -bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val, TypeInfo type, - upb_arena *arena); +bool Convert_PhpToUpbAutoWrap(zval *val, upb_MessageValue *upb_val, TypeInfo type, + upb_Arena *arena); // Converts |upb_val| to a PHP zval according to |type|. This may involve // creating a PHP wrapper object. Any newly created wrapper object // will reference |arena|. // // The caller owns a reference to the returned value. -void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, TypeInfo type, +void Convert_UpbToPhp(upb_MessageValue upb_val, zval *php_val, TypeInfo type, zval *arena); // Registers the GPBUtil class. diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 666238302b99b..9210026df2f55 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -39,13 +39,13 @@ #include "php-upb.h" #include "protobuf.h" -static void CheckUpbStatus(const upb_status* status, const char* msg) { - if (!upb_ok(status)) { - zend_error(E_ERROR, "%s: %s\n", msg, upb_status_errmsg(status)); +static void CheckUpbStatus(const upb_Status* status, const char* msg) { + if (!upb_Status_IsOk(status)) { + zend_error(E_ERROR, "%s: %s\n", msg, upb_Status_ErrorMessage(status)); } } -static void FieldDescriptor_FromFieldDef(zval *val, const upb_fielddef *f); +static void FieldDescriptor_FromFieldDef(zval *val, const upb_FieldDef *f); // We use this for objects that should not be created directly from PHP. static zend_object *CreateHandler_ReturnNull(zend_class_entry *class_type) { @@ -117,7 +117,7 @@ static zend_function_entry EnumValueDescriptor_methods[] = { typedef struct { zend_object std; - const upb_enumdef *enumdef; + const upb_EnumDef *enumdef; void *cache_key; } EnumDescriptor; @@ -141,7 +141,7 @@ static void EnumDescriptor_FromClassEntry(zval *val, zend_class_entry *ce) { } if (!ObjCache_Get(key, val)) { - const upb_enumdef *e = NameMap_GetEnum(ce); + const upb_EnumDef *e = NameMap_GetEnum(ce); if (!e) { ZVAL_NULL(val); return; @@ -157,12 +157,12 @@ static void EnumDescriptor_FromClassEntry(zval *val, zend_class_entry *ce) { } // Caller owns a ref on the returned zval. -static void EnumDescriptor_FromEnumDef(zval *val, const upb_enumdef *m) { +static void EnumDescriptor_FromEnumDef(zval *val, const upb_EnumDef *m) { if (!m) { ZVAL_NULL(val); } else { char *classname = - GetPhpClassname(upb_enumdef_file(m), upb_enumdef_fullname(m)); + GetPhpClassname(upb_EnumDef_File(m), upb_EnumDef_FullName(m)); zend_string *str = zend_string_init(classname, strlen(classname), 0); zend_class_entry *ce = zend_lookup_class(str); // May autoload the class. @@ -193,20 +193,14 @@ PHP_METHOD(EnumDescriptor, getValue) { return; } - int field_num = upb_enumdef_numvals(intern->enumdef); - if (index < 0 || index >= field_num) { + if (index < 0 || index >= upb_EnumDef_ValueCount(intern->enumdef)) { zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); return; } - upb_enum_iter iter; - int i; - for(upb_enum_begin(&iter, intern->enumdef), i = 0; - !upb_enum_done(&iter) && i < index; - upb_enum_next(&iter), i++); - - EnumValueDescriptor_Make(&ret, upb_enum_iter_name(&iter), - upb_enum_iter_number(&iter)); + const upb_EnumValueDef* ev = upb_EnumDef_Value(intern->enumdef, index); + EnumValueDescriptor_Make(&ret, upb_EnumValueDef_Name(ev), + upb_EnumValueDef_Number(ev)); RETURN_COPY_VALUE(&ret); } @@ -217,7 +211,7 @@ PHP_METHOD(EnumDescriptor, getValue) { */ PHP_METHOD(EnumDescriptor, getValueCount) { EnumDescriptor *intern = (EnumDescriptor*)Z_OBJ_P(getThis()); - RETURN_LONG(upb_enumdef_numvals(intern->enumdef)); + RETURN_LONG(upb_EnumDef_ValueCount(intern->enumdef)); } /* @@ -244,7 +238,7 @@ static zend_function_entry EnumDescriptor_methods[] = { typedef struct { zend_object std; - const upb_oneofdef *oneofdef; + const upb_OneofDef *oneofdef; } OneofDescriptor; zend_class_entry *OneofDescriptor_class_entry; @@ -255,7 +249,7 @@ static void OneofDescriptor_destructor(zend_object* obj) { ObjCache_Delete(intern->oneofdef); } -static void OneofDescriptor_FromOneofDef(zval *val, const upb_oneofdef *o) { +static void OneofDescriptor_FromOneofDef(zval *val, const upb_OneofDef *o) { if (o == NULL) { ZVAL_NULL(val); return; @@ -278,7 +272,7 @@ static void OneofDescriptor_FromOneofDef(zval *val, const upb_oneofdef *o) { */ PHP_METHOD(OneofDescriptor, getName) { OneofDescriptor *intern = (OneofDescriptor*)Z_OBJ_P(getThis()); - RETURN_STRING(upb_oneofdef_name(intern->oneofdef)); + RETURN_STRING(upb_OneofDef_Name(intern->oneofdef)); } /* @@ -297,19 +291,12 @@ PHP_METHOD(OneofDescriptor, getField) { return; } - int field_num = upb_oneofdef_numfields(intern->oneofdef); - if (index < 0 || index >= field_num) { + if (index < 0 || index >= upb_OneofDef_FieldCount(intern->oneofdef)) { zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); return; } - upb_oneof_iter iter; - int i; - for(upb_oneof_begin(&iter, intern->oneofdef), i = 0; - !upb_oneof_done(&iter) && i < index; - upb_oneof_next(&iter), i++); - const upb_fielddef *field = upb_oneof_iter_field(&iter); - + const upb_FieldDef* field = upb_OneofDef_Field(intern->oneofdef, index); FieldDescriptor_FromFieldDef(&ret, field); RETURN_COPY_VALUE(&ret); } @@ -321,7 +308,7 @@ PHP_METHOD(OneofDescriptor, getField) { */ PHP_METHOD(OneofDescriptor, getFieldCount) { OneofDescriptor *intern = (OneofDescriptor*)Z_OBJ_P(getThis()); - RETURN_LONG(upb_oneofdef_numfields(intern->oneofdef)); + RETURN_LONG(upb_OneofDef_FieldCount(intern->oneofdef)); } static zend_function_entry OneofDescriptor_methods[] = { @@ -337,7 +324,7 @@ static zend_function_entry OneofDescriptor_methods[] = { typedef struct { zend_object std; - const upb_fielddef *fielddef; + const upb_FieldDef *fielddef; } FieldDescriptor; zend_class_entry *FieldDescriptor_class_entry; @@ -349,7 +336,7 @@ static void FieldDescriptor_destructor(zend_object* obj) { } // Caller owns a ref on the returned zval. -static void FieldDescriptor_FromFieldDef(zval *val, const upb_fielddef *f) { +static void FieldDescriptor_FromFieldDef(zval *val, const upb_FieldDef *f) { if (f == NULL) { ZVAL_NULL(val); return; @@ -365,30 +352,30 @@ static void FieldDescriptor_FromFieldDef(zval *val, const upb_fielddef *f) { } } -upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { +upb_CType to_fieldtype(upb_FieldType type) { switch (type) { #define CASE(descriptor_type, type) \ - case UPB_DESCRIPTOR_TYPE_##descriptor_type: \ - return UPB_TYPE_##type; - - CASE(FLOAT, FLOAT); - CASE(DOUBLE, DOUBLE); - CASE(BOOL, BOOL); - CASE(STRING, STRING); - CASE(BYTES, BYTES); - CASE(MESSAGE, MESSAGE); - CASE(GROUP, MESSAGE); - CASE(ENUM, ENUM); - CASE(INT32, INT32); - CASE(INT64, INT64); - CASE(UINT32, UINT32); - CASE(UINT64, UINT64); - CASE(SINT32, INT32); - CASE(SINT64, INT64); - CASE(FIXED32, UINT32); - CASE(FIXED64, UINT64); - CASE(SFIXED32, INT32); - CASE(SFIXED64, INT64); + case kUpb_FieldType_##descriptor_type: \ + return kUpb_CType_##type; + + CASE(Float, Float); + CASE(Double, Double); + CASE(Bool, Bool); + CASE(String, String); + CASE(Bytes, Bytes); + CASE(Message, Message); + CASE(Group, Message); + CASE(Enum, Enum); + CASE(Int32, Int32); + CASE(Int64, Int64); + CASE(UInt32, UInt32); + CASE(UInt64, UInt64); + CASE(SInt32, Int32); + CASE(SInt64, Int64); + CASE(Fixed32, UInt32); + CASE(Fixed64, UInt64); + CASE(SFixed32, Int32); + CASE(SFixed64, Int64); #undef CONVERT @@ -405,7 +392,7 @@ upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { */ PHP_METHOD(FieldDescriptor, getName) { FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); - RETURN_STRING(upb_fielddef_name(intern->fielddef)); + RETURN_STRING(upb_FieldDef_Name(intern->fielddef)); } /* @@ -415,7 +402,7 @@ PHP_METHOD(FieldDescriptor, getName) { */ PHP_METHOD(FieldDescriptor, getNumber) { FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); - RETURN_LONG(upb_fielddef_number(intern->fielddef)); + RETURN_LONG(upb_FieldDef_Number(intern->fielddef)); } /* @@ -425,7 +412,7 @@ PHP_METHOD(FieldDescriptor, getNumber) { */ PHP_METHOD(FieldDescriptor, getLabel) { FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); - RETURN_LONG(upb_fielddef_label(intern->fielddef)); + RETURN_LONG(upb_FieldDef_Label(intern->fielddef)); } /* @@ -435,7 +422,7 @@ PHP_METHOD(FieldDescriptor, getLabel) { */ PHP_METHOD(FieldDescriptor, getType) { FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); - RETURN_LONG(upb_fielddef_descriptortype(intern->fielddef)); + RETURN_LONG(upb_FieldDef_Type(intern->fielddef)); } /* @@ -445,7 +432,7 @@ PHP_METHOD(FieldDescriptor, getType) { */ PHP_METHOD(FieldDescriptor, isMap) { FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); - RETURN_BOOL(upb_fielddef_ismap(intern->fielddef)); + RETURN_BOOL(upb_FieldDef_IsMap(intern->fielddef)); } /* @@ -455,13 +442,13 @@ PHP_METHOD(FieldDescriptor, isMap) { */ PHP_METHOD(FieldDescriptor, getEnumType) { FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); - const upb_enumdef *e = upb_fielddef_enumsubdef(intern->fielddef); + const upb_EnumDef *e = upb_FieldDef_EnumSubDef(intern->fielddef); zval ret; if (!e) { zend_throw_exception_ex(NULL, 0, "Cannot get enum type for non-enum field '%s'", - upb_fielddef_name(intern->fielddef)); + upb_FieldDef_Name(intern->fielddef)); return; } @@ -481,7 +468,7 @@ PHP_METHOD(FieldDescriptor, getMessageType) { if (!desc) { zend_throw_exception_ex( NULL, 0, "Cannot get message type for non-message field '%s'", - upb_fielddef_name(intern->fielddef)); + upb_FieldDef_Name(intern->fielddef)); return; } @@ -511,9 +498,9 @@ static void Descriptor_destructor(zend_object* obj) { // collected before the end of the request. } -static zend_class_entry *Descriptor_GetGeneratedClass(const upb_msgdef *m) { +static zend_class_entry *Descriptor_GetGeneratedClass(const upb_MessageDef *m) { char *classname = - GetPhpClassname(upb_msgdef_file(m), upb_msgdef_fullname(m)); + GetPhpClassname(upb_MessageDef_File(m), upb_MessageDef_FullName(m)); zend_string *str = zend_string_init(classname, strlen(classname), 0); zend_class_entry *ce = zend_lookup_class(str); // May autoload the class. @@ -527,7 +514,7 @@ static zend_class_entry *Descriptor_GetGeneratedClass(const upb_msgdef *m) { return ce; } -void Descriptor_FromMessageDef(zval *val, const upb_msgdef *m) { +void Descriptor_FromMessageDef(zval *val, const upb_MessageDef *m) { if (m == NULL) { ZVAL_NULL(val); return; @@ -535,7 +522,7 @@ void Descriptor_FromMessageDef(zval *val, const upb_msgdef *m) { if (!ObjCache_Get(m, val)) { zend_class_entry *ce = NULL; - if (!upb_msgdef_mapentry(m)) { // Map entries don't have a class. + if (!upb_MessageDef_IsMapEntry(m)) { // Map entries don't have a class. ce = Descriptor_GetGeneratedClass(m); if (!ce) { ZVAL_NULL(val); @@ -581,14 +568,14 @@ Descriptor* Descriptor_GetFromClassEntry(zend_class_entry *ce) { return Descriptor_GetFromZval(&desc); } -Descriptor* Descriptor_GetFromMessageDef(const upb_msgdef *m) { +Descriptor* Descriptor_GetFromMessageDef(const upb_MessageDef *m) { zval desc; Descriptor_FromMessageDef(&desc, m); return Descriptor_GetFromZval(&desc); } -Descriptor* Descriptor_GetFromFieldDef(const upb_fielddef *f) { - return Descriptor_GetFromMessageDef(upb_fielddef_msgsubdef(f)); +Descriptor* Descriptor_GetFromFieldDef(const upb_FieldDef *f) { + return Descriptor_GetFromMessageDef(upb_FieldDef_MessageSubDef(f)); } /* @@ -609,7 +596,7 @@ PHP_METHOD(Descriptor, getPublicDescriptor) { */ PHP_METHOD(Descriptor, getFullName) { Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); - RETURN_STRING(upb_msgdef_fullname(intern->msgdef)); + RETURN_STRING(upb_MessageDef_FullName(intern->msgdef)); } /* @@ -620,7 +607,7 @@ PHP_METHOD(Descriptor, getFullName) { */ PHP_METHOD(Descriptor, getField) { Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); - int count = upb_msgdef_numfields(intern->msgdef); + int count = upb_MessageDef_FieldCount(intern->msgdef); zval ret; zend_long index; @@ -634,7 +621,7 @@ PHP_METHOD(Descriptor, getField) { return; } - FieldDescriptor_FromFieldDef(&ret, upb_msgdef_field(intern->msgdef, index)); + FieldDescriptor_FromFieldDef(&ret, upb_MessageDef_Field(intern->msgdef, index)); RETURN_COPY_VALUE(&ret); } @@ -645,7 +632,7 @@ PHP_METHOD(Descriptor, getField) { */ PHP_METHOD(Descriptor, getFieldCount) { Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); - RETURN_LONG(upb_msgdef_numfields(intern->msgdef)); + RETURN_LONG(upb_MessageDef_FieldCount(intern->msgdef)); } /* @@ -664,20 +651,12 @@ PHP_METHOD(Descriptor, getOneofDecl) { return; } - int field_num = upb_msgdef_numoneofs(intern->msgdef); - if (index < 0 || index >= field_num) { + if (index < 0 || index >= upb_MessageDef_OneofCount(intern->msgdef)) { zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); return; } - upb_msg_oneof_iter iter; - int i; - for(upb_msg_oneof_begin(&iter, intern->msgdef), i = 0; - !upb_msg_oneof_done(&iter) && i < index; - upb_msg_oneof_next(&iter), i++); - const upb_oneofdef *oneof = upb_msg_iter_oneof(&iter); - - OneofDescriptor_FromOneofDef(&ret, oneof); + OneofDescriptor_FromOneofDef(&ret, upb_MessageDef_Oneof(intern->msgdef, index)); RETURN_COPY_VALUE(&ret); } @@ -688,7 +667,7 @@ PHP_METHOD(Descriptor, getOneofDecl) { */ PHP_METHOD(Descriptor, getOneofDeclCount) { Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); - RETURN_LONG(upb_msgdef_numoneofs(intern->msgdef)); + RETURN_LONG(upb_MessageDef_OneofCount(intern->msgdef)); } /* @@ -720,7 +699,7 @@ static zend_function_entry Descriptor_methods[] = { typedef struct DescriptorPool { zend_object std; - upb_symtab *symtab; + upb_DefPool *symtab; } DescriptorPool; zend_class_entry *DescriptorPool_class_entry; @@ -743,7 +722,7 @@ static void DescriptorPool_destructor(zend_object* obj) { zend_object_std_dtor(&intern->std); } -void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab) { +void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_DefPool *symtab) { DescriptorPool *intern = emalloc(sizeof(DescriptorPool)); zend_object_std_init(&intern->std, DescriptorPool_class_entry); intern->std.handlers = &DescriptorPool_object_handlers; @@ -752,7 +731,7 @@ void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab) { ZVAL_OBJ(zv, &intern->std); } -upb_symtab *DescriptorPool_GetSymbolTable() { +upb_DefPool *DescriptorPool_GetSymbolTable() { DescriptorPool *intern = GetPool(get_generated_pool()); return intern->symtab; } @@ -836,7 +815,7 @@ PHP_METHOD(DescriptorPool, getDescriptorByProtoName) { DescriptorPool *intern = GetPool(getThis()); char *protoname = NULL; zend_long protoname_len; - const upb_msgdef *m; + const upb_MessageDef *m; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &protoname, &protoname_len) == FAILURE) { @@ -845,7 +824,7 @@ PHP_METHOD(DescriptorPool, getDescriptorByProtoName) { if (*protoname == '.') protoname++; - m = upb_symtab_lookupmsg(intern->symtab, protoname); + m = upb_DefPool_FindMessageByName(intern->symtab, protoname); if (m) { RETURN_OBJ_COPY(&Descriptor_GetFromMessageDef(m)->std); @@ -860,13 +839,13 @@ PHP_METHOD(DescriptorPool, getDescriptorByProtoName) { * Returns true if this FileDescriptorProto depends on descriptor.proto. */ bool depends_on_descriptor(const google_protobuf_FileDescriptorProto* file) { - const upb_strview *deps; - upb_strview name = upb_strview_makez("google/protobuf/descriptor.proto"); + const upb_StringView *deps; + upb_StringView name = upb_StringView_FromString("google/protobuf/descriptor.proto"); size_t i, n; deps = google_protobuf_FileDescriptorProto_dependency(file, &n); for (i = 0; i < n; i++) { - if (upb_strview_eql(deps[i], name)) { + if (upb_StringView_IsEqual(deps[i], name)) { return true; } } @@ -874,37 +853,48 @@ bool depends_on_descriptor(const google_protobuf_FileDescriptorProto* file) { return false; } +static void add_message_name_mappings(const upb_MessageDef *message) { + NameMap_AddMessage(message); + int msg_n = upb_MessageDef_NestedMessageCount(message); + for (int i = 0; i < msg_n; i++) { + add_message_name_mappings(upb_MessageDef_NestedMessage(message, i)); + } + int enum_n = upb_MessageDef_NestedEnumCount(message); + for (int i = 0; i < enum_n; i++) { + NameMap_AddEnum(upb_MessageDef_NestedEnum(message, i)); + } +} + /* * add_name_mappings() * * Adds the messages and enums in this file to the NameMap. */ -static void add_name_mappings(const upb_filedef *file) { - size_t i; - for (i = 0; i < upb_filedef_msgcount(file); i++) { - NameMap_AddMessage(upb_filedef_msg(file, i)); +static void add_name_mappings(const upb_FileDef *file) { + for (int i = 0; i < upb_FileDef_TopLevelMessageCount(file); i++) { + add_message_name_mappings(upb_FileDef_TopLevelMessage(file, i)); } - for (i = 0; i < upb_filedef_enumcount(file); i++) { - NameMap_AddEnum(upb_filedef_enum(file, i)); + for (int i = 0; i < upb_FileDef_TopLevelEnumCount(file); i++) { + NameMap_AddEnum(upb_FileDef_TopLevelEnum(file, i)); } } static void add_descriptor(DescriptorPool *pool, const google_protobuf_FileDescriptorProto *file) { - upb_strview name = google_protobuf_FileDescriptorProto_name(file); - upb_status status; - const upb_filedef *file_def; - upb_status_clear(&status); + upb_StringView name = google_protobuf_FileDescriptorProto_name(file); + upb_Status status; + const upb_FileDef *file_def; + upb_Status_Clear(&status); - if (upb_symtab_lookupfile2(pool->symtab, name.data, name.size)) { + if (upb_DefPool_FindFileByNameWithSize(pool->symtab, name.data, name.size)) { // Already added. // TODO(teboring): Re-enable this warning when aggregate metadata is // deprecated. // zend_error(E_USER_WARNING, // "proto descriptor was previously loaded (included in multiple " - // "metadata bundles?): " UPB_STRVIEW_FORMAT, - // UPB_STRVIEW_ARGS(name)); + // "metadata bundles?): " UPB_STRINGVIEW_FORMAT, + // UPB_STRINGVIEW_ARGS(name)); return; } @@ -915,7 +905,7 @@ static void add_descriptor(DescriptorPool *pool, google_protobuf_FileDescriptorProto_getmsgdef(pool->symtab); } - file_def = upb_symtab_addfile(pool->symtab, file, &status); + file_def = upb_DefPool_AddFile(pool->symtab, file, &status); CheckUpbStatus(&status, "Unable to load descriptor"); add_name_mappings(file_def); } @@ -926,7 +916,7 @@ static void add_descriptor(DescriptorPool *pool, * Adds the given descriptor data to this DescriptorPool. */ static void add_descriptor_set(DescriptorPool *pool, const char *data, - int data_len, upb_arena *arena) { + int data_len, upb_Arena *arena) { size_t i, n; google_protobuf_FileDescriptorSet *set; const google_protobuf_FileDescriptorProto* const* files; @@ -948,12 +938,12 @@ static void add_descriptor_set(DescriptorPool *pool, const char *data, bool DescriptorPool_HasFile(const char *filename) { DescriptorPool *intern = GetPool(get_generated_pool()); - return upb_symtab_lookupfile(intern->symtab, filename) != NULL; + return upb_DefPool_FindFileByName(intern->symtab, filename) != NULL; } void DescriptorPool_AddDescriptor(const char *filename, const char *data, int size) { - upb_arena *arena = upb_arena_new(); + upb_Arena *arena = upb_Arena_New(); const google_protobuf_FileDescriptorProto *file = google_protobuf_FileDescriptorProto_parse(data, size, arena); @@ -963,7 +953,7 @@ void DescriptorPool_AddDescriptor(const char *filename, const char *data, } add_descriptor(GetPool(get_generated_pool()), file); - upb_arena_free(arena); + upb_Arena_Free(arena); } /* @@ -976,16 +966,16 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { char *data = NULL; zend_long data_len; zend_bool use_nested_submsg = false; - upb_arena *arena; + upb_Arena *arena; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &data, &data_len, &use_nested_submsg) != SUCCESS) { return; } - arena = upb_arena_new(); + arena = upb_Arena_New(); add_descriptor_set(intern, data, data_len, arena); - upb_arena_free(arena); + upb_Arena_Free(arena); } ZEND_BEGIN_ARG_INFO_EX(arginfo_lookupByName, 0, 0, 1) diff --git a/php/ext/google/protobuf/def.h b/php/ext/google/protobuf/def.h index ed944abb313a5..8d82797b758ae 100644 --- a/php/ext/google/protobuf/def.h +++ b/php/ext/google/protobuf/def.h @@ -40,9 +40,9 @@ void Def_ModuleInit(); // Creates a new DescriptorPool to wrap the given symtab, which must not be // NULL. -void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab); +void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_DefPool *symtab); -upb_symtab *DescriptorPool_GetSymbolTable(); +upb_DefPool *DescriptorPool_GetSymbolTable(); // Returns true if the global descriptor pool already has the given filename. bool DescriptorPool_HasFile(const char *filename); @@ -52,38 +52,38 @@ void DescriptorPool_AddDescriptor(const char *filename, const char *data, int si typedef struct Descriptor { zend_object std; - const upb_msgdef *msgdef; + const upb_MessageDef *msgdef; zend_class_entry *class_entry; } Descriptor; -// Gets or creates a Descriptor* for the given class entry, upb_msgdef, or -// upb_fielddef. The returned Descriptor* will live for the entire request, +// Gets or creates a Descriptor* for the given class entry, upb_MessageDef, or +// upb_FieldDef. The returned Descriptor* will live for the entire request, // so no ref is necessary to keep it alive. The caller does *not* own a ref // on the returned object. Descriptor* Descriptor_GetFromClassEntry(zend_class_entry *ce); -Descriptor* Descriptor_GetFromMessageDef(const upb_msgdef *m); -Descriptor* Descriptor_GetFromFieldDef(const upb_fielddef *f); +Descriptor* Descriptor_GetFromMessageDef(const upb_MessageDef *m); +Descriptor* Descriptor_GetFromFieldDef(const upb_FieldDef *f); -// Packages up a upb_fieldtype_t with a Descriptor, since many functions need +// Packages up a upb_CType with a Descriptor, since many functions need // both. typedef struct { - upb_fieldtype_t type; - const Descriptor *desc; // When type == UPB_TYPE_MESSAGE. + upb_CType type; + const Descriptor *desc; // When type == kUpb_CType_Message. } TypeInfo; -static inline TypeInfo TypeInfo_Get(const upb_fielddef *f) { - TypeInfo ret = {upb_fielddef_type(f), Descriptor_GetFromFieldDef(f)}; +static inline TypeInfo TypeInfo_Get(const upb_FieldDef *f) { + TypeInfo ret = {upb_FieldDef_CType(f), Descriptor_GetFromFieldDef(f)}; return ret; } -static inline TypeInfo TypeInfo_FromType(upb_fieldtype_t type) { +static inline TypeInfo TypeInfo_FromType(upb_CType type) { TypeInfo ret = {type}; return ret; } static inline bool TypeInfo_Eq(TypeInfo a, TypeInfo b) { if (a.type != b.type) return false; - if (a.type == UPB_TYPE_MESSAGE && a.desc != b.desc) return false; + if (a.type == kUpb_CType_Message && a.desc != b.desc) return false; return true; } diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index bbdfe29c5d703..fce88b277cfa7 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -50,7 +50,7 @@ static void MapFieldIter_make(zval *val, zval *map_field); typedef struct { zend_object std; zval arena; - upb_map *map; + upb_Map *map; MapField_Type type; } MapField; @@ -66,13 +66,13 @@ static TypeInfo KeyType(MapField_Type type) { return ret; } -MapField_Type MapType_Get(const upb_fielddef *f) { - const upb_msgdef *ent = upb_fielddef_msgsubdef(f); - const upb_fielddef *key_f = upb_msgdef_itof(ent, 1); - const upb_fielddef *val_f = upb_msgdef_itof(ent, 2); +MapField_Type MapType_Get(const upb_FieldDef *f) { + const upb_MessageDef *ent = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef *key_f = upb_MessageDef_FindFieldByNumber(ent, 1); + const upb_FieldDef *val_f = upb_MessageDef_FindFieldByNumber(ent, 2); MapField_Type type = { - upb_fielddef_type(key_f), - {upb_fielddef_type(val_f), Descriptor_GetFromFieldDef(val_f)}}; + upb_FieldDef_CType(key_f), + {upb_FieldDef_CType(val_f), Descriptor_GetFromFieldDef(val_f)}}; return type; } @@ -135,15 +135,15 @@ static int MapField_compare_objects(zval *map1, zval *map2) { */ static zend_object *MapField_clone_obj(PROTO_VAL *object) { MapField* intern = PROTO_VAL_P(object); - upb_arena *arena = Arena_Get(&intern->arena); - upb_map *clone = - upb_map_new(arena, intern->type.key_type, intern->type.val_type.type); - size_t iter = UPB_MAP_BEGIN; - - while (upb_mapiter_next(intern->map, &iter)) { - upb_msgval key = upb_mapiter_key(intern->map, iter); - upb_msgval val = upb_mapiter_value(intern->map, iter); - upb_map_set(clone, key, val, arena); + upb_Arena *arena = Arena_Get(&intern->arena); + upb_Map *clone = + upb_Map_New(arena, intern->type.key_type, intern->type.val_type.type); + size_t iter = kUpb_Map_Begin; + + while (upb_MapIterator_Next(intern->map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(intern->map, iter); + upb_MessageValue val = upb_MapIterator_Value(intern->map, iter); + upb_Map_Set(clone, key, val, arena); } zval ret; @@ -164,7 +164,7 @@ static HashTable *Map_GetProperties(PROTO_VAL *object) { // These are documented in the header file. -void MapField_GetPhpWrapper(zval *val, upb_map *map, MapField_Type type, +void MapField_GetPhpWrapper(zval *val, upb_Map *map, MapField_Type type, zval *arena) { if (!map) { ZVAL_NULL(val); @@ -184,13 +184,13 @@ void MapField_GetPhpWrapper(zval *val, upb_map *map, MapField_Type type, } } -upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena) { +upb_Map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_Arena *arena) { if (Z_ISREF_P(val)) { ZVAL_DEREF(val); } if (Z_TYPE_P(val) == IS_ARRAY) { - upb_map *map = upb_map_new(arena, type.key_type, type.val_type.type); + upb_Map *map = upb_Map_New(arena, type.key_type, type.val_type.type); HashTable *table = HASH_OF(val); HashPosition pos; @@ -199,8 +199,8 @@ upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena) { while (true) { zval php_key; zval *php_val; - upb_msgval upb_key; - upb_msgval upb_val; + upb_MessageValue upb_key; + upb_MessageValue upb_val; zend_hash_get_current_key_zval_ex(table, &php_key, &pos); php_val = zend_hash_get_current_data_ex(table, &pos); @@ -212,7 +212,7 @@ upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena) { return NULL; } - upb_map_set(map, upb_key, upb_val, arena); + upb_Map_Set(map, upb_key, upb_val, arena); zend_hash_move_forward_ex(table, &pos); zval_dtor(&php_key); } @@ -225,7 +225,7 @@ upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena) { return NULL; } - upb_arena_fuse(arena, Arena_Get(&intern->arena)); + upb_Arena_Fuse(arena, Arena_Get(&intern->arena)); return intern->map; } else { php_error_docref(NULL, E_USER_ERROR, "Must be a map"); @@ -233,19 +233,19 @@ upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena) { } } -bool MapEq(const upb_map *m1, const upb_map *m2, MapField_Type type) { - size_t iter = UPB_MAP_BEGIN; +bool MapEq(const upb_Map *m1, const upb_Map *m2, MapField_Type type) { + size_t iter = kUpb_Map_Begin; if ((m1 == NULL) != (m2 == NULL)) return false; if (m1 == NULL) return true; - if (upb_map_size(m1) != upb_map_size(m2)) return false; + if (upb_Map_Size(m1) != upb_Map_Size(m2)) return false; - while (upb_mapiter_next(m1, &iter)) { - upb_msgval key = upb_mapiter_key(m1, iter); - upb_msgval val1 = upb_mapiter_value(m1, iter); - upb_msgval val2; + while (upb_MapIterator_Next(m1, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(m1, iter); + upb_MessageValue val1 = upb_MapIterator_Value(m1, iter); + upb_MessageValue val2; - if (!upb_map_get(m2, key, &val2)) return false; + if (!upb_Map_Get(m2, key, &val2)) return false; if (!ValueEq(val1, val2, type.val_type)) return false; } @@ -265,7 +265,7 @@ bool MapEq(const upb_map *m1, const upb_map *m2, MapField_Type type) { */ PHP_METHOD(MapField, __construct) { MapField *intern = (MapField*)Z_OBJ_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); + upb_Arena *arena = Arena_Get(&intern->arena); zend_long key_type, val_type; zend_class_entry* klass = NULL; @@ -280,32 +280,32 @@ PHP_METHOD(MapField, __construct) { // Check that the key type is an allowed type. switch (intern->type.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: zend_error(E_USER_ERROR, "Invalid key type for map."); } - if (intern->type.val_type.type == UPB_TYPE_MESSAGE && klass == NULL) { + if (intern->type.val_type.type == kUpb_CType_Message && klass == NULL) { php_error_docref(NULL, E_USER_ERROR, "Message/enum type must have concrete class."); return; } intern->map = - upb_map_new(arena, intern->type.key_type, intern->type.val_type.type); + upb_Map_New(arena, intern->type.key_type, intern->type.val_type.type); ObjCache_Add(intern->map, &intern->std); } /** - * MapField::offsetExists() + * MapField::offsetExists(): bool * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -318,18 +318,18 @@ PHP_METHOD(MapField, __construct) { PHP_METHOD(MapField, offsetExists) { MapField *intern = (MapField*)Z_OBJ_P(getThis()); zval *key; - upb_msgval upb_key; + upb_MessageValue upb_key; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS || !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) { return; } - RETURN_BOOL(upb_map_get(intern->map, upb_key, NULL)); + RETURN_BOOL(upb_Map_Get(intern->map, upb_key, NULL)); } /** - * MapField::offsetGet() + * MapField::offsetGet(): mixed * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -344,14 +344,14 @@ PHP_METHOD(MapField, offsetGet) { MapField *intern = (MapField*)Z_OBJ_P(getThis()); zval *key; zval ret; - upb_msgval upb_key, upb_val; + upb_MessageValue upb_key, upb_val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS || !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) { return; } - if (!upb_map_get(intern->map, upb_key, &upb_val)) { + if (!upb_Map_Get(intern->map, upb_key, &upb_val)) { zend_error(E_USER_ERROR, "Given key doesn't exist."); return; } @@ -361,7 +361,7 @@ PHP_METHOD(MapField, offsetGet) { } /** - * MapField::offsetSet() + * MapField::offsetSet(): void * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -375,9 +375,9 @@ PHP_METHOD(MapField, offsetGet) { */ PHP_METHOD(MapField, offsetSet) { MapField *intern = (MapField*)Z_OBJ_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); + upb_Arena *arena = Arena_Get(&intern->arena); zval *key, *val; - upb_msgval upb_key, upb_val; + upb_MessageValue upb_key, upb_val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &key, &val) != SUCCESS || !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL) || @@ -385,11 +385,11 @@ PHP_METHOD(MapField, offsetSet) { return; } - upb_map_set(intern->map, upb_key, upb_val, arena); + upb_Map_Set(intern->map, upb_key, upb_val, arena); } /** - * MapField::offsetUnset() + * MapField::offsetUnset(): void * * Implements the ArrayAccess interface. Invoked when PHP code calls: * @@ -402,18 +402,18 @@ PHP_METHOD(MapField, offsetSet) { PHP_METHOD(MapField, offsetUnset) { MapField *intern = (MapField*)Z_OBJ_P(getThis()); zval *key; - upb_msgval upb_key; + upb_MessageValue upb_key; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS || !Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) { return; } - upb_map_delete(intern->map, upb_key); + upb_Map_Delete(intern->map, upb_key); } /** - * MapField::count() + * MapField::count(): int * * Implements the Countable interface. Invoked when PHP code calls: * @@ -429,11 +429,11 @@ PHP_METHOD(MapField, count) { return; } - RETURN_LONG(upb_map_size(intern->map)); + RETURN_LONG(upb_Map_Size(intern->map)); } /** - * MapField::getIterator() + * MapField::getIterator(): Traversable * * Implements the IteratorAggregate interface. Invoked when PHP code calls: * @@ -453,23 +453,38 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2) ZEND_ARG_INFO(0, value_class) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) + +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_offsetGet, 0, 0, IS_MIXED, 1) ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetSet, 0, 2, IS_VOID, 0) ZEND_ARG_INFO(0, index) ZEND_ARG_INFO(0, newval) ZEND_END_ARG_INFO() +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetUnset, 0, 0, IS_VOID, 0) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_offsetExists, 0, 0, _IS_BOOL, 0) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_getIterator, 0, 0, Traversable, 0) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_count, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + static zend_function_entry MapField_methods[] = { - PHP_ME(MapField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, count, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapField, getIterator, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(MapField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetExists, arginfo_offsetExists, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetUnset, arginfo_offsetUnset, ZEND_ACC_PUBLIC) + PHP_ME(MapField, count, arginfo_count, ZEND_ACC_PUBLIC) + PHP_ME(MapField, getIterator, arginfo_getIterator, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -547,26 +562,26 @@ static void MapFieldIter_make(zval *val, zval *map_field) { */ /** - * MapFieldIter::rewind() + * MapFieldIter::rewind(): void * * Implements the Iterator interface. Sets the iterator to the first element. */ PHP_METHOD(MapFieldIter, rewind) { MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); MapField *map_field = (MapField*)Z_OBJ_P(&intern->map_field); - intern->position = UPB_MAP_BEGIN; - upb_mapiter_next(map_field->map, &intern->position); + intern->position = kUpb_Map_Begin; + upb_MapIterator_Next(map_field->map, &intern->position); } /** - * MapFieldIter::current() + * MapFieldIter::current(): mixed * * Implements the Iterator interface. Returns the current value. */ PHP_METHOD(MapFieldIter, current) { MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); - upb_msgval upb_val = upb_mapiter_value(field->map, intern->position); + upb_MessageValue upb_val = upb_MapIterator_Value(field->map, intern->position); zval ret; Convert_UpbToPhp(upb_val, &ret, field->type.val_type, &field->arena); RETURN_COPY_VALUE(&ret); @@ -580,41 +595,56 @@ PHP_METHOD(MapFieldIter, current) { PHP_METHOD(MapFieldIter, key) { MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); - upb_msgval upb_key = upb_mapiter_key(field->map, intern->position); + upb_MessageValue upb_key = upb_MapIterator_Key(field->map, intern->position); zval ret; Convert_UpbToPhp(upb_key, &ret, KeyType(field->type), NULL); RETURN_COPY_VALUE(&ret); } /** - * MapFieldIter::next() + * MapFieldIter::next(): void * * Implements the Iterator interface. Advances to the next element. */ PHP_METHOD(MapFieldIter, next) { MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); - upb_mapiter_next(field->map, &intern->position); + upb_MapIterator_Next(field->map, &intern->position); } /** - * MapFieldIter::valid() + * MapFieldIter::valid(): bool * * Implements the Iterator interface. Returns true if this is a valid element. */ PHP_METHOD(MapFieldIter, valid) { MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); - bool done = upb_mapiter_done(field->map, intern->position); + bool done = upb_MapIterator_Done(field->map, intern->position); RETURN_BOOL(!done); } +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rewind, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_current, 0, 0, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_key, 0, 0, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_next, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + +PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_valid, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + static zend_function_entry map_field_iter_methods[] = { - PHP_ME(MapFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, rewind, arginfo_rewind, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, current, arginfo_current, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, key, arginfo_key, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, next, arginfo_next, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, valid, arginfo_valid, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/php/ext/google/protobuf/map.h b/php/ext/google/protobuf/map.h index c523cd0da937b..d104ec96fb6d2 100644 --- a/php/ext/google/protobuf/map.h +++ b/php/ext/google/protobuf/map.h @@ -39,32 +39,32 @@ void Map_ModuleInit(); typedef struct { - upb_fieldtype_t key_type; + upb_CType key_type; TypeInfo val_type; } MapField_Type; -MapField_Type MapType_Get(const upb_fielddef *f); +MapField_Type MapType_Get(const upb_FieldDef *f); -// Gets a upb_map* for the PHP object |val|: +// Gets a upb_Map* for the PHP object |val|: // * If |val| is a RepeatedField object, we first check its type and verify // that that the elements have the correct type for |f|. If so, we return the -// wrapped upb_map*. We also make sure that this map's arena is fused to -// |arena|, so the returned upb_map is guaranteed to live as long as +// wrapped upb_Map*. We also make sure that this map's arena is fused to +// |arena|, so the returned upb_Map is guaranteed to live as long as // |arena|. -// * If |val| is a PHP Map, we attempt to create a new upb_map using +// * If |val| is a PHP Map, we attempt to create a new upb_Map using // |arena| and add all of the PHP elements to it. // // If an error occurs, we raise a PHP error and return NULL. -upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena); +upb_Map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_Arena *arena); -// Creates a PHP MapField object for the given upb_map* and |f| and returns it +// Creates a PHP MapField object for the given upb_Map* and |f| and returns it // in |val|. The PHP object will keep a reference to this |arena| to ensure the // underlying array data stays alive. // // If |map| is NULL, this will return a PHP null object. -void MapField_GetPhpWrapper(zval *val, upb_map *arr, MapField_Type type, +void MapField_GetPhpWrapper(zval *val, upb_Map *arr, MapField_Type type, zval *arena); -bool MapEq(const upb_map *m1, const upb_map *m2, MapField_Type type); +bool MapEq(const upb_Map *m1, const upb_Map *m2, MapField_Type type); #endif // PHP_PROTOBUF_MAP_H_ diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 923890b0d01be..27199640c9ca2 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -54,7 +54,7 @@ typedef struct { zend_object std; zval arena; const Descriptor* desc; - upb_msg *msg; + upb_Message *msg; } Message; zend_class_entry *message_ce; @@ -110,10 +110,10 @@ static void Message_dtor(zend_object* obj) { * * Helper function to look up a field given a member name (as a string). */ -static const upb_fielddef *get_field(Message *msg, PROTO_STR *member) { - const upb_msgdef *m = msg->desc->msgdef; - const upb_fielddef *f = - upb_msgdef_ntof(m, PROTO_STRVAL_P(member), PROTO_STRLEN_P(member)); +static const upb_FieldDef *get_field(Message *msg, PROTO_STR *member) { + const upb_MessageDef *m = msg->desc->msgdef; + const upb_FieldDef *f = + upb_MessageDef_FindFieldByNameWithSize(m, PROTO_STRVAL_P(member), PROTO_STRLEN_P(member)); if (!f) { zend_throw_exception_ex(NULL, 0, "No such property %s.", @@ -123,72 +123,91 @@ static const upb_fielddef *get_field(Message *msg, PROTO_STR *member) { return f; } -static void Message_get(Message *intern, const upb_fielddef *f, zval *rv) { - upb_arena *arena = Arena_Get(&intern->arena); +// Check if the field is a well known wrapper type +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 void Message_get(Message *intern, const upb_FieldDef *f, zval *rv) { + upb_Arena *arena = Arena_Get(&intern->arena); - if (upb_fielddef_ismap(f)) { - upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); + if (upb_FieldDef_IsMap(f)) { + upb_MutableMessageValue msgval = upb_Message_Mutable(intern->msg, f, arena); MapField_GetPhpWrapper(rv, msgval.map, MapType_Get(f), &intern->arena); - } else if (upb_fielddef_isseq(f)) { - upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); + } else if (upb_FieldDef_IsRepeated(f)) { + upb_MutableMessageValue msgval = upb_Message_Mutable(intern->msg, f, arena); RepeatedField_GetPhpWrapper(rv, msgval.array, TypeInfo_Get(f), &intern->arena); } else { - if (upb_fielddef_issubmsg(f) && !upb_msg_has(intern->msg, f)) { + if (upb_FieldDef_IsSubMessage(f) && !upb_Message_Has(intern->msg, f)) { ZVAL_NULL(rv); return; } - upb_msgval msgval = upb_msg_get(intern->msg, f); + upb_MessageValue msgval = upb_Message_Get(intern->msg, f); Convert_UpbToPhp(msgval, rv, TypeInfo_Get(f), &intern->arena); } } -static bool Message_set(Message *intern, const upb_fielddef *f, zval *val) { - upb_arena *arena = Arena_Get(&intern->arena); - upb_msgval msgval; +static bool Message_set(Message *intern, const upb_FieldDef *f, zval *val) { + upb_Arena *arena = Arena_Get(&intern->arena); + upb_MessageValue msgval; - if (upb_fielddef_ismap(f)) { + if (upb_FieldDef_IsMap(f)) { msgval.map_val = MapField_GetUpbMap(val, MapType_Get(f), arena); if (!msgval.map_val) return false; - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(f)) { msgval.array_val = RepeatedField_GetUpbArray(val, TypeInfo_Get(f), arena); if (!msgval.array_val) return false; - } else if (upb_fielddef_issubmsg(f) && Z_TYPE_P(val) == IS_NULL) { - upb_msg_clearfield(intern->msg, f); + } else if (upb_FieldDef_IsSubMessage(f) && Z_TYPE_P(val) == IS_NULL) { + upb_Message_ClearField(intern->msg, f); return true; } else { if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(f), arena)) return false; } - upb_msg_set(intern->msg, f, msgval, arena); + upb_Message_Set(intern->msg, f, msgval, arena); return true; } -static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m); +static bool MessageEq(const upb_Message *m1, const upb_Message *m2, const upb_MessageDef *m); /** * ValueEq() */ -bool ValueEq(upb_msgval val1, upb_msgval val2, TypeInfo type) { +bool ValueEq(upb_MessageValue val1, upb_MessageValue val2, TypeInfo type) { switch (type.type) { - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return val1.bool_val == val2.bool_val; - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_ENUM: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: return val1.int32_val == val2.int32_val; - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: return val1.int64_val == val2.int64_val; - case UPB_TYPE_FLOAT: + case kUpb_CType_Float: return val1.float_val == val2.float_val; - case UPB_TYPE_DOUBLE: + case kUpb_CType_Double: return val1.double_val == val2.double_val; - 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: + case kUpb_CType_Message: return MessageEq(val1.msg_val, val2.msg_val, type.desc->msgdef); default: return false; @@ -198,27 +217,25 @@ bool ValueEq(upb_msgval val1, upb_msgval val2, TypeInfo type) { /** * MessageEq() */ -static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) { - upb_msg_field_iter i; +static bool MessageEq(const upb_Message *m1, const upb_Message *m2, const upb_MessageDef *m) { + int n = upb_MessageDef_FieldCount(m); - for(upb_msg_field_begin(&i, m); - !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - const upb_fielddef *f = upb_msg_iter_field(&i); + for(int i = 0; i < n; i++) { + const upb_FieldDef *f = upb_MessageDef_Field(m, i); - if (upb_fielddef_haspresence(f)) { - if (upb_msg_has(m1, f) != upb_msg_has(m2, f)) { + if (upb_FieldDef_HasPresence(f)) { + if (upb_Message_Has(m1, f) != upb_Message_Has(m2, f)) { return false; } - if (!upb_msg_has(m1, f)) continue; + if (!upb_Message_Has(m1, f)) continue; } - upb_msgval val1 = upb_msg_get(m1, f); - upb_msgval val2 = upb_msg_get(m2, f); + upb_MessageValue val1 = upb_Message_Get(m1, f); + upb_MessageValue val2 = upb_Message_Get(m2, f); - if (upb_fielddef_ismap(f)) { + if (upb_FieldDef_IsMap(f)) { if (!MapEq(val1.map_val, val2.map_val, MapType_Get(f))) return false; - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(f)) { if (!ArrayEq(val1.array_val, val2.array_val, TypeInfo_Get(f))) return false; } else { if (!ValueEq(val1, val2, TypeInfo_Get(f))) return false; @@ -239,7 +256,7 @@ static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) static int Message_compare_objects(zval *m1, zval *m2) { Message* intern1 = (Message*)Z_OBJ_P(m1); Message* intern2 = (Message*)Z_OBJ_P(m2); - const upb_msgdef *m = intern1->desc->msgdef; + const upb_MessageDef *m = intern1->desc->msgdef; if (intern2->desc->msgdef != m) return 1; @@ -268,19 +285,19 @@ static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member, int has_set_exists, void **cache_slot) { Message* intern = PROTO_VAL_P(obj); - const upb_fielddef *f = get_field(intern, member); + const upb_FieldDef *f = get_field(intern, member); if (!f) return 0; - if (!upb_fielddef_haspresence(f)) { + if (!upb_FieldDef_HasPresence(f)) { zend_throw_exception_ex( NULL, 0, "Cannot call isset() on field %s which does not have presence.", - upb_fielddef_name(f)); + upb_FieldDef_Name(f)); return 0; } - return upb_msg_has(intern->msg, f); + return upb_Message_Has(intern->msg, f); } /** @@ -302,19 +319,19 @@ static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member, static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member, void **cache_slot) { Message* intern = PROTO_VAL_P(obj); - const upb_fielddef *f = get_field(intern, member); + const upb_FieldDef *f = get_field(intern, member); if (!f) return; - if (!upb_fielddef_haspresence(f)) { + if (!upb_FieldDef_HasPresence(f)) { zend_throw_exception_ex( NULL, 0, "Cannot call unset() on field %s which does not have presence.", - upb_fielddef_name(f)); + upb_FieldDef_Name(f)); return; } - upb_msg_clearfield(intern->msg, f); + upb_Message_ClearField(intern->msg, f); } @@ -339,7 +356,7 @@ static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member, static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member, int type, void **cache_slot, zval *rv) { Message* intern = PROTO_VAL_P(obj); - const upb_fielddef *f = get_field(intern, member); + const upb_FieldDef *f = get_field(intern, member); if (!f) return &EG(uninitialized_zval); Message_get(intern, f, rv); @@ -370,7 +387,7 @@ static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member, static PROTO_RETURN_VAL Message_write_property( PROTO_VAL *obj, PROTO_STR *member, zval *val, void **cache_slot) { Message* intern = PROTO_VAL_P(obj); - const upb_fielddef *f = get_field(intern, member); + const upb_FieldDef *f = get_field(intern, member); if (f && Message_set(intern, f, val)) { #if PHP_VERSION_ID < 70400 @@ -409,11 +426,11 @@ static zval *Message_get_property_ptr_ptr(PROTO_VAL *object, PROTO_STR *member, */ static zend_object *Message_clone_obj(PROTO_VAL *object) { Message* intern = PROTO_VAL_P(object); - upb_msg *clone = upb_msg_new(intern->desc->msgdef, Arena_Get(&intern->arena)); + upb_Message *clone = upb_Message_New(intern->desc->msgdef, Arena_Get(&intern->arena)); // TODO: copy unknown fields? // TODO: use official upb msg copy function - memcpy(clone, intern->msg, upb_msgdef_layout(intern->desc->msgdef)->size); + memcpy(clone, intern->msg, upb_MessageDef_MiniTable(intern->desc->msgdef)->size); zval ret; Message_GetPhpWrapper(&ret, intern->desc, clone, &intern->arena); return Z_OBJ_P(&ret); @@ -433,7 +450,7 @@ static HashTable *Message_get_properties(PROTO_VAL *object) { // These are documented in the header file. -void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg, +void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_Message *msg, zval *arena) { if (!msg) { ZVAL_NULL(val); @@ -453,8 +470,8 @@ void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg, } } -bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena, - upb_msg **msg) { +bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_Arena *arena, + upb_Message **msg) { PBPHP_ASSERT(desc); if (Z_ISREF_P(val)) { @@ -464,7 +481,7 @@ bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena, if (Z_TYPE_P(val) == IS_OBJECT && instanceof_function(Z_OBJCE_P(val), desc->class_entry)) { Message *intern = (Message*)Z_OBJ_P(val); - upb_arena_fuse(arena, Arena_Get(&intern->arena)); + upb_Arena_Fuse(arena, Arena_Get(&intern->arena)); *msg = intern->msg; return true; } else { @@ -501,8 +518,8 @@ bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena, * * The initializer must be an array. */ -bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, - upb_arena *arena) { +bool Message_InitFromPhp(upb_Message *msg, const upb_MessageDef *m, zval *init, + upb_Arena *arena) { HashTable* table = HASH_OF(init); HashPosition pos; @@ -513,7 +530,7 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, if (Z_TYPE_P(init) != IS_ARRAY) { zend_throw_exception_ex(NULL, 0, "Initializer for a message %s must be an array.", - upb_msgdef_fullname(m)); + upb_MessageDef_FullName(m)); return false; } @@ -522,8 +539,8 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, while (true) { // Iterate over key/value pairs. zval key; zval *val; - const upb_fielddef *f; - upb_msgval msgval; + const upb_FieldDef *f; + upb_MessageValue msgval; zend_hash_get_current_key_zval_ex(table, &key, &pos); val = zend_hash_get_current_data_ex(table, &pos); @@ -534,7 +551,7 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, ZVAL_DEREF(val); } - f = upb_msgdef_ntof(m, Z_STRVAL_P(&key), Z_STRLEN_P(&key)); + f = upb_MessageDef_FindFieldByNameWithSize(m, Z_STRVAL_P(&key), Z_STRLEN_P(&key)); if (!f) { zend_throw_exception_ex(NULL, 0, @@ -542,10 +559,10 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, return false; } - if (upb_fielddef_ismap(f)) { + if (upb_FieldDef_IsMap(f)) { msgval.map_val = MapField_GetUpbMap(val, MapType_Get(f), arena); if (!msgval.map_val) return false; - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(f)) { msgval.array_val = RepeatedField_GetUpbArray(val, TypeInfo_Get(f), arena); if (!msgval.array_val) return false; } else { @@ -554,7 +571,7 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, } } - upb_msg_set(msg, f, msgval, arena); + upb_Message_Set(msg, f, msgval, arena); zend_hash_move_forward_ex(table, &pos); zval_dtor(&key); } @@ -562,7 +579,7 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, static void Message_Initialize(Message *intern, const Descriptor *desc) { intern->desc = desc; - intern->msg = upb_msg_new(desc->msgdef, Arena_Get(&intern->arena)); + intern->msg = upb_Message_New(desc->msgdef, Arena_Get(&intern->arena)); ObjCache_Add(intern->msg, &intern->std); } @@ -576,7 +593,7 @@ PHP_METHOD(Message, __construct) { Message* intern = (Message*)Z_OBJ_P(getThis()); const Descriptor* desc; zend_class_entry *ce = Z_OBJCE_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); + upb_Arena *arena = Arena_Get(&intern->arena); zval *init_arr = NULL; // This descriptor should always be available, as the generated __construct @@ -617,7 +634,7 @@ PHP_METHOD(Message, __construct) { */ PHP_METHOD(Message, discardUnknownFields) { Message* intern = (Message*)Z_OBJ_P(getThis()); - upb_msg_discardunknown(intern->msg, intern->desc->msgdef, 64); + upb_Message_DiscardUnknown(intern->msg, intern->desc->msgdef, 64); } /** @@ -627,7 +644,7 @@ PHP_METHOD(Message, discardUnknownFields) { */ PHP_METHOD(Message, clear) { Message* intern = (Message*)Z_OBJ_P(getThis()); - upb_msg_clear(intern->msg, intern->desc->msgdef); + upb_Message_Clear(intern->msg, intern->desc->msgdef); } /** @@ -639,8 +656,8 @@ PHP_METHOD(Message, clear) { PHP_METHOD(Message, mergeFrom) { Message* intern = (Message*)Z_OBJ_P(getThis()); Message* from; - upb_arena *arena = Arena_Get(&intern->arena); - const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef); + upb_Arena *arena = Arena_Get(&intern->arena); + const upb_MiniTable *l = upb_MessageDef_MiniTable(intern->desc->msgdef); zval* value; char *pb; size_t size; @@ -659,14 +676,15 @@ PHP_METHOD(Message, mergeFrom) { // TODO(haberman): use a temp arena for this once we can make upb_decode() // copy strings. - pb = upb_encode(from->msg, l, arena, &size); + pb = upb_Encode(from->msg, l, 0, arena, &size); if (!pb) { zend_throw_exception_ex(NULL, 0, "Max nesting exceeded"); return; } - ok = upb_decode(pb, size, intern->msg, l, arena); + ok = upb_Decode(pb, size, intern->msg, l, NULL, 0, arena) == + kUpb_DecodeStatus_Ok; PBPHP_ASSERT(ok); } @@ -681,8 +699,8 @@ PHP_METHOD(Message, mergeFromString) { char *data = NULL; char *data_copy = NULL; zend_long data_len; - const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef); - upb_arena *arena = Arena_Get(&intern->arena); + const upb_MiniTable *l = upb_MessageDef_MiniTable(intern->desc->msgdef); + upb_Arena *arena = Arena_Get(&intern->arena); if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data, &data_len) == FAILURE) { @@ -690,10 +708,11 @@ PHP_METHOD(Message, mergeFromString) { } // TODO(haberman): avoid this copy when we can make the decoder copy. - data_copy = upb_arena_malloc(arena, data_len); + data_copy = upb_Arena_Malloc(arena, data_len); memcpy(data_copy, data, data_len); - if (!upb_decode(data_copy, data_len, intern->msg, l, arena)) { + if (upb_Decode(data_copy, data_len, intern->msg, l, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { zend_throw_exception_ex(NULL, 0, "Error occurred during parsing"); return; } @@ -707,21 +726,21 @@ PHP_METHOD(Message, mergeFromString) { */ PHP_METHOD(Message, serializeToString) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef); - upb_arena *tmp_arena = upb_arena_new(); + const upb_MiniTable *l = upb_MessageDef_MiniTable(intern->desc->msgdef); + upb_Arena *tmp_arena = upb_Arena_New(); char *data; size_t size; - data = upb_encode(intern->msg, l, tmp_arena, &size); + data = upb_Encode(intern->msg, l, 0, tmp_arena, &size); if (!data) { zend_throw_exception_ex(NULL, 0, "Error occurred during serialization"); - upb_arena_free(tmp_arena); + upb_Arena_Free(tmp_arena); return; } RETVAL_STRINGL(data, size); - upb_arena_free(tmp_arena); + upb_Arena_Free(tmp_arena); } /** @@ -735,8 +754,8 @@ PHP_METHOD(Message, mergeFromJsonString) { char *data = NULL; char *data_copy = NULL; zend_long data_len; - upb_arena *arena = Arena_Get(&intern->arena); - upb_status status; + upb_Arena *arena = Arena_Get(&intern->arena); + upb_Status status; zend_bool ignore_json_unknown = false; int options = 0; @@ -746,20 +765,20 @@ PHP_METHOD(Message, mergeFromJsonString) { } // TODO(haberman): avoid this copy when we can make the decoder copy. - data_copy = upb_arena_malloc(arena, data_len + 1); + data_copy = upb_Arena_Malloc(arena, data_len + 1); memcpy(data_copy, data, data_len); data_copy[data_len] = '\0'; if (ignore_json_unknown) { - options |= UPB_JSONDEC_IGNOREUNKNOWN; + options |= upb_JsonDecode_IgnoreUnknown; } - upb_status_clear(&status); - if (!upb_json_decode(data_copy, data_len, intern->msg, intern->desc->msgdef, + upb_Status_Clear(&status); + if (!upb_JsonDecode(data_copy, data_len, intern->msg, intern->desc->msgdef, DescriptorPool_GetSymbolTable(), options, arena, &status)) { zend_throw_exception_ex(NULL, 0, "Error occurred during parsing: %s", - upb_status_errmsg(&status)); + upb_Status_ErrorMessage(&status)); return; } } @@ -776,7 +795,7 @@ PHP_METHOD(Message, serializeToJsonString) { int options = 0; char buf[1024]; zend_bool preserve_proto_fieldnames = false; - upb_status status; + upb_Status status; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &preserve_proto_fieldnames) == FAILURE) { @@ -784,24 +803,24 @@ PHP_METHOD(Message, serializeToJsonString) { } if (preserve_proto_fieldnames) { - options |= UPB_JSONENC_PROTONAMES; + options |= upb_JsonEncode_UseProtoNames; } - upb_status_clear(&status); - size = upb_json_encode(intern->msg, intern->desc->msgdef, + upb_Status_Clear(&status); + size = upb_JsonEncode(intern->msg, intern->desc->msgdef, DescriptorPool_GetSymbolTable(), options, buf, sizeof(buf), &status); - if (!upb_ok(&status)) { + if (!upb_Status_IsOk(&status)) { zend_throw_exception_ex(NULL, 0, "Error occurred during JSON serialization: %s", - upb_status_errmsg(&status)); + upb_Status_ErrorMessage(&status)); return; } if (size >= sizeof(buf)) { char *buf2 = malloc(size + 1); - upb_json_encode(intern->msg, intern->desc->msgdef, + upb_JsonEncode(intern->msg, intern->desc->msgdef, DescriptorPool_GetSymbolTable(), options, buf2, size + 1, &status); RETVAL_STRINGL(buf2, size); @@ -827,26 +846,26 @@ PHP_METHOD(Message, serializeToJsonString) { PHP_METHOD(Message, readWrapperValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); char* member; - const upb_fielddef *f; + const upb_FieldDef *f; zend_long size; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &member, &size) == FAILURE) { return; } - f = upb_msgdef_ntof(intern->desc->msgdef, member, size); + f = upb_MessageDef_FindFieldByNameWithSize(intern->desc->msgdef, member, size); - if (!f || !upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f))) { + if (!f || !IsWrapper(upb_FieldDef_MessageSubDef(f))) { zend_throw_exception_ex(NULL, 0, "Message %s has no field %s", - upb_msgdef_fullname(intern->desc->msgdef), member); + upb_MessageDef_FullName(intern->desc->msgdef), member); return; } - if (upb_msg_has(intern->msg, f)) { - const upb_msg *wrapper = upb_msg_get(intern->msg, f).msg_val; - const upb_msgdef *m = upb_fielddef_msgsubdef(f); - const upb_fielddef *val_f = upb_msgdef_itof(m, 1); - upb_msgval msgval = upb_msg_get(wrapper, val_f); + if (upb_Message_Has(intern->msg, f)) { + const upb_Message *wrapper = upb_Message_Get(intern->msg, f).msg_val; + const upb_MessageDef *m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef *val_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_MessageValue msgval = upb_Message_Get(wrapper, val_f); zval ret; Convert_UpbToPhp(msgval, &ret, TypeInfo_Get(val_f), &intern->arena); RETURN_COPY_VALUE(&ret); @@ -872,10 +891,10 @@ PHP_METHOD(Message, readWrapperValue) { */ PHP_METHOD(Message, writeWrapperValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); + upb_Arena *arena = Arena_Get(&intern->arena); char* member; - const upb_fielddef *f; - upb_msgval msgval; + const upb_FieldDef *f; + upb_MessageValue msgval; zend_long size; zval* val; @@ -884,11 +903,11 @@ PHP_METHOD(Message, writeWrapperValue) { return; } - f = upb_msgdef_ntof(intern->desc->msgdef, member, size); + f = upb_MessageDef_FindFieldByNameWithSize(intern->desc->msgdef, member, size); - if (!f || !upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f))) { + if (!f || !IsWrapper(upb_FieldDef_MessageSubDef(f))) { zend_throw_exception_ex(NULL, 0, "Message %s has no field %s", - upb_msgdef_fullname(intern->desc->msgdef), member); + upb_MessageDef_FullName(intern->desc->msgdef), member); return; } @@ -897,18 +916,18 @@ PHP_METHOD(Message, writeWrapperValue) { } if (Z_TYPE_P(val) == IS_NULL) { - upb_msg_clearfield(intern->msg, f); + upb_Message_ClearField(intern->msg, f); } else { - const upb_msgdef *m = upb_fielddef_msgsubdef(f); - const upb_fielddef *val_f = upb_msgdef_itof(m, 1); - upb_msg *wrapper; + const upb_MessageDef *m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef *val_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_Message *wrapper; if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(val_f), arena)) { return; // Error is already set. } - wrapper = upb_msg_mutable(intern->msg, f, arena).msg; - upb_msg_set(wrapper, val_f, msgval, arena); + wrapper = upb_Message_Mutable(intern->msg, f, arena).msg; + upb_Message_Set(wrapper, val_f, msgval, arena); } } @@ -922,8 +941,8 @@ PHP_METHOD(Message, writeWrapperValue) { */ PHP_METHOD(Message, whichOneof) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_oneofdef* oneof; - const upb_fielddef* field; + const upb_OneofDef* oneof; + const upb_FieldDef* field; char* name; zend_long len; @@ -931,16 +950,16 @@ PHP_METHOD(Message, whichOneof) { return; } - oneof = upb_msgdef_ntoo(intern->desc->msgdef, name, len); + oneof = upb_MessageDef_FindOneofByNameWithSize(intern->desc->msgdef, name, len); if (!oneof) { zend_throw_exception_ex(NULL, 0, "Message %s has no oneof %s", - upb_msgdef_fullname(intern->desc->msgdef), name); + upb_MessageDef_FullName(intern->desc->msgdef), name); return; } - field = upb_msg_whichoneof(intern->msg, oneof); - RETURN_STRING(field ? upb_fielddef_name(field) : ""); + field = upb_Message_WhichOneof(intern->msg, oneof); + RETURN_STRING(field ? upb_FieldDef_Name(field) : ""); } /** @@ -959,21 +978,21 @@ PHP_METHOD(Message, whichOneof) { PHP_METHOD(Message, hasOneof) { Message* intern = (Message*)Z_OBJ_P(getThis()); zend_long field_num; - const upb_fielddef* f; + const upb_FieldDef* f; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &field_num) == FAILURE) { return; } - f = upb_msgdef_itof(intern->desc->msgdef, field_num); + f = upb_MessageDef_FindFieldByNumber(intern->desc->msgdef, field_num); - if (!f || !upb_fielddef_realcontainingoneof(f)) { + if (!f || !upb_FieldDef_RealContainingOneof(f)) { php_error_docref(NULL, E_USER_ERROR, "Internal error, no such oneof field %d\n", (int)field_num); } - RETVAL_BOOL(upb_msg_has(intern->msg, f)); + RETVAL_BOOL(upb_Message_Has(intern->msg, f)); } /** @@ -992,27 +1011,27 @@ PHP_METHOD(Message, hasOneof) { PHP_METHOD(Message, readOneof) { Message* intern = (Message*)Z_OBJ_P(getThis()); zend_long field_num; - const upb_fielddef* f; + const upb_FieldDef* f; zval ret; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &field_num) == FAILURE) { return; } - f = upb_msgdef_itof(intern->desc->msgdef, field_num); + f = upb_MessageDef_FindFieldByNumber(intern->desc->msgdef, field_num); - if (!f || !upb_fielddef_realcontainingoneof(f)) { + if (!f || !upb_FieldDef_RealContainingOneof(f)) { php_error_docref(NULL, E_USER_ERROR, "Internal error, no such oneof field %d\n", (int)field_num); } - if (upb_fielddef_issubmsg(f) && !upb_msg_has(intern->msg, f)) { + if (upb_FieldDef_IsSubMessage(f) && !upb_Message_Has(intern->msg, f)) { RETURN_NULL(); } { - upb_msgval msgval = upb_msg_get(intern->msg, f); + upb_MessageValue msgval = upb_Message_Get(intern->msg, f); Convert_UpbToPhp(msgval, &ret, TypeInfo_Get(f), &intern->arena); } @@ -1042,9 +1061,9 @@ PHP_METHOD(Message, readOneof) { PHP_METHOD(Message, writeOneof) { Message* intern = (Message*)Z_OBJ_P(getThis()); zend_long field_num; - const upb_fielddef* f; - upb_arena *arena = Arena_Get(&intern->arena); - upb_msgval msgval; + const upb_FieldDef* f; + upb_Arena *arena = Arena_Get(&intern->arena); + upb_MessageValue msgval; zval* val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz", &field_num, &val) == @@ -1052,16 +1071,16 @@ PHP_METHOD(Message, writeOneof) { return; } - f = upb_msgdef_itof(intern->desc->msgdef, field_num); + f = upb_MessageDef_FindFieldByNumber(intern->desc->msgdef, field_num); - if (upb_fielddef_issubmsg(f) && Z_TYPE_P(val) == IS_NULL) { - upb_msg_clearfield(intern->msg, f); + if (upb_FieldDef_IsSubMessage(f) && Z_TYPE_P(val) == IS_NULL) { + upb_Message_ClearField(intern->msg, f); return; } else if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(f), arena)) { return; } - upb_msg_set(intern->msg, f, msgval, arena); + upb_Message_Set(intern->msg, f, msgval, arena); } ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 0) @@ -1108,26 +1127,27 @@ static zend_function_entry Message_methods[] = { static const char TYPE_URL_PREFIX[] = "type.googleapis.com/"; -static upb_msgval Message_getval(Message *intern, const char *field_name) { - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, field_name); +static upb_MessageValue Message_getval(Message *intern, const char *field_name) { + const upb_FieldDef *f = upb_MessageDef_FindFieldByName(intern->desc->msgdef, field_name); PBPHP_ASSERT(f); - return upb_msg_get(intern->msg, f); + return upb_Message_Get(intern->msg, f); } static void Message_setval(Message *intern, const char *field_name, - upb_msgval val) { - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, field_name); + upb_MessageValue val) { + const upb_FieldDef *f = + upb_MessageDef_FindFieldByName(intern->desc->msgdef, field_name); PBPHP_ASSERT(f); - return upb_msg_set(intern->msg, f, val, Arena_Get(&intern->arena)); + upb_Message_Set(intern->msg, f, val, Arena_Get(&intern->arena)); } -static upb_msgval StringVal(upb_strview view) { - upb_msgval ret; +static upb_MessageValue StringVal(upb_StringView view) { + upb_MessageValue ret; ret.str_val = view; return ret; } -static bool TryStripUrlPrefix(upb_strview *str) { +static bool TryStripUrlPrefix(upb_StringView *str) { size_t size = strlen(TYPE_URL_PREFIX); if (str->size < size || memcmp(TYPE_URL_PREFIX, str->data, size) != 0) { return false; @@ -1137,17 +1157,17 @@ static bool TryStripUrlPrefix(upb_strview *str) { return true; } -static bool StrViewEq(upb_strview view, const char *str) { +static bool StrViewEq(upb_StringView view, const char *str) { size_t size = strlen(str); return view.size == size && memcmp(view.data, str, size) == 0; } PHP_METHOD(google_protobuf_Any, unpack) { Message* intern = (Message*)Z_OBJ_P(getThis()); - upb_strview type_url = Message_getval(intern, "type_url").str_val; - upb_strview value = Message_getval(intern, "value").str_val; - upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_msgdef *m; + upb_StringView type_url = Message_getval(intern, "type_url").str_val; + upb_StringView value = Message_getval(intern, "value").str_val; + upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_MessageDef *m; Descriptor *desc; zval ret; @@ -1159,7 +1179,7 @@ PHP_METHOD(google_protobuf_Any, unpack) { return; } - m = upb_symtab_lookupmsg2(symtab, type_url.data, type_url.size); + m = upb_DefPool_FindMessageByNameWithSize(symtab, type_url.data, type_url.size); if (m == NULL) { zend_throw_exception( @@ -1176,26 +1196,27 @@ PHP_METHOD(google_protobuf_Any, unpack) { ZVAL_OBJ(&ret, obj); // Get value. - if (!upb_decode(value.data, value.size, msg->msg, - upb_msgdef_layout(desc->msgdef), Arena_Get(&msg->arena))) { + if (upb_Decode(value.data, value.size, msg->msg, + upb_MessageDef_MiniTable(desc->msgdef), NULL, 0, + Arena_Get(&msg->arena)) != kUpb_DecodeStatus_Ok) { zend_throw_exception_ex(NULL, 0, "Error occurred during parsing"); zval_dtor(&ret); return; } // Fuse since the parsed message could alias "value". - upb_arena_fuse(Arena_Get(&intern->arena), Arena_Get(&msg->arena)); + upb_Arena_Fuse(Arena_Get(&intern->arena), Arena_Get(&msg->arena)); RETURN_COPY_VALUE(&ret); } PHP_METHOD(google_protobuf_Any, pack) { Message* intern = (Message*)Z_OBJ_P(getThis()); - upb_arena *arena = Arena_Get(&intern->arena); + upb_Arena *arena = Arena_Get(&intern->arena); zval *val; Message *msg; - upb_strview value; - upb_strview type_url; + upb_StringView value; + upb_StringView type_url; const char *full_name; char *buf; @@ -1212,14 +1233,14 @@ PHP_METHOD(google_protobuf_Any, pack) { msg = (Message*)Z_OBJ_P(val); // Serialize and set value. - value.data = upb_encode(msg->msg, upb_msgdef_layout(msg->desc->msgdef), arena, - &value.size); + value.data = upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->desc->msgdef), + 0, arena, &value.size); Message_setval(intern, "value", StringVal(value)); // Set type url: type_url_prefix + fully_qualified_name - full_name = upb_msgdef_fullname(msg->desc->msgdef); + full_name = upb_MessageDef_FullName(msg->desc->msgdef); type_url.size = strlen(TYPE_URL_PREFIX) + strlen(full_name); - buf = upb_arena_malloc(arena, type_url.size + 1); + buf = upb_Arena_Malloc(arena, type_url.size + 1); memcpy(buf, TYPE_URL_PREFIX, strlen(TYPE_URL_PREFIX)); memcpy(buf + strlen(TYPE_URL_PREFIX), full_name, strlen(full_name)); type_url.data = buf; @@ -1228,9 +1249,9 @@ PHP_METHOD(google_protobuf_Any, pack) { PHP_METHOD(google_protobuf_Any, is) { Message* intern = (Message*)Z_OBJ_P(getThis()); - upb_strview type_url = Message_getval(intern, "type_url").str_val; + upb_StringView type_url = Message_getval(intern, "type_url").str_val; zend_class_entry *klass = NULL; - const upb_msgdef *m; + const upb_MessageDef *m; if (zend_parse_parameters(ZEND_NUM_ARGS(), "C", &klass) == FAILURE) { @@ -1244,7 +1265,7 @@ PHP_METHOD(google_protobuf_Any, is) { } RETURN_BOOL(TryStripUrlPrefix(&type_url) && - StrViewEq(type_url, upb_msgdef_fullname(m))); + StrViewEq(type_url, upb_MessageDef_FullName(m))); } PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { @@ -1266,7 +1287,7 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { return; } - upb_msgval timestamp_seconds; + upb_MessageValue timestamp_seconds; { zval retval; zval function_name; @@ -1276,7 +1297,7 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1, datetime) == FAILURE || !Convert_PhpToUpb(&retval, ×tamp_seconds, - TypeInfo_FromType(UPB_TYPE_INT64), NULL)) { + TypeInfo_FromType(kUpb_CType_Int64), NULL)) { zend_error(E_ERROR, "Cannot get timestamp from DateTime."); return; } @@ -1285,7 +1306,7 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { zval_dtor(&function_name); } - upb_msgval timestamp_nanos; + upb_MessageValue timestamp_nanos; { zval retval; zval function_name; @@ -1302,7 +1323,7 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { if (call_user_function(EG(function_table), NULL, &function_name, &retval, 2, params) == FAILURE || !Convert_PhpToUpb(&retval, ×tamp_nanos, - TypeInfo_FromType(UPB_TYPE_INT32), NULL)) { + TypeInfo_FromType(kUpb_CType_Int32), NULL)) { zend_error(E_ERROR, "Cannot format DateTime."); return; } @@ -1322,8 +1343,8 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { PHP_METHOD(google_protobuf_Timestamp, toDateTime) { Message* intern = (Message*)Z_OBJ_P(getThis()); - upb_msgval seconds = Message_getval(intern, "seconds"); - upb_msgval nanos = Message_getval(intern, "nanos"); + upb_MessageValue seconds = Message_getval(intern, "seconds"); + upb_MessageValue nanos = Message_getval(intern, "nanos"); // Get formatted time string. char formatted_time[32]; diff --git a/php/ext/google/protobuf/message.h b/php/ext/google/protobuf/message.h index 5b49e0db84dba..5b3ba0f165423 100644 --- a/php/ext/google/protobuf/message.h +++ b/php/ext/google/protobuf/message.h @@ -38,24 +38,24 @@ // Registers the PHP Message class. void Message_ModuleInit(); -// Gets a upb_msg* for the PHP object |val|, which must either be a Message +// Gets a upb_Message* for the PHP object |val|, which must either be a Message // object or 'null'. Returns true and stores the message in |msg| if the -// conversion succeeded (we can't return upb_msg* because null->NULL is a valid +// conversion succeeded (we can't return upb_Message* because null->NULL is a valid // conversion). Returns false and raises a PHP error if this isn't a Message // object or null, or if the Message object doesn't match this Descriptor. // // The given |arena| will be fused to this message's arena. -bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena, - upb_msg **msg); +bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_Arena *arena, + upb_Message **msg); -// Gets or creates a PHP Message object to wrap the given upb_msg* and |desc| +// Gets or creates a PHP Message object to wrap the given upb_Message* and |desc| // and returns it in |val|. The PHP object will keep a reference to this |arena| // to ensure the underlying message data stays alive. // // If |msg| is NULL, this will return a PHP null. -void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg, +void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_Message *msg, zval *arena); -bool ValueEq(upb_msgval val1, upb_msgval val2, TypeInfo type); +bool ValueEq(upb_MessageValue val1, upb_MessageValue val2, TypeInfo type); #endif // PHP_PROTOBUF_MESSAGE_H_ diff --git a/php/ext/google/protobuf/names.c b/php/ext/google/protobuf/names.c index a99188800df07..5d7b68aaf5dd4 100644 --- a/php/ext/google/protobuf/names.c +++ b/php/ext/google/protobuf/names.c @@ -71,22 +71,23 @@ 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", "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}; + "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", "parent", "print", "private", "protected", + "public", "require", "require_once", "return", "self", + "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; @@ -207,14 +208,29 @@ static void fill_classname(const char *fullname, } } -char *GetPhpClassname(const upb_filedef *file, const char *fullname) { +char *str_view_dup(upb_StringView str) { + char *ret = malloc(str.size + 1); + memcpy(ret, str.data, str.size); + ret[str.size] = '\0'; + return ret; +} + +char *GetPhpClassname(const upb_FileDef *file, const char *fullname) { // Prepend '.' to package name to make it absolute. In the 5 additional // bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if // given message is google.protobuf.Empty. - const char *package = upb_filedef_package(file); - const char *php_namespace = upb_filedef_phpnamespace(file); - const char *prefix = upb_filedef_phpprefix(file); + const google_protobuf_FileOptions* opts = upb_FileDef_Options(file); + const char *package = upb_FileDef_Package(file); + char *php_namespace = + google_protobuf_FileOptions_has_php_namespace(opts) + ? str_view_dup(google_protobuf_FileOptions_php_namespace(opts)) + : NULL; + char *prefix = + google_protobuf_FileOptions_has_php_class_prefix(opts) + ? str_view_dup(google_protobuf_FileOptions_php_class_prefix(opts)) + : NULL; char *ret; + stringsink namesink; stringsink_init(&namesink); @@ -223,5 +239,7 @@ char *GetPhpClassname(const upb_filedef *file, const char *fullname) { stringsink_string(&namesink, "\0", 1); ret = strdup(namesink.ptr); stringsink_uninit(&namesink); + free(php_namespace); + free(prefix); return ret; } diff --git a/php/ext/google/protobuf/names.h b/php/ext/google/protobuf/names.h index 75101c5a78c39..86af799ac0c24 100644 --- a/php/ext/google/protobuf/names.h +++ b/php/ext/google/protobuf/names.h @@ -35,6 +35,6 @@ // Translates a protobuf symbol name (eg. foo.bar.Baz) into a PHP class name // (eg. \Foo\Bar\Baz). -char *GetPhpClassname(const upb_filedef *file, const char *fullname); +char *GetPhpClassname(const upb_FileDef *file, const char *fullname); #endif // PHP_PROTOBUF_NAMES_H_ diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index 5ef101bc7ade5..17d6b9f998344 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -1,5 +1,5 @@ - + protobuf pecl.php.net

    Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data. @@ -10,19 +10,19 @@ protobuf-opensource@google.com yes - 2022-01-28 - + 2022-03-18 + - 3.19.4 - 3.19.4 + 3.20.0RC2 + 3.20.0 - stable - stable + beta + beta - 3-Clause BSD License + BSD-3-Clause - * Fixed a data loss bug that could occur when the number of optional fields in a message is an exact multiple of 32. (#9440). + * See github.com/protocolbuffers/protobuf/releases for release notes. @@ -47,6 +47,11 @@ + + + + + @@ -73,7 +78,7 @@ 2016-09-23 - 3-Clause BSD License + BSD-3-Clause First alpha release @@ -89,7 +94,7 @@ First alpha release 2017-01-13 - 3-Clause BSD License + BSD-3-Clause Second alpha release. @@ -105,7 +110,7 @@ Second alpha release. 2017-04-28 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -121,7 +126,7 @@ GA release. 2017-05-08 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -137,7 +142,7 @@ GA release. 2017-06-21 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -153,7 +158,7 @@ GA release. 2017-08-16 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -169,7 +174,7 @@ GA release. 2017-09-14 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -185,7 +190,7 @@ GA release. 2017-11-15 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -201,7 +206,7 @@ GA release. 2017-12-06 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -217,7 +222,7 @@ GA release. 2017-12-11 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -233,7 +238,7 @@ GA release. 2018-03-06 - 3-Clause BSD License + BSD-3-Clause G A release. @@ -249,7 +254,7 @@ G A release. 2018-06-06 - 3-Clause BSD License + BSD-3-Clause G A release. @@ -265,7 +270,7 @@ G A release. 2018-08-03 - 3-Clause BSD License + BSD-3-Clause G A release. @@ -281,7 +286,7 @@ G A release. 2019-02-1 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -295,7 +300,7 @@ G A release. 2019-02-22 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -309,7 +314,7 @@ G A release. 2019-02-28 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -323,7 +328,7 @@ G A release. 2019-03-25 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -337,7 +342,7 @@ G A release. 2019-04-23 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -351,7 +356,7 @@ G A release. 2019-05-21 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -365,7 +370,7 @@ G A release. 2019-06-17 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -379,7 +384,7 @@ G A release. 2019-07-10 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -393,7 +398,7 @@ G A release. 2019-08-02 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -407,7 +412,7 @@ G A release. 2019-09-04 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -421,7 +426,7 @@ G A release. 2019-09-05 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -435,7 +440,7 @@ G A release. 2019-09-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -449,7 +454,7 @@ G A release. 2019-11-15 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -463,7 +468,7 @@ G A release. 2019-11-21 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -477,7 +482,7 @@ G A release. 2019-11-25 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -491,7 +496,7 @@ G A release. 2019-12-02 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -505,7 +510,7 @@ G A release. 2019-12-10 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -519,7 +524,7 @@ G A release. 2020-01-28 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -533,7 +538,7 @@ G A release. 2020-02-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -547,7 +552,7 @@ G A release. 2020-04-30 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -561,7 +566,7 @@ G A release. 2020-05-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -575,7 +580,7 @@ G A release. 2020-05-15 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -589,7 +594,7 @@ G A release. 2020-05-20 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -603,7 +608,7 @@ G A release. 2020-05-26 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -617,7 +622,7 @@ G A release. 2020-06-01 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -631,7 +636,7 @@ G A release. 2020-08-05 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -645,7 +650,7 @@ G A release. 2020-08-05 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -659,7 +664,7 @@ G A release. 2020-08-12 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -673,7 +678,7 @@ G A release. 2020-08-14 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -687,7 +692,7 @@ G A release. 2020-10-08 - 3-Clause BSD License + BSD-3-Clause GA release. @@ -701,7 +706,7 @@ G A release. 2020-11-05 - 3-Clause BSD License + BSD-3-Clause @@ -716,7 +721,7 @@ G A release. 2020-11-10 - 3-Clause BSD License + BSD-3-Clause @@ -731,7 +736,7 @@ G A release. 2020-11-11 - 3-Clause BSD License + BSD-3-Clause @@ -746,7 +751,7 @@ G A release. 2020-11-12 - 3-Clause BSD License + BSD-3-Clause @@ -761,7 +766,7 @@ G A release. 2021-02-05 - 3-Clause BSD License + BSD-3-Clause @@ -776,7 +781,7 @@ G A release. 2021-02-17 - 3-Clause BSD License + BSD-3-Clause @@ -791,7 +796,7 @@ G A release. 2021-02-18 - 3-Clause BSD License + BSD-3-Clause @@ -806,7 +811,7 @@ G A release. 2021-02-19 - 3-Clause BSD License + BSD-3-Clause @@ -821,7 +826,7 @@ G A release. 2021-02-23 - 3-Clause BSD License + BSD-3-Clause @@ -836,7 +841,7 @@ G A release. 2021-02-24 - 3-Clause BSD License + BSD-3-Clause @@ -851,7 +856,7 @@ G A release. 2021-03-02 - 3-Clause BSD License + BSD-3-Clause @@ -866,7 +871,7 @@ G A release. 2021-03-04 - 3-Clause BSD License + BSD-3-Clause @@ -881,7 +886,7 @@ G A release. 2021-03-10 - 3-Clause BSD License + BSD-3-Clause @@ -896,7 +901,7 @@ G A release. 2021-04-02 - 3-Clause BSD License + BSD-3-Clause @@ -911,7 +916,7 @@ G A release. 2021-04-02 - 3-Clause BSD License + BSD-3-Clause @@ -926,7 +931,7 @@ G A release. 2021-05-03 - 3-Clause BSD License + BSD-3-Clause @@ -941,7 +946,7 @@ G A release. 2021-05-05 - 3-Clause BSD License + BSD-3-Clause @@ -956,7 +961,7 @@ G A release. 2021-05-06 - 3-Clause BSD License + BSD-3-Clause @@ -971,7 +976,7 @@ G A release. 2021-05-07 - 3-Clause BSD License + BSD-3-Clause @@ -986,7 +991,7 @@ G A release. 2021-05-11 - 3-Clause BSD License + BSD-3-Clause @@ -1001,7 +1006,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 +1024,7 @@ G A release. 2021-05-25 - 3-Clause BSD License + BSD-3-Clause @@ -1034,7 +1039,7 @@ G A release. 2021-06-04 - 3-Clause BSD License + BSD-3-Clause @@ -1049,7 +1054,7 @@ G A release. 2021-08-18 - 3-Clause BSD License + BSD-3-Clause @@ -1064,7 +1069,7 @@ G A release. 2021-08-27 - 3-Clause BSD License + BSD-3-Clause @@ -1079,7 +1084,7 @@ G A release. 2021-09-13 - 3-Clause BSD License + BSD-3-Clause @@ -1094,7 +1099,7 @@ G A release. 2021-10-04 - 3-Clause BSD License + BSD-3-Clause @@ -1109,7 +1114,7 @@ G A release. 2021-10-15 - 3-Clause BSD License + BSD-3-Clause @@ -1124,7 +1129,7 @@ G A release. 2021-10-18 - 3-Clause BSD License + BSD-3-Clause @@ -1139,7 +1144,7 @@ G A release. 2021-10-19 - 3-Clause BSD License + BSD-3-Clause @@ -1154,7 +1159,7 @@ G A release. 2021-10-28 - 3-Clause BSD License + BSD-3-Clause @@ -1169,7 +1174,7 @@ G A release. 2022-01-05 - 3-Clause BSD License + BSD-3-Clause @@ -1184,7 +1189,7 @@ G A release. 2022-01-11 - 3-Clause BSD License + BSD-3-Clause @@ -1203,5 +1208,35 @@ G A release. + + + 3.20.0RC1 + 3.20.0 + + + beta + beta + + 2022-03-04 + + BSD-3-Clause + + + + + + 3.20.0RC2 + 3.20.0 + + + beta + beta + + 2022-03-15 + + BSD-3-Clause + + + diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 925faa645a564..1179ac399919c 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-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); + if (size) 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,147 @@ 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); } } - 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 (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); + if (ext_count) { + const upb_Message_Extension* end = ext + 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); + } + } } } - *size = (e->limit - e->ptr) - pre_len; + if (m->field_count) { + const upb_MiniTable_Field* f = &m->fields[m->field_count]; + const upb_MiniTable_Field* first = &m->fields[0]; + while (f != first) { + f--; + 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 +1905,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 +1938,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 +1957,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 +1984,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 +1997,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 +2014,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 +2061,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 +2072,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 +2122,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 +2192,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 +2205,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 +2242,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 +2283,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 +2315,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 +2340,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 +2365,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 +2388,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 +2407,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 +2416,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 +2429,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 +2446,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 +2465,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 +2482,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 +2496,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 +2511,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 +2521,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 +2536,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 +2550,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 +2577,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,7 +2626,7 @@ static uint64_t WyhashMix(uint64_t v0, uint64_t v1) { return low ^ high; } -static uint64_t Wyhash(const void *data, size_t len, uint64_t seed, +static 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; @@ -2261,45 +2710,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 +2756,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 +2778,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 +2793,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 +2817,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 +2840,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 +2873,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 +2881,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 +2891,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 +2900,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 +2926,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 +2945,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 +2980,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 +3019,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 +3038,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 +3070,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 +3209,57 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, #include -/* upb_status *****************************************************************/ +// Must be last. -void upb_status_clear(upb_status *status) { +/* upb_Status *****************************************************************/ + +void upb_Status_Clear(upb_Status* status) { if (!status) return; status->ok = true; status->msg[0] = '\0'; } -bool upb_ok(const upb_status *status) { return status->ok; } +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 +3271,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 +3335,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 +3369,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 +3380,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 +3419,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 +3442,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 +3468,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 +3484,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 +3500,39 @@ 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 +3552,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 +3615,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 +3635,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 +3644,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 +3657,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 +3687,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 +3703,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 +3714,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 +3748,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 +3781,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 +3800,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 +3829,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 +3861,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 +3887,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 +3907,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 +3915,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 +3931,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 +3948,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 +3995,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 +4031,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 +4087,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 +4126,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 +4153,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 +4179,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 +4204,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 +4230,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 +4326,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 +4358,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 +4397,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 +4430,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 +4443,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 +4470,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 +4486,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 +4508,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 +4532,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 +4558,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,516 +4571,484 @@ 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[8] = { + {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)}, + {15, UPB_SIZE(16, 16), 7, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 24), 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, 32), 8, 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, }; - - -/** bazel-out/k8-fastbuild/bin/external/com_google_protobuf/google/protobuf/descriptor.upbdefs.c ************************************************************//* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/descriptor.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - - -extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit; -extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit; -extern const upb_msglayout google_protobuf_DescriptorProto_msginit; -extern const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit; -extern const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit; -extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit; -extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit; -extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit; -extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit; -extern const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; -extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit; -extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit; -extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit; -extern const upb_msglayout google_protobuf_FileOptions_msginit; -extern const upb_msglayout google_protobuf_MessageOptions_msginit; -extern const upb_msglayout google_protobuf_FieldOptions_msginit; -extern const upb_msglayout google_protobuf_OneofOptions_msginit; -extern const upb_msglayout google_protobuf_EnumOptions_msginit; -extern const upb_msglayout google_protobuf_EnumValueOptions_msginit; -extern const upb_msglayout google_protobuf_ServiceOptions_msginit; -extern const upb_msglayout google_protobuf_MethodOptions_msginit; -extern const upb_msglayout google_protobuf_UninterpretedOption_msginit; -extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit; -extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit; -extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; -extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; -extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; - -static const upb_msglayout *layouts[27] = { +static const upb_MiniTable *messages_layout[27] = { &google_protobuf_FileDescriptorSet_msginit, &google_protobuf_FileDescriptorProto_msginit, &google_protobuf_DescriptorProto_msginit, @@ -4523,7 +5078,72 @@ static const upb_msglayout *layouts[27] = { &google_protobuf_GeneratedCodeInfo_Annotation_msginit, }; -static const char descriptor[7601] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', +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, +}; + + + +/** bazel-out/k8-fastbuild/bin/external/com_google_protobuf/google/protobuf/descriptor.upbdefs.c ************************************************************//* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + + +static const char descriptor[7667] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n', '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', @@ -4712,7 +5332,7 @@ static const char descriptor[7601] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', ' 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', ':', '\n', '\014', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', 'e', '\022', '\t', '\n', '\005', 'S', 'P', 'E', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'C', 'O', 'D', 'E', '_', 'S', 'I', 'Z', 'E', '\020', '\002', '\022', '\020', '\n', '\014', 'L', 'I', 'T', 'E', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\003', '*', '\t', '\010', '\350', -'\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\321', '\002', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e', +'\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\343', '\002', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '<', '\n', '\027', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 's', 'e', 't', '_', 'w', 'i', 'r', 'e', '_', 'f', 'o', 'r', 'm', 'a', 't', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\024', 'm', 'e', 's', 's', 'a', 'g', 'e', 'S', 'e', 't', 'W', 'i', 'r', 'e', 'F', 'o', 'r', 'm', 'a', 't', '\022', 'L', '\n', '\037', 'n', 'o', @@ -4725,120 +5345,122 @@ static const char descriptor[7601] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', ' 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', -'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\010', '\020', '\t', 'J', '\004', '\010', -'\t', '\020', '\n', '\"', '\342', '\003', '\n', '\014', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'A', '\n', '\005', 'c', -'t', 'y', 'p', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', -'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'C', 'T', 'y', 'p', 'e', ':', '\006', 'S', -'T', 'R', 'I', 'N', 'G', 'R', '\005', 'c', 't', 'y', 'p', 'e', '\022', '\026', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\002', ' ', -'\001', '(', '\010', 'R', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\022', 'G', '\n', '\006', 'j', 's', 't', 'y', 'p', 'e', '\030', '\006', ' ', '\001', -'(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', -'d', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'J', 'S', 'T', 'y', 'p', 'e', ':', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', -'L', 'R', '\006', 'j', 's', 't', 'y', 'p', 'e', '\022', '\031', '\n', '\004', 'l', 'a', 'z', 'y', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', -'f', 'a', 'l', 's', 'e', 'R', '\004', 'l', 'a', 'z', 'y', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', -'\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', -'\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'w', 'e', -'a', 'k', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', -'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', -'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', -'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p', -'e', '\022', '\n', '\n', '\006', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\000', '\022', '\010', '\n', '\004', 'C', 'O', 'R', 'D', '\020', '\001', '\022', '\020', -'\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_', 'P', 'I', 'E', 'C', 'E', '\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p', -'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', '\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T', -'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'U', 'M', 'B', 'E', 'R', '\020', '\002', '*', '\t', '\010', '\350', -'\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', '\"', 's', '\n', '\014', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', -'i', 'o', 'n', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', -'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', -'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', -'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', -'\200', '\200', '\200', '\200', '\002', '\"', '\300', '\001', '\n', '\013', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\037', '\n', '\013', -'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i', 'a', 's', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A', -'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', -'\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', +'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', 'J', '\004', '\010', +'\005', '\020', '\006', 'J', '\004', '\010', '\006', '\020', '\007', 'J', '\004', '\010', '\010', '\020', '\t', 'J', '\004', '\010', '\t', '\020', '\n', '\"', '\222', '\004', '\n', +'\014', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'A', '\n', '\005', 'c', 't', 'y', 'p', 'e', '\030', '\001', ' ', +'\001', '(', '\016', '2', '#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', +'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'C', 'T', 'y', 'p', 'e', ':', '\006', 'S', 'T', 'R', 'I', 'N', 'G', 'R', '\005', +'c', 't', 'y', 'p', 'e', '\022', '\026', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\006', 'p', 'a', +'c', 'k', 'e', 'd', '\022', 'G', '\n', '\006', 'j', 's', 't', 'y', 'p', 'e', '\030', '\006', ' ', '\001', '(', '\016', '2', '$', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', +'s', '.', 'J', 'S', 'T', 'y', 'p', 'e', ':', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', 'R', '\006', 'j', 's', 't', 'y', +'p', 'e', '\022', '\031', '\n', '\004', 'l', 'a', 'z', 'y', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', +'l', 'a', 'z', 'y', '\022', '.', '\n', '\017', 'u', 'n', 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', '_', 'l', 'a', 'z', 'y', '\030', '\017', +' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\016', 'u', 'n', 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', 'L', 'a', +'z', 'y', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', +'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030', +'\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'w', 'e', 'a', 'k', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', -'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\005', '\020', '\006', -'\"', '\236', '\001', '\n', '\020', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', -'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', +'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p', 'e', '\022', '\n', '\n', '\006', 'S', 'T', 'R', 'I', +'N', 'G', '\020', '\000', '\022', '\010', '\n', '\004', 'C', 'O', 'R', 'D', '\020', '\001', '\022', '\020', '\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_', +'P', 'I', 'E', 'C', 'E', '\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p', 'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', +'O', 'R', 'M', 'A', 'L', '\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n', +'\t', 'J', 'S', '_', 'N', 'U', 'M', 'B', 'E', 'R', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', +'\010', '\004', '\020', '\005', '\"', 's', '\n', '\014', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'X', '\n', '\024', 'u', +'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', +'\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', +'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', +'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\300', '\001', '\n', +'\013', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\037', '\n', '\013', 'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i', +'a', 's', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A', 'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd', +'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', +'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', +'d', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', +'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', +'\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\005', '\020', '\006', '\"', '\236', '\001', '\n', '\020', 'E', 'n', 'u', 'm', +'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', +'d', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', +'d', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', +'\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', +'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', +'\200', '\002', '\"', '\234', '\001', '\n', '\016', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', +'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', -'*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\234', '\001', '\n', '\016', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', -'t', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', -':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', -'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', -'2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', -'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', -'t', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\340', '\002', '\n', '\r', -'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', -'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', -'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"', -' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', -'t', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', -'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R', -'\020', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', -'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', -'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', -'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', -'d', 'O', 'p', 't', 'i', 'o', 'n', '\"', 'P', '\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', -'e', 'l', '\022', '\027', '\n', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', -'\020', '\000', '\022', '\023', '\n', '\017', 'N', 'O', '_', 'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016', -'\n', '\n', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', -'\"', '\232', '\003', '\n', '\023', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022', -'A', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', -'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', -'n', '.', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't', -'i', 'f', 'i', 'e', 'r', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i', -'f', 'i', 'e', 'r', 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', -'_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ', '\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't', -'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', -'u', 'e', '\030', '\005', ' ', '\001', '(', '\003', 'R', '\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', -'e', '\022', '!', '\n', '\014', 'd', 'o', 'u', 'b', 'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013', -'d', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l', -'u', 'e', '\030', '\007', ' ', '\001', '(', '\014', 'R', '\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017', -'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g', -'g', 'r', 'e', 'g', 'a', 't', 'e', 'V', 'a', 'l', 'u', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', -'\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p', 'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P', -'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's', '_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010', -'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\"', '\247', '\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', 'C', -'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', -'2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', -'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', 'i', -'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', -' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', ' ', -'\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', -'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', 'o', -'m', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', -'t', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', -'s', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', 'm', -'m', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', 'c', -'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\321', '\001', '\n', '\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', -'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', -'\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', -'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', -'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\032', 'm', '\n', '\n', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', -'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', -'\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o', -'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005', -'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '~', -'\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', -'s', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.', -'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', -'/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', -'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', -'n', +'*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\340', '\002', '\n', '\r', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', +'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', +'\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e', +'m', 'p', 'o', 't', 'e', 'n', 'c', 'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"', ' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', +'n', 's', '.', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M', +'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R', '\020', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', +'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', +'_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', +'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', 'P', +'\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', '\027', '\n', '\023', 'I', 'D', 'E', +'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\017', 'N', 'O', '_', +'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016', '\n', '\n', 'I', 'D', 'E', 'M', 'P', 'O', 'T', +'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\232', '\003', '\n', '\023', 'U', 'n', 'i', 'n', +'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022', 'A', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\002', +' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', +'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '.', 'N', 'a', 'm', 'e', 'P', 'a', 'r', +'t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', '_', 'v', 'a', 'l', +'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 'V', 'a', 'l', 'u', 'e', +'\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ', +'\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', +'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\005', ' ', '\001', '(', '\003', 'R', +'\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 'd', 'o', 'u', 'b', +'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013', 'd', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', +'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', ' ', '\001', '(', '\014', 'R', +'\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017', 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', +'_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', 'V', 'a', +'l', 'u', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p', +'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's', +'_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010', 'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n', +'s', 'i', 'o', 'n', '\"', '\247', '\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', +'\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', +'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', +'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', +'\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', +'s', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', +'\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', +'\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', +'\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', +'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', +'(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', 'c', 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', +'t', 's', '\"', '\321', '\001', '\n', '\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', +'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', +'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', 'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', +'i', 'o', 'n', '\032', 'm', '\n', '\n', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', +'\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', +'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', +'\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005', 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', +'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '~', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', +'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', +'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', +'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', +'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 'n', }; -static upb_def_init *deps[1] = { +static _upb_DefPool_Init *deps[1] = { NULL }; -upb_def_init google_protobuf_descriptor_proto_upbdefinit = { +_upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit = { deps, - layouts, + &google_protobuf_descriptor_proto_upb_file_layout, "google/protobuf/descriptor.proto", - UPB_STRVIEW_INIT(descriptor, 7601) + UPB_STRINGVIEW_INIT(descriptor, 7667) }; /** upb/def.c ************************************************************/ @@ -4854,143 +5476,267 @@ upb_def_init google_protobuf_descriptor_proto_upbdefinit = { 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_; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif +}; + +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; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; -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; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; -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; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; -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; + int index; + bool client_streaming; + bool server_streaming; }; -struct upb_symtab { - upb_arena *arena; +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_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) { + // Our 3-bit pointer tagging requires all pointers to be multiples of 8. + // The arena will always yield 8-byte-aligned addresses, however we put + // the defs into arrays. For each element in the array to be 8-byte-aligned, + // the sizes of each def type must also be a multiple of 8. + // + // If any of these asserts fail, we need to add or remove padding on 32-bit + // machines (64-bit machines will have 8-byte alignment already due to + // pointers, which all of these structs have). + UPB_ASSERT((sizeof(upb_FieldDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_MessageDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_EnumDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_EnumValueDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_ServiceDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_OneofDef) & UPB_DEFTYPE_MASK) == 0); + 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; @@ -5005,371 +5751,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_; } + +uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } -uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT64); - return f->defaultval.uint; +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_IsProto3Optional(const upb_FieldDef* f) { + return f->proto3_optional_; +} + +bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Message; } -bool upb_fielddef_isstring(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_STRING || - upb_fielddef_type(f) == UPB_TYPE_BYTES; +bool upb_FieldDef_IsString(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_String || + upb_FieldDef_CType(f) == kUpb_CType_Bytes; } -bool upb_fielddef_isseq(const upb_fielddef *f) { - return upb_fielddef_label(f) == UPB_LABEL_REPEATED; +bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Repeated; } -bool upb_fielddef_isprimitive(const upb_fielddef *f) { - return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f); +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_isseq(f) && upb_fielddef_issubmsg(f) && - upb_msgdef_mapentry(upb_fielddef_msgsubdef(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_hassubdef(const upb_fielddef *f) { - return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM; +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 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_msgdef_fullname(const upb_msgdef *m) { +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_FindFieldByNumber(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)) { @@ -5379,8 +6171,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)) { @@ -5390,23 +6182,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; @@ -5418,293 +6214,465 @@ 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]; } -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; +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_iswrapper(const upb_msgdef *m) { - upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); - return type >= UPB_WELLKNOWN_DOUBLEVALUE && - type <= UPB_WELLKNOWN_BOOLVALUE; +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { + return m->well_known_type; } -void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) { - upb_inttable_begin(iter, &m->itof); +/* upb_OneofDef ***************************************************************/ + +const google_protobuf_OneofOptions* upb_OneofDef_Options( + const upb_OneofDef* o) { + return o->opts; } -void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); } +bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { + return o->opts != (void*)opt_default; +} -bool upb_msg_field_done(const upb_msg_field_iter *iter) { - return upb_inttable_done(iter); +const char* upb_OneofDef_Name(const upb_OneofDef* o) { + return shortdefname(o->full_name); } -upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) { + return o->parent; } -void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { - upb_inttable_iter_setdone(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]; } -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); +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; } -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); - } +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_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)); +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; } -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { - return upb_strtable_done(iter); +/* upb_FileDef ****************************************************************/ + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) { + return f->opts; } -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); +bool upb_FileDef_HasOptions(const upb_FileDef* f) { + return f->opts != (void*)opt_default; } -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { - upb_strtable_iter_setdone(iter); +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; } -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_DependencyCount(const upb_FileDef* f) { return f->dep_count; } + +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) { + return f->public_dep_count; } -/* upb_oneofdef ***************************************************************/ +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { + return f->weak_dep_count; +} -const char *upb_oneofdef_name(const upb_oneofdef *o) { - return shortdefname(o->full_name); +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { + return f->public_deps; } -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { - return o->parent; +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) { + return f->weak_deps; } -int upb_oneofdef_fieldcount(const upb_oneofdef *o) { - return o->field_count; +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) { + return f->top_lvl_enum_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_TopLevelExtensionCount(const upb_FileDef* f) { + return f->top_lvl_ext_count; } -int upb_oneofdef_numfields(const upb_oneofdef *o) { - return o->field_count; +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]; } -uint32_t upb_oneofdef_index(const upb_oneofdef *o) { - return o - o->parent->oneofs; +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]]; } -bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { - return o->synthetic; +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]]; } -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_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_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_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]; } -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { - upb_inttable_begin(iter, &o->itof); +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_next(upb_oneof_iter *iter) { - upb_inttable_next(iter); +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->service_count); + return &f->services[i]; } -bool upb_oneof_done(upb_oneof_iter *iter) { - return upb_inttable_done(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; } -upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { + return m->opts != (void*)opt_default; } -void upb_oneof_iter_setdone(upb_oneof_iter *iter) { - upb_inttable_iter_setdone(iter); +const char* upb_MethodDef_FullName(const upb_MethodDef* m) { + return m->full_name; } -/* upb_filedef ****************************************************************/ +int upb_MethodDef_Index(const upb_MethodDef* m) { return m->index; } + +const char* upb_MethodDef_Name(const upb_MethodDef* m) { + return shortdefname(m->full_name); +} -const char *upb_filedef_name(const upb_filedef *f) { - return f->name; +const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) { + return m->service; } -const char *upb_filedef_package(const upb_filedef *f) { - return f->package; +const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) { + return m->input_type; } -const char *upb_filedef_phpprefix(const upb_filedef *f) { - return f->phpprefix; +const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) { + return m->output_type; } -const char *upb_filedef_phpnamespace(const upb_filedef *f) { - return f->phpnamespace; +bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) { + return m->client_streaming; } -upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { - return f->syntax; +bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { + return m->server_streaming; } -int upb_filedef_msgcount(const upb_filedef *f) { - return f->msg_count; +/* upb_ServiceDef *************************************************************/ + +const google_protobuf_ServiceOptions* upb_ServiceDef_Options( + const upb_ServiceDef* s) { + return s->opts; } -int upb_filedef_depcount(const upb_filedef *f) { - return f->dep_count; +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { + return s->opts != (void*)opt_default; } -int upb_filedef_enumcount(const upb_filedef *f) { - return f->enum_count; +const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { + return 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]; +const char* upb_ServiceDef_Name(const upb_ServiceDef* s) { + return shortdefname(s->full_name); } -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_Index(const upb_ServiceDef* s) { return s->index; } + +const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) { + return s->file; } -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { - return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; +int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) { + return s->method_count; } -const upb_symtab *upb_filedef_symtab(const upb_filedef *f) { - return f->symtab; +const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) { + return i < 0 || i >= s->method_count ? NULL : &s->methods[i]; } -void upb_symtab_free(upb_symtab *s) { - upb_arena_free(s->arena); +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; +} + +/* 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_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { +const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, + const char* sym) { + return symtab_lookup(s, sym, UPB_DEFTYPE_MSG); +} + +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. *********************************/ @@ -5714,40 +6682,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; @@ -5778,158 +6767,218 @@ 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_FindFieldByNumber(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 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++; + } + if (upb_FieldDef_CType(f) == kUpb_CType_Enum && + f->sub.enumdef->file->syntax == kUpb_Syntax_Proto2) { + 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_FindFieldByNumber(m, 1); + const upb_FieldDef* val = upb_MessageDef_FindFieldByNumber(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; } + 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; } @@ -5942,23 +6991,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->sub.enumdef->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; @@ -5968,55 +7038,51 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { } /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit + 1, 8); + l->size = hasbit ? div_round_up(hasbit + 1, 8) : 0; /* 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; + + if (o->field_count == 0) { + symtab_errf(ctx, "Oneof must have at least one field (%s)", o->full_name); + } /* 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; } } @@ -6025,28 +7091,33 @@ 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); + if (fields) { + 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); @@ -6057,33 +7128,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; } @@ -6092,14 +7163,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'); @@ -6130,14 +7203,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); } @@ -6146,83 +7224,269 @@ 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 = base ? strlen(base) : 0; + char* tmp = malloc(sym.size + baselen + 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 " UPB_STRINGVIEW_FORMAT " with type=%d", + from_name_dbg, UPB_STRINGVIEW_ARGS(sym), (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); + + upb_value existing_v; + if (upb_strtable_lookup2(&m->ntof, name.data, name.size, &existing_v)) { + symtab_errf(ctx, "duplicate oneof name (%s)", o->full_name); + } + 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); @@ -6235,8 +7499,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; @@ -6244,16 +7508,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; @@ -6261,7 +7526,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; @@ -6269,7 +7534,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; @@ -6277,7 +7542,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; @@ -6285,7 +7550,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; @@ -6293,75 +7558,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"); } name = google_protobuf_FieldDescriptorProto_name(field_proto); @@ -6372,57 +7640,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 (upb_inttable_lookup(&m->itof, field_number, NULL)) { + symtab_errf(ctx, "duplicate field number (%u)", field_number); } - if (ctx->layouts) { - const upb_msglayout_field *fields = m->layout->fields; + 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; @@ -6433,37 +7738,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); + } } - 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); + 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_); + } /* 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); } @@ -6477,8 +7787,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_) { @@ -6488,43 +7798,184 @@ 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->index = i; + 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; +} + +static int compare_int32(const void* a_ptr, const void* b_ptr) { + int32_t a = *(int32_t*)a_ptr; + int32_t b = *(int32_t*)b_ptr; + return a < b ? -1 : (a == b ? 0 : 1); +} + +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 |= 1ULL << 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); + } + + // Enums can have duplicate values; we must sort+uniq them. + if (values) qsort(values, n, sizeof(*values), &compare_int32); + + int dst = 0; + for (int i = 0; i < n; dst++) { + int32_t val = values[i]; + while (i < n && values[i] == val) i++; // Skip duplicates. + values[dst] = val; + } + n = dst; + + 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)); @@ -6532,225 +7983,371 @@ 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(upb_inttable_count(&e->iton) == + 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; - - google_protobuf_FileDescriptorProto_extension(file_proto, &n); - file->ext_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; -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; + bool found = false; - 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]); + } + + m->in_message_set = false; + for (int i = 0; i < m->nested_ext_count; i++) { + upb_FieldDef* ext = (upb_FieldDef*)&m->nested_exts[i]; + resolve_fielddef(ctx, m->full_name, ext); + 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; + } + } + + if (!ctx->layout) make_layout(ctx, m); + + 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"); @@ -6758,11 +8355,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); @@ -6771,133 +8366,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, "weak_dep %d is out of range", (int)weak_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; @@ -6906,51 +8557,53 @@ 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_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable) { /* 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_LoadDefInitEx(s, *deps, rebuild_minitable)) 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.", @@ -6958,24 +8611,81 @@ 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; + const upb_MiniTable_File* mt = rebuild_minitable ? NULL : init->layout; + if (!_upb_DefPool_AddFile(s, file, mt, &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 @@ -6985,199 +8695,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_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber); + const upb_FieldDef* value = + upb_MessageDef_FindFieldByNumber(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; } @@ -7185,10 +8930,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; } } @@ -7197,48 +8942,66 @@ 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_FindFieldByNumber(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; } } @@ -7247,22 +9010,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); @@ -7270,86 +9032,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 ************************************************************/ @@ -7367,62 +9157,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': @@ -7441,13 +9233,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) { @@ -7456,23 +9248,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; @@ -7513,19 +9305,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); @@ -7534,31 +9326,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"); @@ -7568,8 +9358,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') { @@ -7581,14 +9371,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); @@ -7648,7 +9438,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 '\"'; @@ -7671,9 +9461,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"); @@ -7698,7 +9488,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. */ @@ -7740,22 +9530,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); @@ -7772,10 +9562,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 '\\': @@ -7804,7 +9594,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); @@ -7887,8 +9677,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) { @@ -7915,13 +9705,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 | @@ -7959,8 +9749,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'; @@ -7977,8 +9767,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; @@ -7996,8 +9786,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"); @@ -8005,8 +9795,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"); @@ -8017,8 +9807,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: { @@ -8026,7 +9816,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); @@ -8034,7 +9824,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; } @@ -8042,7 +9832,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."); } @@ -8053,8 +9844,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: { @@ -8062,7 +9853,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); @@ -8070,7 +9861,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; } @@ -8078,7 +9869,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."); } @@ -8089,9 +9880,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: @@ -8113,7 +9904,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"); @@ -8125,34 +9916,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; @@ -8164,13 +9959,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")) { @@ -8198,65 +9993,81 @@ 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_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(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; @@ -8268,31 +10079,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); @@ -8300,25 +10112,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(); @@ -8327,14 +10139,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)) { @@ -8347,12 +10159,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) { @@ -8369,8 +10181,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; @@ -8383,12 +10195,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; @@ -8437,20 +10250,22 @@ 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_FindFieldByNumber(m, 1), seconds, + d->arena); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(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. */ @@ -8466,110 +10281,114 @@ 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_FindFieldByNumber(m, 1), seconds, + d->arena); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(m, 1); + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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) { @@ -8577,7 +10396,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; @@ -8596,17 +10415,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_FindFieldByNumber(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; @@ -8614,19 +10434,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'"); @@ -8635,27 +10456,28 @@ 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_FindFieldByNumber(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"); @@ -8664,22 +10486,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_FindFieldByNumber(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); @@ -8697,13 +10519,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; @@ -8722,49 +10544,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_FindFieldByNumber(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: @@ -8772,9 +10596,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; @@ -8782,7 +10606,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; @@ -8816,43 +10640,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); @@ -8866,12 +10693,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; @@ -8888,7 +10715,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; @@ -8904,12 +10731,12 @@ 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_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(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) { @@ -8926,7 +10753,8 @@ static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg, * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for * Processing Calendar Dates," Communications of the Association of * Computing Machines, vol. 11 (1968), p. 657. */ - L = (int)(seconds / 86400) + 68569 + 2440588; + seconds += 62135596800; // Ensure seconds is positive. + L = (int)(seconds / 86400) - 719162 + 68569 + 2440588; N = 4 * L / 146097; L = L - (146097 * N + 3) / 4; I = 4000 * (L + 1) / 1461001; @@ -8946,11 +10774,12 @@ 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_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(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)) { @@ -8966,28 +10795,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, "\""); @@ -9021,9 +10850,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) { @@ -9062,13 +10891,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) { @@ -9076,32 +10905,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_FindFieldByNumber(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"); @@ -9120,7 +10955,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); @@ -9129,28 +10964,30 @@ 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_FindFieldByNumber(m, 1); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(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 { @@ -9162,7 +10999,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 { @@ -9170,9 +11007,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; @@ -9191,65 +11028,65 @@ 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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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); @@ -9259,22 +11096,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); @@ -9283,113 +11121,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: @@ -9399,95 +11239,103 @@ 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_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(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) { @@ -9498,9 +11346,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; @@ -9515,7 +11363,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/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index 8883668b790c9..5af4e27dfc8de 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-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); + +/* Returns the number of extensions present in this message. */ +size_t upb_Message_ExtensionCount(const upb_Message* msg); -/** upb_extreg *******************************************************************/ +/** 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,11 +780,12 @@ bool upb_decode(const char *buf, size_t size, upb_msg *msg, #include +// Must be last. + #ifdef __cplusplus extern "C" { #endif - /* upb_value ******************************************************************/ typedef struct { @@ -782,11 +794,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 +806,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 +852,6 @@ UPB_INLINE upb_value upb_value_double(double cval) { #undef SET_TYPE - /* upb_tabkey *****************************************************************/ /* Either: @@ -855,14 +863,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,7 +883,8 @@ typedef struct upb_tabval { uint64_t val; } upb_tabval; -#define UPB_TABVALUE_EMPTY_INIT {-1} +#define UPB_TABVALUE_EMPTY_INIT \ + { -1 } /* upb_table ******************************************************************/ @@ -887,15 +896,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 { @@ -903,13 +912,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 @@ -917,22 +926,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 @@ -941,45 +948,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: @@ -1000,7 +1046,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; @@ -1013,19 +1058,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 **********************************************************/ @@ -1039,31 +1083,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. */ @@ -1071,110 +1114,208 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, extern "C" { #endif -/** upb_msglayout *************************************************************/ +/** upb_*Int* conversion routines ********************************************/ -/* upb_msglayout represents the memory layout of a given upb_msgdef. The +UPB_INLINE int32_t _upb_Int32_FromI(int v) { return (int32_t)v; } + +UPB_INLINE int64_t _upb_Int64_FromLL(long long v) { return (int64_t)v; } + +UPB_INLINE uint32_t _upb_UInt32_FromU(unsigned v) { return (uint32_t)v; } + +UPB_INLINE uint64_t _upb_UInt64_FromULL(unsigned long long v) { + return (uint64_t)v; +} + +/** upb_MiniTable *************************************************************/ + +/* 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, }; -UPB_INLINE upb_fieldmode _upb_getmode(const upb_msglayout_field *field) { - return (upb_fieldmode)(field->mode & 3); +/* 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_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. @@ -1184,160 +1325,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); } @@ -1347,7 +1504,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); } @@ -1357,11 +1514,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; @@ -1370,30 +1527,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); @@ -1403,9 +1560,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); @@ -1415,28 +1572,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); @@ -1445,42 +1602,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.*/ @@ -1491,25 +1647,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. * @@ -1520,15 +1676,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 { @@ -1536,12 +1692,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); @@ -1551,8 +1707,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); } @@ -1560,14 +1716,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); @@ -1575,7 +1731,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; @@ -1585,108 +1741,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; @@ -1697,29 +1856,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); @@ -1727,7 +1886,7 @@ UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, } #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif @@ -1741,8 +1900,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. */ @@ -1750,38 +1909,56 @@ 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 @@ -1790,50 +1967,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; @@ -1844,19 +2029,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; @@ -1870,10 +2055,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; @@ -1891,11 +2076,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); @@ -1905,7 +2090,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); @@ -1915,11 +2100,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_ @@ -1939,28 +2124,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. @@ -2001,22 +2184,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) \ @@ -2043,8 +2226,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) \ @@ -2064,17 +2247,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) @@ -2087,7 +2270,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: @@ -2160,33 +2343,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, @@ -2240,44 +2423,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; @@ -2285,35 +2480,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)); } @@ -2323,41 +2527,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; @@ -2365,12 +2575,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; @@ -2378,12 +2588,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; @@ -2391,12 +2601,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; @@ -2405,10 +2615,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); } @@ -2418,10 +2628,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); } @@ -2430,56 +2640,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)); } @@ -2491,26 +2708,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; @@ -2518,12 +2737,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; @@ -2531,12 +2750,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; @@ -2544,12 +2763,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; @@ -2557,12 +2776,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; @@ -2571,10 +2790,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); } @@ -2583,12 +2802,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; @@ -2596,59 +2815,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); @@ -2662,10 +2892,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); } @@ -2674,34 +2904,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); @@ -2714,42 +2953,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; @@ -2757,60 +3001,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); @@ -2824,22 +3095,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); } @@ -2849,9 +3120,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); @@ -2860,47 +3131,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); } @@ -2909,53 +3189,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; @@ -2964,10 +3253,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); } @@ -2976,57 +3265,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); @@ -3039,40 +3337,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); @@ -3082,10 +3391,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); } @@ -3094,50 +3403,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; @@ -3146,10 +3464,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); } @@ -3158,63 +3476,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); } @@ -3231,80 +3566,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); @@ -3314,9 +3694,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); @@ -3346,47 +3726,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; @@ -3394,38 +3774,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); } @@ -3448,12 +3841,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; @@ -3461,44 +3854,65 @@ 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_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 16)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); } +UPB_INLINE 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_unverified_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 7); } +UPB_INLINE bool google_protobuf_FieldOptions_unverified_lazy(const google_protobuf_FieldOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); +} +UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); } +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(20, 24), len); } UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 1); @@ -3524,58 +3938,67 @@ UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptio _upb_sethas(msg, 6); *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value; } +UPB_INLINE void google_protobuf_FieldOptions_set_unverified_lazy(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 7); + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; +} UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) { - return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len); + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), 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(20, 24), len, UPB_SIZE(2, 3), arena); } -UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); - bool ok = _upb_array_append_accessor2( - msg, UPB_SIZE(16, 16), UPB_SIZE(2, 3), &sub, arena); +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(20, 24), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } /* google.protobuf.OneofOptions */ -UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) { - return (google_protobuf_OneofOptions *)_upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_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; @@ -3583,34 +4006,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); } @@ -3625,12 +4057,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; @@ -3638,32 +4070,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); } @@ -3674,12 +4113,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; @@ -3687,32 +4126,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); } @@ -3723,12 +4169,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; @@ -3736,34 +4182,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); } @@ -3778,12 +4233,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; @@ -3791,61 +4246,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); @@ -3859,49 +4331,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); @@ -3910,42 +4391,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; @@ -3953,115 +4439,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; @@ -4069,51 +4569,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); @@ -4124,6 +4635,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 @@ -4132,19 +4649,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_ @@ -4153,288 +4657,373 @@ 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_FindFieldByNumber(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); +int upb_MethodDef_Index(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); +// Should only be directly called by tests. This variant lets us suppress +// the use of compiled-in tables, forcing a rebuild of the tables at runtime. +bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable); + +UPB_INLINE bool _upb_DefPool_LoadDefInit(upb_DefPool* s, + const _upb_DefPool_Init* init) { + return _upb_DefPool_LoadDefInitEx(s, init, false); +} #ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ +} /* extern "C" */ +#endif /* __cplusplus */ #endif /* UPB_DEF_H_ */ @@ -4455,141 +5044,141 @@ extern "C" { -extern upb_def_init google_protobuf_descriptor_proto_upbdefinit; +extern _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit; -UPB_INLINE const upb_msgdef *google_protobuf_FileDescriptorSet_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorSet"); +UPB_INLINE const upb_MessageDef *google_protobuf_FileDescriptorSet_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.FileDescriptorSet"); } -UPB_INLINE const upb_msgdef *google_protobuf_FileDescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_FileDescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.FileDescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_DescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_DescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.DescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_DescriptorProto_ExtensionRange_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto.ExtensionRange"); +UPB_INLINE const upb_MessageDef *google_protobuf_DescriptorProto_ExtensionRange_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.DescriptorProto.ExtensionRange"); } -UPB_INLINE const upb_msgdef *google_protobuf_DescriptorProto_ReservedRange_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto.ReservedRange"); +UPB_INLINE const upb_MessageDef *google_protobuf_DescriptorProto_ReservedRange_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.DescriptorProto.ReservedRange"); } -UPB_INLINE const upb_msgdef *google_protobuf_ExtensionRangeOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.ExtensionRangeOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_ExtensionRangeOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.ExtensionRangeOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_FieldDescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.FieldDescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_FieldDescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.FieldDescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_OneofDescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.OneofDescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_OneofDescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.OneofDescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_EnumDescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.EnumDescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_EnumDescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.EnumDescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_EnumDescriptorProto_EnumReservedRange_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.EnumDescriptorProto.EnumReservedRange"); +UPB_INLINE const upb_MessageDef *google_protobuf_EnumDescriptorProto_EnumReservedRange_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.EnumDescriptorProto.EnumReservedRange"); } -UPB_INLINE const upb_msgdef *google_protobuf_EnumValueDescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.EnumValueDescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_EnumValueDescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.EnumValueDescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_ServiceDescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.ServiceDescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_ServiceDescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.ServiceDescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_MethodDescriptorProto_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.MethodDescriptorProto"); +UPB_INLINE const upb_MessageDef *google_protobuf_MethodDescriptorProto_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.MethodDescriptorProto"); } -UPB_INLINE const upb_msgdef *google_protobuf_FileOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.FileOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_FileOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.FileOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_MessageOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.MessageOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_MessageOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.MessageOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_FieldOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.FieldOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_FieldOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.FieldOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_OneofOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.OneofOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_OneofOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.OneofOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_EnumOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.EnumOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_EnumOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.EnumOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_EnumValueOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.EnumValueOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_EnumValueOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.EnumValueOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_ServiceOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.ServiceOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_ServiceOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.ServiceOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_MethodOptions_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.MethodOptions"); +UPB_INLINE const upb_MessageDef *google_protobuf_MethodOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.MethodOptions"); } -UPB_INLINE const upb_msgdef *google_protobuf_UninterpretedOption_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption"); +UPB_INLINE const upb_MessageDef *google_protobuf_UninterpretedOption_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.UninterpretedOption"); } -UPB_INLINE const upb_msgdef *google_protobuf_UninterpretedOption_NamePart_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption.NamePart"); +UPB_INLINE const upb_MessageDef *google_protobuf_UninterpretedOption_NamePart_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.UninterpretedOption.NamePart"); } -UPB_INLINE const upb_msgdef *google_protobuf_SourceCodeInfo_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo"); +UPB_INLINE const upb_MessageDef *google_protobuf_SourceCodeInfo_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.SourceCodeInfo"); } -UPB_INLINE const upb_msgdef *google_protobuf_SourceCodeInfo_Location_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo.Location"); +UPB_INLINE const upb_MessageDef *google_protobuf_SourceCodeInfo_Location_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.SourceCodeInfo.Location"); } -UPB_INLINE const upb_msgdef *google_protobuf_GeneratedCodeInfo_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.GeneratedCodeInfo"); +UPB_INLINE const upb_MessageDef *google_protobuf_GeneratedCodeInfo_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.GeneratedCodeInfo"); } -UPB_INLINE const upb_msgdef *google_protobuf_GeneratedCodeInfo_Annotation_getmsgdef(upb_symtab *s) { - _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); - return upb_symtab_lookupmsg(s, "google.protobuf.GeneratedCodeInfo.Annotation"); +UPB_INLINE const upb_MessageDef *google_protobuf_GeneratedCodeInfo_Annotation_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "google.protobuf.GeneratedCodeInfo.Annotation"); } #ifdef __cplusplus @@ -4604,7 +5193,6 @@ UPB_INLINE const upb_msgdef *google_protobuf_GeneratedCodeInfo_Annotation_getmsg #define UPB_REFLECTION_H_ - #ifdef __cplusplus extern "C" { #endif @@ -4617,57 +5205,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); * } * @@ -4676,90 +5270,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 @@ -4774,19 +5387,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_ @@ -4799,11 +5410,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 @@ -4814,15 +5425,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/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c index 625008f5b0359..6f8a534f27e2a 100644 --- a/php/ext/google/protobuf/protobuf.c +++ b/php/ext/google/protobuf/protobuf.c @@ -62,11 +62,11 @@ ZEND_BEGIN_MODULE_GLOBALS(protobuf) // that all descriptors are loaded from the main thread. zval generated_pool; - // A upb_symtab that we are saving for the next request so that we don't have + // A upb_DefPool that we are saving for the next request so that we don't have // to rebuild it from scratch. When keep_descriptor_pool_after_request==true, - // we steal the upb_symtab from the global DescriptorPool object just before + // we steal the upb_DefPool from the global DescriptorPool object just before // destroying it. - upb_symtab *global_symtab; + upb_DefPool *global_symtab; // Object cache (see interface in protobuf.h). HashTable object_cache; @@ -85,7 +85,7 @@ ZEND_END_MODULE_GLOBALS(protobuf) void free_protobuf_globals(zend_protobuf_globals *globals) { zend_hash_destroy(&globals->name_msg_cache); zend_hash_destroy(&globals->name_enum_cache); - upb_symtab_free(globals->global_symtab); + upb_DefPool_Free(globals->global_symtab); globals->global_symtab = NULL; } @@ -171,9 +171,9 @@ static PHP_GINIT_FUNCTION(protobuf) { static PHP_RINIT_FUNCTION(protobuf) { // Create the global generated pool. // Reuse the symtab (if any) left to us by the last request. - upb_symtab *symtab = PROTOBUF_G(global_symtab); + upb_DefPool *symtab = PROTOBUF_G(global_symtab); if (!symtab) { - PROTOBUF_G(global_symtab) = symtab = upb_symtab_new(); + PROTOBUF_G(global_symtab) = symtab = upb_DefPool_New(); zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0); zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0); } @@ -246,20 +246,20 @@ bool ObjCache_Get(const void *upb_obj, zval *val) { // Name Cache. // ----------------------------------------------------------------------------- -void NameMap_AddMessage(const upb_msgdef *m) { - char *k = GetPhpClassname(upb_msgdef_file(m), upb_msgdef_fullname(m)); +void NameMap_AddMessage(const upb_MessageDef *m) { + char *k = GetPhpClassname(upb_MessageDef_File(m), upb_MessageDef_FullName(m)); zend_hash_str_add_ptr(&PROTOBUF_G(name_msg_cache), k, strlen(k), (void*)m); free(k); } -void NameMap_AddEnum(const upb_enumdef *e) { - char *k = GetPhpClassname(upb_enumdef_file(e), upb_enumdef_fullname(e)); +void NameMap_AddEnum(const upb_EnumDef *e) { + char *k = GetPhpClassname(upb_EnumDef_File(e), upb_EnumDef_FullName(e)); zend_hash_str_add_ptr(&PROTOBUF_G(name_enum_cache), k, strlen(k), (void*)e); free(k); } -const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce) { - const upb_msgdef *ret = +const upb_MessageDef *NameMap_GetMessage(zend_class_entry *ce) { + const upb_MessageDef *ret = zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name); if (!ret && ce->create_object) { @@ -282,8 +282,8 @@ const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce) { return ret; } -const upb_enumdef *NameMap_GetEnum(zend_class_entry *ce) { - const upb_enumdef *ret = +const upb_EnumDef *NameMap_GetEnum(zend_class_entry *ce) { + const upb_EnumDef *ret = zend_hash_find_ptr(&PROTOBUF_G(name_enum_cache), ce->name); return ret; } diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 41ae2718b461e..46c560810a2ce 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -82,6 +82,42 @@ const zval *get_generated_pool(); // PHP 7.2.0. #if PHP_VERSION_ID < 70200 #define zend_ce_countable spl_ce_Countable +#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \ + ZEND_BEGIN_ARG_INFO_EX(name, return_reference, required_num_args, allow_null) +#endif + +// polyfill for ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX, which changes between 7.1 and 7.2 +#if PHP_VERSION_ID < 70200 +#define PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, /*class_name*/ 0, allow_null) +#else +#define PROTOBUF_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) +#endif + +// In PHP 8.1, mismatched tentative return types emit a deprecation notice. +// https://wiki.php.net/rfc/internal_method_return_types +// +// When compiling for earlier php versions, the return type is dropped. +#if PHP_VERSION_ID < 80100 +#define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_INFO_EX(name, return_reference, required_num_args, allow_null) +#endif + +#ifndef IS_VOID +#define IS_VOID 99 +#endif + +#ifndef IS_MIXED +#define IS_MIXED 99 +#endif + +#ifndef _IS_BOOL +#define _IS_BOOL 99 +#endif + +#ifndef IS_LONG +#define IS_LONG 99 #endif ZEND_BEGIN_ARG_INFO(arginfo_void, 0) @@ -91,16 +127,16 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() -#define PHP_PROTOBUF_VERSION "3.19.4" +#define PHP_PROTOBUF_VERSION "3.20.0RC2" // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: -// * upb_msg* -> Message -// * upb_array* -> RepeatedField -// * upb_map*, -> MapField -// * upb_msgdef* -> Descriptor -// * upb_enumdef* -> EnumDescriptor -// * upb_msgdef* -> Descriptor +// * upb_Message* -> Message +// * upb_Array* -> RepeatedField +// * upb_Map*, -> MapField +// * upb_MessageDef* -> Descriptor +// * upb_EnumDef* -> EnumDescriptor +// * upb_MessageDef* -> Descriptor // // Each wrapped object should add itself to the map when it is constructed, and // remove itself from the map when it is destroyed. This is how we ensure that @@ -113,12 +149,12 @@ bool ObjCache_Get(const void *key, zval *val); // PHP class name map. This is necessary because the pb_name->php_class_name // transformation is non-reversible, so when we need to look up a msgdef or // enumdef by PHP class, we can't turn the class name into a pb_name. -// * php_class_name -> upb_msgdef* -// * php_class_name -> upb_enumdef* -void NameMap_AddMessage(const upb_msgdef *m); -void NameMap_AddEnum(const upb_enumdef *m); -const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce); -const upb_enumdef *NameMap_GetEnum(zend_class_entry *ce); +// * php_class_name -> upb_MessageDef* +// * php_class_name -> upb_EnumDef* +void NameMap_AddMessage(const upb_MessageDef *m); +void NameMap_AddEnum(const upb_EnumDef *m); +const upb_MessageDef *NameMap_GetMessage(zend_class_entry *ce); +const upb_EnumDef *NameMap_GetEnum(zend_class_entry *ce); // Add this descriptor object to the global list of descriptors that will be // kept alive for the duration of the request but destroyed when the request diff --git a/php/ext/google/protobuf/wkt.inc b/php/ext/google/protobuf/wkt.inc index df3cce9136d96..4579c7e30dc4d 100644 --- a/php/ext/google/protobuf/wkt.inc +++ b/php/ext/google/protobuf/wkt.inc @@ -66,8 +66,8 @@ static PHP_METHOD(google_protobuf_Any, __construct) { static PHP_METHOD(google_protobuf_Any, getTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "type_url"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -75,8 +75,8 @@ static PHP_METHOD(google_protobuf_Any, getTypeUrl) { static PHP_METHOD(google_protobuf_Any, setTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "type_url"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -88,8 +88,8 @@ static PHP_METHOD(google_protobuf_Any, setTypeUrl) { static PHP_METHOD(google_protobuf_Any, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -97,8 +97,8 @@ static PHP_METHOD(google_protobuf_Any, getValue) { static PHP_METHOD(google_protobuf_Any, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -211,8 +211,8 @@ static PHP_METHOD(google_protobuf_Api, __construct) { static PHP_METHOD(google_protobuf_Api, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -220,8 +220,8 @@ static PHP_METHOD(google_protobuf_Api, getName) { static PHP_METHOD(google_protobuf_Api, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -233,8 +233,8 @@ static PHP_METHOD(google_protobuf_Api, setName) { static PHP_METHOD(google_protobuf_Api, getMethods) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "methods"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "methods"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -242,8 +242,8 @@ static PHP_METHOD(google_protobuf_Api, getMethods) { static PHP_METHOD(google_protobuf_Api, setMethods) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "methods"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "methods"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -255,8 +255,8 @@ static PHP_METHOD(google_protobuf_Api, setMethods) { static PHP_METHOD(google_protobuf_Api, getOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -264,8 +264,8 @@ static PHP_METHOD(google_protobuf_Api, getOptions) { static PHP_METHOD(google_protobuf_Api, setOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -277,8 +277,8 @@ static PHP_METHOD(google_protobuf_Api, setOptions) { static PHP_METHOD(google_protobuf_Api, getVersion) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "version"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "version"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -286,8 +286,8 @@ static PHP_METHOD(google_protobuf_Api, getVersion) { static PHP_METHOD(google_protobuf_Api, setVersion) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "version"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "version"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -299,8 +299,8 @@ static PHP_METHOD(google_protobuf_Api, setVersion) { static PHP_METHOD(google_protobuf_Api, getSourceContext) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "source_context"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "source_context"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -308,8 +308,8 @@ static PHP_METHOD(google_protobuf_Api, getSourceContext) { static PHP_METHOD(google_protobuf_Api, setSourceContext) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "source_context"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "source_context"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -321,8 +321,8 @@ static PHP_METHOD(google_protobuf_Api, setSourceContext) { static PHP_METHOD(google_protobuf_Api, getMixins) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "mixins"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "mixins"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -330,8 +330,8 @@ static PHP_METHOD(google_protobuf_Api, getMixins) { static PHP_METHOD(google_protobuf_Api, setMixins) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "mixins"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "mixins"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -343,8 +343,8 @@ static PHP_METHOD(google_protobuf_Api, setMixins) { static PHP_METHOD(google_protobuf_Api, getSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -352,8 +352,8 @@ static PHP_METHOD(google_protobuf_Api, getSyntax) { static PHP_METHOD(google_protobuf_Api, setSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -405,8 +405,8 @@ static PHP_METHOD(google_protobuf_Method, __construct) { static PHP_METHOD(google_protobuf_Method, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -414,8 +414,8 @@ static PHP_METHOD(google_protobuf_Method, getName) { static PHP_METHOD(google_protobuf_Method, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -427,8 +427,8 @@ static PHP_METHOD(google_protobuf_Method, setName) { static PHP_METHOD(google_protobuf_Method, getRequestTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "request_type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "request_type_url"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -436,8 +436,8 @@ static PHP_METHOD(google_protobuf_Method, getRequestTypeUrl) { static PHP_METHOD(google_protobuf_Method, setRequestTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "request_type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "request_type_url"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -449,8 +449,8 @@ static PHP_METHOD(google_protobuf_Method, setRequestTypeUrl) { static PHP_METHOD(google_protobuf_Method, getRequestStreaming) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "request_streaming"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "request_streaming"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -458,8 +458,8 @@ static PHP_METHOD(google_protobuf_Method, getRequestStreaming) { static PHP_METHOD(google_protobuf_Method, setRequestStreaming) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "request_streaming"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "request_streaming"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -471,8 +471,8 @@ static PHP_METHOD(google_protobuf_Method, setRequestStreaming) { static PHP_METHOD(google_protobuf_Method, getResponseTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "response_type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "response_type_url"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -480,8 +480,8 @@ static PHP_METHOD(google_protobuf_Method, getResponseTypeUrl) { static PHP_METHOD(google_protobuf_Method, setResponseTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "response_type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "response_type_url"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -493,8 +493,8 @@ static PHP_METHOD(google_protobuf_Method, setResponseTypeUrl) { static PHP_METHOD(google_protobuf_Method, getResponseStreaming) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "response_streaming"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "response_streaming"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -502,8 +502,8 @@ static PHP_METHOD(google_protobuf_Method, getResponseStreaming) { static PHP_METHOD(google_protobuf_Method, setResponseStreaming) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "response_streaming"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "response_streaming"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -515,8 +515,8 @@ static PHP_METHOD(google_protobuf_Method, setResponseStreaming) { static PHP_METHOD(google_protobuf_Method, getOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -524,8 +524,8 @@ static PHP_METHOD(google_protobuf_Method, getOptions) { static PHP_METHOD(google_protobuf_Method, setOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -537,8 +537,8 @@ static PHP_METHOD(google_protobuf_Method, setOptions) { static PHP_METHOD(google_protobuf_Method, getSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -546,8 +546,8 @@ static PHP_METHOD(google_protobuf_Method, getSyntax) { static PHP_METHOD(google_protobuf_Method, setSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -599,8 +599,8 @@ static PHP_METHOD(google_protobuf_Mixin, __construct) { static PHP_METHOD(google_protobuf_Mixin, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -608,8 +608,8 @@ static PHP_METHOD(google_protobuf_Mixin, getName) { static PHP_METHOD(google_protobuf_Mixin, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -621,8 +621,8 @@ static PHP_METHOD(google_protobuf_Mixin, setName) { static PHP_METHOD(google_protobuf_Mixin, getRoot) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "root"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "root"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -630,8 +630,8 @@ static PHP_METHOD(google_protobuf_Mixin, getRoot) { static PHP_METHOD(google_protobuf_Mixin, setRoot) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "root"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "root"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -714,8 +714,8 @@ static PHP_METHOD(google_protobuf_Duration, __construct) { static PHP_METHOD(google_protobuf_Duration, getSeconds) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "seconds"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "seconds"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -723,8 +723,8 @@ static PHP_METHOD(google_protobuf_Duration, getSeconds) { static PHP_METHOD(google_protobuf_Duration, setSeconds) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "seconds"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "seconds"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -736,8 +736,8 @@ static PHP_METHOD(google_protobuf_Duration, setSeconds) { static PHP_METHOD(google_protobuf_Duration, getNanos) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "nanos"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "nanos"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -745,8 +745,8 @@ static PHP_METHOD(google_protobuf_Duration, getNanos) { static PHP_METHOD(google_protobuf_Duration, setNanos) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "nanos"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "nanos"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -893,8 +893,8 @@ static PHP_METHOD(google_protobuf_FieldMask, __construct) { static PHP_METHOD(google_protobuf_FieldMask, getPaths) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "paths"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "paths"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -902,8 +902,8 @@ static PHP_METHOD(google_protobuf_FieldMask, getPaths) { static PHP_METHOD(google_protobuf_FieldMask, setPaths) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "paths"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "paths"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -984,8 +984,8 @@ static PHP_METHOD(google_protobuf_SourceContext, __construct) { static PHP_METHOD(google_protobuf_SourceContext, getFileName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "file_name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "file_name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -993,8 +993,8 @@ static PHP_METHOD(google_protobuf_SourceContext, getFileName) { static PHP_METHOD(google_protobuf_SourceContext, setFileName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "file_name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "file_name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1091,8 +1091,8 @@ static PHP_METHOD(google_protobuf_Struct, __construct) { static PHP_METHOD(google_protobuf_Struct, getFields) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "fields"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "fields"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1100,8 +1100,8 @@ static PHP_METHOD(google_protobuf_Struct, getFields) { static PHP_METHOD(google_protobuf_Struct, setFields) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "fields"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "fields"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1141,8 +1141,8 @@ static PHP_METHOD(google_protobuf_Struct_FieldsEntry, __construct) { static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getKey) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "key"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "key"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1150,8 +1150,8 @@ static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getKey) { static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setKey) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "key"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "key"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1163,8 +1163,8 @@ static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setKey) { static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1172,8 +1172,8 @@ static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getValue) { static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1215,8 +1215,8 @@ static PHP_METHOD(google_protobuf_Value, __construct) { static PHP_METHOD(google_protobuf_Value, getNullValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "null_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "null_value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1224,8 +1224,8 @@ static PHP_METHOD(google_protobuf_Value, getNullValue) { static PHP_METHOD(google_protobuf_Value, setNullValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "null_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "null_value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1237,8 +1237,8 @@ static PHP_METHOD(google_protobuf_Value, setNullValue) { static PHP_METHOD(google_protobuf_Value, getNumberValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "number_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "number_value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1246,8 +1246,8 @@ static PHP_METHOD(google_protobuf_Value, getNumberValue) { static PHP_METHOD(google_protobuf_Value, setNumberValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "number_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "number_value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1259,8 +1259,8 @@ static PHP_METHOD(google_protobuf_Value, setNumberValue) { static PHP_METHOD(google_protobuf_Value, getStringValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "string_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "string_value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1268,8 +1268,8 @@ static PHP_METHOD(google_protobuf_Value, getStringValue) { static PHP_METHOD(google_protobuf_Value, setStringValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "string_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "string_value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1281,8 +1281,8 @@ static PHP_METHOD(google_protobuf_Value, setStringValue) { static PHP_METHOD(google_protobuf_Value, getBoolValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "bool_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "bool_value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1290,8 +1290,8 @@ static PHP_METHOD(google_protobuf_Value, getBoolValue) { static PHP_METHOD(google_protobuf_Value, setBoolValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "bool_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "bool_value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1303,8 +1303,8 @@ static PHP_METHOD(google_protobuf_Value, setBoolValue) { static PHP_METHOD(google_protobuf_Value, getStructValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "struct_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "struct_value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1312,8 +1312,8 @@ static PHP_METHOD(google_protobuf_Value, getStructValue) { static PHP_METHOD(google_protobuf_Value, setStructValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "struct_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "struct_value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1325,8 +1325,8 @@ static PHP_METHOD(google_protobuf_Value, setStructValue) { static PHP_METHOD(google_protobuf_Value, getListValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "list_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "list_value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1334,8 +1334,8 @@ static PHP_METHOD(google_protobuf_Value, getListValue) { static PHP_METHOD(google_protobuf_Value, setListValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "list_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "list_value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1347,10 +1347,11 @@ static PHP_METHOD(google_protobuf_Value, setListValue) { static PHP_METHOD(google_protobuf_Value, getKind) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef, - "kind"); - const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof); - RETURN_STRING(field ? upb_fielddef_name(field) : ""); + const upb_OneofDef *oneof = upb_MessageDef_FindOneofByName( + intern->desc->msgdef, "kind"); + const upb_FieldDef *field = + upb_Message_WhichOneof(intern->msg, oneof); + RETURN_STRING(field ? upb_FieldDef_Name(field) : ""); } static zend_function_entry google_protobuf_Value_phpmethods[] = { PHP_ME(google_protobuf_Value, __construct, arginfo_construct, ZEND_ACC_PUBLIC) @@ -1393,8 +1394,8 @@ static PHP_METHOD(google_protobuf_ListValue, __construct) { static PHP_METHOD(google_protobuf_ListValue, getValues) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "values"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "values"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1402,8 +1403,8 @@ static PHP_METHOD(google_protobuf_ListValue, getValues) { static PHP_METHOD(google_protobuf_ListValue, setValues) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "values"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "values"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1438,44 +1439,45 @@ zend_class_entry* google_protobuf_NullValue_ce; PHP_METHOD(google_protobuf_NullValue, name) { google_protobuf_struct_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue"); - const char *name; + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.NullValue"); zend_long value; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) == FAILURE) { return; } - name = upb_enumdef_iton(e, value); - if (!name) { + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(e, value); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\NullValue has no name " "defined for value " ZEND_LONG_FMT ".", value); return; } - RETURN_STRING(name); + RETURN_STRING(upb_EnumValueDef_Name(ev)); } PHP_METHOD(google_protobuf_NullValue, value) { google_protobuf_struct_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue"); + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.NullValue"); char *name = NULL; size_t name_len; - int32_t num; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { return; } - if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize( + e, name, name_len); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\NullValue has no value " "defined for name %s.", name); return; } - RETURN_LONG(num); + RETURN_LONG(upb_EnumValueDef_Number(ev)); } static zend_function_entry google_protobuf_NullValue_phpmethods[] = { @@ -1603,8 +1605,8 @@ static PHP_METHOD(google_protobuf_Type, __construct) { static PHP_METHOD(google_protobuf_Type, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1612,8 +1614,8 @@ static PHP_METHOD(google_protobuf_Type, getName) { static PHP_METHOD(google_protobuf_Type, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1625,8 +1627,8 @@ static PHP_METHOD(google_protobuf_Type, setName) { static PHP_METHOD(google_protobuf_Type, getFields) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "fields"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "fields"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1634,8 +1636,8 @@ static PHP_METHOD(google_protobuf_Type, getFields) { static PHP_METHOD(google_protobuf_Type, setFields) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "fields"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "fields"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1647,8 +1649,8 @@ static PHP_METHOD(google_protobuf_Type, setFields) { static PHP_METHOD(google_protobuf_Type, getOneofs) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "oneofs"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "oneofs"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1656,8 +1658,8 @@ static PHP_METHOD(google_protobuf_Type, getOneofs) { static PHP_METHOD(google_protobuf_Type, setOneofs) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "oneofs"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "oneofs"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1669,8 +1671,8 @@ static PHP_METHOD(google_protobuf_Type, setOneofs) { static PHP_METHOD(google_protobuf_Type, getOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1678,8 +1680,8 @@ static PHP_METHOD(google_protobuf_Type, getOptions) { static PHP_METHOD(google_protobuf_Type, setOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1691,8 +1693,8 @@ static PHP_METHOD(google_protobuf_Type, setOptions) { static PHP_METHOD(google_protobuf_Type, getSourceContext) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "source_context"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "source_context"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1700,8 +1702,8 @@ static PHP_METHOD(google_protobuf_Type, getSourceContext) { static PHP_METHOD(google_protobuf_Type, setSourceContext) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "source_context"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "source_context"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1713,8 +1715,8 @@ static PHP_METHOD(google_protobuf_Type, setSourceContext) { static PHP_METHOD(google_protobuf_Type, getSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1722,8 +1724,8 @@ static PHP_METHOD(google_protobuf_Type, getSyntax) { static PHP_METHOD(google_protobuf_Type, setSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1773,8 +1775,8 @@ static PHP_METHOD(google_protobuf_Field, __construct) { static PHP_METHOD(google_protobuf_Field, getKind) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "kind"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "kind"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1782,8 +1784,8 @@ static PHP_METHOD(google_protobuf_Field, getKind) { static PHP_METHOD(google_protobuf_Field, setKind) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "kind"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "kind"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1795,8 +1797,8 @@ static PHP_METHOD(google_protobuf_Field, setKind) { static PHP_METHOD(google_protobuf_Field, getCardinality) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "cardinality"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "cardinality"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1804,8 +1806,8 @@ static PHP_METHOD(google_protobuf_Field, getCardinality) { static PHP_METHOD(google_protobuf_Field, setCardinality) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "cardinality"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "cardinality"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1817,8 +1819,8 @@ static PHP_METHOD(google_protobuf_Field, setCardinality) { static PHP_METHOD(google_protobuf_Field, getNumber) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "number"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "number"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1826,8 +1828,8 @@ static PHP_METHOD(google_protobuf_Field, getNumber) { static PHP_METHOD(google_protobuf_Field, setNumber) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "number"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "number"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1839,8 +1841,8 @@ static PHP_METHOD(google_protobuf_Field, setNumber) { static PHP_METHOD(google_protobuf_Field, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1848,8 +1850,8 @@ static PHP_METHOD(google_protobuf_Field, getName) { static PHP_METHOD(google_protobuf_Field, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1861,8 +1863,8 @@ static PHP_METHOD(google_protobuf_Field, setName) { static PHP_METHOD(google_protobuf_Field, getTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "type_url"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1870,8 +1872,8 @@ static PHP_METHOD(google_protobuf_Field, getTypeUrl) { static PHP_METHOD(google_protobuf_Field, setTypeUrl) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "type_url"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "type_url"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1883,8 +1885,8 @@ static PHP_METHOD(google_protobuf_Field, setTypeUrl) { static PHP_METHOD(google_protobuf_Field, getOneofIndex) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "oneof_index"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "oneof_index"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1892,8 +1894,8 @@ static PHP_METHOD(google_protobuf_Field, getOneofIndex) { static PHP_METHOD(google_protobuf_Field, setOneofIndex) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "oneof_index"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "oneof_index"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1905,8 +1907,8 @@ static PHP_METHOD(google_protobuf_Field, setOneofIndex) { static PHP_METHOD(google_protobuf_Field, getPacked) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "packed"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "packed"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1914,8 +1916,8 @@ static PHP_METHOD(google_protobuf_Field, getPacked) { static PHP_METHOD(google_protobuf_Field, setPacked) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "packed"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "packed"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1927,8 +1929,8 @@ static PHP_METHOD(google_protobuf_Field, setPacked) { static PHP_METHOD(google_protobuf_Field, getOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1936,8 +1938,8 @@ static PHP_METHOD(google_protobuf_Field, getOptions) { static PHP_METHOD(google_protobuf_Field, setOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1949,8 +1951,8 @@ static PHP_METHOD(google_protobuf_Field, setOptions) { static PHP_METHOD(google_protobuf_Field, getJsonName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "json_name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "json_name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1958,8 +1960,8 @@ static PHP_METHOD(google_protobuf_Field, getJsonName) { static PHP_METHOD(google_protobuf_Field, setJsonName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "json_name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "json_name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -1971,8 +1973,8 @@ static PHP_METHOD(google_protobuf_Field, setJsonName) { static PHP_METHOD(google_protobuf_Field, getDefaultValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "default_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "default_value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -1980,8 +1982,8 @@ static PHP_METHOD(google_protobuf_Field, getDefaultValue) { static PHP_METHOD(google_protobuf_Field, setDefaultValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "default_value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "default_value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2034,44 +2036,45 @@ zend_class_entry* google_protobuf_Field_Kind_ce; PHP_METHOD(google_protobuf_Field_Kind, name) { google_protobuf_type_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind"); - const char *name; + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.Field.Kind"); zend_long value; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) == FAILURE) { return; } - name = upb_enumdef_iton(e, value); - if (!name) { + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(e, value); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\Field\\Kind has no name " "defined for value " ZEND_LONG_FMT ".", value); return; } - RETURN_STRING(name); + RETURN_STRING(upb_EnumValueDef_Name(ev)); } PHP_METHOD(google_protobuf_Field_Kind, value) { google_protobuf_type_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind"); + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.Field.Kind"); char *name = NULL; size_t name_len; - int32_t num; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { return; } - if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize( + e, name, name_len); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\Field\\Kind has no value " "defined for name %s.", name); return; } - RETURN_LONG(num); + RETURN_LONG(upb_EnumValueDef_Number(ev)); } static zend_function_entry google_protobuf_Field_Kind_phpmethods[] = { @@ -2133,44 +2136,45 @@ zend_class_entry* google_protobuf_Field_Cardinality_ce; PHP_METHOD(google_protobuf_Field_Cardinality, name) { google_protobuf_type_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality"); - const char *name; + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.Field.Cardinality"); zend_long value; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) == FAILURE) { return; } - name = upb_enumdef_iton(e, value); - if (!name) { + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(e, value); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\Field\\Cardinality has no name " "defined for value " ZEND_LONG_FMT ".", value); return; } - RETURN_STRING(name); + RETURN_STRING(upb_EnumValueDef_Name(ev)); } PHP_METHOD(google_protobuf_Field_Cardinality, value) { google_protobuf_type_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality"); + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.Field.Cardinality"); char *name = NULL; size_t name_len; - int32_t num; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { return; } - if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize( + e, name, name_len); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\Field\\Cardinality has no value " "defined for name %s.", name); return; } - RETURN_LONG(num); + RETURN_LONG(upb_EnumValueDef_Number(ev)); } static zend_function_entry google_protobuf_Field_Cardinality_phpmethods[] = { @@ -2207,8 +2211,8 @@ static PHP_METHOD(google_protobuf_Enum, __construct) { static PHP_METHOD(google_protobuf_Enum, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2216,8 +2220,8 @@ static PHP_METHOD(google_protobuf_Enum, getName) { static PHP_METHOD(google_protobuf_Enum, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2229,8 +2233,8 @@ static PHP_METHOD(google_protobuf_Enum, setName) { static PHP_METHOD(google_protobuf_Enum, getEnumvalue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "enumvalue"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "enumvalue"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2238,8 +2242,8 @@ static PHP_METHOD(google_protobuf_Enum, getEnumvalue) { static PHP_METHOD(google_protobuf_Enum, setEnumvalue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "enumvalue"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "enumvalue"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2251,8 +2255,8 @@ static PHP_METHOD(google_protobuf_Enum, setEnumvalue) { static PHP_METHOD(google_protobuf_Enum, getOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2260,8 +2264,8 @@ static PHP_METHOD(google_protobuf_Enum, getOptions) { static PHP_METHOD(google_protobuf_Enum, setOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2273,8 +2277,8 @@ static PHP_METHOD(google_protobuf_Enum, setOptions) { static PHP_METHOD(google_protobuf_Enum, getSourceContext) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "source_context"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "source_context"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2282,8 +2286,8 @@ static PHP_METHOD(google_protobuf_Enum, getSourceContext) { static PHP_METHOD(google_protobuf_Enum, setSourceContext) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "source_context"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "source_context"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2295,8 +2299,8 @@ static PHP_METHOD(google_protobuf_Enum, setSourceContext) { static PHP_METHOD(google_protobuf_Enum, getSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2304,8 +2308,8 @@ static PHP_METHOD(google_protobuf_Enum, getSyntax) { static PHP_METHOD(google_protobuf_Enum, setSyntax) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "syntax"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "syntax"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2353,8 +2357,8 @@ static PHP_METHOD(google_protobuf_EnumValue, __construct) { static PHP_METHOD(google_protobuf_EnumValue, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2362,8 +2366,8 @@ static PHP_METHOD(google_protobuf_EnumValue, getName) { static PHP_METHOD(google_protobuf_EnumValue, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2375,8 +2379,8 @@ static PHP_METHOD(google_protobuf_EnumValue, setName) { static PHP_METHOD(google_protobuf_EnumValue, getNumber) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "number"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "number"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2384,8 +2388,8 @@ static PHP_METHOD(google_protobuf_EnumValue, getNumber) { static PHP_METHOD(google_protobuf_EnumValue, setNumber) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "number"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "number"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2397,8 +2401,8 @@ static PHP_METHOD(google_protobuf_EnumValue, setNumber) { static PHP_METHOD(google_protobuf_EnumValue, getOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2406,8 +2410,8 @@ static PHP_METHOD(google_protobuf_EnumValue, getOptions) { static PHP_METHOD(google_protobuf_EnumValue, setOptions) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "options"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "options"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2451,8 +2455,8 @@ static PHP_METHOD(google_protobuf_Option, __construct) { static PHP_METHOD(google_protobuf_Option, getName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2460,8 +2464,8 @@ static PHP_METHOD(google_protobuf_Option, getName) { static PHP_METHOD(google_protobuf_Option, setName) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "name"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "name"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2473,8 +2477,8 @@ static PHP_METHOD(google_protobuf_Option, setName) { static PHP_METHOD(google_protobuf_Option, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2482,8 +2486,8 @@ static PHP_METHOD(google_protobuf_Option, getValue) { static PHP_METHOD(google_protobuf_Option, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2520,44 +2524,45 @@ zend_class_entry* google_protobuf_Syntax_ce; PHP_METHOD(google_protobuf_Syntax, name) { google_protobuf_type_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax"); - const char *name; + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.Syntax"); zend_long value; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) == FAILURE) { return; } - name = upb_enumdef_iton(e, value); - if (!name) { + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(e, value); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\Syntax has no name " "defined for value " ZEND_LONG_FMT ".", value); return; } - RETURN_STRING(name); + RETURN_STRING(upb_EnumValueDef_Name(ev)); } PHP_METHOD(google_protobuf_Syntax, value) { google_protobuf_type_proto_AddDescriptor(); - const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); - const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax"); + const upb_DefPool *symtab = DescriptorPool_GetSymbolTable(); + const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, "google.protobuf.Syntax"); char *name = NULL; size_t name_len; - int32_t num; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { return; } - if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize( + e, name, name_len); + if (!ev) { zend_throw_exception_ex(NULL, 0, "Google\\Protobuf\\Syntax has no value " "defined for name %s.", name); return; } - RETURN_LONG(num); + RETURN_LONG(upb_EnumValueDef_Number(ev)); } static zend_function_entry google_protobuf_Syntax_phpmethods[] = { @@ -2631,8 +2636,8 @@ static PHP_METHOD(google_protobuf_Timestamp, __construct) { static PHP_METHOD(google_protobuf_Timestamp, getSeconds) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "seconds"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "seconds"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2640,8 +2645,8 @@ static PHP_METHOD(google_protobuf_Timestamp, getSeconds) { static PHP_METHOD(google_protobuf_Timestamp, setSeconds) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "seconds"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "seconds"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2653,8 +2658,8 @@ static PHP_METHOD(google_protobuf_Timestamp, setSeconds) { static PHP_METHOD(google_protobuf_Timestamp, getNanos) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "nanos"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "nanos"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2662,8 +2667,8 @@ static PHP_METHOD(google_protobuf_Timestamp, getNanos) { static PHP_METHOD(google_protobuf_Timestamp, setNanos) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "nanos"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "nanos"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2761,8 +2766,8 @@ static PHP_METHOD(google_protobuf_DoubleValue, __construct) { static PHP_METHOD(google_protobuf_DoubleValue, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2770,8 +2775,8 @@ static PHP_METHOD(google_protobuf_DoubleValue, getValue) { static PHP_METHOD(google_protobuf_DoubleValue, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2811,8 +2816,8 @@ static PHP_METHOD(google_protobuf_FloatValue, __construct) { static PHP_METHOD(google_protobuf_FloatValue, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2820,8 +2825,8 @@ static PHP_METHOD(google_protobuf_FloatValue, getValue) { static PHP_METHOD(google_protobuf_FloatValue, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2861,8 +2866,8 @@ static PHP_METHOD(google_protobuf_Int64Value, __construct) { static PHP_METHOD(google_protobuf_Int64Value, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2870,8 +2875,8 @@ static PHP_METHOD(google_protobuf_Int64Value, getValue) { static PHP_METHOD(google_protobuf_Int64Value, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2911,8 +2916,8 @@ static PHP_METHOD(google_protobuf_UInt64Value, __construct) { static PHP_METHOD(google_protobuf_UInt64Value, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2920,8 +2925,8 @@ static PHP_METHOD(google_protobuf_UInt64Value, getValue) { static PHP_METHOD(google_protobuf_UInt64Value, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -2961,8 +2966,8 @@ static PHP_METHOD(google_protobuf_Int32Value, __construct) { static PHP_METHOD(google_protobuf_Int32Value, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -2970,8 +2975,8 @@ static PHP_METHOD(google_protobuf_Int32Value, getValue) { static PHP_METHOD(google_protobuf_Int32Value, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -3011,8 +3016,8 @@ static PHP_METHOD(google_protobuf_UInt32Value, __construct) { static PHP_METHOD(google_protobuf_UInt32Value, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -3020,8 +3025,8 @@ static PHP_METHOD(google_protobuf_UInt32Value, getValue) { static PHP_METHOD(google_protobuf_UInt32Value, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -3061,8 +3066,8 @@ static PHP_METHOD(google_protobuf_BoolValue, __construct) { static PHP_METHOD(google_protobuf_BoolValue, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -3070,8 +3075,8 @@ static PHP_METHOD(google_protobuf_BoolValue, getValue) { static PHP_METHOD(google_protobuf_BoolValue, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -3111,8 +3116,8 @@ static PHP_METHOD(google_protobuf_StringValue, __construct) { static PHP_METHOD(google_protobuf_StringValue, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -3120,8 +3125,8 @@ static PHP_METHOD(google_protobuf_StringValue, getValue) { static PHP_METHOD(google_protobuf_StringValue, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { @@ -3161,8 +3166,8 @@ static PHP_METHOD(google_protobuf_BytesValue, __construct) { static PHP_METHOD(google_protobuf_BytesValue, getValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval ret; Message_get(intern, f, &ret); RETURN_COPY_VALUE(&ret); @@ -3170,8 +3175,8 @@ static PHP_METHOD(google_protobuf_BytesValue, getValue) { static PHP_METHOD(google_protobuf_BytesValue, setValue) { Message* intern = (Message*)Z_OBJ_P(getThis()); - const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, - "value"); + const upb_FieldDef *f = upb_MessageDef_FindFieldByName( + intern->desc->msgdef, "value"); zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) { diff --git a/php/release.sh b/php/release.sh index 6b0baac78ff57..9a4b139126522 100755 --- a/php/release.sh +++ b/php/release.sh @@ -30,7 +30,11 @@ mv ../protobuf/composer.json composer.json sed -i 's|php/src|src|g' composer.json git add . git commit -m "$VERSION" -git tag "$VERSION" +if [ $(git tag -l "$VERSION") ]; then + echo "tag $VERSION already exists" +else + git tag "$VERSION" +fi popd # Clean up 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/Any.php b/php/src/Google/Protobuf/Any.php index 8fdc3c483d22a..cc64bad3db307 100644 --- a/php/src/Google/Protobuf/Any.php +++ b/php/src/Google/Protobuf/Any.php @@ -28,7 +28,7 @@ * if (any.is(Foo.class)) { * foo = any.unpack(Foo.class); * } - * Example 3: Pack and unpack a message in Python. + * Example 3: Pack and unpack a message in Python. * foo = Foo(...) * any = Any() * any.Pack(foo) @@ -36,7 +36,7 @@ * if any.Is(Foo.DESCRIPTOR): * any.Unpack(foo) * ... - * Example 4: Pack and unpack a message in Go + * Example 4: Pack and unpack a message in Go * foo := &pb.Foo{...} * any, err := anypb.New(foo) * if err != nil { @@ -53,7 +53,6 @@ * in the type URL, for example "foo.bar.com/x/y.z" will yield type * name "y.z". * JSON - * ==== * The JSON representation of an `Any` value uses the regular * representation of the deserialized, embedded message, with an * additional field `@type` which contains the type URL. Example: diff --git a/php/src/Google/Protobuf/Internal/DescriptorPool.php b/php/src/Google/Protobuf/Internal/DescriptorPool.php index 2880cee641b2a..1468a02380d9e 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorPool.php +++ b/php/src/Google/Protobuf/Internal/DescriptorPool.php @@ -159,7 +159,7 @@ private function crossLink(Descriptor $desc) if (is_null($subdesc)) { trigger_error( 'proto not added: ' . $proto - . " for " . $desc->getFullName(), E_ERROR); + . " for " . $desc->getFullName(), E_USER_ERROR); } $field->setMessageType($subdesc); break; 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/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php index 1dd6645bcd0ef..4b152839ec5e5 100644 --- a/php/src/Google/Protobuf/Internal/GPBUtil.php +++ b/php/src/Google/Protobuf/Internal/GPBUtil.php @@ -37,6 +37,7 @@ use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\MapField; +use function bccomp; function camel2underscore($input) { preg_match_all( @@ -283,12 +284,12 @@ public static function getClassNamePrefix( "function"=>0, "global"=>0, "goto"=>0, "if"=>0, "implements"=>0, "include"=>0, "include_once"=>0, "instanceof"=>0, "insteadof"=>0, "interface"=>0, "isset"=>0, "list"=>0, "match"=>0, "namespace"=>0, - "new"=>0, "or"=>0, "print"=>0, "private"=>0, "protected"=>0, - "public"=>0, "require"=>0, "require_once"=>0, "return"=>0, - "static"=>0, "switch"=>0, "throw"=>0, "trait"=>0, "try"=>0, - "unset"=>0, "use"=>0, "var"=>0, "while"=>0, "xor"=>0, "yield"=>0, - "int"=>0, "float"=>0, "bool"=>0, "string"=>0, "true"=>0, "false"=>0, - "null"=>0, "void"=>0, "iterable"=>0 + "new"=>0, "or"=>0, "parent"=>0, "print"=>0, "private"=>0, + "protected"=>0,"public"=>0, "require"=>0, "require_once"=>0, + "return"=>0, "self"=>0, "static"=>0, "switch"=>0, "throw"=>0, + "trait"=>0, "try"=>0,"unset"=>0, "use"=>0, "var"=>0, "while"=>0, + "xor"=>0, "yield"=>0, "int"=>0, "float"=>0, "bool"=>0, "string"=>0, + "true"=>0, "false"=>0, "null"=>0, "void"=>0, "iterable"=>0 ); if (array_key_exists(strtolower($classname), $reserved_words)) { diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php index 29569530fdac6..034f5df92edcf 100644 --- a/php/src/Google/Protobuf/Internal/GPBWire.php +++ b/php/src/Google/Protobuf/Internal/GPBWire.php @@ -146,7 +146,7 @@ public static function zigZagEncode64($int64) return bcsub(bcmul(bcsub(0, $int64), 2), 1); } } else { - return ($int64 << 1) ^ ($int64 >> 63); + return ((int)$int64 << 1) ^ ((int)$int64 >> 63); } } diff --git a/php/src/Google/Protobuf/Internal/MapField.php b/php/src/Google/Protobuf/Internal/MapField.php index 719fb350bd646..d44377a1794e6 100644 --- a/php/src/Google/Protobuf/Internal/MapField.php +++ b/php/src/Google/Protobuf/Internal/MapField.php @@ -37,6 +37,8 @@ namespace Google\Protobuf\Internal; +use Traversable; + /** * MapField is used by generated protocol message classes to manipulate map * fields. It can be used like native PHP array. @@ -133,7 +135,9 @@ public function getLegacyValueClass() * @return object The stored element at given key. * @throws \ErrorException Invalid type for index. * @throws \ErrorException Non-existing index. + * @todo need to add return type mixed (require update php version to 8.0) */ + #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->container[$key]; @@ -150,7 +154,9 @@ public function offsetGet($key) * @throws \ErrorException Invalid type for key. * @throws \ErrorException Invalid type for value. * @throws \ErrorException Non-existing key. + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->checkKey($this->key_type, $key); @@ -208,7 +214,9 @@ public function offsetSet($key, $value) * @param object $key The key of the element to be removed. * @return void * @throws \ErrorException Invalid type for key. + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function offsetUnset($key) { $this->checkKey($this->key_type, $key); @@ -224,7 +232,7 @@ public function offsetUnset($key) * @return bool True if the element at the given key exists. * @throws \ErrorException Invalid type for key. */ - public function offsetExists($key) + public function offsetExists($key): bool { $this->checkKey($this->key_type, $key); return isset($this->container[$key]); @@ -233,7 +241,7 @@ public function offsetExists($key) /** * @ignore */ - public function getIterator() + public function getIterator(): Traversable { return new MapFieldIter($this->container, $this->key_type); } @@ -245,7 +253,7 @@ public function getIterator() * * @return integer The number of stored elements. */ - public function count() + public function count(): int { return count($this->container); } diff --git a/php/src/Google/Protobuf/Internal/MapFieldIter.php b/php/src/Google/Protobuf/Internal/MapFieldIter.php index 4e18005ea879d..2ff6b44ae31ba 100644 --- a/php/src/Google/Protobuf/Internal/MapFieldIter.php +++ b/php/src/Google/Protobuf/Internal/MapFieldIter.php @@ -67,17 +67,21 @@ public function __construct($container, $key_type) * Reset the status of the iterator * * @return void + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function rewind() { - return reset($this->container); + reset($this->container); } /** * Return the element at the current position. * * @return object The element at the current position. + * @todo need to add return type mixed (require update php version to 8.0) */ + #[\ReturnTypeWillChange] public function current() { return current($this->container); @@ -87,7 +91,9 @@ public function current() * Return the current key. * * @return object The current key. + * @todo need to add return type mixed (require update php version to 8.0) */ + #[\ReturnTypeWillChange] public function key() { $key = key($this->container); @@ -116,10 +122,12 @@ public function key() * Move to the next position. * * @return void + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function next() { - return next($this->container); + next($this->container); } /** @@ -127,7 +135,7 @@ public function next() * * @return bool True if there are more elements to iterate. */ - public function valid() + public function valid(): bool { return key($this->container) !== null; } diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 19b48f0b50392..1d1fbf27c5600 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -423,7 +423,7 @@ private static function parseFieldFromStreamNoTag($input, $field, &$value) } break; case GPBType::GROUP: - trigger_error("Not implemented.", E_ERROR); + trigger_error("Not implemented.", E_USER_ERROR); break; case GPBType::MESSAGE: if ($field->isMap()) { diff --git a/php/src/Google/Protobuf/Internal/RepeatedField.php b/php/src/Google/Protobuf/Internal/RepeatedField.php index c0331ff38e55b..cfe5140d77d4c 100644 --- a/php/src/Google/Protobuf/Internal/RepeatedField.php +++ b/php/src/Google/Protobuf/Internal/RepeatedField.php @@ -39,6 +39,7 @@ use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBUtil; +use Traversable; /** * RepeatedField is used by generated protocol message classes to manipulate @@ -120,7 +121,9 @@ public function getLegacyClass() * @return object The stored element at given index. * @throws \ErrorException Invalid type for index. * @throws \ErrorException Non-existing index. + * @todo need to add return type mixed (require update php version to 8.0) */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->container[$offset]; @@ -137,7 +140,9 @@ public function offsetGet($offset) * @throws \ErrorException Invalid type for index. * @throws \ErrorException Non-existing index. * @throws \ErrorException Incorrect type of the element. + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { switch ($this->type) { @@ -208,7 +213,9 @@ public function offsetSet($offset, $value) * @throws \ErrorException Invalid type for index. * @throws \ErrorException The element to be removed is not at the end of the * RepeatedField. + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $count = count($this->container); @@ -230,7 +237,7 @@ public function offsetUnset($offset) * @return bool True if the element at the given offset exists. * @throws \ErrorException Invalid type for index. */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->container[$offset]); } @@ -238,7 +245,7 @@ public function offsetExists($offset) /** * @ignore */ - public function getIterator() + public function getIterator(): Traversable { return new RepeatedFieldIter($this->container); } @@ -250,7 +257,7 @@ public function getIterator() * * @return integer The number of stored elements. */ - public function count() + public function count(): int { return count($this->container); } diff --git a/php/src/Google/Protobuf/Internal/RepeatedFieldIter.php b/php/src/Google/Protobuf/Internal/RepeatedFieldIter.php index 2b6f82309b217..ec99b64ae7a52 100644 --- a/php/src/Google/Protobuf/Internal/RepeatedFieldIter.php +++ b/php/src/Google/Protobuf/Internal/RepeatedFieldIter.php @@ -70,7 +70,9 @@ public function __construct($container) * Reset the status of the iterator * * @return void + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function rewind() { $this->position = 0; @@ -80,7 +82,9 @@ public function rewind() * Return the element at the current position. * * @return object The element at the current position. + * @todo need to add return type mixed (require update php version to 8.0) */ + #[\ReturnTypeWillChange] public function current() { return $this->container[$this->position]; @@ -90,7 +94,9 @@ public function current() * Return the current position. * * @return integer The current position. + * @todo need to add return type mixed (require update php version to 8.0) */ + #[\ReturnTypeWillChange] public function key() { return $this->position; @@ -100,7 +106,9 @@ public function key() * Move to the next position. * * @return void + * @todo need to add return type void (require update php version to 7.1) */ + #[\ReturnTypeWillChange] public function next() { ++$this->position; @@ -111,7 +119,7 @@ public function next() * * @return bool True if there are more elements to iterate. */ - public function valid() + public function valid(): bool { return isset($this->container[$this->position]); } diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php index c4cc667e3a4bf..a3e8e721a2292 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php @@ -19,8 +19,8 @@ class Location extends \Google\Protobuf\Internal\Message * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from - * the root FileDescriptorProto to the place where the definition. For - * example, this path: + * the root FileDescriptorProto to the place where the definition occurs. + * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 @@ -111,8 +111,8 @@ class Location extends \Google\Protobuf\Internal\Message * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from - * the root FileDescriptorProto to the place where the definition. For - * example, this path: + * the root FileDescriptorProto to the place where the definition occurs. + * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 @@ -185,8 +185,8 @@ public function __construct($data = NULL) { * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from - * the root FileDescriptorProto to the place where the definition. For - * example, this path: + * the root FileDescriptorProto to the place where the definition occurs. + * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 @@ -216,8 +216,8 @@ public function getPath() * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from - * the root FileDescriptorProto to the place where the definition. For - * example, this path: + * the root FileDescriptorProto to the place where the definition occurs. + * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 diff --git a/php/tests/EncodeDecodeTest.php b/php/tests/EncodeDecodeTest.php index ac01ca17a37b0..33d8da1795339 100644 --- a/php/tests/EncodeDecodeTest.php +++ b/php/tests/EncodeDecodeTest.php @@ -698,6 +698,16 @@ public function testDecodeInvalidBytesDataMiss() $m->mergeFromString(hex2bin('7A01')); } + public function testEncodeDecodeValidUtf8() + { + $m = new TestMessage(); + $m->mergeFromJsonString("{\"optionalString\":\"\\u1000\"}"); + $serialized = $m->serializeToString(); + $m2 = new TestMessage(); + $m2->mergeFromString($serialized); + $this->assertSame($m->getOptionalString(), $m2->getOptionalString()); + } + public function testDecodeInvalidEnum() { $this->expectException(Exception::class); diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php index a6101dcbfb2ba..42b1f7458b843 100644 --- a/php/tests/GeneratedClassTest.php +++ b/php/tests/GeneratedClassTest.php @@ -934,6 +934,7 @@ public function testPrefixForReservedWords() $m = new \Lower\PBnamespace(); $m = new \Lower\PBnew(); $m = new \Lower\PBor(); + $m = new \Lower\PBparent(); $m = new \Lower\PBprint(); $m = new \Lower\PBprivate(); $m = new \Lower\PBprotected(); @@ -941,6 +942,7 @@ public function testPrefixForReservedWords() $m = new \Lower\PBrequire(); $m = new \Lower\PBrequire_once(); $m = new \Lower\PBreturn(); + $m = new \Lower\PBself(); $m = new \Lower\PBstatic(); $m = new \Lower\PBswitch(); $m = new \Lower\PBthrow(); @@ -1012,6 +1014,7 @@ public function testPrefixForReservedWords() $m = new \Upper\PBNAMESPACE(); $m = new \Upper\PBNEW(); $m = new \Upper\PBOR(); + $m = new \Upper\PBPARENT(); $m = new \Upper\PBPRINT(); $m = new \Upper\PBPRIVATE(); $m = new \Upper\PBPROTECTED(); @@ -1019,6 +1022,7 @@ public function testPrefixForReservedWords() $m = new \Upper\PBREQUIRE(); $m = new \Upper\PBREQUIRE_ONCE(); $m = new \Upper\PBRETURN(); + $m = new \Upper\PBSELF(); $m = new \Upper\PBSTATIC(); $m = new \Upper\PBSWITCH(); $m = new \Upper\PBTHROW(); @@ -1090,6 +1094,7 @@ public function testPrefixForReservedWords() $m = new \Lower_enum\PBnamespace(); $m = new \Lower_enum\PBnew(); $m = new \Lower_enum\PBor(); + $m = new \Lower_enum\PBparent(); $m = new \Lower_enum\PBprint(); $m = new \Lower_enum\PBprivate(); $m = new \Lower_enum\PBprotected(); @@ -1097,6 +1102,7 @@ public function testPrefixForReservedWords() $m = new \Lower_enum\PBrequire(); $m = new \Lower_enum\PBrequire_once(); $m = new \Lower_enum\PBreturn(); + $m = new \Lower_enum\PBself(); $m = new \Lower_enum\PBstatic(); $m = new \Lower_enum\PBswitch(); $m = new \Lower_enum\PBthrow(); @@ -1168,6 +1174,7 @@ public function testPrefixForReservedWords() $m = new \Upper_enum\PBNAMESPACE(); $m = new \Upper_enum\PBNEW(); $m = new \Upper_enum\PBOR(); + $m = new \Upper_enum\PBPARENT(); $m = new \Upper_enum\PBPRINT(); $m = new \Upper_enum\PBPRIVATE(); $m = new \Upper_enum\PBPROTECTED(); @@ -1175,6 +1182,7 @@ public function testPrefixForReservedWords() $m = new \Upper_enum\PBREQUIRE(); $m = new \Upper_enum\PBREQUIRE_ONCE(); $m = new \Upper_enum\PBRETURN(); + $m = new \Upper_enum\PBSELF(); $m = new \Upper_enum\PBSTATIC(); $m = new \Upper_enum\PBSWITCH(); $m = new \Upper_enum\PBTHROW(); @@ -1273,6 +1281,8 @@ public function testPrefixForReservedWords() $m = \Lower_enum_value\NotAllowed::null; $m = \Lower_enum_value\NotAllowed::void; $m = \Lower_enum_value\NotAllowed::iterable; + $m = \Lower_enum_value\NotAllowed::parent; + $m = \Lower_enum_value\NotAllowed::self; $m = \Upper_enum_value\NotAllowed::PBABSTRACT; $m = \Upper_enum_value\NotAllowed::PBAND; @@ -1351,6 +1361,8 @@ public function testPrefixForReservedWords() $m = \Upper_enum_value\NotAllowed::NULL; $m = \Upper_enum_value\NotAllowed::VOID; $m = \Upper_enum_value\NotAllowed::ITERABLE; + $m = \Upper_enum_value\NotAllowed::PARENT; + $m = \Upper_enum_value\NotAllowed::SELF; $this->assertTrue(true); } diff --git a/php/tests/compile_extension.sh b/php/tests/compile_extension.sh index 80378f02d59a0..d33458746cc40 100755 --- a/php/tests/compile_extension.sh +++ b/php/tests/compile_extension.sh @@ -2,9 +2,18 @@ set -e -cd $(dirname $0) +cd $(dirname $0)/.. -pushd ../ext/google/protobuf > /dev/null +# utf8_range has to live in the base third_party directory. +# We copy it into the ext/google/protobuf directory for the build +# (and for the release to PECL). +rm -rf ext/google/protobuf/third_party +mkdir -p ext/google/protobuf/third_party/utf8_range +cp ../third_party/utf8_range/* ext/google/protobuf/third_party/utf8_range + +echo "Copied utf8_range from ../third_party -> ext/google/protobuf/third_party" + +pushd ext/google/protobuf > /dev/null CONFIGURE_OPTIONS=("./configure" "--with-php-config=$(which php-config)") diff --git a/php/tests/proto/test_reserved_enum_lower.proto b/php/tests/proto/test_reserved_enum_lower.proto index 60807d97cb6f1..f8557d250fea9 100644 --- a/php/tests/proto/test_reserved_enum_lower.proto +++ b/php/tests/proto/test_reserved_enum_lower.proto @@ -52,6 +52,7 @@ enum match { ZERO47 = 0; } enum namespace { ZERO48 = 0; } enum new { ZERO49 = 0; } enum or { ZERO50 = 0; } +enum parent { ZERO78 = 0; } enum print { ZERO51 = 0; } enum private { ZERO52 = 0; } enum protected { ZERO53 = 0; } @@ -59,6 +60,7 @@ enum public { ZERO54 = 0; } enum require { ZERO55 = 0; } enum require_once { ZERO56 = 0; } enum return { ZERO57 = 0; } +enum self { ZERO79 = 0; } enum static { ZERO58 = 0; } enum switch { ZERO59 = 0; } enum throw { ZERO60 = 0; } diff --git a/php/tests/proto/test_reserved_enum_upper.proto b/php/tests/proto/test_reserved_enum_upper.proto index a10733291855a..8d382ab31e5d3 100644 --- a/php/tests/proto/test_reserved_enum_upper.proto +++ b/php/tests/proto/test_reserved_enum_upper.proto @@ -52,6 +52,7 @@ enum MATCH { ZERO47 = 0; } enum NAMESPACE { ZERO48 = 0; } enum NEW { ZERO49 = 0; } enum OR { ZERO50 = 0; } +enum PARENT { ZERO78 = 0; } enum PRINT { ZERO51 = 0; } enum PRIVATE { ZERO52 = 0; } enum PROTECTED { ZERO53 = 0; } @@ -59,6 +60,7 @@ enum PUBLIC { ZERO54 = 0; } enum REQUIRE { ZERO55 = 0; } enum REQUIRE_ONCE { ZERO56 = 0; } enum RETURN { ZERO57 = 0; } +enum SELF { ZERO79 = 0; } enum STATIC { ZERO58 = 0; } enum SWITCH { ZERO59 = 0; } enum THROW { ZERO60 = 0; } diff --git a/php/tests/proto/test_reserved_enum_value_lower.proto b/php/tests/proto/test_reserved_enum_value_lower.proto index 46829060fcd7f..ca5a7c7352a09 100644 --- a/php/tests/proto/test_reserved_enum_value_lower.proto +++ b/php/tests/proto/test_reserved_enum_value_lower.proto @@ -53,6 +53,7 @@ enum NotAllowed { namespace = 47; new = 48; or = 49; + parent = 77; print = 50; private = 51; protected = 52; @@ -60,6 +61,7 @@ enum NotAllowed { require = 54; require_once = 55; return = 56; + self = 78; static = 57; switch = 58; throw = 59; diff --git a/php/tests/proto/test_reserved_enum_value_upper.proto b/php/tests/proto/test_reserved_enum_value_upper.proto index f30d7ff1ef0d5..6b4040d5e4ab6 100644 --- a/php/tests/proto/test_reserved_enum_value_upper.proto +++ b/php/tests/proto/test_reserved_enum_value_upper.proto @@ -53,6 +53,7 @@ enum NotAllowed { NAMESPACE = 47; NEW = 48; OR = 49; + PARENT = 77; PRINT = 50; PRIVATE = 51; PROTECTED = 52; @@ -60,6 +61,7 @@ enum NotAllowed { REQUIRE = 54; REQUIRE_ONCE = 55; RETURN = 56; + SELF = 78; STATIC = 57; SWITCH = 58; THROW = 59; diff --git a/php/tests/proto/test_reserved_message_lower.proto b/php/tests/proto/test_reserved_message_lower.proto index 05344fff59186..2390a87dd696e 100644 --- a/php/tests/proto/test_reserved_message_lower.proto +++ b/php/tests/proto/test_reserved_message_lower.proto @@ -52,6 +52,7 @@ message match {} message namespace {} message new {} message or {} +message parent {} message print {} message private {} message protected {} @@ -59,6 +60,7 @@ message public {} message require {} message require_once {} message return {} +message self {} message static {} message switch {} message throw {} diff --git a/php/tests/proto/test_reserved_message_upper.proto b/php/tests/proto/test_reserved_message_upper.proto index 853a17d405668..9f55330223472 100644 --- a/php/tests/proto/test_reserved_message_upper.proto +++ b/php/tests/proto/test_reserved_message_upper.proto @@ -52,6 +52,7 @@ message MATCH {} message NAMESPACE {} message NEW {} message OR {} +message PARENT {} message PRINT {} message PRIVATE {} message PROTECTED {} @@ -59,6 +60,7 @@ message PUBLIC {} message REQUIRE {} message REQUIRE_ONCE {} message RETURN {} +message SELF {} message STATIC {} message SWITCH {} message THROW {} diff --git a/protobuf.bzl b/protobuf.bzl index 9716128121573..ffd7c8df67487 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,11 +386,75 @@ internal_gen_well_known_protos_java = rule( "_protoc": attr.label( executable = True, cfg = "exec", - default = "@com_google_protobuf//:protoc", + default = "//:protoc", ), }, ) +def _internal_gen_kt_protos(ctx): + args = ctx.actions.args() + + deps = [d[ProtoInfo] for d in ctx.attr.deps] + + srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name)) + if ctx.attr.lite: + out = "lite:%s" % srcjar.path + else: + out = srcjar + + args.add("--kotlin_out", out) + + descriptors = depset( + transitive = [dep.transitive_descriptor_sets for dep in deps], + ) + args.add_joined( + "--descriptor_set_in", + descriptors, + join_with = ctx.configuration.host_path_separator, + ) + + for dep in deps: + if "." == dep.proto_source_root: + args.add_all([src.path for src in dep.direct_sources]) + else: + source_root = dep.proto_source_root + offset = len(source_root) + 1 # + '/'. + args.add_all([src.path[offset:] for src in dep.direct_sources]) + + ctx.actions.run( + executable = ctx.executable._protoc, + inputs = descriptors, + outputs = [srcjar], + arguments = [args], + use_default_shell_env = True, + ) + + return [ + DefaultInfo( + files = depset([srcjar]), + ), + ] + +internal_gen_kt_protos = rule( + implementation = _internal_gen_kt_protos, + attrs = { + "deps": attr.label_list( + mandatory = True, + providers = [ProtoInfo], + ), + "lite": attr.bool( + default = False, + ), + "_protoc": attr.label( + executable = True, + cfg = "exec", + default = "//:protoc", + ), + }, +) + + + def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs): """Macro to copy files to a different directory and then create a filegroup. @@ -422,8 +493,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_deps.bzl b/protobuf_deps.bzl index 32f38ebb6ea0b..2bee1b763c66d 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -4,13 +4,14 @@ 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.6", + "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", + "org.mockito:mockito-core:4.3.1", ] def protobuf_deps(): @@ -29,7 +30,7 @@ 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"], @@ -69,7 +70,24 @@ def protobuf_deps(): if not native.existing_rule("rules_jvm_external"): 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"], + sha256 = "744bd7436f63af7e9872948773b8b106016dc164acb3960b4963f86754532ee7", + strip_prefix = "rules_jvm_external-906875b0d5eaaf61a8ca2c9c3835bde6f435d011", + urls = ["https://github.com/bazelbuild/rules_jvm_external/archive/906875b0d5eaaf61a8ca2c9c3835bde6f435d011.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_release.bzl b/protobuf_release.bzl new file mode 100644 index 0000000000000..c5d5f2bf2ce67 --- /dev/null +++ b/protobuf_release.bzl @@ -0,0 +1,50 @@ +""" +Generates package naming variables for use with rules_pkg. +""" + +load("@rules_pkg//:providers.bzl", "PackageVariablesInfo") +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") +load(":protobuf_version.bzl", "PROTOBUF_VERSION") + +def _package_naming_impl(ctx): + values = {} + values["version"] = PROTOBUF_VERSION + + # infer from the current cpp toolchain. + toolchain = find_cpp_toolchain(ctx) + cpu = toolchain.cpu + system_name = toolchain.target_gnu_system_name + + # rename cpus to match what we want artifacts to be + if cpu == "systemz": + cpu = "s390_64" + elif cpu == "aarch64": + cpu = "aarch_64" + elif cpu == "ppc64": + cpu = "ppcle_64" + + # use the system name to determine the os and then create platform names + if "apple" in system_name: + values["platform"] = "osx-" + cpu + elif "linux" in system_name: + values["platform"] = "linux-" + cpu + elif "mingw" in system_name: + if cpu == "x86_64": + values["platform"] = "win64" + else: + values["platform"] = "win32" + else: + values["platform"] = "unknown" + + return PackageVariablesInfo(values = values) + + +package_naming = rule( + implementation = _package_naming_impl, + attrs = { + # Necessary data dependency for find_cpp_toolchain. + "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), + }, + toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], + incompatible_use_toolchain_transition = True, +) diff --git a/protobuf_version.bzl b/protobuf_version.bzl index 9ae134074173a..d6c42df98014e 100644 --- a/protobuf_version.bzl +++ b/protobuf_version.bzl @@ -1 +1 @@ -PROTOBUF_VERSION = '3.19.4' +PROTOBUF_VERSION = '3.20.0-rc-2' 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 dec2e7047ce1a..7150c78c845cd 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -8,7 +8,7 @@ com.google.protobuf protoc - 3.19.4 + 3.20.0-rc-2 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/README.md b/python/README.md index f0c9ce4f44d36..27f22c82c0806 100644 --- a/python/README.md +++ b/python/README.md @@ -26,7 +26,7 @@ use python c++ implementation. Installation ============ -1) Make sure you have Python 3.5 or newer. If in doubt, run: +1) Make sure you have Python 3.7 or newer. If in doubt, run: $ python -V diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index 9319c67f1fbc3..cd0daeaeab5ec 100644 --- a/python/google/protobuf/__init__.py +++ b/python/google/protobuf/__init__.py @@ -30,4 +30,4 @@ # Copyright 2007 Google Inc. All Rights Reserved. -__version__ = '3.19.4' +__version__ = '3.20.0rc2' diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index 61c242f9dff07..ad70be9a11488 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. @@ -647,7 +667,7 @@ class EnumDescriptor(_NestedDescriptorBase): full_name (str): Full name of the type, including package name and any enclosing type(s). - values (list[EnumValueDescriptors]): List of the values + values (list[EnumValueDescriptor]): List of the values in this enum. values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, but indexed by the "name" field of each EnumValueDescriptor. @@ -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..911372a8b00e5 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) @@ -1233,21 +1235,25 @@ def _ExtractSymbols(self, descriptors): for enum in desc.enum_types: yield (_PrefixWithDot(enum.full_name), enum) - def _GetDeps(self, dependencies): + def _GetDeps(self, dependencies, visited=None): """Recursively finds dependencies for file protos. Args: dependencies: The names of the files being depended on. + visited: The names of files already found. Yields: Each direct and indirect dependency. """ + visited = visited or set() for dependency in dependencies: - dep_desc = self.FindFileByName(dependency) - yield dep_desc - for parent_dep in dep_desc.dependencies: - yield parent_dep + if dependency not in visited: + visited.add(dependency) + dep_desc = self.FindFileByName(dependency) + yield dep_desc + public_files = [d.name for d in dep_desc.public_dependencies] + yield from self._GetDeps(public_files, visited) def _GetTypeFromScope(self, package, type_name, scope): """Finds a given type name in the current scope. diff --git a/python/google/protobuf/internal/_parameterized.py b/python/google/protobuf/internal/_parameterized.py index 2229671ed6bb8..afdbb78c365bb 100755 --- a/python/google/protobuf/internal/_parameterized.py +++ b/python/google/protobuf/internal/_parameterized.py @@ -148,10 +148,7 @@ def testIsNegative(self, arg): import functools import re import types -try: - import unittest2 as unittest -except ImportError: - import unittest +import unittest import uuid try: @@ -357,7 +354,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 +386,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 802322424e363..33f5b04f49b44 100644 --- a/python/google/protobuf/internal/api_implementation.cc +++ b/python/google/protobuf/internal/api_implementation.cc @@ -82,24 +82,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_database_test.py b/python/google/protobuf/internal/descriptor_database_test.py index ad3ca645f929f..3c086b92471ad 100644 --- a/python/google/protobuf/internal/descriptor_database_test.py +++ b/python/google/protobuf/internal/descriptor_database_test.py @@ -100,7 +100,7 @@ def testAdd(self): self.assertEqual(file_desc_proto2, db.FindFileContainingSymbol( 'protobuf_unittest.TestAllTypes.none_field')) - with self.assertRaisesRegexp(KeyError, r'\'protobuf_unittest\.NoneMessage\''): + with self.assertRaisesRegex(KeyError, r'\'protobuf_unittest\.NoneMessage\''): db.FindFileContainingSymbol('protobuf_unittest.NoneMessage') def testConflictRegister(self): diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py index e59cf9b97e123..61cec3f9d3657 100644 --- a/python/google/protobuf/internal/descriptor_pool_test.py +++ b/python/google/protobuf/internal/descriptor_pool_test.py @@ -541,7 +541,13 @@ def testConflictRegister(self): pool._AddExtensionDescriptor( file_descriptor.extensions_by_name['optional_int32_extension']) pool.Add(unittest_fd) - pool.Add(conflict_fd) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + pool.Add(conflict_fd) + self.assertTrue(len(w)) + self.assertIs(w[0].category, RuntimeWarning) + self.assertIn('Conflict register for file "other_file": ', + str(w[0].message)) pool.FindFileByName(unittest_fd.name) with self.assertRaises(TypeError): pool.FindFileByName(conflict_fd.name) @@ -648,11 +654,11 @@ def testErrorCollector(self): enum_value.number = 0 self.db.Add(file_proto) - self.assertRaisesRegexp(KeyError, 'SubMessage', - self.pool.FindMessageTypeByName, - 'collector.ErrorMessage') - self.assertRaisesRegexp(KeyError, 'SubMessage', - self.pool.FindFileByName, 'error_file') + self.assertRaisesRegex(KeyError, 'SubMessage', + self.pool.FindMessageTypeByName, + 'collector.ErrorMessage') + self.assertRaisesRegex(KeyError, 'SubMessage', self.pool.FindFileByName, + 'error_file') with self.assertRaises(KeyError) as exc: self.pool.FindFileByName('none_file') self.assertIn(str(exc.exception), ('\'none_file\'', 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/enum_type_wrapper.py b/python/google/protobuf/internal/enum_type_wrapper.py index 9a53999a43088..65d2c7a5c0c02 100644 --- a/python/google/protobuf/internal/enum_type_wrapper.py +++ b/python/google/protobuf/internal/enum_type_wrapper.py @@ -43,6 +43,15 @@ class EnumTypeWrapper(object): DESCRIPTOR = None + # This is a type alias, which mypy typing stubs can type as + # a genericized parameter constrained to an int, allowing subclasses + # to be typed with more constraint in .pyi stubs + # Eg. + # def MyGeneratedEnum(Message): + # ValueType = NewType('ValueType', int) + # def Name(self, number: MyGeneratedEnum.ValueType) -> str + ValueType = int + def __init__(self, enum_type): """Inits EnumTypeWrapper with an EnumDescriptor.""" self._enum_type = enum_type diff --git a/python/google/protobuf/internal/generator_test.py b/python/google/protobuf/internal/generator_test.py index 0c4299a3d1108..9883fce31ef63 100644 --- a/python/google/protobuf/internal/generator_test.py +++ b/python/google/protobuf/internal/generator_test.py @@ -39,10 +39,7 @@ __author__ = 'robinson@google.com (Will Robinson)' -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest from google.protobuf.internal import test_bad_identifiers_pb2 from google.protobuf import unittest_custom_options_pb2 diff --git a/python/google/protobuf/internal/import_test.py b/python/google/protobuf/internal/import_test.py new file mode 100644 index 0000000000000..b5c572cfca80a --- /dev/null +++ b/python/google/protobuf/internal/import_test.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# 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. + +"""Unittest for nested public imports.""" + +import unittest + +from google.protobuf.internal.import_test_package import outer_pb2 + + +class ImportTest(unittest.TestCase): + + def testPackageInitializationImport(self): + """Test that we can import nested import public messages.""" + + msg = outer_pb2.Outer() + self.assertEqual(58, msg.import_public_nested.value) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/google/protobuf/internal/import_test_package/import_public.proto b/python/google/protobuf/internal/import_test_package/import_public.proto new file mode 100644 index 0000000000000..8774702d7f24d --- /dev/null +++ b/python/google/protobuf/internal/import_test_package/import_public.proto @@ -0,0 +1,40 @@ +// 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. + +// A proto file which is imported by inner.proto to test public importing. + +syntax = "proto2"; + +package google.protobuf.python.internal.import_test_package; + +option optimize_for = SPEED; + +// Test nested public import +import public "google/protobuf/internal/import_test_package/import_public_nested.proto"; diff --git a/python/google/protobuf/internal/import_test_package/import_public_nested.proto b/python/google/protobuf/internal/import_test_package/import_public_nested.proto new file mode 100644 index 0000000000000..fcf4d68273f6c --- /dev/null +++ b/python/google/protobuf/internal/import_test_package/import_public_nested.proto @@ -0,0 +1,40 @@ +// 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. + +// A proto file which is imported by import_public.proto to test nested public +// importing. + +syntax = "proto2"; + +package google.protobuf.python.internal.import_test_package; + +message ImportPublicNestedMessage { + optional int32 value = 1 [default = 58]; +} diff --git a/python/google/protobuf/internal/import_test_package/inner.proto b/python/google/protobuf/internal/import_test_package/inner.proto index 2887c1230e549..f20c22e18226f 100644 --- a/python/google/protobuf/internal/import_test_package/inner.proto +++ b/python/google/protobuf/internal/import_test_package/inner.proto @@ -32,6 +32,9 @@ syntax = "proto2"; package google.protobuf.python.internal.import_test_package; +// Test public import +import public "google/protobuf/internal/import_test_package/import_public.proto"; + message Inner { optional int32 value = 1 [default = 57]; } diff --git a/python/google/protobuf/internal/import_test_package/outer.proto b/python/google/protobuf/internal/import_test_package/outer.proto index a27fb5c8f4207..7810aec5e596d 100644 --- a/python/google/protobuf/internal/import_test_package/outer.proto +++ b/python/google/protobuf/internal/import_test_package/outer.proto @@ -36,4 +36,5 @@ import "google/protobuf/internal/import_test_package/inner.proto"; message Outer { optional Inner inner = 1; + optional ImportPublicNestedMessage import_public_nested = 2; } diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index af3713fcb5a2d..d018c3f2e69ce 100644 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -100,10 +100,8 @@ def CheckParseBack(self, message, parsed_message): def CheckError(self, text, error_message): message = json_format_proto3_pb2.TestMessage() - self.assertRaisesRegexp( - json_format.ParseError, - error_message, - json_format.Parse, text, message) + self.assertRaisesRegex(json_format.ParseError, error_message, + json_format.Parse, text, message) class JsonFormatTest(JsonFormatBase): @@ -697,8 +695,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() @@ -813,16 +810,16 @@ def testParseNull(self): json_format.Parse('{"messageValue": {}}', parsed_message) self.assertTrue(parsed_message.HasField('message_value')) # 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.') + self.assertRaisesRegex( + json_format.ParseError, 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 +837,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,17 +892,18 @@ 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) # Proto2 does not accept unknown enums. message = unittest_pb2.TestAllTypes() - self.assertRaisesRegexp( + self.assertRaisesRegex( 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 +926,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 +949,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 +985,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,71 +1008,65 @@ 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() text = '{"int32Map": {"null": 2, "2": 3}}' - self.assertRaisesRegexp( - json_format.ParseError, - 'Failed to parse int32Map field: invalid literal', - json_format.Parse, text, message) + self.assertRaisesRegex(json_format.ParseError, + 'Failed to parse int32Map field: invalid literal', + json_format.Parse, text, message) text = '{"int32Map": {1: 2, "2": 3}}' - self.assertRaisesRegexp( - json_format.ParseError, - (r'Failed to load JSON: Expecting property name' - r'( enclosed in double quotes)?: line 1'), - json_format.Parse, text, message) + self.assertRaisesRegex(json_format.ParseError, + (r'Failed to load JSON: Expecting property name' + r'( enclosed in double quotes)?: line 1'), + json_format.Parse, text, message) text = '{"boolMap": {"null": 1}}' - self.assertRaisesRegexp( + self.assertRaisesRegex( 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, - 'Failed to load JSON: duplicate key a', - json_format.Parse, text, message) + self.assertRaisesRegex(json_format.ParseError, + 'Failed to load JSON: duplicate key a', + json_format.Parse, text, message) text = r'{"stringMap": 0}' - self.assertRaisesRegexp( + self.assertRaisesRegex( 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( + self.assertRaisesRegex( json_format.ParseError, - 'nanos 0123456789012 more than 9 fractional digits.', - json_format.Parse, text, message) + 'nanos 0123456789012 more than 9 fractional digits.', json_format.Parse, + text, message) text = '{"value": "1972-01-01T01:00:00.01+08"}' - self.assertRaisesRegexp( - json_format.ParseError, - (r'Invalid timezone offset value: \+08.'), - json_format.Parse, text, message) + self.assertRaisesRegex(json_format.ParseError, + (r'Invalid timezone offset value: \+08.'), + json_format.Parse, text, message) # Time smaller than minimum time. text = '{"value": "0000-01-01T00:00:00Z"}' - self.assertRaisesRegexp( + self.assertRaisesRegex( json_format.ParseError, 'Failed to parse value field: year (0 )?is out of range.', json_format.Parse, text, message) # Time bigger than maximum time. message.value.seconds = 253402300800 - self.assertRaisesRegexp( - OverflowError, - 'date value out of range', - json_format.MessageToJson, message) + self.assertRaisesRegex(OverflowError, 'date value out of range', + json_format.MessageToJson, message) # Lower case t does not accept. text = '{"value": "0001-01-01t00:00:00Z"}' with self.assertRaises(json_format.ParseError) as e: @@ -1080,38 +1074,47 @@ 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): message = json_format_proto3_pb2.TestListValue() text = '{"value": 1234}' - self.assertRaisesRegexp( + self.assertRaisesRegex( json_format.ParseError, - r'Failed to parse value field: ListValue must be in \[\] which is 1234', - json_format.Parse, text, message) + 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( + self.assertRaisesRegex( json_format.ParseError, - 'Failed to parse value field: Struct must be in a dict which is 1234', - json_format.Parse, text, message) + '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): message = json_format_proto3_pb2.TestTimestamp() text = '{"value": {"foo": 123}}' - self.assertRaisesRegexp( + self.assertRaisesRegex( json_format.ParseError, r"Timestamp JSON value not a string: {u?'foo': 123}", json_format.Parse, text, message) @@ -1119,15 +1122,14 @@ def testTimestampInvalidStringValue(self): def testDurationInvalidStringValue(self): message = json_format_proto3_pb2.TestDuration() text = '{"value": {"foo": 123}}' - self.assertRaisesRegexp( - json_format.ParseError, - r"Duration JSON value not a string: {u?'foo': 123}", json_format.Parse, - text, message) + self.assertRaisesRegex(json_format.ParseError, + r"Duration JSON value not a string: {u?'foo': 123}", + json_format.Parse, text, message) def testFieldMaskInvalidStringValue(self): message = json_format_proto3_pb2.TestFieldMask() text = '{"value": {"foo": 123}}' - self.assertRaisesRegexp( + self.assertRaisesRegex( json_format.ParseError, r"FieldMask JSON value not a string: {u?'foo': 123}", json_format.Parse, text, message) @@ -1135,21 +1137,16 @@ def testFieldMaskInvalidStringValue(self): def testInvalidAny(self): message = any_pb2.Any() text = '{"@type": "type.googleapis.com/google.protobuf.Int32Value"}' - self.assertRaisesRegexp( - KeyError, - 'value', - json_format.Parse, text, message) + self.assertRaisesRegex(KeyError, '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 +1222,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): @@ -1233,12 +1232,10 @@ class UnknownClass(object): def __repr__(self): return 'v' message = json_format_proto3_pb2.TestValue() - self.assertRaisesRegexp( + self.assertRaisesRegex( json_format.ParseError, r"Value v has unexpected type .", - json_format.ParseDict, - {'value': UnknownClass()}, - message) + json_format.ParseDict, {'value': UnknownClass()}, message) def testMessageToDict(self): message = json_format_proto3_pb2.TestMessage() @@ -1271,6 +1268,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..a5c5a0d740b04 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 @@ -74,21 +75,19 @@ UCS2_MAXUNICODE = 65535 - warnings.simplefilter('error', DeprecationWarning) -@_parameterized.named_parameters( - ('_proto2', unittest_pb2), - ('_proto3', unittest_proto3_arena_pb2)) +@_parameterized.named_parameters(('_proto2', unittest_pb2), + ('_proto3', unittest_proto3_arena_pb2)) @testing_refleaks.TestCase class MessageTest(unittest.TestCase): def testBadUtf8String(self, message_module): if api_implementation.Type() != 'python': - self.skipTest("Skipping testBadUtf8String, currently only the python " - "api implementation raises UnicodeDecodeError when a " - "string field contains bad utf-8.") + self.skipTest('Skipping testBadUtf8String, currently only the python ' + 'api implementation raises UnicodeDecodeError when a ' + 'string field contains bad utf-8.') bad_utf8_data = test_util.GoldenFileData('bad_utf8_string') with self.assertRaises(UnicodeDecodeError) as context: message_module.TestAllTypes.FromString(bad_utf8_data) @@ -99,8 +98,7 @@ def testGoldenMessage(self, message_module): # and doesn't preserve unknown fields, so for proto3 we use a golden # message that doesn't have these fields set. if message_module is unittest_pb2: - golden_data = test_util.GoldenFileData( - 'golden_message_oneof_implemented') + golden_data = test_util.GoldenFileData('golden_message_oneof_implemented') else: golden_data = test_util.GoldenFileData('golden_message_proto3') @@ -439,8 +437,7 @@ def testAppendRepeatedCompositeField(self, message_module): except TypeError: pass self.assertEqual(2, len(msg.repeated_nested_message)) - self.assertEqual([1, 2], - [m.bb for m in msg.repeated_nested_message]) + self.assertEqual([1, 2], [m.bb for m in msg.repeated_nested_message]) def testInsertRepeatedCompositeField(self, message_module): msg = message_module.TestAllTypes() @@ -462,22 +459,22 @@ def testInsertRepeatedCompositeField(self, message_module): self.assertEqual(5, len(msg.repeated_nested_message)) self.assertEqual([-1000, 2, -1, 1, 3], [m.bb for m in msg.repeated_nested_message]) - self.assertEqual(str(msg), - 'repeated_nested_message {\n' - ' bb: -1000\n' - '}\n' - 'repeated_nested_message {\n' - ' bb: 2\n' - '}\n' - 'repeated_nested_message {\n' - ' bb: -1\n' - '}\n' - 'repeated_nested_message {\n' - ' bb: 1\n' - '}\n' - 'repeated_nested_message {\n' - ' bb: 3\n' - '}\n') + self.assertEqual( + str(msg), 'repeated_nested_message {\n' + ' bb: -1000\n' + '}\n' + 'repeated_nested_message {\n' + ' bb: 2\n' + '}\n' + 'repeated_nested_message {\n' + ' bb: -1\n' + '}\n' + 'repeated_nested_message {\n' + ' bb: 1\n' + '}\n' + 'repeated_nested_message {\n' + ' bb: 3\n' + '}\n') self.assertEqual(sub_msg.bb, 1) def testMergeFromRepeatedField(self, message_module): @@ -496,8 +493,7 @@ def testMergeFromRepeatedField(self, message_module): self.assertEqual(4, len(msg.repeated_int32)) msg.repeated_nested_message.MergeFrom(other_msg.repeated_nested_message) - self.assertEqual([1, 2, 3, 4], - [m.bb for m in msg.repeated_nested_message]) + self.assertEqual([1, 2, 3, 4], [m.bb for m in msg.repeated_nested_message]) def testAddWrongRepeatedNestedField(self, message_module): msg = message_module.TestAllTypes() @@ -542,8 +538,7 @@ def testRepeatedNestedFieldIteration(self, message_module): msg.repeated_nested_message.add(bb=3) msg.repeated_nested_message.add(bb=4) - self.assertEqual([1, 2, 3, 4], - [m.bb for m in msg.repeated_nested_message]) + self.assertEqual([1, 2, 3, 4], [m.bb for m in msg.repeated_nested_message]) self.assertEqual([4, 3, 2, 1], [m.bb for m in reversed(msg.repeated_nested_message)]) self.assertEqual([4, 3, 2, 1], @@ -626,8 +621,9 @@ def testSortingRepeatedCompositeFieldsCustomComparator(self, message_module): self.assertEqual(message.repeated_nested_message[3].bb, 4) self.assertEqual(message.repeated_nested_message[4].bb, 5) self.assertEqual(message.repeated_nested_message[5].bb, 6) - self.assertEqual(str(message.repeated_nested_message), - '[bb: 1\n, bb: 2\n, bb: 3\n, bb: 4\n, bb: 5\n, bb: 6\n]') + self.assertEqual( + str(message.repeated_nested_message), + '[bb: 1\n, bb: 2\n, bb: 3\n, bb: 4\n, bb: 5\n, bb: 6\n]') def testSortingRepeatedCompositeFieldsStable(self, message_module): """Check passing a custom comparator to sort a repeated composite field.""" @@ -641,18 +637,16 @@ def testSortingRepeatedCompositeFieldsStable(self, message_module): message.repeated_nested_message.add().bb = 24 message.repeated_nested_message.add().bb = 10 message.repeated_nested_message.sort(key=lambda z: z.bb // 10) - self.assertEqual( - [13, 11, 10, 21, 20, 24, 33], - [n.bb for n in message.repeated_nested_message]) + self.assertEqual([13, 11, 10, 21, 20, 24, 33], + [n.bb for n in message.repeated_nested_message]) # Make sure that for the C++ implementation, the underlying fields # are actually reordered. pb = message.SerializeToString() message.Clear() message.MergeFromString(pb) - self.assertEqual( - [13, 11, 10, 21, 20, 24, 33], - [n.bb for n in message.repeated_nested_message]) + self.assertEqual([13, 11, 10, 21, 20, 24, 33], + [n.bb for n in message.repeated_nested_message]) def testRepeatedCompositeFieldSortArguments(self, message_module): """Check sorting a repeated composite field using list.sort() arguments.""" @@ -825,7 +819,7 @@ def testOneofDefaultValues(self, message_module): self.assertTrue(m.HasField('oneof_uint32')) self.assertFalse(m.HasField('oneof_string')) - m.oneof_string = "" + m.oneof_string = '' self.assertEqual('oneof_string', m.WhichOneof('oneof_field')) self.assertTrue(m.HasField('oneof_string')) self.assertFalse(m.HasField('oneof_uint32')) @@ -972,7 +966,9 @@ def testOneofClear(self, message_module): def testAssignByteStringToUnicodeField(self, message_module): """Assigning a byte string to a string field should result - in the value being converted to a Unicode string.""" + + in the value being converted to a Unicode string. + """ m = message_module.TestAllTypes() m.optional_string = str('') self.assertIsInstance(m.optional_string, str) @@ -1000,8 +996,7 @@ def testExtendShouldNotSwallowExceptions(self, message_module): with self.assertRaises(NameError) as _: m.repeated_int32.extend(a for i in range(10)) # pylint: disable=undefined-variable with self.assertRaises(NameError) as _: - m.repeated_nested_enum.extend( - a for i in range(10)) # pylint: disable=undefined-variable + m.repeated_nested_enum.extend(a for i in range(10)) # pylint: disable=undefined-variable FALSY_VALUES = [None, False, 0, 0.0, b'', u'', bytearray(), [], {}, set()] @@ -1147,29 +1142,43 @@ 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) def testSortEmptyRepeatedCompositeContainer(self, message_module): - """Exercise a scenario that has led to segfaults in the past. - """ + """Exercise a scenario that has led to segfaults in the past.""" m = message_module.TestAllTypes() m.repeated_nested_message.sort() def testHasFieldOnRepeatedField(self, message_module): - """Using HasField on a repeated field should raise an exception. - """ + """Using HasField on a repeated field should raise an exception.""" m = message_module.TestAllTypes() with self.assertRaises(ValueError) as _: m.HasField('repeated_int32') @@ -1209,6 +1218,7 @@ def testRepeatedCompareWithSelf(self, message_module): def testReleasedNestedMessages(self, message_module): """A case that lead to a segfault when a message detached from its parent + container has itself a child container. """ m = message_module.NestedTestAllTypes() @@ -1254,17 +1264,17 @@ class Proto2Test(unittest.TestCase): def testFieldPresence(self): message = unittest_pb2.TestAllTypes() - self.assertFalse(message.HasField("optional_int32")) - self.assertFalse(message.HasField("optional_bool")) - self.assertFalse(message.HasField("optional_nested_message")) + self.assertFalse(message.HasField('optional_int32')) + self.assertFalse(message.HasField('optional_bool')) + self.assertFalse(message.HasField('optional_nested_message')) with self.assertRaises(ValueError): - message.HasField("field_doesnt_exist") + message.HasField('field_doesnt_exist') with self.assertRaises(ValueError): - message.HasField("repeated_int32") + message.HasField('repeated_int32') with self.assertRaises(ValueError): - message.HasField("repeated_nested_message") + message.HasField('repeated_nested_message') self.assertEqual(0, message.optional_int32) self.assertEqual(False, message.optional_bool) @@ -1274,27 +1284,27 @@ def testFieldPresence(self): message.optional_int32 = 0 message.optional_bool = False message.optional_nested_message.bb = 0 - self.assertTrue(message.HasField("optional_int32")) - self.assertTrue(message.HasField("optional_bool")) - self.assertTrue(message.HasField("optional_nested_message")) + self.assertTrue(message.HasField('optional_int32')) + self.assertTrue(message.HasField('optional_bool')) + self.assertTrue(message.HasField('optional_nested_message')) # Set the fields to non-default values. message.optional_int32 = 5 message.optional_bool = True message.optional_nested_message.bb = 15 - self.assertTrue(message.HasField(u"optional_int32")) - self.assertTrue(message.HasField("optional_bool")) - self.assertTrue(message.HasField("optional_nested_message")) + self.assertTrue(message.HasField(u'optional_int32')) + self.assertTrue(message.HasField('optional_bool')) + self.assertTrue(message.HasField('optional_nested_message')) # Clearing the fields unsets them and resets their value to default. - message.ClearField("optional_int32") - message.ClearField(u"optional_bool") - message.ClearField("optional_nested_message") + message.ClearField('optional_int32') + message.ClearField(u'optional_bool') + message.ClearField('optional_nested_message') - self.assertFalse(message.HasField("optional_int32")) - self.assertFalse(message.HasField("optional_bool")) - self.assertFalse(message.HasField("optional_nested_message")) + self.assertFalse(message.HasField('optional_int32')) + self.assertFalse(message.HasField('optional_bool')) + self.assertFalse(message.HasField('optional_nested_message')) self.assertEqual(0, message.optional_int32) self.assertEqual(False, message.optional_bool) self.assertEqual(0, message.optional_nested_message.bb) @@ -1344,16 +1354,17 @@ def testMergeFromExtensions(self): msg1 = more_extensions_pb2.TopLevelMessage() msg2 = more_extensions_pb2.TopLevelMessage() # Cpp extension will lazily create a sub message which is immutable. - self.assertEqual(0, msg1.submessage.Extensions[ - more_extensions_pb2.optional_int_extension]) + self.assertEqual( + 0, + msg1.submessage.Extensions[more_extensions_pb2.optional_int_extension]) self.assertFalse(msg1.HasField('submessage')) - msg2.submessage.Extensions[ - more_extensions_pb2.optional_int_extension] = 123 + msg2.submessage.Extensions[more_extensions_pb2.optional_int_extension] = 123 # Make sure cmessage and extensions pointing to a mutable message # after merge instead of the lazily created message. msg1.MergeFrom(msg2) - self.assertEqual(123, msg1.submessage.Extensions[ - more_extensions_pb2.optional_int_extension]) + self.assertEqual( + 123, + msg1.submessage.Extensions[more_extensions_pb2.optional_int_extension]) def testGoldenExtensions(self): golden_data = test_util.GoldenFileData('golden_message') @@ -1387,17 +1398,19 @@ def testPickleIncompleteProto(self): # This is still an incomplete proto - so serializing should fail self.assertRaises(message.EncodeError, unpickled_message.SerializeToString) - # TODO(haberman): this isn't really a proto2-specific test except that this # message has a required field in it. Should probably be factored out so # that we can test the other parts with proto3. def testParsingMerge(self): """Check the merge behavior when a required or optional field appears - multiple times in the input.""" + + multiple times in the input. + """ messages = [ unittest_pb2.TestAllTypes(), unittest_pb2.TestAllTypes(), - unittest_pb2.TestAllTypes() ] + unittest_pb2.TestAllTypes() + ] messages[0].optional_int32 = 1 messages[1].optional_int64 = 2 messages[2].optional_int32 = 3 @@ -1430,15 +1443,16 @@ def testParsingMerge(self): self.assertEqual(parsing_merge.optional_all_types, merged_message) self.assertEqual(parsing_merge.optionalgroup.optional_group_all_types, merged_message) - self.assertEqual(parsing_merge.Extensions[ - unittest_pb2.TestParsingMerge.optional_ext], - merged_message) + self.assertEqual( + parsing_merge.Extensions[unittest_pb2.TestParsingMerge.optional_ext], + merged_message) # Repeated fields should not be merged. self.assertEqual(len(parsing_merge.repeated_all_types), 3) self.assertEqual(len(parsing_merge.repeatedgroup), 3) - self.assertEqual(len(parsing_merge.Extensions[ - unittest_pb2.TestParsingMerge.repeated_ext]), 3) + self.assertEqual( + len(parsing_merge.Extensions[ + unittest_pb2.TestParsingMerge.repeated_ext]), 3) def testPythonicInit(self): message = unittest_pb2.TestAllTypes( @@ -1450,8 +1464,11 @@ def testPythonicInit(self): optional_nested_message={'bb': 500}, optional_foreign_message={}, optional_nested_enum='BAZ', - repeatedgroup=[{'a': 600}, - {'a': 700}], + repeatedgroup=[{ + 'a': 600 + }, { + 'a': 700 + }], repeated_nested_enum=['FOO', unittest_pb2.TestAllTypes.BAR], default_int32=800, oneof_string='y') @@ -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() @@ -1811,8 +1848,7 @@ def testScalarMap(self): self.assertEqual(True, msg2.map_bool_bool[True]) self.assertEqual(2, msg2.map_int32_enum[888]) self.assertEqual(456, msg2.map_int32_enum[123]) - self.assertEqual('{-123: -456}', - str(msg2.map_int32_int32)) + self.assertEqual('{-123: -456}', str(msg2.map_int32_int32)) def testMapEntryAlwaysSerialized(self): msg = map_unittest_pb2.TestMap() @@ -1875,8 +1911,9 @@ def testMessageMap(self): self.assertEqual(2, len(msg2.map_int32_foreign_message)) msg2.map_int32_foreign_message[123].c = 1 # TODO(jieluo): Fix text format for message map. - self.assertIn(str(msg2.map_int32_foreign_message), - ('{-456: , 123: c: 1\n}', '{123: c: 1\n, -456: }')) + self.assertIn( + str(msg2.map_int32_foreign_message), + ('{-456: , 123: c: 1\n}', '{123: c: 1\n, -456: }')) def testNestedMessageMapItemDelete(self): msg = map_unittest_pb2.TestMap() @@ -2004,8 +2041,7 @@ def testMapMergeFrom(self): # Test when cpp extension cache a map. m1 = map_unittest_pb2.TestMap() m2 = map_unittest_pb2.TestMap() - self.assertEqual(m1.map_int32_foreign_message, - m1.map_int32_foreign_message) + self.assertEqual(m1.map_int32_foreign_message, m1.map_int32_foreign_message) m2.map_int32_foreign_message[123].c = 10 m1.MergeFrom(m2) self.assertEqual(10, m2.map_int32_foreign_message[123].c) @@ -2033,7 +2069,7 @@ def testMapMergeFrom(self): def testMergeFromBadType(self): msg = map_unittest_pb2.TestMap() - with self.assertRaisesRegexp( + with self.assertRaisesRegex( TypeError, r'Parameter to MergeFrom\(\) must be instance of same class: expected ' r'.+TestMap got int\.'): @@ -2041,7 +2077,7 @@ def testMergeFromBadType(self): def testCopyFromBadType(self): msg = map_unittest_pb2.TestMap() - with self.assertRaisesRegexp( + with self.assertRaisesRegex( TypeError, r'Parameter to [A-Za-z]*From\(\) must be instance of same class: ' r'expected .+TestMap got int\.'): @@ -2130,6 +2166,34 @@ def testModifyMapWhileIterating(self): for key in int32_foreign_iter: pass + def testModifyMapEntryWhileIterating(self): + msg = map_unittest_pb2.TestMap() + + msg.map_string_string['abc'] = '123' + msg.map_string_string['def'] = '456' + msg.map_string_string['ghi'] = '789' + + msg.map_int32_foreign_message[5].c = 5 + msg.map_int32_foreign_message[6].c = 6 + msg.map_int32_foreign_message[7].c = 7 + + string_string_keys = list(msg.map_string_string.keys()) + int32_foreign_keys = list(msg.map_int32_foreign_message.keys()) + + keys = [] + for key in msg.map_string_string: + keys.append(key) + msg.map_string_string[key] = '000' + self.assertEqual(keys, string_string_keys) + self.assertEqual(keys, list(msg.map_string_string.keys())) + + keys = [] + for key in msg.map_int32_foreign_message: + keys.append(key) + msg.map_int32_foreign_message[key].c = 0 + self.assertEqual(keys, int32_foreign_keys) + self.assertEqual(keys, list(msg.map_int32_foreign_message.keys())) + def testSubmessageMap(self): msg = map_unittest_pb2.TestMap() @@ -2241,7 +2305,7 @@ def testMapMessageFieldConstruction(self): msg1 = map_unittest_pb2.TestMap() msg1.map_string_foreign_message['test'].c = 42 msg2 = map_unittest_pb2.TestMap( - map_string_foreign_message=msg1.map_string_foreign_message) + map_string_foreign_message=msg1.map_string_foreign_message) self.assertEqual(42, msg2.map_string_foreign_message['test'].c) def testMapFieldRaisesCorrectError(self): @@ -2376,24 +2440,21 @@ def testStrictUtf8Check(self): msg2.MergeFromString(serialized) self.assertEqual(msg2.optional_string, u'😍') - msg = unittest_proto3_arena_pb2.TestAllTypes( - optional_string=u'\ud001') + msg = unittest_proto3_arena_pb2.TestAllTypes(optional_string=u'\ud001') self.assertEqual(msg.optional_string, u'\ud001') def testSurrogatesInPython3(self): # Surrogates are rejected at setters in Python3. with self.assertRaises(ValueError): - unittest_proto3_arena_pb2.TestAllTypes( - optional_string=u'\ud801\udc01') + unittest_proto3_arena_pb2.TestAllTypes(optional_string=u'\ud801\udc01') with self.assertRaises(ValueError): - unittest_proto3_arena_pb2.TestAllTypes( - optional_string=b'\xed\xa0\x81') + unittest_proto3_arena_pb2.TestAllTypes(optional_string=b'\xed\xa0\x81') with self.assertRaises(ValueError): - unittest_proto3_arena_pb2.TestAllTypes( - optional_string=u'\ud801') + unittest_proto3_arena_pb2.TestAllTypes(optional_string=u'\ud801') with self.assertRaises(ValueError): - unittest_proto3_arena_pb2.TestAllTypes( - optional_string=u'\ud801\ud801') + unittest_proto3_arena_pb2.TestAllTypes(optional_string=u'\ud801\ud801') + + @testing_refleaks.TestCase @@ -2404,8 +2465,9 @@ def assertImportFromName(self, msg, base_name): tp_name = str(type(msg)).split("'")[1] valid_names = ('Repeated%sContainer' % base_name, 'Repeated%sFieldContainer' % base_name) - self.assertTrue(any(tp_name.endswith(v) for v in valid_names), - '%r does end with any of %r' % (tp_name, valid_names)) + self.assertTrue( + any(tp_name.endswith(v) for v in valid_names), + '%r does end with any of %r' % (tp_name, valid_names)) parts = tp_name.split('.') class_name = parts[-1] @@ -2418,6 +2480,7 @@ def testTypeNamesCanBeImported(self): self.assertImportFromName(pb.repeated_int32, 'Scalar') self.assertImportFromName(pb.repeated_nested_message, 'Composite') + @testing_refleaks.TestCase class PackedFieldTest(unittest.TestCase): @@ -2537,5 +2600,6 @@ def testSucceedOversizeProto(self): q.ParseFromString(self.p_serialized) self.assertEqual(self.p.field.payload, q.field.payload) + if __name__ == '__main__': unittest.main() 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/proto_builder_test.py b/python/google/protobuf/internal/proto_builder_test.py index 8e2afaf98cf31..48077b0a4bbe1 100644 --- a/python/google/protobuf/internal/proto_builder_test.py +++ b/python/google/protobuf/internal/proto_builder_test.py @@ -31,10 +31,7 @@ """Tests for google.protobuf.proto_builder.""" import collections -try: - import unittest2 as unittest -except ImportError: - import unittest +import unittest from google.protobuf import descriptor_pb2 # pylint: disable=g-import-not-at-top from google.protobuf import descriptor 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/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index d1d595625df27..66dd0c710af2a 100644 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -429,7 +429,7 @@ def testIllegalValuesForIntegers(self, message_module): pb.optional_uint64 = '2' # The exact error should propagate with a poorly written custom integer. - with self.assertRaisesRegexp(RuntimeError, 'my_error'): + with self.assertRaisesRegex(RuntimeError, 'my_error'): pb.optional_uint64 = test_util.NonStandardInteger(5, 'my_error') def assetIntegerBoundsChecking(self, integer_fn, message_module): diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py index 9b9b859e1ef26..a53e71fe8e576 100644 --- a/python/google/protobuf/internal/type_checkers.py +++ b/python/google/protobuf/internal/type_checkers.py @@ -48,7 +48,6 @@ import ctypes import numbers -from google.protobuf.internal import api_implementation from google.protobuf.internal import decoder from google.protobuf.internal import encoder from google.protobuf.internal import wire_format @@ -77,7 +76,8 @@ def ToShortestFloat(original): def SupportsOpenEnums(field_descriptor): - return field_descriptor.containing_type.syntax == "proto3" + return field_descriptor.containing_type.syntax == 'proto3' + def GetTypeChecker(field): """Returns a type checker for a message field of the specified types. @@ -105,7 +105,6 @@ def GetTypeChecker(field): # subclassing builtin types and doing weird things. We're not trying to # protect against malicious clients here, just people accidentally shooting # themselves in the foot in obvious ways. - class TypeChecker(object): """Type checker used to catch type errors as early as possible @@ -124,11 +123,6 @@ def CheckValue(self, proposed_value): message = ('%.1024r has type %s, but expected one of: %s' % (proposed_value, type(proposed_value), self._acceptable_types)) raise TypeError(message) - # Some field types(float, double and bool) accept other types, must - # convert to the correct type in such cases. - if self._acceptable_types: - if self._acceptable_types[0] in (bool, float): - return self._acceptable_types[0](proposed_value) return proposed_value @@ -142,6 +136,22 @@ def DefaultValue(self): return self._default_value +class BoolValueChecker(object): + """Type checker used for bool fields.""" + + def CheckValue(self, proposed_value): + if not hasattr(proposed_value, '__index__') or ( + type(proposed_value).__module__ == 'numpy' and + type(proposed_value).__name__ == 'ndarray'): + message = ('%.1024r has type %s, but expected one of: %s' % + (proposed_value, type(proposed_value), (bool, int))) + raise TypeError(message) + return bool(proposed_value) + + def DefaultValue(self): + return False + + # IntValueChecker and its subclasses perform integer type-checks # and bounds-checks. class IntValueChecker(object): @@ -149,10 +159,13 @@ class IntValueChecker(object): """Checker used for integer fields. Performs type-check and range check.""" def CheckValue(self, proposed_value): - if not isinstance(proposed_value, numbers.Integral): + if not hasattr(proposed_value, '__index__') or ( + type(proposed_value).__module__ == 'numpy' and + type(proposed_value).__name__ == 'ndarray'): message = ('%.1024r has type %s, but expected one of: %s' % (proposed_value, type(proposed_value), (int,))) raise TypeError(message) + if not self._MIN <= int(proposed_value) <= self._MAX: raise ValueError('Value out of range: %d' % proposed_value) # We force all values to int to make alternate implementations where the @@ -249,20 +262,38 @@ class Uint64ValueChecker(IntValueChecker): _NEG_INF = float('-inf') -class FloatValueChecker(object): +class DoubleValueChecker(object): + """Checker used for double fields. - """Checker used for float fields. Performs type-check and range check. - - Values exceeding a 32-bit float will be converted to inf/-inf. + Performs type-check and range check. """ def CheckValue(self, proposed_value): """Check and convert proposed_value to float.""" - if not isinstance(proposed_value, numbers.Real): - message = ('%.1024r has type %s, but expected one of: numbers.Real' % + if (not hasattr(proposed_value, '__float__') and + not hasattr(proposed_value, '__index__')) or ( + type(proposed_value).__module__ == 'numpy' and + type(proposed_value).__name__ == 'ndarray'): + message = ('%.1024r has type %s, but expected one of: int, float' % (proposed_value, type(proposed_value))) raise TypeError(message) - converted_value = float(proposed_value) + return float(proposed_value) + + def DefaultValue(self): + return 0.0 + + +class FloatValueChecker(DoubleValueChecker): + """Checker used for float fields. + + Performs type-check and range check. + + Values exceeding a 32-bit float will be converted to inf/-inf. + """ + + def CheckValue(self, proposed_value): + """Check and convert proposed_value to float.""" + converted_value = super().CheckValue(proposed_value) # This inf rounding matches the C++ proto SafeDoubleToFloat logic. if converted_value > _FLOAT_MAX: return _INF @@ -271,23 +302,17 @@ def CheckValue(self, proposed_value): return TruncateToFourByteFloat(converted_value) - def DefaultValue(self): - return 0.0 - - # Type-checkers for all scalar CPPTYPEs. _VALUE_CHECKERS = { _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), - _FieldDescriptor.CPPTYPE_DOUBLE: TypeCheckerWithDefault( - 0.0, float, numbers.Real), + _FieldDescriptor.CPPTYPE_DOUBLE: DoubleValueChecker(), _FieldDescriptor.CPPTYPE_FLOAT: FloatValueChecker(), - _FieldDescriptor.CPPTYPE_BOOL: TypeCheckerWithDefault( - False, bool, numbers.Integral), + _FieldDescriptor.CPPTYPE_BOOL: BoolValueChecker(), _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes), - } +} # Map from field type to a function F, such that F(field_num, value) 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..391290194f35d 100644 --- a/python/google/protobuf/internal/well_known_types_test.py +++ b/python/google/protobuf/internal/well_known_types_test.py @@ -48,9 +48,19 @@ from google.protobuf.internal import well_known_types from google.protobuf import descriptor from google.protobuf import text_format +from google.protobuf.internal import _parameterized +try: + # New module in Python 3.9: + import zoneinfo # pylint:disable=g-import-not-at-top + _TZ_JAPAN = zoneinfo.ZoneInfo('Japan') + _TZ_PACIFIC = zoneinfo.ZoneInfo('US/Pacific') +except ImportError: + _TZ_JAPAN = datetime.timezone(datetime.timedelta(hours=9), 'Japan') + _TZ_PACIFIC = datetime.timezone(datetime.timedelta(hours=-8), 'US/Pacific') -class TimeUtilTestBase(unittest.TestCase): + +class TimeUtilTestBase(_parameterized.TestCase): def CheckTimestampConversion(self, message, text): self.assertEqual(text, message.ToJsonString()) @@ -233,43 +243,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()) - - def testDatetimeConversionWithTimezone(self): - class TZ(datetime.tzinfo): + naive_future = datetime.datetime(2555, 2, 22, 1, 2, 3, 456789) + message.FromDatetime(naive_future) + self.assertEqual(naive_future, message.ToDatetime()) - def utcoffset(self, _): - return datetime.timedelta(hours=1) + naive_end_of_time = datetime.datetime.max + message.FromDatetime(naive_end_of_time) + self.assertEqual(naive_end_of_time, message.ToDatetime()) - def dst(self, _): - return datetime.timedelta(0) + # Two hours after the Unix Epoch, around the world. + @_parameterized.named_parameters( + ('London', [1970, 1, 1, 2], datetime.timezone.utc), + ('Tokyo', [1970, 1, 1, 11], _TZ_JAPAN), + ('LA', [1969, 12, 31, 18], _TZ_PACIFIC), + ) + def testTimezoneAwareDatetimeConversion(self, date_parts, tzinfo): + original_datetime = datetime.datetime(*date_parts, tzinfo=tzinfo) # pylint:disable=g-tzinfo-datetime - 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( + datetime.datetime(1970, 1, 1, 2, tzinfo=datetime.timezone.utc), + aware_datetime) + self.assertEqual(tzinfo, aware_datetime.tzinfo) def testTimedeltaConversion(self): message = duration_pb2.Duration() @@ -295,85 +330,64 @@ def testTimedeltaConversion(self): def testInvalidTimestamp(self): message = timestamp_pb2.Timestamp() - self.assertRaisesRegexp( - ValueError, - 'Failed to parse timestamp: missing valid timezone offset.', - message.FromJsonString, - '') - self.assertRaisesRegexp( - ValueError, - 'Failed to parse timestamp: invalid trailing data ' - '1970-01-01T00:00:01Ztrail.', - message.FromJsonString, + self.assertRaisesRegex( + ValueError, 'Failed to parse timestamp: missing valid timezone offset.', + message.FromJsonString, '') + self.assertRaisesRegex( + ValueError, 'Failed to parse timestamp: invalid trailing data ' + '1970-01-01T00:00:01Ztrail.', message.FromJsonString, '1970-01-01T00:00:01Ztrail') - self.assertRaisesRegexp( - ValueError, - 'time data \'10000-01-01T00:00:00\' does not match' - ' format \'%Y-%m-%dT%H:%M:%S\'', - message.FromJsonString, '10000-01-01T00:00:00.00Z') - self.assertRaisesRegexp( - ValueError, - 'nanos 0123456789012 more than 9 fractional digits.', - message.FromJsonString, - '1970-01-01T00:00:00.0123456789012Z') - self.assertRaisesRegexp( + self.assertRaisesRegex( + ValueError, 'time data \'10000-01-01T00:00:00\' does not match' + ' format \'%Y-%m-%dT%H:%M:%S\'', message.FromJsonString, + '10000-01-01T00:00:00.00Z') + self.assertRaisesRegex( + ValueError, 'nanos 0123456789012 more than 9 fractional digits.', + message.FromJsonString, '1970-01-01T00:00:00.0123456789012Z') + self.assertRaisesRegex( ValueError, (r'Invalid timezone offset value: \+08.'), message.FromJsonString, - '1972-01-01T01:00:00.01+08',) - self.assertRaisesRegexp( - ValueError, - 'year (0 )?is out of range', - message.FromJsonString, - '0000-01-01T00:00:00Z') + '1972-01-01T01:00:00.01+08', + ) + self.assertRaisesRegex(ValueError, 'year (0 )?is out of range', + message.FromJsonString, '0000-01-01T00:00:00Z') message.seconds = 253402300800 - self.assertRaisesRegexp( - OverflowError, - 'date value out of range', - message.ToJsonString) + self.assertRaisesRegex(OverflowError, 'date value out of range', + message.ToJsonString) def testInvalidDuration(self): message = duration_pb2.Duration() - self.assertRaisesRegexp( - ValueError, - 'Duration must end with letter "s": 1.', - message.FromJsonString, '1') - self.assertRaisesRegexp( - ValueError, - 'Couldn\'t parse duration: 1...2s.', - message.FromJsonString, '1...2s') + self.assertRaisesRegex(ValueError, 'Duration must end with letter "s": 1.', + message.FromJsonString, '1') + self.assertRaisesRegex(ValueError, 'Couldn\'t parse duration: 1...2s.', + message.FromJsonString, '1...2s') text = '-315576000001.000000000s' - self.assertRaisesRegexp( + self.assertRaisesRegex( ValueError, r'Duration is not valid\: Seconds -315576000001 must be in range' - r' \[-315576000000\, 315576000000\].', - message.FromJsonString, text) + r' \[-315576000000\, 315576000000\].', message.FromJsonString, text) text = '315576000001.000000000s' - self.assertRaisesRegexp( + self.assertRaisesRegex( ValueError, r'Duration is not valid\: Seconds 315576000001 must be in range' - r' \[-315576000000\, 315576000000\].', - message.FromJsonString, text) + r' \[-315576000000\, 315576000000\].', message.FromJsonString, text) message.seconds = -315576000001 message.nanos = 0 - self.assertRaisesRegexp( + self.assertRaisesRegex( ValueError, r'Duration is not valid\: Seconds -315576000001 must be in range' - r' \[-315576000000\, 315576000000\].', - message.ToJsonString) + r' \[-315576000000\, 315576000000\].', message.ToJsonString) message.seconds = 0 message.nanos = 999999999 + 1 - self.assertRaisesRegexp( - ValueError, - r'Duration is not valid\: Nanos 1000000000 must be in range' - r' \[-999999999\, 999999999\].', - message.ToJsonString) + self.assertRaisesRegex( + ValueError, r'Duration is not valid\: Nanos 1000000000 must be in range' + r' \[-999999999\, 999999999\].', message.ToJsonString) message.seconds = -1 message.nanos = 1 - self.assertRaisesRegexp( - ValueError, - r'Duration is not valid\: Sign mismatch.', - message.ToJsonString) + self.assertRaisesRegex(ValueError, + r'Duration is not valid\: Sign mismatch.', + message.ToJsonString) class FieldMaskTest(unittest.TestCase): @@ -695,34 +709,29 @@ def testSnakeCaseToCamelCase(self): well_known_types._SnakeCaseToCamelCase('foo3_bar')) # No uppercase letter is allowed. - self.assertRaisesRegexp( + self.assertRaisesRegex( ValueError, 'Fail to print FieldMask to Json string: Path name Foo must ' 'not contain uppercase letters.', - well_known_types._SnakeCaseToCamelCase, - 'Foo') + well_known_types._SnakeCaseToCamelCase, 'Foo') # Any character after a "_" must be a lowercase letter. # 1. "_" cannot be followed by another "_". # 2. "_" cannot be followed by a digit. # 3. "_" cannot appear as the last character. - self.assertRaisesRegexp( + self.assertRaisesRegex( ValueError, 'Fail to print FieldMask to Json string: The character after a ' '"_" must be a lowercase letter in path name foo__bar.', - well_known_types._SnakeCaseToCamelCase, - 'foo__bar') - self.assertRaisesRegexp( + well_known_types._SnakeCaseToCamelCase, 'foo__bar') + self.assertRaisesRegex( ValueError, 'Fail to print FieldMask to Json string: The character after a ' '"_" must be a lowercase letter in path name foo_3bar.', - well_known_types._SnakeCaseToCamelCase, - 'foo_3bar') - self.assertRaisesRegexp( + well_known_types._SnakeCaseToCamelCase, 'foo_3bar') + self.assertRaisesRegex( ValueError, 'Fail to print FieldMask to Json string: Trailing "_" in path ' - 'name foo_bar_.', - well_known_types._SnakeCaseToCamelCase, - 'foo_bar_') + 'name foo_bar_.', well_known_types._SnakeCaseToCamelCase, 'foo_bar_') def testCamelCaseToSnakeCase(self): self.assertEqual('foo_bar', @@ -731,11 +740,10 @@ def testCamelCaseToSnakeCase(self): well_known_types._CamelCaseToSnakeCase('FooBar')) self.assertEqual('foo3_bar', well_known_types._CamelCaseToSnakeCase('foo3Bar')) - self.assertRaisesRegexp( + self.assertRaisesRegex( ValueError, 'Fail to parse FieldMask: Path name foo_bar must not contain "_"s.', - well_known_types._CamelCaseToSnakeCase, - 'foo_bar') + well_known_types._CamelCaseToSnakeCase, 'foo_bar') class StructTest(unittest.TestCase): diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index 21eb749b993a1..5024ed89d7d3a 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -95,7 +95,8 @@ def MessageToJson( sort_keys=False, use_integers_for_enums=False, descriptor_pool=None, - float_precision=None): + float_precision=None, + ensure_ascii=True): """Converts protobuf message to JSON format. Args: @@ -114,6 +115,8 @@ def MessageToJson( descriptor_pool: A Descriptor Pool for resolving types. If None use the default. float_precision: If set, use this to specify float field valid digits. + ensure_ascii: If True, strings with non-ASCII characters are escaped. + If False, Unicode strings are returned unchanged. Returns: A string containing the JSON formatted protocol buffer message. @@ -124,7 +127,7 @@ def MessageToJson( use_integers_for_enums, descriptor_pool, float_precision=float_precision) - return printer.ToJsonString(message, indent, sort_keys) + return printer.ToJsonString(message, indent, sort_keys, ensure_ascii) def MessageToDict( @@ -190,9 +193,10 @@ def __init__( else: self.float_format = None - def ToJsonString(self, message, indent, sort_keys): + def ToJsonString(self, message, indent, sort_keys, ensure_ascii): js = self._MessageToJsonObject(message) - return json.dumps(js, indent=indent, sort_keys=sort_keys) + return json.dumps( + js, indent=indent, sort_keys=sort_keys, ensure_ascii=ensure_ascii) def _MessageToJsonObject(self, message): """Converts message to an object according to Proto3 JSON Specification.""" @@ -395,12 +399,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 +416,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 +433,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 +450,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 +468,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 +524,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 +542,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 +557,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 +577,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 +632,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 +687,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 +765,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 +821,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 +837,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 +853,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 +866,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 +888,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/message.py b/python/google/protobuf/message.py index ee46d0e4c9c68..76c6802f70966 100644 --- a/python/google/protobuf/message.py +++ b/python/google/protobuf/message.py @@ -194,6 +194,9 @@ def ParseFromString(self, serialized): """Parse serialized protocol buffer data into this message. Like :func:`MergeFromString()`, except we clear the object first. + + Raises: + message.DecodeError if the input cannot be parsed. """ self.Clear() return self.MergeFromString(serialized) diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index a2993d908bfad..162531226e5f8 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -50,12 +50,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 { @@ -95,17 +96,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; @@ -236,23 +237,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()); @@ -264,7 +265,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; } } @@ -288,7 +289,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 = @@ -324,7 +325,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; @@ -345,9 +346,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 @@ -361,8 +362,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; @@ -373,10 +374,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; @@ -410,39 +411,43 @@ static int GcClear(PyObject* pself) { } static PyGetSetDef Getters[] = { - {NULL} + {nullptr}, }; PyTypeObject PyBaseDescriptor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME - ".DescriptorBase", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 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 + ".DescriptorBase", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + (destructor)Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 }; @@ -451,7 +456,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; } @@ -613,19 +618,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()); } @@ -636,94 +640,102 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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); @@ -851,7 +863,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; } @@ -942,6 +954,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)); } @@ -957,89 +977,95 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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); @@ -1125,76 +1151,81 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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); @@ -1252,63 +1283,68 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 { @@ -1340,7 +1376,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; } @@ -1350,8 +1386,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; @@ -1394,6 +1430,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)); } @@ -1418,31 +1458,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,46 +1498,50 @@ PyTypeObject PyFileDescriptor_Type = { sizeof(PyFileDescriptor), // tp_basicsize 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 - Py_TPFLAGS_DEFAULT, // tp_flags - "A File Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - file_descriptor::Methods, // tp_methods - 0, // tp_members - file_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // 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 - PyObject_GC_Del, // tp_free +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + file_descriptor::Methods, // tp_methods + nullptr, // tp_members + file_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // 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 + PyObject_GC_Del, // tp_free }; PyObject* PyFileDescriptor_FromDescriptor( const FileDescriptor* file_descriptor) { return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor, - NULL); + nullptr); } PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( @@ -1500,8 +1549,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 = @@ -1518,7 +1567,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); @@ -1566,6 +1615,7 @@ static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) { Py_RETURN_FALSE; } } + static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("has_options"); @@ -1586,64 +1636,69 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 { @@ -1682,14 +1737,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); @@ -1705,69 +1760,73 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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); @@ -1809,6 +1868,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)); } @@ -1818,62 +1885,70 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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. @@ -1882,7 +1957,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 4caff6941ad83..a87155bc4e4b7 100644 --- a/python/google/protobuf/pyext/descriptor_containers.cc +++ b/python/google/protobuf/pyext/descriptor_containers.cc @@ -58,12 +58,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 { @@ -158,59 +159,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; @@ -222,25 +220,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; } } @@ -258,13 +253,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); } @@ -286,7 +281,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; } @@ -345,11 +340,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); @@ -389,15 +384,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; } @@ -427,7 +422,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; @@ -437,28 +432,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; } @@ -468,13 +463,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); } @@ -484,13 +479,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); } @@ -500,22 +495,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()); @@ -540,56 +535,59 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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. @@ -600,7 +598,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); } @@ -610,15 +608,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); } @@ -633,7 +630,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; @@ -669,7 +666,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); } @@ -702,7 +699,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) { @@ -711,77 +708,80 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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; @@ -792,8 +792,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; @@ -803,14 +803,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; @@ -821,8 +821,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; @@ -840,8 +840,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; @@ -852,80 +852,83 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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; @@ -993,17 +996,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 @@ -1054,17 +1049,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 @@ -1106,17 +1101,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 @@ -1155,7 +1150,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); @@ -1181,17 +1176,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 @@ -1229,17 +1215,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 @@ -1281,17 +1267,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 @@ -1352,17 +1330,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 @@ -1410,17 +1380,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 @@ -1468,17 +1429,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 @@ -1530,17 +1483,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 @@ -1578,17 +1523,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 @@ -1626,17 +1563,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 @@ -1674,17 +1603,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 @@ -1710,17 +1631,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 @@ -1746,17 +1658,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 3bc99e7dbc633..5621a229ef217 100644 --- a/python/google/protobuf/pyext/descriptor_database.h +++ b/python/google/protobuf/pyext/descriptor_database.h @@ -43,17 +43,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. @@ -61,14 +62,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 f6bdb6e4c8ef6..2f392818303e4 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -44,12 +44,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 { @@ -99,13 +100,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; @@ -113,9 +114,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); @@ -131,8 +132,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; @@ -143,7 +144,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; @@ -152,10 +153,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; @@ -169,7 +170,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; @@ -178,13 +179,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); } @@ -230,24 +231,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"); @@ -264,14 +265,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); @@ -281,12 +282,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"); } @@ -302,12 +303,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"); } @@ -324,12 +325,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"); } @@ -345,12 +346,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"); } @@ -366,13 +367,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"); @@ -386,13 +387,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"); @@ -406,13 +407,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"); @@ -426,18 +427,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); @@ -445,10 +446,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; } @@ -457,8 +458,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; @@ -466,13 +467,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. } @@ -492,7 +493,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( @@ -500,7 +501,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; } @@ -509,7 +510,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( @@ -517,7 +518,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; } @@ -526,7 +527,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( @@ -534,7 +535,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; } @@ -543,7 +544,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( @@ -551,7 +552,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; } @@ -560,7 +561,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( @@ -568,7 +569,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; } @@ -579,12 +580,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( @@ -594,22 +595,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); } @@ -619,11 +620,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; } @@ -633,105 +634,109 @@ 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 PyTypeObject PyDescriptorPool_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME - ".DescriptorPool", // tp_name - sizeof(PyDescriptorPool), // tp_basicsize - 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 + ".DescriptorPool", // tp_name + sizeof(PyDescriptorPool), // tp_basicsize + 0, // tp_itemsize + cdescriptor_pool::Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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) @@ -744,7 +749,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; } @@ -775,7 +780,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..692029f682a6e 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,48 +361,52 @@ 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 PyTypeObject ExtensionDict_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) // - FULL_MODULE_NAME ".ExtensionDict", // tp_name - sizeof(ExtensionDict), // tp_basicsize - 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 + PyVarObject_HEAD_INIT(&PyType_Type, 0) // + FULL_MODULE_NAME ".ExtensionDict", // tp_name + sizeof(ExtensionDict), // tp_basicsize + 0, // tp_itemsize + (destructor)extension_dict::dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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) { @@ -438,37 +443,41 @@ PyTypeObject ExtensionIterator_Type = { sizeof(extension_dict::ExtensionIterator), // tp_basicsize 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 - 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 - 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 + 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 }; } // namespace python } // namespace protobuf diff --git a/python/google/protobuf/pyext/field.cc b/python/google/protobuf/pyext/field.cc index 5eab3ef2bc486..0d3b0b9607120 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,55 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 +131,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..4d516d29170e9 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, @@ -432,12 +432,12 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key, return -1; } - self->version++; - if (v) { // Set item to v. - reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, - map_key, &value); + if (reflection->InsertOrLookupMapValue( + message, self->parent_field_descriptor, map_key, &value)) { + self->version++; + } if (!PythonToMapValueRef(self, v, reflection->SupportsUnknownEnumValues(), &value)) { @@ -448,6 +448,7 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key, // Delete key from map. if (reflection->DeleteMapValue(message, self->parent_field_descriptor, map_key)) { + self->version++; return 0; } else { PyErr_Format(PyExc_KeyError, "Key not present in map"); @@ -460,22 +461,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 +487,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 +501,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 +543,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 +555,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 +580,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 +661,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 +674,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 +688,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 +705,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 +760,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 +772,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 +788,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 +825,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 +834,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 +853,64 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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..920c17d8d1388 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(); @@ -453,42 +454,46 @@ static bool allow_oversize_protos = false; static PyTypeObject _CMessageClass_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME - ".MessageMeta", // tp_name - sizeof(CMessageClass), // tp_basicsize - 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 + ".MessageMeta", // tp_name + sizeof(CMessageClass), // tp_basicsize + 0, // tp_itemsize + message_meta::Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, /* tp_print */ +#else + 0, /* tp_vectorcall_offset */ +#endif + 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 +501,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; } @@ -571,32 +576,24 @@ template bool CheckAndGetInteger(PyObject* arg, T* value) { // This effectively defines an integer as "an object that can be cast as // an integer and can be used as an ordinal number". - // This definition includes everything that implements numbers.Integral + // This definition includes everything with a valid __index__() implementation // and shouldn't cast the net too wide. - if (PROTOBUF_PREDICT_FALSE(!PyIndex_Check(arg))) { - FormatTypeError(arg, "int, long"); + if (!strcmp(Py_TYPE(arg)->tp_name, "numpy.ndarray") || + PROTOBUF_PREDICT_FALSE(!PyIndex_Check(arg))) { + FormatTypeError(arg, "int"); + return false; + } + + PyObject* arg_py_int = PyNumber_Index(arg); + if (PyErr_Occurred()) { + // Propagate existing error. return false; } - // Now we have an integral number so we can safely use PyLong_ functions. - // We need to treat the signed and unsigned cases differently in case arg is - // holding a value above the maximum for signed longs. if (std::numeric_limits::min() == 0) { // Unsigned case. - unsigned PY_LONG_LONG ulong_result; - if (PyLong_Check(arg)) { - ulong_result = PyLong_AsUnsignedLongLong(arg); - } else { - // Unlike PyLong_AsLongLong, PyLong_AsUnsignedLongLong is very - // picky about the exact type. - PyObject* casted = PyNumber_Long(arg); - if (PROTOBUF_PREDICT_FALSE(casted == nullptr)) { - // Propagate existing error. - return false; - } - ulong_result = PyLong_AsUnsignedLongLong(casted); - Py_DECREF(casted); - } + unsigned PY_LONG_LONG ulong_result = PyLong_AsUnsignedLongLong(arg_py_int); + Py_DECREF(arg_py_int); if (VerifyIntegerCastAndRange(arg, ulong_result)) { *value = static_cast(ulong_result); @@ -605,30 +602,14 @@ bool CheckAndGetInteger(PyObject* arg, T* value) { } } else { // Signed case. - PY_LONG_LONG long_result; - PyNumberMethods *nb; - if ((nb = arg->ob_type->tp_as_number) != NULL && nb->nb_int != NULL) { - // PyLong_AsLongLong requires it to be a long or to have an __int__() - // method. - long_result = PyLong_AsLongLong(arg); - } else { - // Valid subclasses of numbers.Integral should have a __long__() method - // so fall back to that. - PyObject* casted = PyNumber_Long(arg); - if (PROTOBUF_PREDICT_FALSE(casted == nullptr)) { - // Propagate existing error. - return false; - } - long_result = PyLong_AsLongLong(casted); - Py_DECREF(casted); - } + Py_DECREF(arg_py_int); + PY_LONG_LONG long_result = PyLong_AsLongLong(arg); if (VerifyIntegerCastAndRange(arg, long_result)) { *value = static_cast(long_result); } else { return false; } } - return true; } @@ -641,8 +622,9 @@ template bool CheckAndGetInteger(PyObject*, uint64*); bool CheckAndGetDouble(PyObject* arg, double* value) { *value = PyFloat_AsDouble(arg); - if (PROTOBUF_PREDICT_FALSE(*value == -1 && PyErr_Occurred())) { - FormatTypeError(arg, "int, long, float"); + if (!strcmp(Py_TYPE(arg)->tp_name, "numpy.ndarray") || + PROTOBUF_PREDICT_FALSE(*value == -1 && PyErr_Occurred())) { + FormatTypeError(arg, "int, float"); return false; } return true; @@ -659,8 +641,9 @@ bool CheckAndGetFloat(PyObject* arg, float* value) { bool CheckAndGetBool(PyObject* arg, bool* value) { long long_value = PyLong_AsLong(arg); // NOLINT - if (long_value == -1 && PyErr_Occurred()) { - FormatTypeError(arg, "int, long, bool"); + if (!strcmp(Py_TYPE(arg)->tp_name, "numpy.ndarray") || + (long_value == -1 && PyErr_Occurred())) { + FormatTypeError(arg, "int, bool"); return false; } *value = static_cast(long_value); @@ -672,7 +655,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 +680,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 +691,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 +724,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 +752,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()); } @@ -802,7 +786,6 @@ PyMessageFactory* GetFactoryForMessage(CMessage* message) { static int MaybeReleaseOverlappingOneofField( CMessage* cmessage, const FieldDescriptor* field) { -#ifdef GOOGLE_PROTOBUF_HAS_ONEOF Message* message = cmessage->message; const Reflection* reflection = message->GetReflection(); if (!field->containing_oneof() || @@ -822,7 +805,6 @@ static int MaybeReleaseOverlappingOneofField( if (InternalReleaseFieldByDescriptor(cmessage, existing_field) < 0) { return -1; } -#endif return 0; } @@ -864,7 +846,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 +869,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 +888,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 +899,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()); } @@ -1000,7 +982,7 @@ int DeleteRepeatedField( } } - Arena* arena = Arena::InternalHelper::GetArenaForAllocation(message); + Arena* arena = Arena::InternalGetArenaForAllocation(message); GOOGLE_DCHECK_EQ(arena, nullptr) << "python protobuf is expected to be allocated from heap"; // Remove items, starting from the end. @@ -1038,12 +1020,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 +1039,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 +1056,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 +1081,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 +1123,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 +1147,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 +1173,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 +1191,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 +1295,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 +1342,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 +1380,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 +1410,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 +1421,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 +1565,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 +1605,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 +1619,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 +1630,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 +1668,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 +1697,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 +1773,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 +1786,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 +1797,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 +1805,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 +1819,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 +1835,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 +1855,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 +1868,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 +1890,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 NULL; + 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 nullptr; } + // 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 +1925,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 +1938,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 +1969,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 +1997,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 +2007,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 +2045,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 +2061,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 +2080,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 +2135,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 +2206,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 +2298,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 +2333,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 +2372,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 +2401,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 +2412,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 +2444,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 +2515,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 +2526,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 +2555,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 +2566,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 +2582,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 +2598,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 +2679,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 +2709,51 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 +2763,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 +2782,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 +2791,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 +2805,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 +2878,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 +2946,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 +3030,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 +3039,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 +3048,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 5098379f35c52..bc44dd4572192 100644 --- a/python/google/protobuf/pyext/message_factory.cc +++ b/python/google/protobuf/pyext/message_factory.cc @@ -39,12 +39,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 { @@ -55,8 +56,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(); @@ -73,25 +74,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; } } @@ -162,8 +163,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( @@ -171,24 +172,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); } @@ -200,17 +201,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()); @@ -224,14 +225,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); @@ -239,8 +241,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,38 +253,42 @@ PyTypeObject PyMessageFactory_Type = { sizeof(PyMessageFactory), // tp_basicsize 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 a0806a3160a5f..2d3c1d20874c2 100644 --- a/python/google/protobuf/pyext/message_module.cc +++ b/python/google/protobuf/pyext/message_module.cc @@ -94,28 +94,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 @@ -127,7 +127,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 985df2c3bb4ef..ad3fa9462d4dc 100644 --- a/python/google/protobuf/pyext/scoped_pyobject_ptr.h +++ b/python/google/protobuf/pyext/scoped_pyobject_ptr.h @@ -48,7 +48,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. @@ -60,7 +60,7 @@ class ScopedPythonPtr { // This function must be called with a reference that you own. // this->reset(this->get()) is wrong! // this->reset(this->release()) is OK. - PyObjectStruct* reset(PyObjectStruct* p = NULL) { + PyObjectStruct* reset(PyObjectStruct* p = nullptr) { Py_XDECREF(ptr_); ptr_ = p; return ptr_; @@ -70,7 +70,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 6d919b361ad94..dcd63b2e29ad0 100644 --- a/python/google/protobuf/pyext/unknown_fields.cc +++ b/python/google/protobuf/pyext/unknown_fields.cc @@ -50,7 +50,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."); @@ -65,7 +65,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(); } @@ -75,11 +75,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) { @@ -89,7 +89,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); @@ -98,8 +98,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; @@ -117,8 +117,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); @@ -138,58 +138,63 @@ static void Dealloc(PyObject* pself) { reinterpret_cast(self->parent)->unknown_field_set = nullptr; } Py_CLEAR(self->parent); + auto* py_type = Py_TYPE(pself); self->~PyUnknownFields(); - Py_TYPE(pself)->tp_free(pself); + py_type->tp_free(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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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 { @@ -197,8 +202,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; @@ -213,26 +218,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; } Py_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()); } @@ -240,8 +245,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 @@ -269,19 +274,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(), @@ -302,54 +307,57 @@ 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 +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + 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/google/protobuf/service_reflection.py b/python/google/protobuf/service_reflection.py index 75c51ff3221af..f82ab7145a601 100644 --- a/python/google/protobuf/service_reflection.py +++ b/python/google/protobuf/service_reflection.py @@ -133,7 +133,7 @@ def __init__(self, service_descriptor): """ self.descriptor = service_descriptor - def BuildService(self, cls): + def BuildService(builder, cls): """Constructs the service class. Args: @@ -143,18 +143,26 @@ def BuildService(self, cls): # CallMethod needs to operate with an instance of the Service class. This # internal wrapper function exists only to be able to pass the service # instance to the method that does the real CallMethod work. - def _WrapCallMethod(srvc, method_descriptor, - rpc_controller, request, callback): - return self._CallMethod(srvc, method_descriptor, - rpc_controller, request, callback) - self.cls = cls + # Making sure to use exact argument names from the abstract interface in + # service.py to match the type signature + def _WrapCallMethod(self, method_descriptor, rpc_controller, request, done): + return builder._CallMethod(self, method_descriptor, rpc_controller, + request, done) + + def _WrapGetRequestClass(self, method_descriptor): + return builder._GetRequestClass(method_descriptor) + + def _WrapGetResponseClass(self, method_descriptor): + return builder._GetResponseClass(method_descriptor) + + builder.cls = cls cls.CallMethod = _WrapCallMethod - cls.GetDescriptor = staticmethod(lambda: self.descriptor) - cls.GetDescriptor.__doc__ = "Returns the service descriptor." - cls.GetRequestClass = self._GetRequestClass - cls.GetResponseClass = self._GetResponseClass - for method in self.descriptor.methods: - setattr(cls, method.name, self._GenerateNonImplementedMethod(method)) + cls.GetDescriptor = staticmethod(lambda: builder.descriptor) + cls.GetDescriptor.__doc__ = 'Returns the service descriptor.' + cls.GetRequestClass = _WrapGetRequestClass + cls.GetResponseClass = _WrapGetResponseClass + for method in builder.descriptor.methods: + setattr(cls, method.name, builder._GenerateNonImplementedMethod(method)) def _CallMethod(self, srvc, method_descriptor, rpc_controller, request, callback): 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/setup.py b/python/setup.py index 4a6161c21fa6b..127476184c411 100755 --- a/python/setup.py +++ b/python/setup.py @@ -1,6 +1,9 @@ #! /usr/bin/env python # # See README for usage instructions. + +# pylint:disable=missing-module-docstring +# pylint:disable=g-bad-import-order from distutils import util import fnmatch import glob @@ -10,7 +13,9 @@ import subprocess import sys import sysconfig -import platform + +# pylint:disable=g-importing-member +# pylint:disable=g-multiple-import # We must use setuptools, not distutils, because we need to use the # namespace_packages option for the "google" package. @@ -24,44 +29,52 @@ # Find the Protocol Compiler. if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']): protoc = os.environ['PROTOC'] -elif os.path.exists("../src/protoc"): - protoc = "../src/protoc" -elif os.path.exists("../src/protoc.exe"): - protoc = "../src/protoc.exe" -elif os.path.exists("../vsprojects/Debug/protoc.exe"): - protoc = "../vsprojects/Debug/protoc.exe" -elif os.path.exists("../vsprojects/Release/protoc.exe"): - protoc = "../vsprojects/Release/protoc.exe" +elif os.path.exists('../src/protoc'): + protoc = '../src/protoc' +elif os.path.exists('../src/protoc.exe'): + protoc = '../src/protoc.exe' +elif os.path.exists('../vsprojects/Debug/protoc.exe'): + protoc = '../vsprojects/Debug/protoc.exe' +elif os.path.exists('../vsprojects/Release/protoc.exe'): + protoc = '../vsprojects/Release/protoc.exe' else: - protoc = find_executable("protoc") + protoc = find_executable('protoc') def GetVersion(): - """Gets the version from google/protobuf/__init__.py + """Reads and returns the version from google/protobuf/__init__.py. Do not import google.protobuf.__init__ directly, because an installed - protobuf library may be loaded instead.""" + protobuf library may be loaded instead. + + Returns: + The version. + """ with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file: - exec(version_file.read(), globals()) - global __version__ - return __version__ + exec(version_file.read(), globals()) # pylint:disable=exec-used + return __version__ # pylint:disable=undefined-variable + +def GenProto(source, require=True): + """Generates a _pb2.py from the given .proto file. -def generate_proto(source, require = True): - """Invokes the Protocol Compiler to generate a _pb2.py from the given - .proto file. Does nothing if the output already exists and is newer than - the input.""" + Does nothing if the output already exists and is newer than the input. + + Args: + source: the .proto file path. + require: if True, exit immediately when a path is not found. + """ if not require and not os.path.exists(source): return - output = source.replace(".proto", "_pb2.py").replace("../src/", "") + output = source.replace('.proto', '_pb2.py').replace('../src/', '') if (not os.path.exists(output) or (os.path.exists(source) and os.path.getmtime(source) > os.path.getmtime(output))): - print("Generating %s..." % output) + print('Generating %s...' % output) if not os.path.exists(source): sys.stderr.write("Can't find required file: %s\n" % source) @@ -69,78 +82,87 @@ def generate_proto(source, require = True): if protoc is None: sys.stderr.write( - "protoc is not installed nor found in ../src. Please compile it " - "or install the binary package.\n") + 'protoc is not installed nor found in ../src. Please compile it ' + 'or install the binary package.\n') sys.exit(-1) - protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ] + protoc_command = [protoc, '-I../src', '-I.', '--python_out=.', source] if subprocess.call(protoc_command) != 0: sys.exit(-1) + def GenerateUnittestProtos(): - generate_proto("../src/google/protobuf/any_test.proto", False) - generate_proto("../src/google/protobuf/map_proto2_unittest.proto", False) - generate_proto("../src/google/protobuf/map_unittest.proto", False) - generate_proto("../src/google/protobuf/test_messages_proto3.proto", False) - generate_proto("../src/google/protobuf/test_messages_proto2.proto", False) - generate_proto("../src/google/protobuf/unittest_arena.proto", False) - generate_proto("../src/google/protobuf/unittest.proto", False) - generate_proto("../src/google/protobuf/unittest_custom_options.proto", False) - generate_proto("../src/google/protobuf/unittest_import.proto", False) - generate_proto("../src/google/protobuf/unittest_import_public.proto", False) - generate_proto("../src/google/protobuf/unittest_mset.proto", False) - generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False) - generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False) - generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False) - generate_proto("../src/google/protobuf/util/json_format.proto", False) - generate_proto("../src/google/protobuf/util/json_format_proto3.proto", False) - generate_proto("google/protobuf/internal/any_test.proto", False) - generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False) - generate_proto("google/protobuf/internal/descriptor_pool_test2.proto", False) - generate_proto("google/protobuf/internal/factory_test1.proto", False) - generate_proto("google/protobuf/internal/factory_test2.proto", False) - generate_proto("google/protobuf/internal/file_options_test.proto", False) - generate_proto("google/protobuf/internal/import_test_package/inner.proto", False) - generate_proto("google/protobuf/internal/import_test_package/outer.proto", False) - generate_proto("google/protobuf/internal/missing_enum_values.proto", False) - generate_proto("google/protobuf/internal/message_set_extensions.proto", False) - generate_proto("google/protobuf/internal/more_extensions.proto", False) - generate_proto("google/protobuf/internal/more_extensions_dynamic.proto", False) - generate_proto("google/protobuf/internal/more_messages.proto", False) - generate_proto("google/protobuf/internal/no_package.proto", False) - generate_proto("google/protobuf/internal/packed_field_test.proto", False) - generate_proto("google/protobuf/internal/test_bad_identifiers.proto", False) - generate_proto("google/protobuf/internal/test_proto3_optional.proto", False) - generate_proto("google/protobuf/pyext/python.proto", False) - - -class clean(_clean): + """Generates protobuf code for unittests.""" + GenProto('../src/google/protobuf/any_test.proto', False) + GenProto('../src/google/protobuf/map_proto2_unittest.proto', False) + GenProto('../src/google/protobuf/map_unittest.proto', False) + GenProto('../src/google/protobuf/test_messages_proto3.proto', False) + GenProto('../src/google/protobuf/test_messages_proto2.proto', False) + GenProto('../src/google/protobuf/unittest_arena.proto', False) + GenProto('../src/google/protobuf/unittest.proto', False) + GenProto('../src/google/protobuf/unittest_custom_options.proto', False) + GenProto('../src/google/protobuf/unittest_import.proto', False) + GenProto('../src/google/protobuf/unittest_import_public.proto', False) + GenProto('../src/google/protobuf/unittest_mset.proto', False) + GenProto('../src/google/protobuf/unittest_mset_wire_format.proto', False) + GenProto('../src/google/protobuf/unittest_no_generic_services.proto', False) + GenProto('../src/google/protobuf/unittest_proto3_arena.proto', False) + GenProto('../src/google/protobuf/util/json_format.proto', False) + GenProto('../src/google/protobuf/util/json_format_proto3.proto', False) + GenProto('google/protobuf/internal/any_test.proto', False) + GenProto('google/protobuf/internal/descriptor_pool_test1.proto', False) + GenProto('google/protobuf/internal/descriptor_pool_test2.proto', False) + GenProto('google/protobuf/internal/factory_test1.proto', False) + GenProto('google/protobuf/internal/factory_test2.proto', False) + GenProto('google/protobuf/internal/file_options_test.proto', False) + GenProto('google/protobuf/internal/import_test_package/import_public.proto', False) + GenProto('google/protobuf/internal/import_test_package/import_public_nested.proto', False) + GenProto('google/protobuf/internal/import_test_package/inner.proto', False) + GenProto('google/protobuf/internal/import_test_package/outer.proto', False) + GenProto('google/protobuf/internal/missing_enum_values.proto', False) + GenProto('google/protobuf/internal/message_set_extensions.proto', False) + GenProto('google/protobuf/internal/more_extensions.proto', False) + GenProto('google/protobuf/internal/more_extensions_dynamic.proto', False) + GenProto('google/protobuf/internal/more_messages.proto', False) + GenProto('google/protobuf/internal/no_package.proto', False) + GenProto('google/protobuf/internal/packed_field_test.proto', False) + GenProto('google/protobuf/internal/test_bad_identifiers.proto', False) + GenProto('google/protobuf/internal/test_proto3_optional.proto', False) + GenProto('google/protobuf/pyext/python.proto', False) + + +class CleanCmd(_clean): + """Custom clean command for building the protobuf extension.""" + def run(self): # Delete generated files in the code tree. - for (dirpath, dirnames, filenames) in os.walk("."): + for (dirpath, unused_dirnames, filenames) in os.walk('.'): for filename in filenames: filepath = os.path.join(dirpath, filename) - if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \ - filepath.endswith(".so") or filepath.endswith(".o"): + if (filepath.endswith('_pb2.py') or filepath.endswith('.pyc') or + filepath.endswith('.so') or filepath.endswith('.o')): os.remove(filepath) # _clean is an old-style class, so super() doesn't work. _clean.run(self) -class build_py(_build_py): + +class BuildPyCmd(_build_py): + """Custom build_py command for building the protobuf runtime.""" + def run(self): # Generate necessary .proto file if it doesn't exist. - generate_proto("../src/google/protobuf/descriptor.proto") - generate_proto("../src/google/protobuf/compiler/plugin.proto") - generate_proto("../src/google/protobuf/any.proto") - generate_proto("../src/google/protobuf/api.proto") - generate_proto("../src/google/protobuf/duration.proto") - generate_proto("../src/google/protobuf/empty.proto") - generate_proto("../src/google/protobuf/field_mask.proto") - generate_proto("../src/google/protobuf/source_context.proto") - generate_proto("../src/google/protobuf/struct.proto") - generate_proto("../src/google/protobuf/timestamp.proto") - generate_proto("../src/google/protobuf/type.proto") - generate_proto("../src/google/protobuf/wrappers.proto") + GenProto('../src/google/protobuf/descriptor.proto') + GenProto('../src/google/protobuf/compiler/plugin.proto') + GenProto('../src/google/protobuf/any.proto') + GenProto('../src/google/protobuf/api.proto') + GenProto('../src/google/protobuf/duration.proto') + GenProto('../src/google/protobuf/empty.proto') + GenProto('../src/google/protobuf/field_mask.proto') + GenProto('../src/google/protobuf/source_context.proto') + GenProto('../src/google/protobuf/struct.proto') + GenProto('../src/google/protobuf/timestamp.proto') + GenProto('../src/google/protobuf/type.proto') + GenProto('../src/google/protobuf/wrappers.proto') GenerateUnittestProtos() # _build_py is an old-style class, so super() doesn't work. @@ -148,17 +170,18 @@ def run(self): def find_package_modules(self, package, package_dir): exclude = ( - "*test*", - "google/protobuf/internal/*_pb2.py", - "google/protobuf/internal/_parameterized.py", - "google/protobuf/pyext/python_pb2.py", + '*test*', + 'google/protobuf/internal/*_pb2.py', + 'google/protobuf/internal/_parameterized.py', + 'google/protobuf/pyext/python_pb2.py', ) modules = _build_py.find_package_modules(self, package, package_dir) return [(pkg, mod, fil) for (pkg, mod, fil) in modules if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)] -class build_ext(_build_ext): +class BuildExtCmd(_build_ext): + """Command class for building the protobuf Python extension.""" def get_ext_filename(self, ext_name): # since python3.5, python extensions' shared libraries use a suffix that @@ -169,23 +192,25 @@ def get_ext_filename(self, ext_name): # suffix so that the resulting file name matches the target architecture # and we end up with a well-formed wheel. filename = _build_ext.get_ext_filename(self, ext_name) - orig_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") - new_ext_suffix = os.getenv("PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX") + orig_ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') + new_ext_suffix = os.getenv('PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX') if new_ext_suffix and filename.endswith(orig_ext_suffix): filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix return filename -class test_conformance(_build_py): + +class TestConformanceCmd(_build_py): target = 'test_python' + def run(self): # Python 2.6 dodges these extra failures. - os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = ( - "--failure_list failure_list_python-post26.txt") - cmd = 'cd ../conformance && make %s' % (test_conformance.target) - status = subprocess.check_call(cmd, shell=True) + os.environ['CONFORMANCE_PYTHON_EXTRA_FAILURES'] = ( + '--failure_list failure_list_python-post26.txt') + cmd = 'cd ../conformance && make %s' % (TestConformanceCmd.target) + subprocess.check_call(cmd, shell=True) -def get_option_from_sys_argv(option_str): +def GetOptionFromArgv(option_str): if option_str in sys.argv: sys.argv.remove(option_str) return True @@ -195,32 +220,36 @@ def get_option_from_sys_argv(option_str): if __name__ == '__main__': ext_module_list = [] warnings_as_errors = '--warnings_as_errors' - if get_option_from_sys_argv('--cpp_implementation'): + if GetOptionFromArgv('--cpp_implementation'): # Link libprotobuf.a and libprotobuf-lite.a statically with the # extension. Note that those libraries have to be compiled with # -fPIC for this to work. - compile_static_ext = get_option_from_sys_argv('--compile_static_extension') + compile_static_ext = GetOptionFromArgv('--compile_static_extension') libraries = ['protobuf'] extra_objects = None if compile_static_ext: libraries = None extra_objects = ['../src/.libs/libprotobuf.a', '../src/.libs/libprotobuf-lite.a'] - test_conformance.target = 'test_python_cpp' + TestConformanceCmd.target = 'test_python_cpp' extra_compile_args = [] message_extra_link_args = None api_implementation_link_args = None - if "darwin" in sys.platform: + if 'darwin' in sys.platform: if sys.version_info[0] == 2: - message_init_symbol = 'init_message' - api_implementation_init_symbol = 'init_api_implementation' + message_init_symbol = 'init_message' + api_implementation_init_symbol = 'init_api_implementation' else: - message_init_symbol = 'PyInit__message' - api_implementation_init_symbol = 'PyInit__api_implementation' - message_extra_link_args = ['-Wl,-exported_symbol,_%s' % message_init_symbol] - api_implementation_link_args = ['-Wl,-exported_symbol,_%s' % api_implementation_init_symbol] + message_init_symbol = 'PyInit__message' + api_implementation_init_symbol = 'PyInit__api_implementation' + message_extra_link_args = [ + '-Wl,-exported_symbol,_%s' % message_init_symbol + ] + api_implementation_link_args = [ + '-Wl,-exported_symbol,_%s' % api_implementation_init_symbol + ] if sys.platform != 'win32': extra_compile_args.append('-Wno-write-strings') @@ -230,8 +259,8 @@ def get_option_from_sys_argv(option_str): extra_compile_args.append('-std=c++11') if sys.platform == 'darwin': - extra_compile_args.append("-Wno-shorten-64-to-32"); - extra_compile_args.append("-Wno-deprecated-register"); + extra_compile_args.append('-Wno-shorten-64-to-32') + extra_compile_args.append('-Wno-deprecated-register') # https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes # C++ projects must now migrate to libc++ and are recommended to set a @@ -239,7 +268,7 @@ def get_option_from_sys_argv(option_str): if sys.platform == 'darwin': mac_target = str(sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')) if mac_target and (pkg_resources.parse_version(mac_target) < - pkg_resources.parse_version('10.9.0')): + pkg_resources.parse_version('10.9.0')): os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9' os.environ['_PYTHON_HOST_PLATFORM'] = re.sub( r'macosx-[0-9]+\.[0-9]+-(.+)', r'macosx-10.9-\1', @@ -254,10 +283,10 @@ def get_option_from_sys_argv(option_str): extra_compile_args.append('-DMS_WIN64') # MSVS default is dymanic - if (sys.platform == 'win32'): + if sys.platform == 'win32': extra_compile_args.append('/MT') - if "clang" in os.popen('$CC --version 2> /dev/null').read(): + if 'clang' in os.popen('$CC --version 2> /dev/null').read(): extra_compile_args.append('-Wno-shorten-64-to-32') if warnings_as_errors in sys.argv: @@ -267,9 +296,9 @@ def get_option_from_sys_argv(option_str): # C++ implementation extension ext_module_list.extend([ Extension( - "google.protobuf.pyext._message", + 'google.protobuf.pyext._message', glob.glob('google/protobuf/pyext/*.cc'), - include_dirs=[".", "../src"], + include_dirs=['.', '../src'], libraries=libraries, extra_objects=extra_objects, extra_link_args=message_extra_link_args, @@ -277,9 +306,10 @@ def get_option_from_sys_argv(option_str): extra_compile_args=extra_compile_args, ), Extension( - "google.protobuf.internal._api_implementation", + 'google.protobuf.internal._api_implementation', glob.glob('google/protobuf/internal/api_implementation.cc'), - extra_compile_args=extra_compile_args + ['-DPYTHON_PROTO2_CPP_IMPL_V2'], + extra_compile_args=(extra_compile_args + + ['-DPYTHON_PROTO2_CPP_IMPL_V2']), extra_link_args=api_implementation_link_args, ), ]) @@ -297,16 +327,14 @@ def get_option_from_sys_argv(option_str): url='https://developers.google.com/protocol-buffers/', maintainer='protobuf@googlegroups.com', maintainer_email='protobuf@googlegroups.com', - license='3-Clause BSD License', + license='BSD-3-Clause', classifiers=[ - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', ], namespace_packages=['google'], packages=find_packages( @@ -316,12 +344,12 @@ def get_option_from_sys_argv(option_str): ],), test_suite='google.protobuf.internal', cmdclass={ - 'clean': clean, - 'build_py': build_py, - 'build_ext': build_ext, - 'test_conformance': test_conformance, + 'clean': CleanCmd, + 'build_py': BuildPyCmd, + 'build_ext': BuildExtCmd, + 'test_conformance': TestConformanceCmd, }, install_requires=install_requires, ext_modules=ext_module_list, - python_requires=">=3.5", + python_requires='>=3.7', ) diff --git a/python/tox.ini b/python/tox.ini index 7142b86f0fdf0..b923a4a58ea02 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{35,36,37,38,39,310}-{cpp,python} + py{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,310}-cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + py{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/Rakefile b/ruby/Rakefile index 89b9ca5bfcef1..1892e6209fe39 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -80,6 +80,16 @@ 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/naive.c", "ext/google/protobuf_c/third_party/utf8_range") + FileUtils.cp("../third_party/utf8_range/range2-neon.c", "ext/google/protobuf_c/third_party/utf8_range") + FileUtils.cp("../third_party/utf8_range/range2-sse.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, @@ -117,7 +127,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 + IN_DOCKER=true rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem RUBY_CC_VERSION=3.1.0:3.0.0:2.7.0:2.6.0:2.5.0 EOT end end @@ -125,7 +135,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" + system "rake cross native gem RUBY_CC_VERSION=3.1.0: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/compatibility_tests/v3.0.0/tests/repeated_field_test.rb b/ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb index 4f70f52dc4a96..caebde1db781e 100755 --- a/ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb +++ b/ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb @@ -21,6 +21,7 @@ def test_acts_like_an_array :nitems, :iter_for_reverse_each, :indexes, :append, :prepend] arr_methods -= [:union, :difference, :filter!] arr_methods -= [:intersection, :deconstruct] # ruby 2.7 methods we can ignore + arr_methods -= [:intersect?] # ruby 3.1 methods we can ignore arr_methods.each do |method_name| assert m.repeated_string.respond_to?(method_name) == true, "does not respond to #{method_name}" end diff --git a/ruby/ext/google/protobuf_c/convert.c b/ruby/ext/google/protobuf_c/convert.c index 8bcf6eee00673..bdc71599fbe90 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) { + if (rb_obj_class(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))); + } else if (rb_obj_class(value) != rb_cString) { + 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))); + if (rb_obj_class(value) != rb_cString) { + 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: - return Wyhash(&val, 1, seed, kWyhashSalt); - case UPB_TYPE_FLOAT: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_ENUM: - return Wyhash(&val, 4, seed, kWyhashSalt); - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: - return Wyhash(&val, 8, seed, kWyhashSalt); - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - return Wyhash(val.str_val.data, val.str_val.size, seed, kWyhashSalt); - case UPB_TYPE_MESSAGE: + case kUpb_CType_Bool: + return _upb_Hash(&val, 1, seed); + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + return _upb_Hash(&val, 4, seed); + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return _upb_Hash(&val, 8, seed); + case kUpb_CType_String: + case kUpb_CType_Bytes: + return _upb_Hash(val.str_val.data, val.str_val.size, seed); + 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..3bd18e840028a 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,14 +151,15 @@ 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)); } + RB_GC_GUARD(arena_rb); return get_filedef_obj(_self, filedef); } @@ -172,15 +173,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 +203,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 +222,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 +236,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 +281,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 +294,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 +307,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 +319,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 +338,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 +355,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 +374,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 +396,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 +416,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 +428,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 +455,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 +464,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 +477,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 +493,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 +518,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 +530,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 +571,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 +584,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 +616,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 +656,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 +667,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 +685,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 +701,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 +724,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 +738,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 +761,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 +782,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 +802,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 +822,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 +843,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 +883,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 +928,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 +937,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 +950,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 +961,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 +972,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 +987,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 +1001,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 +1022,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 +1043,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 +1057,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 +1068,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 +1080,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 +1100,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 +1118,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 +1144,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 +1171,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 +1179,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 +1205,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 +1214,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 +1235,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 +1253,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..8bc96ae84a391 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", + "naive.c", "range2-neon.c", "range2-sse.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 2f6de4d8bad33..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); } 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 d07eba760d239..6b8bbaa3c5e54 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,17 @@ 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_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(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 +189,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 IsFieldWrapper(const upb_FieldDef* f) { + return IsWrapper(upb_FieldDef_MessageSubDef(f)); } -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 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 +225,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 +240,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_FindFieldByNumber(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_FindFieldByNumber(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 +437,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 +475,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 +494,54 @@ 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_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(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 +550,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 +613,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 +629,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 +655,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 +666,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 +680,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 +732,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); + uint64_t ret = _upb_Hash(data, size, seed); + upb_Arena_Free(arena); return ret; } else { - upb_arena_free(arena); + upb_Arena_Free(arena); rb_raise(cParseError, "Error calculating hash"); } } @@ -759,13 +787,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 +801,55 @@ 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_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(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 +863,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 +907,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,32 +928,54 @@ 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; } /* * call-seq: - * MessageClass.decode(data) => message + * MessageClass.decode(data, options) => message * * Decodes the given data (as a string containing bytes in protocol buffers wire * format) under the interpretration given by this message class's definition * and returns a message object with the corresponding field values. + * @param options [Hash] options for the decoder + * recursion_limit: set to maximum decoding depth for message (default is 64) */ -static VALUE Message_decode(VALUE klass, VALUE data) { +static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) { + VALUE data = argv[0]; + int options = 0; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + + VALUE depth = rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit"))); + + if (depth != Qnil && TYPE(depth) == T_FIXNUM) { + options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth)); + } + } + if (TYPE(data) != T_STRING) { rb_raise(rb_eArgError, "Expected string for binary protobuf data."); } @@ -932,9 +983,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, options, Arena_get(msg->arena)); + + if (status != kUpb_DecodeStatus_Ok) { rb_raise(cParseError, "Error occurred during parsing"); } @@ -956,10 +1009,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 +1024,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 +1042,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; @@ -1005,32 +1059,51 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { /* * call-seq: - * MessageClass.encode(msg) => bytes + * MessageClass.encode(msg, options) => bytes * * Encodes the given message object to its serialized form in protocol buffers * wire format. + * @param options [Hash] options for the encoder + * recursion_limit: set to maximum encoding depth for message (default is 64) */ -static VALUE Message_encode(VALUE klass, VALUE msg_rb) { - Message* msg = ruby_to_Message(msg_rb); - const char *data; +static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) { + Message* msg = ruby_to_Message(argv[0]); + int options = 0; + const char* data; size_t size; - if (CLASS_OF(msg_rb) != klass) { + if (CLASS_OF(argv[0]) != klass) { rb_raise(rb_eArgError, "Message of wrong type."); } - upb_arena *arena = upb_arena_new(); + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } - data = upb_encode(msg->msg, upb_msgdef_layout(msg->msgdef), arena, - &size); + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + VALUE depth = rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit"))); + + if (depth != Qnil && TYPE(depth) == T_FIXNUM) { + options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth)); + } + } + + upb_Arena *arena = upb_Arena_New(); + + data = upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), + options, 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)"); } } @@ -1041,18 +1114,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."); @@ -1061,35 +1135,39 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) { if (argc == 2) { VALUE hash_args = argv[1]; if (TYPE(hash_args) != T_HASH) { - rb_raise(rb_eArgError, "Expected hash arguments."); + if (RTEST(rb_funcall(hash_args, rb_intern("respond_to?"), 1, rb_str_new2("to_h")))) { + hash_args = rb_funcall(hash_args, rb_intern("to_h"), 0); + } else { + rb_raise(rb_eArgError, "Expected hash arguments."); + } } 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 { @@ -1112,10 +1190,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."); } @@ -1123,8 +1201,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"); @@ -1132,10 +1209,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. @@ -1149,8 +1225,8 @@ VALUE build_class_from_descriptor(VALUE descriptor) { rb_define_method(klass, "to_s", Message_inspect, 0); rb_define_method(klass, "[]", Message_index, 1); rb_define_method(klass, "[]=", Message_index_set, 2); - rb_define_singleton_method(klass, "decode", Message_decode, 1); - rb_define_singleton_method(klass, "encode", Message_encode, 1); + rb_define_singleton_method(klass, "decode", Message_decode, -1); + rb_define_singleton_method(klass, "encode", Message_encode, -1); rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1); rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1); rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0); @@ -1168,13 +1244,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; } } @@ -1188,14 +1263,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; } } @@ -1211,19 +1284,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)); } @@ -1237,80 +1310,80 @@ 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_FindFieldByNumber(m, 1); + const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(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_FindFieldByNumber(m, 1); + const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(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..3c765c564d230 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_FindFieldByNumber(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_FindFieldByNumber(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,53 @@ 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 void* ruby_upb_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size) { + if (size == 0) { + xfree(ptr); + return NULL; + } else { + return xrealloc(ptr, size); + } +} + +upb_alloc ruby_upb_alloc = {&ruby_upb_allocfunc}; + static VALUE Arena_alloc(VALUE klass) { Arena *arena = ALLOC(Arena); - arena->arena = upb_arena_new(); + arena->arena = upb_Arena_Init(NULL, 0, &ruby_upb_alloc); 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 +344,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 +364,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 +391,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 +405,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 +418,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 +442,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 +456,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 +475,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 d6c2a0bc5d3ea..d50bd99f9c421 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -254,6 +254,14 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); ((void)(addr), (void)(size)) #endif +/* Disable proto2 arena behavior (TEMPORARY) **********************************/ + +#ifdef UPB_DISABLE_PROTO2_ENUM_CHECKING +#define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 1 +#else +#define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 0 +#endif + /** upb/decode.c ************************************************************/ #include @@ -264,25 +272,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 +305,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 +316,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 +404,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 +419,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 +468,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 +562,226 @@ 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; +} + +static void upb_Decode_AddUnknownVarints(upb_Decoder* d, upb_Message* msg, + uint32_t val1, uint32_t val2) { + char buf[20]; + char* end = buf; + end = encode_varint32(val1, end); + end = encode_varint32(val2, end); + + if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) { + decode_err(d, kUpb_DecodeStatus_OutOfMemory); + } +} + +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 and value here. + uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; + upb_Decode_AddUnknownVarints(d, msg, tag, v); + 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 +799,107 @@ 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); + const char* start = ptr; + ptr = decode_tosubmsg(d, ptr, &ent.k, subs, field, val->size); + // check if ent had any unknown fields + size_t size; + upb_Message_GetUnknown(&ent.k, &size); + if (size != 0) { + uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Delimited; + upb_Decode_AddUnknownVarints(d, msg, tag, (uint32_t)(ptr - start)); + if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) { + decode_err(d, kUpb_DecodeStatus_OutOfMemory); + } + } else { + _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 +909,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 +930,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 +944,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 +976,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 = kUpb_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 kUpb_ExtMode_Extendable: { + const upb_MiniTable_Extension* ext = + _upb_extreg_get(d->extreg, l, field_number); + if (ext) return &ext->field; + break; + } + case kUpb_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 kUpb_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 & kUpb_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); + if (size) 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 +1370,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 +1381,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 +1405,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 +1430,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 +1440,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 +1469,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 +1478,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 +1527,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 +1613,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 & kUpb_LabelFlags_IsPacked; size_t pre_len = e->limit - e->ptr; if (arr == NULL || arr->len == 0) { @@ -1254,9 +1626,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 +1640,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 +1715,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 +1754,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 +1765,153 @@ 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 >> kUpb_FieldRep_Shift) { + case kUpb_FieldRep_1Byte: { + char ch; + memcpy(&ch, mem, 1); + return ch != 0; + } +#if UINTPTR_MAX == 0xffffffff + case kUpb_FieldRep_Pointer: +#endif + case kUpb_FieldRep_4Byte: { + uint32_t u32; + memcpy(&u32, mem, 4); + return u32 != 0; + } +#if UINTPTR_MAX != 0xffffffff + case kUpb_FieldRep_Pointer: +#endif + case kUpb_FieldRep_8Byte: { + uint64_t u64; + memcpy(&u64, mem, 8); + return u64 != 0; + } + case kUpb_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; } - 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) { - 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) { - size_t unknown_size; - const char *unknown = upb_msg_getunknown(msg, &unknown_size); - - if (unknown) { - encode_bytes(e, unknown, unknown_size); - } +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(); } +} - 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(); +/* 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; + + 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_Message_GetUnknown(msg, &unknown_size); + + if (unknown) { + encode_bytes(e, unknown, unknown_size); + } + } + + if (m->ext != kUpb_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); + if (ext_count) { + const upb_Message_Extension* end = ext + ext_count; + for (; ext != end; ext++) { + if (UPB_UNLIKELY(m->ext == kUpb_ExtMode_IsMessageSet)) { + encode_msgset_item(e, ext); + } else { + encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field); + } + } + } + } + + if (m->field_count) { + const upb_MiniTable_Field* f = &m->fields[m->field_count]; + const upb_MiniTable_Field* first = &m->fields[0]; + while (f != first) { + f--; + 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 +1935,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 +1968,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 +1987,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 +2014,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 +2027,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 +2044,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 +2091,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 +2102,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 +2152,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 +2222,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 +2235,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 +2272,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 +2313,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 +2345,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 +2370,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 +2395,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 +2418,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 +2437,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 +2446,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 +2459,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 +2476,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 +2495,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 +2512,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 +2526,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 +2541,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 +2551,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 +2566,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 +2580,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 +2607,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 +2656,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[]) { +static 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 +2740,49 @@ const uint64_t kWyhashSalt[5] = { 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL, }; -static uint32_t table_hash(const char *p, size_t n) { - return Wyhash(p, n, 0, kWyhashSalt); +uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed) { + return Wyhash(p, n, seed, kWyhashSalt); +} + +static uint32_t _upb_Hash_NoSeed(const char* p, size_t n) { + return _upb_Hash(p, n, 0); } static uint32_t strhash(upb_tabkey key) { uint32_t len; - char *str = upb_tabstr(key, &len); - return table_hash(str, len); + char* str = upb_tabstr(key, &len); + return _upb_Hash_NoSeed(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 +2790,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; @@ -2324,43 +2807,43 @@ bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len, tabkey = strcopy(key, a); if (tabkey == 0) return false; - hash = table_hash(key.str.str, key.str.len); + hash = _upb_Hash_NoSeed(key.str.str, key.str.len); insert(&t->t, key, tabkey, v, hash, &strhash, &streql); return true; } -bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, - upb_value *v) { - uint32_t hash = table_hash(key, len); +bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, + upb_value* v) { + uint32_t hash = _upb_Hash_NoSeed(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) { - uint32_t hash = table_hash(key, len); +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val) { + uint32_t hash = _upb_Hash_NoSeed(key, len); upb_tabkey tabkey; return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql); } /* 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 +2851,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 +2874,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 +2907,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 +2915,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 +2925,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 +2934,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 +2960,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 +2979,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 +3014,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 +3053,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 +3072,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 +3104,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 +3243,57 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, #include -/* upb_status *****************************************************************/ +// Must be last. -void upb_status_clear(upb_status *status) { +/* upb_Status *****************************************************************/ + +void upb_Status_Clear(upb_Status* status) { if (!status) return; status->ok = true; status->msg[0] = '\0'; } -bool upb_ok(const upb_status *status) { return status->ok; } +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 +3305,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 +3369,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 +3403,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 +3414,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 +3453,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 +3476,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 +3502,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 +3518,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 +3534,39 @@ 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 +3586,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 +3649,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 +3669,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 +3678,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 +3691,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 +3721,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 +3737,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 +3748,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 +3782,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 +3815,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 +3834,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 +3863,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 +3895,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 +3921,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 +3941,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 +3949,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 +3965,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 +3982,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 +4029,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 +4065,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 +4121,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 +4160,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 +4187,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 +4213,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 +4238,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 +4264,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 +4360,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 +4392,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 +4431,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 +4464,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 +4477,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 +4504,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 +4520,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 +4542,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 +4566,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 +4592,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,628 +4605,843 @@ 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 | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 24), 2, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(36, 72), 0, 0, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(40, 80), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(44, 88), 0, 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(48, 96), 0, 4, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(52, 104), 0, 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(28, 56), 3, 3, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(32, 64), 4, 5, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(56, 112), 0, 0, 5, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(60, 120), 0, 0, 5, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {12, UPB_SIZE(20, 40), 5, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 32), 0, 4, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(20, 40), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(24, 48), 0, 3, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(28, 56), 0, 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(32, 64), 0, 4, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(12, 24), 2, 5, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(36, 72), 0, 6, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(40, 80), 0, 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(44, 88), 0, 0, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 8), 2, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 16), 3, 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 8), 2, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_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, kUpb_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 | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(32, 40), 2, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 12), 3, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(4, 4), 4, 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(8, 8), 5, 2, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(40, 56), 6, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(48, 72), 7, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(64, 104), 8, 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(16, 16), 9, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(56, 88), 10, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {17, UPB_SIZE(20, 20), 11, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 24), 2, 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 32), 0, 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 24), 2, 1, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 40), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 48), 0, 0, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 8), 2, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(4, 4), 2, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 24), 3, 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 32), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 24), 2, 1, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 24), 2, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(20, 40), 3, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(28, 56), 4, 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(1, 1), 5, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(2, 2), 6, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(28, 40), 2, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(4, 4), 3, 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(8, 8), 4, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(36, 56), 5, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {16, UPB_SIZE(9, 9), 6, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {17, UPB_SIZE(10, 10), 7, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {18, UPB_SIZE(11, 11), 8, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {20, UPB_SIZE(12, 12), 9, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {23, UPB_SIZE(13, 13), 10, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {27, UPB_SIZE(14, 14), 11, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {31, UPB_SIZE(15, 15), 12, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {36, UPB_SIZE(44, 72), 13, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {37, UPB_SIZE(52, 88), 14, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {39, UPB_SIZE(60, 104), 15, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {40, UPB_SIZE(68, 120), 16, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {41, UPB_SIZE(76, 136), 17, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {42, UPB_SIZE(16, 16), 18, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {44, UPB_SIZE(84, 152), 19, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {45, UPB_SIZE(92, 168), 20, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(100, 184), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(2, 2), 2, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(3, 3), 3, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(4, 4), 4, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(8, 8), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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[8] = { + {1, UPB_SIZE(4, 4), 1, 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 12), 2, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(13, 13), 3, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(14, 14), 4, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(8, 8), 5, 2, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(15, 15), 6, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {15, UPB_SIZE(16, 16), 7, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 24), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, 32), 8, kUpb_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 | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(2, 2), 2, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(4, 8), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(4, 8), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(4, 8), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {34, UPB_SIZE(4, 4), 2, 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(12, 16), 0, 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(32, 32), 1, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(8, 8), 2, 0, 4, kUpb_FieldMode_Scalar | (kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(16, 16), 3, 0, 3, kUpb_FieldMode_Scalar | (kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(24, 24), 4, 0, 1, kUpb_FieldMode_Scalar | (kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(40, 48), 5, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(48, 64), 6, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_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, kUpb_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 | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(1, 1), 2, 0, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_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, kUpb_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 | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(24, 48), 0, 0, 5, kUpb_FieldMode_Array | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(12, 24), 2, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(28, 56), 0, 0, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | (kUpb_FieldRep_Pointer << kUpb_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, kUpb_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 | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 1, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(4, 4), 2, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(8, 8), 3, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_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, kUpb_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, +}; -/** upb/def.c ************************************************************/ - -#include -#include -#include -#include -#include +const upb_MiniTable_Enum google_protobuf_FieldDescriptorProto_Label_enuminit = { + NULL, + 0xeULL, + 0, +}; +const upb_MiniTable_Enum google_protobuf_FileOptions_OptimizeMode_enuminit = { + NULL, + 0xeULL, + 0, +}; -/* Must be last. */ +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, +}; + + + +/** upb/def.c ************************************************************/ + +#include +#include +#include +#include +#include + + +/* Must be last. */ 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_; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; -struct upb_msgdef { - const upb_msglayout *layout; - const upb_filedef *file; - const char *full_name; +struct upb_ExtensionRange { + const google_protobuf_ExtensionRangeOptions* opts; + int32_t start; + int32_t end; +}; + +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; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; -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; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif +}; + +struct upb_EnumValueDef { + const google_protobuf_EnumValueOptions* opts; + const upb_EnumDef* parent; + const char* full_name; + int32_t number; }; -struct upb_oneofdef { - const upb_msgdef *parent; - const char *full_name; +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; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; -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_symtab { - upb_arena *arena; +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; + int index; + 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_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) { + // Our 3-bit pointer tagging requires all pointers to be multiples of 8. + // The arena will always yield 8-byte-aligned addresses, however we put + // the defs into arrays. For each element in the array to be 8-byte-aligned, + // the sizes of each def type must also be a multiple of 8. + // + // If any of these asserts fail, we need to add or remove padding on 32-bit + // machines (64-bit machines will have 8-byte alignment already due to + // pointers, which all of these structs have). + UPB_ASSERT((sizeof(upb_FieldDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_MessageDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_EnumDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_EnumValueDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_ServiceDef) & UPB_DEFTYPE_MASK) == 0); + UPB_ASSERT((sizeof(upb_OneofDef) & UPB_DEFTYPE_MASK) == 0); + 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 +5456,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_; } + +uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } -uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT64); - return f->defaultval.uint; +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_IsProto3Optional(const upb_FieldDef* f) { + return f->proto3_optional_; +} + +bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Message; } -bool upb_fielddef_isstring(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_STRING || - upb_fielddef_type(f) == UPB_TYPE_BYTES; +bool upb_FieldDef_IsString(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_String || + upb_FieldDef_CType(f) == kUpb_CType_Bytes; } -bool upb_fielddef_isseq(const upb_fielddef *f) { - return upb_fielddef_label(f) == UPB_LABEL_REPEATED; +bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Repeated; } -bool upb_fielddef_isprimitive(const upb_fielddef *f) { - return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f); +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_isseq(f) && upb_fielddef_issubmsg(f) && - upb_msgdef_mapentry(upb_fielddef_msgsubdef(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_hassubdef(const upb_fielddef *f) { - return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM; +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 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_msgdef_fullname(const upb_msgdef *m) { +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_FindFieldByNumber(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 +5876,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 +5887,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 +5919,465 @@ 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]; } -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; +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_iswrapper(const upb_msgdef *m) { - upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); - return type >= UPB_WELLKNOWN_DOUBLEVALUE && - type <= UPB_WELLKNOWN_BOOLVALUE; +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { + return m->well_known_type; } -void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) { - upb_inttable_begin(iter, &m->itof); +/* upb_OneofDef ***************************************************************/ + +const google_protobuf_OneofOptions* upb_OneofDef_Options( + const upb_OneofDef* o) { + return o->opts; } -void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); } +bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { + return o->opts != (void*)opt_default; +} -bool upb_msg_field_done(const upb_msg_field_iter *iter) { - return upb_inttable_done(iter); +const char* upb_OneofDef_Name(const upb_OneofDef* o) { + return shortdefname(o->full_name); } -upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) { + return o->parent; } -void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { - upb_inttable_iter_setdone(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]; } -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); +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; } -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); - } +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_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)); +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; } -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { - return upb_strtable_done(iter); +/* upb_FileDef ****************************************************************/ + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) { + return f->opts; } -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); +bool upb_FileDef_HasOptions(const upb_FileDef* f) { + return f->opts != (void*)opt_default; } -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { - upb_strtable_iter_setdone(iter); +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; } -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_DependencyCount(const upb_FileDef* f) { return f->dep_count; } + +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) { + return f->public_dep_count; } -/* upb_oneofdef ***************************************************************/ +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { + return f->weak_dep_count; +} -const char *upb_oneofdef_name(const upb_oneofdef *o) { - return shortdefname(o->full_name); +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { + return f->public_deps; } -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { - return o->parent; +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) { + return f->weak_deps; } -int upb_oneofdef_fieldcount(const upb_oneofdef *o) { - return o->field_count; +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) { + return f->top_lvl_enum_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_TopLevelExtensionCount(const upb_FileDef* f) { + return f->top_lvl_ext_count; } -int upb_oneofdef_numfields(const upb_oneofdef *o) { - return o->field_count; +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]; } -uint32_t upb_oneofdef_index(const upb_oneofdef *o) { - return o - o->parent->oneofs; +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]]; } -bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { - return o->synthetic; +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]]; } -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_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_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_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]; } -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { - upb_inttable_begin(iter, &o->itof); +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_next(upb_oneof_iter *iter) { - upb_inttable_next(iter); +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->service_count); + return &f->services[i]; } -bool upb_oneof_done(upb_oneof_iter *iter) { - return upb_inttable_done(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_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); +int upb_MethodDef_Index(const upb_MethodDef* m) { return m->index; } + +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_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_symtab_lookupenum(const upb_symtab *s, const char *sym) { +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 +6387,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 +6472,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_FindFieldByNumber(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; - } - - if (upb_fielddef_ismap(f)) { - field->mode = _UPB_MODE_MAP; - } else if (upb_fielddef_isseq(f)) { - field->mode = _UPB_MODE_ARRAY; +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 || + UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 || + // TODO(https://github.com/protocolbuffers/upb/issues/541): + // fix map enum values to check for unknown enum values and put + // them in the unknown field set. + upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f)))) { + return kUpb_FieldType_Int32; + } + return type; +} + +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_IsMap(f)) { + field->mode = + kUpb_FieldMode_Map | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift); + } else if (upb_FieldDef_IsRepeated(f)) { + field->mode = + kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift); } else { - field->mode = _UPB_MODE_SCALAR; - } - - if (upb_fielddef_packed(f)) { - field->mode |= _UPB_MODE_IS_PACKED; + /* Maps descriptor type -> elem_size_lg2. */ + static const uint8_t sizes[] = { + -1, /* invalid descriptor type */ + kUpb_FieldRep_8Byte, /* DOUBLE */ + kUpb_FieldRep_4Byte, /* FLOAT */ + kUpb_FieldRep_8Byte, /* INT64 */ + kUpb_FieldRep_8Byte, /* UINT64 */ + kUpb_FieldRep_4Byte, /* INT32 */ + kUpb_FieldRep_8Byte, /* FIXED64 */ + kUpb_FieldRep_4Byte, /* FIXED32 */ + kUpb_FieldRep_1Byte, /* BOOL */ + kUpb_FieldRep_StringView, /* STRING */ + kUpb_FieldRep_Pointer, /* GROUP */ + kUpb_FieldRep_Pointer, /* MESSAGE */ + kUpb_FieldRep_StringView, /* BYTES */ + kUpb_FieldRep_4Byte, /* UINT32 */ + kUpb_FieldRep_4Byte, /* ENUM */ + kUpb_FieldRep_4Byte, /* SFIXED32 */ + kUpb_FieldRep_8Byte, /* SFIXED64 */ + kUpb_FieldRep_4Byte, /* SINT32 */ + kUpb_FieldRep_8Byte, /* SINT64 */ + }; + field->mode = kUpb_FieldMode_Scalar | + (sizes[field->descriptortype] << kUpb_FieldRep_Shift); + } + + if (upb_FieldDef_IsPacked(f)) { + field->mode |= kUpb_LabelFlags_IsPacked; + } + + if (upb_FieldDef_IsExtension(f)) { + field->mode |= kUpb_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++; + } + if (upb_FieldDef_CType(f) == kUpb_CType_Enum && + f->sub.enumdef->file->syntax == kUpb_Syntax_Proto2) { + 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 = kUpb_ExtMode_IsMessageSet; + } else { + l->ext = kUpb_ExtMode_Extendable; + } + } else { + l->ext = kUpb_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_FindFieldByNumber(m, 1); + const upb_FieldDef* val = upb_MessageDef_FindFieldByNumber(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; } + 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 +6701,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 (field->descriptortype == kUpb_FieldType_Message || + field->descriptortype == kUpb_FieldType_Group) { + field->submsg_index = sublayout_count++; + subs[field->submsg_index].submsg = upb_FieldDef_MessageSubDef(f)->layout; + } else if (field->descriptortype == kUpb_FieldType_Enum) { + 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 +6748,51 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { } /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit + 1, 8); + l->size = hasbit ? div_round_up(hasbit + 1, 8) : 0; /* 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; + + if (o->field_count == 0) { + symtab_errf(ctx, "Oneof must have at least one field (%s)", o->full_name); + } /* 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 +6801,33 @@ 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); + if (fields) { + 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 +6838,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 +6873,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 +6913,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 +6934,269 @@ 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 = base ? strlen(base) : 0; + char* tmp = malloc(sym.size + baselen + 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 " UPB_STRINGVIEW_FORMAT " with type=%d", + from_name_dbg, UPB_STRINGVIEW_ARGS(sym), (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); + + upb_value existing_v; + if (upb_strtable_lookup2(&m->ntof, name.data, name.size, &existing_v)) { + symtab_errf(ctx, "duplicate oneof name (%s)", o->full_name); + } + 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 +7209,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 +7218,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 +7236,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 +7244,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 +7252,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 +7260,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 +7268,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"); } name = google_protobuf_FieldDescriptorProto_name(field_proto); @@ -5987,57 +7350,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 (upb_inttable_lookup(&m->itof, field_number, NULL)) { + symtab_errf(ctx, "duplicate field number (%u)", field_number); } - if (ctx->layouts) { - const upb_msglayout_field *fields = m->layout->fields; + 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 +7448,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); + } } - 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); + 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_); + } /* 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 +7497,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 +7508,184 @@ 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->index = i; + 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; +} + +static int compare_int32(const void* a_ptr, const void* b_ptr) { + int32_t a = *(int32_t*)a_ptr; + int32_t b = *(int32_t*)b_ptr; + return a < b ? -1 : (a == b ? 0 : 1); +} + +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 |= 1ULL << 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); + } + + // Enums can have duplicate values; we must sort+uniq them. + if (values) qsort(values, n, sizeof(*values), &compare_int32); + + int dst = 0; + for (int i = 0; i < n; dst++) { + int32_t val = values[i]; + while (i < n && values[i] == val) i++; // Skip duplicates. + values[dst] = val; + } + n = dst; + + 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 +7693,371 @@ 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(upb_inttable_count(&e->iton) == + 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; - - google_protobuf_FileDescriptorProto_extension(file_proto, &n); - file->ext_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; -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; + bool found = false; - 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]); + } + + m->in_message_set = false; + for (int i = 0; i < m->nested_ext_count; i++) { + upb_FieldDef* ext = (upb_FieldDef*)&m->nested_exts[i]; + resolve_fielddef(ctx, m->full_name, ext); + 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; + } + } + + if (!ctx->layout) make_layout(ctx, m); + + 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 +8065,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 +8076,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, "weak_dep %d is out of range", (int)weak_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 +8267,53 @@ 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_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable) { /* 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_LoadDefInitEx(s, *deps, rebuild_minitable)) 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 +8321,81 @@ 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; + const upb_MiniTable_File* mt = rebuild_minitable ? NULL : init->layout; + if (!_upb_DefPool_AddFile(s, file, mt, &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 +8405,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_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber); + const upb_FieldDef* value = + upb_MessageDef_FindFieldByNumber(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 +8640,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 +8652,66 @@ 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_FindFieldByNumber(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 +8720,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 +8742,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 +8867,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 +8943,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 +8958,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 +9015,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 +9036,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 +9068,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 +9081,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 +9148,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 +9171,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 +9198,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 +9240,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 +9272,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 +9304,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 +9387,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 +9415,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 +9459,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 +9477,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 +9496,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 +9505,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 +9517,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 +9526,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 +9534,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 +9542,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 +9554,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 +9563,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 +9571,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 +9579,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 +9590,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 +9614,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 +9626,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 +9669,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 +9703,81 @@ 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_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(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 +9789,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 +9822,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 +9849,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 +9869,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 +9891,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 +9905,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 +9960,22 @@ 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_FindFieldByNumber(m, 1), seconds, + d->arena); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(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 +9991,114 @@ 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_FindFieldByNumber(m, 1), seconds, + d->arena); + upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(m, 1); + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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 +10106,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 +10125,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_FindFieldByNumber(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 +10144,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 +10166,28 @@ 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_FindFieldByNumber(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 +10196,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_FindFieldByNumber(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 +10229,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 +10254,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_FindFieldByNumber(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 +10306,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 +10316,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 +10350,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 +10403,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 +10425,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 +10441,12 @@ 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_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(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) { @@ -8541,7 +10463,8 @@ static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg, * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for * Processing Calendar Dates," Communications of the Association of * Computing Machines, vol. 11 (1968), p. 657. */ - L = (int)(seconds / 86400) + 68569 + 2440588; + seconds += 62135596800; // Ensure seconds is positive. + L = (int)(seconds / 86400) - 719162 + 68569 + 2440588; N = 4 * L / 146097; L = L - (146097 * N + 3) / 4; I = 4000 * (L + 1) / 1461001; @@ -8561,11 +10484,12 @@ 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_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(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 +10505,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 +10560,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 +10601,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 +10615,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_FindFieldByNumber(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 +10665,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 +10674,30 @@ 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_FindFieldByNumber(m, 1); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(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 +10709,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 +10717,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 +10738,65 @@ 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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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_FindFieldByNumber(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 +10806,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 +10831,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 +10949,103 @@ 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_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(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 +11056,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 +11073,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); } @@ -9169,3 +11112,4 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, #undef UPB_POISON_MEMORY_REGION #undef UPB_UNPOISON_MEMORY_REGION #undef UPB_ASAN +#undef UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 40072772b2fa5..e57eb0edad008 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -1,3 +1,5 @@ +// Ruby is still using proto3 enum semantics for proto2 +#define UPB_DISABLE_PROTO2_ENUM_CHECKING /* Amalgamated source file */ /* * Copyright (c) 2009-2021, Google LLC @@ -253,9 +255,17 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); ((void)(addr), (void)(size)) #endif +/* Disable proto2 arena behavior (TEMPORARY) **********************************/ + +#ifdef UPB_DISABLE_PROTO2_ENUM_CHECKING +#define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 1 +#else +#define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 0 +#endif + /** 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 +307,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 +372,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 +404,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 +474,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 +485,33 @@ 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, +// Shrinks the last alloc from arena. +// REQUIRES: (ptr, oldsize) was the last malloc/realloc from this arena. +// We could also add a upb_Arena_TryShrinkLast() which is simply a no-op if +// this was not the last alloc. +UPB_INLINE void upb_Arena_ShrinkLast(upb_Arena* a, void* ptr, size_t oldsize, + size_t size) { + _upb_ArenaHead* h = (_upb_ArenaHead*)a; + oldsize = UPB_ALIGN_MALLOC(oldsize); + size = UPB_ALIGN_MALLOC(size); + UPB_ASSERT((char*)ptr + oldsize == h->ptr); // Must be the last alloc. + UPB_ASSERT(size <= oldsize); + h->ptr = (char*)ptr + size; +} + +UPB_INLINE void* upb_Arena_Realloc(upb_Arena* a, void* ptr, size_t oldsize, size_t size) { - void *ret = upb_arena_malloc(a, size); + _upb_ArenaHead* h = (_upb_ArenaHead*)a; + oldsize = UPB_ALIGN_MALLOC(oldsize); + size = UPB_ALIGN_MALLOC(size); + if (size <= oldsize) { + if ((char*)ptr + oldsize == h->ptr) { + upb_Arena_ShrinkLast(a, ptr, oldsize, size); + } + return ptr; + } + + void* ret = upb_Arena_Malloc(a, size); if (ret && oldsize > 0) { memcpy(ret, ptr, oldsize); @@ -486,100 +520,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 +598,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 +618,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 + * *******************************************************************/ -/* 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; +typedef void upb_Message; + +/* 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); + +/* Returns the number of extensions present in this message. */ +size_t upb_Message_ExtensionCount(const upb_Message* msg); -/** upb_extreg *******************************************************************/ +/** 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 +684,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 +710,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 +769,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,11 +814,12 @@ bool upb_decode(const char *buf, size_t size, upb_msg *msg, #include +// Must be last. + #ifdef __cplusplus extern "C" { #endif - /* upb_value ******************************************************************/ typedef struct { @@ -782,11 +828,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 +840,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 +886,6 @@ UPB_INLINE upb_value upb_value_double(double cval) { #undef SET_TYPE - /* upb_tabkey *****************************************************************/ /* Either: @@ -855,14 +897,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 +917,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 +930,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 +946,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 +960,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 +982,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 +1080,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 +1092,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 +1117,32 @@ 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); +uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_TABLE_H_ */ +#endif /* UPB_TABLE_H_ */ /* Must be last. */ @@ -1075,110 +1150,204 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, extern "C" { #endif -/** upb_msglayout *************************************************************/ +/** upb_*Int* conversion routines ********************************************/ + +UPB_INLINE int32_t _upb_Int32_FromI(int v) { return (int32_t)v; } + +UPB_INLINE int64_t _upb_Int64_FromLL(long long v) { return (int64_t)v; } -/* upb_msglayout represents the memory layout of a given upb_msgdef. The +UPB_INLINE uint32_t _upb_UInt32_FromU(unsigned v) { return (uint32_t)v; } + +UPB_INLINE uint64_t _upb_UInt64_FromULL(unsigned long long v) { + return (uint64_t)v; +} + +/** upb_MiniTable *************************************************************/ + +/* 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 << kUpb_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, -}; +typedef enum { + kUpb_LabelFlags_IsPacked = 4, + kUpb_LabelFlags_IsExtension = 8, +} upb_LabelFlags; + +// Note: we sort by this number when calculating layout order. +typedef enum { + kUpb_FieldRep_1Byte = 0, + kUpb_FieldRep_4Byte = 1, + kUpb_FieldRep_StringView = 2, + kUpb_FieldRep_Pointer = 3, + kUpb_FieldRep_8Byte = 4, + + kUpb_FieldRep_Shift = 5, // Bit offset of the rep in upb_MiniTable_Field.mode + kUpb_FieldRep_Max = kUpb_FieldRep_8Byte, +} upb_FieldRep; -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 { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} 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; -/** upb_extreg ****************************************************************/ +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_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 +1357,175 @@ 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 +1535,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 +1545,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 +1558,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 +1591,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 +1603,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 +1633,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 +1678,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 +1707,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 +1723,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 +1738,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 +1747,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 +1762,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 +1772,110 @@ 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 +1886,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 +1916,7 @@ UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, } #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif @@ -1745,8 +1930,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 +1939,56 @@ 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 +1997,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 +2059,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 +2085,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 +2106,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 +2120,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 +2130,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 +2154,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 +2214,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 +2256,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 +2277,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 +2300,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 +2373,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,164 +2453,221 @@ 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 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) { +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( - msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, 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_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; } /* 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 bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } -UPB_INLINE upb_strview const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_message_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } -UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_enum_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); } -UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_service(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); } -UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_extension(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); } -UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 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 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 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 void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) { +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_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_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)); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto* msg, size_t* len) { + return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_service(const google_protobuf_FileDescriptorProto* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); +} +UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto* msg, size_t* len) { + return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_extension(const google_protobuf_FileDescriptorProto* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto* msg, size_t* len) { + return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto* msg) { + return _upb_hasbit(msg, 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 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 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_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_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, - arena); +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) { +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( - msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(48, 96), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(52, 104), UPB_SIZE(2, 3), &sub, 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_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 +2675,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,152 +2688,188 @@ 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); } return sub; } -UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { +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, - arena); +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto* msg, int32_t val, upb_Arena* arena) { + return _upb_Array_Append_accessor2(msg, UPB_SIZE(56, 112), 2, &val, arena); } -UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { +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, - arena); +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto* msg, int32_t val, upb_Arena* arena) { + return _upb_Array_Append_accessor2(msg, UPB_SIZE(60, 120), 2, &val, arena); } -UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) { +UPB_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 bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_field(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } -UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_nested_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } -UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_enum_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); } -UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_extension_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); } -UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ExtensionRange* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_extension(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); } -UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_MessageOptions*); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_oneof_decl(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); } -UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_OneofDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_reserved_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } -UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } -UPB_INLINE upb_strview const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } - -UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_strview value) { +UPB_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_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)); +} +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto* msg, size_t* len) { + return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_enum_type(const google_protobuf_DescriptorProto* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto* msg, size_t* len) { + return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_extension_range(const google_protobuf_DescriptorProto* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); +} +UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto* msg, size_t* len) { + return (const google_protobuf_DescriptorProto_ExtensionRange* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_extension(const google_protobuf_DescriptorProto* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto* msg, size_t* len) { + return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto* msg) { + return _upb_hasbit(msg, 2); +} +UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_MessageOptions*); +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_oneof_decl(const google_protobuf_DescriptorProto* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); +} +UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto* msg, size_t* len) { + return (const google_protobuf_OneofDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_reserved_range(const google_protobuf_DescriptorProto* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); +} +UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto* msg, size_t* len) { + return (const google_protobuf_DescriptorProto_ReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); +} +UPB_INLINE upb_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_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) { +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( - msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, 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_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,84 +2877,98 @@ 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); } return sub; } -UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_mutable_oneof_decl(google_protobuf_DescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &sub, 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_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; } -UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, 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_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, - arena); +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 bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + return _upb_hasbit(msg, 2); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); +} +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + return _upb_hasbit(msg, 3); +} +UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const google_protobuf_ExtensionRangeOptions*); } - -UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } -UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } -UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_hasbit(msg, 3); } -UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const google_protobuf_ExtensionRangeOptions*); } UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { _upb_sethas(msg, 1); @@ -2666,10 +2982,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 +2994,47 @@ 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 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 bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } -UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { _upb_sethas(msg, 1); @@ -2718,103 +3047,160 @@ 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 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) { +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( - msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, 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_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; } /* 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 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 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 bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 3); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 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 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 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 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 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 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 bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 10); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 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 void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { +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_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_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 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 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 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_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_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 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 bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto* msg) { + return _upb_hasbit(msg, 10); +} +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 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 +3214,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 +3239,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 +3250,60 @@ 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_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 bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } -UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_OneofOptions*); } - -UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_strview value) { +UPB_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,54 +3312,76 @@ 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_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 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_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 bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_value(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } -UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumValueDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_EnumOptions*); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_reserved_range(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } -UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } -UPB_INLINE upb_strview const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } - -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_strview value) { +UPB_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) { +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( - msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, 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_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,69 +3389,80 @@ 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); } return sub; } -UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_mutable_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t *len) { +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( - msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, 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_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, - arena); +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 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 bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { _upb_sethas(msg, 1); @@ -3043,40 +3475,57 @@ 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_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 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 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 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 bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 3); } -UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const google_protobuf_EnumValueOptions*); } - -UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) { +UPB_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 +3535,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,51 +3547,67 @@ 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_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 bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } -UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_method(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } -UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg, size_t *len) { return (const google_protobuf_MethodDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } -UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_ServiceOptions*); } - -UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_strview value) { +UPB_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) { +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( - msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, 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_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 +3615,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 +3627,92 @@ 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_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_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_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 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_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_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 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 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 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 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_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 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 +3729,169 @@ 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 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 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 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 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_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 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_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_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_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_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_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_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_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 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 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 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 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 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_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 19); } -UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview); } -UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 20); } -UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview); } -UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 184)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(100, 184), len); } - -UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) { +UPB_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_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_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 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_has_go_package(const google_protobuf_FileOptions* msg) { + return _upb_hasbit(msg, 5); +} +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_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_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_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_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_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_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 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_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_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_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_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_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_has_php_metadata_namespace(const google_protobuf_FileOptions* msg) { + return _upb_hasbit(msg, 19); +} +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_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_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 +3901,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,88 +3933,112 @@ 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) { +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( - msg, UPB_SIZE(100, 184), UPB_SIZE(2, 3), &sub, 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_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; } /* 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_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions* msg) { + return _upb_hasbit(msg, 2); +} +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); +} +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions* msg) { + return _upb_hasbit(msg, 3); +} +UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); +} +UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions* msg) { + return _upb_hasbit(msg, 4); +} +UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); +} +UPB_INLINE bool google_protobuf_MessageOptions_has_uninterpreted_option(const google_protobuf_MessageOptions* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions* msg, size_t* len) { + return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); } - -UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } -UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } -UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_hasbit(msg, 3); } -UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); } -UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_hasbit(msg, 4); } -UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); } -UPB_INLINE bool google_protobuf_MessageOptions_has_uninterpreted_option(const google_protobuf_MessageOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); } UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions *msg, bool value) { _upb_sethas(msg, 1); @@ -3449,60 +4056,98 @@ UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_Mes _upb_sethas(msg, 4); *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value; } -UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_mutable_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t *len) { +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( - msg, UPB_SIZE(8, 8), UPB_SIZE(2, 3), &sub, 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_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; } /* 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 bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } -UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 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_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_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_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 bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 6); } -UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); } -UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 16)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); } +UPB_INLINE 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 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_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_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_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 bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions* msg) { + return _upb_hasbit(msg, 6); +} +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); +} +UPB_INLINE bool google_protobuf_FieldOptions_has_unverified_lazy(const google_protobuf_FieldOptions* msg) { + return _upb_hasbit(msg, 7); +} +UPB_INLINE bool google_protobuf_FieldOptions_unverified_lazy(const google_protobuf_FieldOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); +} +UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); +} +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(20, 24), len); +} UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 1); @@ -3528,95 +4173,123 @@ UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptio _upb_sethas(msg, 6); *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value; } -UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) { - return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len); +UPB_INLINE void google_protobuf_FieldOptions_set_unverified_lazy(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 7); + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; } -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_mutable_uninterpreted_option(google_protobuf_FieldOptions* msg, size_t* len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len); } -UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); - bool ok = _upb_array_append_accessor2( - msg, UPB_SIZE(16, 16), UPB_SIZE(2, 3), &sub, arena); +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(20, 24), 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_Message_New(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_Array_Append_accessor2(msg, UPB_SIZE(20, 24), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } /* google.protobuf.OneofOptions */ -UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) { - return (google_protobuf_OneofOptions *)_upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_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 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) { +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( - msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, 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_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; } /* 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_has_deprecated(const google_protobuf_EnumOptions* msg) { + return _upb_hasbit(msg, 2); +} +UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions* msg) { + return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); +} +UPB_INLINE bool google_protobuf_EnumOptions_has_uninterpreted_option(const google_protobuf_EnumOptions* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions* msg, size_t* len) { + return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } - -UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } -UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } -UPB_INLINE bool google_protobuf_EnumOptions_has_uninterpreted_option(const google_protobuf_EnumOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions *msg, bool value) { _upb_sethas(msg, 1); @@ -3626,150 +4299,190 @@ UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumO _upb_sethas(msg, 2); *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value; } -UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mutable_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t *len) { +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( - msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, 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_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; } /* 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_has_uninterpreted_option(const google_protobuf_EnumValueOptions* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions* msg, size_t* len) { + return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } - -UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } -UPB_INLINE bool google_protobuf_EnumValueOptions_has_uninterpreted_option(const google_protobuf_EnumValueOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions *msg, bool value) { _upb_sethas(msg, 1); *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } -UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_mutable_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t *len) { +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( - msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, 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_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; } /* 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_has_uninterpreted_option(const google_protobuf_ServiceOptions* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions* msg, size_t* len) { + return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } - -UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } -UPB_INLINE bool google_protobuf_ServiceOptions_has_uninterpreted_option(const google_protobuf_ServiceOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions *msg, bool value) { _upb_sethas(msg, 1); *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } -UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_mutable_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t *len) { +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( - msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, 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_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; } /* 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_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 bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions* msg) { + return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions* msg, size_t* len) { + return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); } - -UPB_INLINE 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_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 bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); } UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { _upb_sethas(msg, 1); @@ -3779,77 +4492,108 @@ UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_proto _upb_sethas(msg, 2); *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } -UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) { +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( - msg, UPB_SIZE(12, 16), UPB_SIZE(2, 3), &sub, 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_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; } /* 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 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 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 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 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 bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 5); } -UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); } -UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 6); } -UPB_INLINE upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview); } - -UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_mutable_name(google_protobuf_UninterpretedOption *msg, size_t *len) { +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_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 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 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 bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption* msg) { + return _upb_hasbit(msg, 5); +} +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_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( - msg, UPB_SIZE(56, 80), UPB_SIZE(2, 3), &sub, 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_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 +4607,62 @@ 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_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_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 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 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,210 +4671,260 @@ 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 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) { +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( - msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, 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_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; } /* 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_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_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 const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } -UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } -UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } -UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } -UPB_INLINE upb_strview const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } - -UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { +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, - arena); +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location* msg, int32_t val, upb_Arena* arena) { + return _upb_Array_Append_accessor2(msg, UPB_SIZE(20, 40), 2, &val, arena); } -UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { +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, - arena); +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location* msg, int32_t val, upb_Arena* arena) { + return _upb_Array_Append_accessor2(msg, UPB_SIZE(24, 48), 2, &val, arena); } -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { +UPB_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, - arena); +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 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) { +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( - msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, 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_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; } /* 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_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 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 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 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 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_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { +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, - arena); +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t val, upb_Arena* arena) { + return _upb_Array_Append_accessor2(msg, UPB_SIZE(20, 32), 2, &val, arena); } -UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) { +UPB_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 +4935,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 +4949,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 +4957,373 @@ 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_FindFieldByNumber(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); +int upb_MethodDef_Index(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); +// Should only be directly called by tests. This variant lets us suppress +// the use of compiled-in tables, forcing a rebuild of the tables at runtime. +bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable); + +UPB_INLINE bool _upb_DefPool_LoadDefInit(upb_DefPool* s, + const _upb_DefPool_Init* init) { + return _upb_DefPool_LoadDefInitEx(s, init, false); +} #ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ +} /* extern "C" */ +#endif /* __cplusplus */ #endif /* UPB_DEF_H_ */ @@ -4447,7 +5332,6 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); #define UPB_REFLECTION_H_ - #ifdef __cplusplus extern "C" { #endif @@ -4460,57 +5344,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 +5409,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 +5526,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 +5549,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 +5564,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. */ @@ -4702,3 +5609,4 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, #undef UPB_POISON_MEMORY_REGION #undef UPB_UNPOISON_MEMORY_REGION #undef UPB_ASAN +#undef UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 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 87d75a3ba7759..402a6a52f9b58 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.19.4" + s.version = "3.20.0.rc.2" 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,8 +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" - end + s.add_development_dependency "rake-compiler-dock", "= 1.2.1" end s.test_files = ["tests/basic.rb", "tests/stress.rb", "tests/generated_code_test.rb"] diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb index f939a4c7dcd7f..b7a6711051589 100644 --- a/ruby/lib/google/protobuf.rb +++ b/ruby/lib/google/protobuf.rb @@ -59,16 +59,16 @@ class TypeError < ::TypeError; end module Google module Protobuf - def self.encode(msg) - msg.to_proto + def self.encode(msg, options = {}) + msg.to_proto(options) end def self.encode_json(msg, options = {}) msg.to_json(options) end - def self.decode(klass, proto) - klass.decode(proto) + def self.decode(klass, proto, options = {}) + klass.decode(proto, options) end def self.decode_json(klass, json, options = {}) diff --git a/ruby/lib/google/protobuf/descriptor_dsl.rb b/ruby/lib/google/protobuf/descriptor_dsl.rb index c3e9a5a620b59..7349b6df15bd9 100644 --- a/ruby/lib/google/protobuf/descriptor_dsl.rb +++ b/ruby/lib/google/protobuf/descriptor_dsl.rb @@ -2,7 +2,14 @@ # # Code that implements the DSL for defining proto messages. -require 'google/protobuf/descriptor_pb' +# Suppress warning: loading in progress, circular require considered harmful. +# This circular require is intentional to avoid missing dependency. +begin + old_verbose, $VERBOSE = $VERBOSE, nil + require 'google/protobuf/descriptor_pb' +ensure + $VERBOSE = old_verbose +end module Google module Protobuf diff --git a/ruby/lib/google/protobuf/message_exts.rb b/ruby/lib/google/protobuf/message_exts.rb index f432f89fed0c6..660852172896c 100644 --- a/ruby/lib/google/protobuf/message_exts.rb +++ b/ruby/lib/google/protobuf/message_exts.rb @@ -44,8 +44,8 @@ def to_json(options = {}) self.class.encode_json(self, options) end - def to_proto - self.class.encode(self) + def to_proto(options = {}) + self.class.encode(self, options) end end diff --git a/ruby/lib/google/protobuf/well_known_types.rb b/ruby/lib/google/protobuf/well_known_types.rb index c9a9ab1455459..2d06ca27422a4 100755 --- a/ruby/lib/google/protobuf/well_known_types.rb +++ b/ruby/lib/google/protobuf/well_known_types.rb @@ -82,16 +82,16 @@ 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 self.from_time(time) - new.from_time(time) - end - def to_i self.seconds end @@ -137,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 @@ -160,6 +164,8 @@ def from_ruby(value) else raise UnexpectedStructType end + + self end end @@ -230,6 +236,5 @@ def self.from_a(arr) ret end end - end end diff --git a/ruby/pom.xml b/ruby/pom.xml index 0320a05161632..355019e0aa4d3 100644 --- a/ruby/pom.xml +++ b/ruby/pom.xml @@ -9,7 +9,7 @@ com.google.protobuf.jruby protobuf-jruby - 3.19.4 + 3.20.0-rc-2 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,12 +76,12 @@ com.google.protobuf protobuf-java-util - 3.19.4 + 3.20.0-rc-2 org.jruby jruby-complete - 9.2.19.0 + 9.2.20.1 provided 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 f7379b148edfb..7956eebe7611b 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java @@ -389,7 +389,7 @@ protected IRubyObject deepCopy(ThreadContext context) { return newMap; } - protected List build(ThreadContext context, RubyDescriptor descriptor, int depth) { + protected List build(ThreadContext context, RubyDescriptor descriptor, int depth, int recursionLimit) { List list = new ArrayList(); RubyClass rubyClass = (RubyClass) descriptor.msgclass(context); FieldDescriptor keyField = descriptor.getField("key"); @@ -398,7 +398,7 @@ protected List build(ThreadContext context, RubyDescriptor descr RubyMessage mapMessage = (RubyMessage) rubyClass.newInstance(context, Block.NULL_BLOCK); mapMessage.setField(context, keyField, key); mapMessage.setField(context, valueField, table.get(key)); - list.add(mapMessage.build(context, depth + 1)); + list.add(mapMessage.build(context, depth + 1, recursionLimit)); } return list; } diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java index cf59f625972c3..f55eb9b2850d0 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java @@ -39,6 +39,7 @@ import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.ByteString; +import com.google.protobuf.CodedInputStream; import com.google.protobuf.DynamicMessage; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; @@ -461,35 +462,63 @@ public static IRubyObject getDescriptor(ThreadContext context, IRubyObject recv) /* * call-seq: - * MessageClass.encode(msg) => bytes + * MessageClass.encode(msg, options = {}) => bytes * * Encodes the given message object to its serialized form in protocol buffers * wire format. + * @param options [Hash] options for the encoder + * recursion_limit: set to maximum encoding depth for message (default is 64) */ - @JRubyMethod(meta = true) - public static IRubyObject encode(ThreadContext context, IRubyObject recv, IRubyObject value) { - if (recv != value.getMetaClass()) { - throw context.runtime.newArgumentError("Tried to encode a " + value.getMetaClass() + " message with " + recv); + @JRubyMethod(required = 1, optional = 1, meta = true) + public static IRubyObject encode(ThreadContext context, IRubyObject recv, IRubyObject[] args) { + if (recv != args[0].getMetaClass()) { + throw context.runtime.newArgumentError("Tried to encode a " + args[0].getMetaClass() + " message with " + recv); } - RubyMessage message = (RubyMessage) value; - return context.runtime.newString(new ByteList(message.build(context).toByteArray())); + RubyMessage message = (RubyMessage) args[0]; + int recursionLimitInt = SINK_MAXIMUM_NESTING; + + if (args.length > 1) { + RubyHash options = (RubyHash) args[1]; + IRubyObject recursionLimit = options.fastARef(context.runtime.newSymbol("recursion_limit")); + + if (recursionLimit != null) { + recursionLimitInt = ((RubyNumeric) recursionLimit).getIntValue(); + } + } + return context.runtime.newString(new ByteList(message.build(context, 0, recursionLimitInt).toByteArray())); } /* * call-seq: - * MessageClass.decode(data) => message + * MessageClass.decode(data, options = {}) => message * * Decodes the given data (as a string containing bytes in protocol buffers wire * format) under the interpretation given by this message class's definition * and returns a message object with the corresponding field values. + * @param options [Hash] options for the decoder + * recursion_limit: set to maximum decoding depth for message (default is 100) */ - @JRubyMethod(meta = true) - public static IRubyObject decode(ThreadContext context, IRubyObject recv, IRubyObject data) { + @JRubyMethod(required = 1, optional = 1, meta = true) + public static IRubyObject decode(ThreadContext context, IRubyObject recv, IRubyObject[] args) { + IRubyObject data = args[0]; byte[] bin = data.convertToString().getBytes(); + CodedInputStream input = CodedInputStream.newInstance(bin); RubyMessage ret = (RubyMessage) ((RubyClass) recv).newInstance(context, Block.NULL_BLOCK); + + if (args.length == 2) { + if (!(args[1] instanceof RubyHash)) { + throw context.runtime.newArgumentError("Expected hash arguments."); + } + + IRubyObject recursionLimit = ((RubyHash) args[1]).fastARef(context.runtime.newSymbol("recursion_limit")); + if (recursionLimit != null) { + input.setRecursionLimit(((RubyNumeric) recursionLimit).getIntValue()); + } + } + try { - ret.builder.mergeFrom(bin); - } catch (InvalidProtocolBufferException e) { + ret.builder.mergeFrom(input); + } catch (Exception e) { throw RaiseException.from(context.runtime, (RubyClass) context.runtime.getClassFromPath("Google::Protobuf::ParseError"), e.getMessage()); } @@ -526,7 +555,15 @@ public static IRubyObject encodeJson(ThreadContext context, IRubyObject recv, IR String result; if (args.length > 1) { - RubyHash options = (RubyHash) args[1]; + RubyHash options; + if (args[1] instanceof RubyHash) { + options = (RubyHash) args[1]; + } else if (args[1].respondsTo("to_h")) { + options = (RubyHash) args[1].callMethod(context, "to_h"); + } else { + throw runtime.newArgumentError("Expected hash arguments."); + } + IRubyObject emitDefaults = options.fastARef(runtime.newSymbol("emit_defaults")); IRubyObject preserveNames = options.fastARef(runtime.newSymbol("preserve_proto_fieldnames")); @@ -541,7 +578,7 @@ public static IRubyObject encodeJson(ThreadContext context, IRubyObject recv, IR printer = printer.usingTypeRegistry(JsonFormat.TypeRegistry.newBuilder().add(message.descriptor).build()); try { - result = printer.print(message.build(context)); + result = printer.print(message.build(context, 0, SINK_MAXIMUM_NESTING)); } catch (InvalidProtocolBufferException e) { throw runtime.newRuntimeError(e.getMessage()); } catch (IllegalArgumentException e) { @@ -635,13 +672,9 @@ public IRubyObject toHash(ThreadContext context) { return ret; } - protected DynamicMessage build(ThreadContext context) { - return build(context, 0); - } - - protected DynamicMessage build(ThreadContext context, int depth) { - if (depth > SINK_MAXIMUM_NESTING) { - throw context.runtime.newRuntimeError("Maximum recursion depth exceeded during encoding."); + protected DynamicMessage build(ThreadContext context, int depth, int recursionLimit) { + if (depth >= recursionLimit) { + throw context.runtime.newRuntimeError("Recursion limit exceeded during encoding."); } // Handle the typical case where the fields.keySet contain the fieldDescriptors @@ -651,7 +684,7 @@ protected DynamicMessage build(ThreadContext context, int depth) { if (value instanceof RubyMap) { builder.clearField(fieldDescriptor); RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context, fieldDescriptor); - for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth)) { + for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth, recursionLimit)) { builder.addRepeatedField(fieldDescriptor, kv); } @@ -660,7 +693,7 @@ protected DynamicMessage build(ThreadContext context, int depth) { builder.clearField(fieldDescriptor); for (int i = 0; i < repeatedField.size(); i++) { - Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth, + Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth, recursionLimit, /*isDefaultValueForBytes*/ false); builder.addRepeatedField(fieldDescriptor, item); } @@ -682,7 +715,7 @@ protected DynamicMessage build(ThreadContext context, int depth) { fieldDescriptor.getFullName().equals("google.protobuf.FieldDescriptorProto.default_value")) { isDefaultStringForBytes = true; } - builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, isDefaultStringForBytes)); + builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, recursionLimit, isDefaultStringForBytes)); } } @@ -702,7 +735,7 @@ protected DynamicMessage build(ThreadContext context, int depth) { builder.clearField(fieldDescriptor); RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context, fieldDescriptor); - for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth)) { + for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth, recursionLimit)) { builder.addRepeatedField(fieldDescriptor, kv); } } @@ -814,7 +847,8 @@ private FieldDescriptor findField(ThreadContext context, IRubyObject fieldName, // convert a ruby object to protobuf type, skip type check since it is checked on the way in private Object convert(ThreadContext context, FieldDescriptor fieldDescriptor, - IRubyObject value, int depth, boolean isDefaultStringForBytes) { + IRubyObject value, int depth, int recursionLimit, + boolean isDefaultStringForBytes) { Object val = null; switch (fieldDescriptor.getType()) { case INT32: @@ -855,7 +889,7 @@ private Object convert(ThreadContext context, } break; case MESSAGE: - val = ((RubyMessage) value).build(context, depth + 1); + val = ((RubyMessage) value).build(context, depth + 1, recursionLimit); break; case ENUM: EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType(); @@ -1214,7 +1248,7 @@ private void validateMessageType(ThreadContext context, FieldDescriptor fieldDes private static final String CONST_SUFFIX = "_const"; private static final String HAS_PREFIX = "has_"; private static final String QUESTION_MARK = "?"; - private static final int SINK_MAXIMUM_NESTING = 63; + private static final int SINK_MAXIMUM_NESTING = 64; private Descriptor descriptor; private DynamicMessage.Builder builder; diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index b9d1554dbd33a..cdcd2950857a8 100755 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -644,5 +644,27 @@ def test_map_length assert_equal 2, m.map_string_int32.size assert_equal 1, m.map_string_msg.size end + + def test_string_with_singleton_class_enabled + str = 'foobar' + # NOTE: Accessing a singleton class of an object changes its low level class representation + # as far as the C API's CLASS_OF() method concerned, exposing the issue + str.singleton_class + m = proto_module::TestMessage.new( + optional_string: str, + optional_bytes: str + ) + + assert_equal str, m.optional_string + assert_equal str, m.optional_bytes + end + + def test_utf8 + m = proto_module::TestMessage.new( + optional_string: "µpb", + ) + m2 = proto_module::TestMessage.decode(proto_module::TestMessage.encode(m)) + assert_equal m2, m + end end end diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb index 3d9f67eb938f9..358846916dbae 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 @@ -864,6 +870,9 @@ def test_protobuf_encode_decode_json_helpers decoded_msg = Google::Protobuf.decode_json(proto_module::TestMessage, encoded_msg) assert_equal proto_module::TestMessage.decode_json(m.to_json), decoded_msg + + assert_equal [m].to_json, Google::Protobuf.encode_json([m]) + assert_equal proto_module::TestMessage.decode_json([m.to_json].first), decoded_msg end def test_def_errors @@ -1239,7 +1248,7 @@ def test_deep_json struct = struct_from_ruby(JSON.parse(json)) assert_equal json, struct.to_json - assert_raise(RuntimeError, "Maximum recursion depth exceeded during encoding") do + assert_raise(RuntimeError, "Recursion limit exceeded during encoding") do struct = Google::Protobuf::Struct.new struct.fields["foobar"] = Google::Protobuf::Value.new(struct_value: struct) Google::Protobuf::Struct.encode(struct) diff --git a/ruby/tests/encode_decode_test.rb b/ruby/tests/encode_decode_test.rb index 429ac43322165..df2cd3632d76d 100755 --- a/ruby/tests/encode_decode_test.rb +++ b/ruby/tests/encode_decode_test.rb @@ -101,4 +101,55 @@ def test_json_name assert_match json, "{\"CustomJsonName\":42}" end + def test_decode_depth_limit + msg = A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + ) + ) + ) + ) + ) + ) + msg_encoded = A::B::C::TestMessage.encode(msg) + msg_out = A::B::C::TestMessage.decode(msg_encoded) + assert_match msg.to_json, msg_out.to_json + + assert_raise Google::Protobuf::ParseError do + A::B::C::TestMessage.decode(msg_encoded, { recursion_limit: 4 }) + end + + msg_out = A::B::C::TestMessage.decode(msg_encoded, { recursion_limit: 5 }) + assert_match msg.to_json, msg_out.to_json + end + + def test_encode_depth_limit + msg = A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + optional_msg: A::B::C::TestMessage.new( + ) + ) + ) + ) + ) + ) + msg_encoded = A::B::C::TestMessage.encode(msg) + msg_out = A::B::C::TestMessage.decode(msg_encoded) + assert_match msg.to_json, msg_out.to_json + + assert_raise RuntimeError do + A::B::C::TestMessage.encode(msg, { recursion_limit: 5 }) + end + + msg_encoded = A::B::C::TestMessage.encode(msg, { recursion_limit: 6 }) + msg_out = A::B::C::TestMessage.decode(msg_encoded) + assert_match msg.to_json, msg_out.to_json + end + end diff --git a/ruby/tests/gc_test.rb b/ruby/tests/gc_test.rb index d7fecaeea1083..5d48f464aee57 100755 --- a/ruby/tests/gc_test.rb +++ b/ruby/tests/gc_test.rb @@ -94,7 +94,6 @@ def test_generated_msg from = get_msg_proto3 data = A::B::C::TestMessage.encode(from) to = A::B::C::TestMessage.decode(data) - # This doesn't work for proto2 on JRuby because there is a nested required message. # A::B::Proto2::TestMessage has :required_msg which is of type: # A::B::Proto2::TestMessage so there is no way to generate a valid diff --git a/ruby/tests/repeated_field_test.rb b/ruby/tests/repeated_field_test.rb index 1df6e1d4f1549..7ffc0f1801751 100755 --- a/ruby/tests/repeated_field_test.rb +++ b/ruby/tests/repeated_field_test.rb @@ -21,6 +21,7 @@ def test_acts_like_an_array :nitems, :iter_for_reverse_each, :indexes, :append, :prepend] arr_methods -= [:union, :difference, :filter!] arr_methods -= [:intersection, :deconstruct] # ruby 2.7 methods we can ignore + arr_methods -= [:intersect?] # ruby 3.1 methods we can ignore arr_methods.each do |method_name| assert m.repeated_string.respond_to?(method_name) == true, "does not respond to #{method_name}" end diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb index c069764167fc2..fbdee38a29693 100755 --- a/ruby/tests/well_known_types_test.rb +++ b/ruby/tests/well_known_types_test.rb @@ -15,18 +15,28 @@ def test_timestamp # millisecond accuracy time = Time.at(123456, 654321) - ts = Google::Protobuf::Timestamp.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)) + 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 + # 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 @@ -205,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 225061a313e26..35b7b0eabe15d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ else PTHREAD_DEF = endif -PROTOBUF_VERSION = 30:4:0 +PROTOBUF_VERSION = 31:0:0 if GCC # Turn on all warnings except for sign comparison (we ignore sign comparison @@ -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..346fa19f17ac1 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 { @@ -48,10 +49,8 @@ bool AnyMetadata::PackFrom(Arena* arena, const Message& message) { bool AnyMetadata::PackFrom(Arena* arena, const Message& message, StringPiece type_url_prefix) { type_url_->Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(), GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), arena); - return message.SerializeToString( - value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena)); + return message.SerializeToString(value_->Mutable(arena)); } bool AnyMetadata::UnpackTo(Message* message) const { 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..74b7903655c11 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) - : type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) +PROTOBUF_CONSTEXPR Any::Any( + ::_pbi::ConstantInitialized) + : type_url_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , value_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , _any_metadata_(&type_url_, &value_){} struct AnyDefaultTypeInternal { - constexpr AnyDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR AnyDefaultTypeInternal() + : _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,64 +111,57 @@ 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()); + type_url_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_type_url().empty()) { - type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), + type_url_.Set(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()); + value_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_value().empty()) { - value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), + value_.Set(from._internal_value(), GetArenaForAllocation()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Any) } 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()); + type_url_.Set("", 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()); + value_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } 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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + type_url_.Destroy(); + value_.Destroy(); } -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) @@ -323,19 +325,17 @@ void Any::InternalSwap(Any* other) { auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &type_url_, lhs_arena, &other->type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &value_, lhs_arena, &other->value_, rhs_arena ); } ::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 +343,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 ff7ef9cfa023a..7707119d07eef 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3019000 +#if PROTOBUF_VERSION < 3020000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3019004 < PROTOBUF_MIN_PROTOC_VERSION +#if 3020000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -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; @@ -70,7 +61,7 @@ class PROTOBUF_EXPORT Any final : public: inline Any() : Any(nullptr) {} ~Any() override; - explicit constexpr Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Any(const Any& from); Any(Any&& from) noexcept @@ -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_; @@ -287,7 +275,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Any::set_type_url(ArgT0&& arg0, ArgT... args) { - type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + type_url_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url) } inline std::string* Any::mutable_type_url() { @@ -300,15 +288,15 @@ inline const std::string& Any::_internal_type_url() const { } inline void Any::_internal_set_type_url(const std::string& value) { - type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + type_url_.Set(value, GetArenaForAllocation()); } inline std::string* Any::_internal_mutable_type_url() { - return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return type_url_.Mutable(GetArenaForAllocation()); } inline std::string* Any::release_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url) - return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return type_url_.Release(); } inline void Any::set_allocated_type_url(std::string* type_url) { if (type_url != nullptr) { @@ -316,11 +304,10 @@ inline void Any::set_allocated_type_url(std::string* type_url) { } else { } - type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url, - GetArenaForAllocation()); + type_url_.SetAllocated(type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (type_url_.IsDefault()) { + type_url_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url) @@ -338,7 +325,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Any::set_value(ArgT0&& arg0, ArgT... args) { - value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + value_.SetBytes(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Any.value) } inline std::string* Any::mutable_value() { @@ -351,15 +338,15 @@ inline const std::string& Any::_internal_value() const { } inline void Any::_internal_set_value(const std::string& value) { - value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + value_.Set(value, GetArenaForAllocation()); } inline std::string* Any::_internal_mutable_value() { - return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return value_.Mutable(GetArenaForAllocation()); } inline std::string* Any::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.Any.value) - return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return value_.Release(); } inline void Any::set_allocated_value(std::string* value) { if (value != nullptr) { @@ -367,11 +354,10 @@ inline void Any::set_allocated_value(std::string* value) { } else { } - value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, - GetArenaForAllocation()); + value_.SetAllocated(value, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (value_.IsDefault()) { + value_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto index 6ed8a23cf5a30..e2c2042fdc00d 100644 --- a/src/google/protobuf/any.proto +++ b/src/google/protobuf/any.proto @@ -64,7 +64,7 @@ option objc_class_prefix = "GPB"; // foo = any.unpack(Foo.class); // } // -// Example 3: Pack and unpack a message in Python. +// Example 3: Pack and unpack a message in Python. // // foo = Foo(...) // any = Any() @@ -74,7 +74,7 @@ option objc_class_prefix = "GPB"; // any.Unpack(foo) // ... // -// Example 4: Pack and unpack a message in Go +// Example 4: Pack and unpack a message in Go // // foo := &pb.Foo{...} // any, err := anypb.New(foo) @@ -95,7 +95,7 @@ option objc_class_prefix = "GPB"; // // // JSON -// ==== +// // The JSON representation of an `Any` value uses the regular // representation of the deserialized, embedded message, with an // additional field `@type` which contains the type URL. Example: diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index a98559da140ca..f283a31b0cc31 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 { @@ -56,10 +55,8 @@ const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/"; bool AnyMetadata::InternalPackFrom(Arena* arena, const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name) { - type_url_->Set(&::google::protobuf::internal::GetEmptyString(), - GetTypeUrl(type_name, type_url_prefix), arena); - return message.SerializeToString( - value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena)); + type_url_->Set(GetTypeUrl(type_name, type_url_prefix), arena); + return message.SerializeToString(value_->Mutable(arena)); } bool AnyMetadata::InternalUnpackTo(StringPiece type_name, diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 72cc72e03c023..7b35b0c5777de 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -16,62 +16,66 @@ #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) +PROTOBUF_CONSTEXPR Api::Api( + ::_pbi::ConstantInitialized) : methods_() , options_() , mixins_() - , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , version_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , version_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , source_context_(nullptr) , syntax_(0) {} struct ApiDefaultTypeInternal { - constexpr ApiDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR ApiDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~ApiDefaultTypeInternal() {} union { Api _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ApiDefaultTypeInternal _Api_default_instance_; -constexpr Method::Method( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ApiDefaultTypeInternal _Api_default_instance_; +PROTOBUF_CONSTEXPR Method::Method( + ::_pbi::ConstantInitialized) : options_() - , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , request_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , response_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , request_type_url_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , response_type_url_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , request_streaming_(false) , response_streaming_(false) , syntax_(0) {} struct MethodDefaultTypeInternal { - constexpr MethodDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR MethodDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~MethodDefaultTypeInternal() {} union { Method _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodDefaultTypeInternal _Method_default_instance_; -constexpr Mixin::Mixin( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , root_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDefaultTypeInternal _Method_default_instance_; +PROTOBUF_CONSTEXPR Mixin::Mixin( + ::_pbi::ConstantInitialized) + : name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , root_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}){} struct MixinDefaultTypeInternal { - constexpr MixinDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR MixinDefaultTypeInternal() + : _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,20 +202,20 @@ 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()); + name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_name().empty()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + name_.Set(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()); + version_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_version().empty()) { - version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_version(), + version_.Set(from._internal_version(), GetArenaForAllocation()); } if (from._internal_has_source_context()) { @@ -225,13 +228,13 @@ 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()); + name_.Set("", 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()); + version_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING ::memset(reinterpret_cast(this) + static_cast( reinterpret_cast(&source_context_) - reinterpret_cast(this)), @@ -241,24 +244,20 @@ ::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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - version_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.Destroy(); + version_.Destroy(); 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_); @@ -576,12 +574,10 @@ void Api::InternalSwap(Api* other) { options_.InternalSwap(&other->options_); mixins_.InternalSwap(&other->mixins_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &name_, lhs_arena, &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &version_, lhs_arena, &other->version_, rhs_arena ); @@ -594,7 +590,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,37 +609,34 @@ 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()); + name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_name().empty()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + name_.Set(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()); + request_type_url_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_request_type_url().empty()) { - request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_request_type_url(), + request_type_url_.Set(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()); + response_type_url_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_response_type_url().empty()) { - response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_response_type_url(), + response_type_url_.Set(from._internal_response_type_url(), GetArenaForAllocation()); } ::memcpy(&request_streaming_, &from.request_streaming_, @@ -653,17 +646,17 @@ 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()); + name_.Set("", 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()); + request_type_url_.Set("", 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()); + response_type_url_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING ::memset(reinterpret_cast(this) + static_cast( reinterpret_cast(&request_streaming_) - reinterpret_cast(this)), @@ -673,24 +666,20 @@ ::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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - request_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - response_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.Destroy(); + request_type_url_.Destroy(); + response_type_url_.Destroy(); } -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 +700,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 +720,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 +738,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 +826,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 +842,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 +917,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_); @@ -993,17 +982,14 @@ void Method::InternalSwap(Method* other) { _internal_metadata_.InternalSwap(&other->_internal_metadata_); options_.InternalSwap(&other->options_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &name_, lhs_arena, &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &request_type_url_, lhs_arena, &other->request_type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &response_type_url_, lhs_arena, &other->response_type_url_, rhs_arena ); @@ -1016,7 +1002,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,63 +1017,56 @@ 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()); + name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_name().empty()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + name_.Set(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()); + root_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_root().empty()) { - root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_root(), + root_.Set(from._internal_root(), GetArenaForAllocation()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin) } 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()); + name_.Set("", 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()); + root_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } 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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - root_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.Destroy(); + root_.Destroy(); } -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 +1082,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 +1102,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 +1158,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) @@ -1256,19 +1235,17 @@ void Mixin::InternalSwap(Mixin* other) { auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &name_, lhs_arena, &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &root_, lhs_arena, &other->root_, rhs_arena ); } ::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 +1253,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 093a02ef51355..057c63bc692ab 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3019000 +#if PROTOBUF_VERSION < 3020000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3019004 < PROTOBUF_MIN_PROTOC_VERSION +#if 3020000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -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; @@ -80,7 +71,7 @@ class PROTOBUF_EXPORT Api final : public: inline Api() : Api(nullptr) {} ~Api() override; - explicit constexpr Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Api(const Api& from); Api(Api&& from) noexcept @@ -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_; @@ -338,7 +326,7 @@ class PROTOBUF_EXPORT Method final : public: inline Method() : Method(nullptr) {} ~Method() override; - explicit constexpr Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Method(const Method& from); Method(Method&& from) noexcept @@ -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_; @@ -574,7 +559,7 @@ class PROTOBUF_EXPORT Mixin final : public: inline Mixin() : Mixin(nullptr) {} ~Mixin() override; - explicit constexpr Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Mixin(const Mixin& from); Mixin(Mixin&& from) noexcept @@ -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_; @@ -757,7 +739,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Api::set_name(ArgT0&& arg0, ArgT... args) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Api.name) } inline std::string* Api::mutable_name() { @@ -770,15 +752,15 @@ inline const std::string& Api::_internal_name() const { } inline void Api::_internal_set_name(const std::string& value) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + name_.Set(value, GetArenaForAllocation()); } inline std::string* Api::_internal_mutable_name() { - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return name_.Mutable(GetArenaForAllocation()); } inline std::string* Api::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Api.name) - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return name_.Release(); } inline void Api::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -786,11 +768,10 @@ inline void Api::set_allocated_name(std::string* name) { } else { } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (name_.IsDefault()) { + name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name) @@ -885,7 +866,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Api::set_version(ArgT0&& arg0, ArgT... args) { - version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + version_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Api.version) } inline std::string* Api::mutable_version() { @@ -898,15 +879,15 @@ inline const std::string& Api::_internal_version() const { } inline void Api::_internal_set_version(const std::string& value) { - version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + version_.Set(value, GetArenaForAllocation()); } inline std::string* Api::_internal_mutable_version() { - return version_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return version_.Mutable(GetArenaForAllocation()); } inline std::string* Api::release_version() { // @@protoc_insertion_point(field_release:google.protobuf.Api.version) - return version_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return version_.Release(); } inline void Api::set_allocated_version(std::string* version) { if (version != nullptr) { @@ -914,11 +895,10 @@ inline void Api::set_allocated_version(std::string* version) { } else { } - version_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version, - GetArenaForAllocation()); + version_.SetAllocated(version, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (version_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (version_.IsDefault()) { + version_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version) @@ -995,8 +975,7 @@ inline void Api::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceCon } if (source_context) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< - ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena( reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)); if (message_arena != submessage_arena) { source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( @@ -1086,7 +1065,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_name(ArgT0&& arg0, ArgT... args) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Method.name) } inline std::string* Method::mutable_name() { @@ -1099,15 +1078,15 @@ inline const std::string& Method::_internal_name() const { } inline void Method::_internal_set_name(const std::string& value) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + name_.Set(value, GetArenaForAllocation()); } inline std::string* Method::_internal_mutable_name() { - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return name_.Mutable(GetArenaForAllocation()); } inline std::string* Method::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Method.name) - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return name_.Release(); } inline void Method::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1115,11 +1094,10 @@ inline void Method::set_allocated_name(std::string* name) { } else { } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (name_.IsDefault()) { + name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name) @@ -1137,7 +1115,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_request_type_url(ArgT0&& arg0, ArgT... args) { - request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + request_type_url_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url) } inline std::string* Method::mutable_request_type_url() { @@ -1150,15 +1128,15 @@ inline const std::string& Method::_internal_request_type_url() const { } inline void Method::_internal_set_request_type_url(const std::string& value) { - request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + request_type_url_.Set(value, GetArenaForAllocation()); } inline std::string* Method::_internal_mutable_request_type_url() { - return request_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return request_type_url_.Mutable(GetArenaForAllocation()); } inline std::string* Method::release_request_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url) - return request_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return request_type_url_.Release(); } inline void Method::set_allocated_request_type_url(std::string* request_type_url) { if (request_type_url != nullptr) { @@ -1166,11 +1144,10 @@ inline void Method::set_allocated_request_type_url(std::string* request_type_url } else { } - request_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), request_type_url, - GetArenaForAllocation()); + request_type_url_.SetAllocated(request_type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (request_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (request_type_url_.IsDefault()) { + request_type_url_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url) @@ -1208,7 +1185,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_response_type_url(ArgT0&& arg0, ArgT... args) { - response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + response_type_url_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url) } inline std::string* Method::mutable_response_type_url() { @@ -1221,15 +1198,15 @@ inline const std::string& Method::_internal_response_type_url() const { } inline void Method::_internal_set_response_type_url(const std::string& value) { - response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + response_type_url_.Set(value, GetArenaForAllocation()); } inline std::string* Method::_internal_mutable_response_type_url() { - return response_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return response_type_url_.Mutable(GetArenaForAllocation()); } inline std::string* Method::release_response_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url) - return response_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return response_type_url_.Release(); } inline void Method::set_allocated_response_type_url(std::string* response_type_url) { if (response_type_url != nullptr) { @@ -1237,11 +1214,10 @@ inline void Method::set_allocated_response_type_url(std::string* response_type_u } else { } - response_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), response_type_url, - GetArenaForAllocation()); + response_type_url_.SetAllocated(response_type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (response_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (response_type_url_.IsDefault()) { + response_type_url_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url) @@ -1340,7 +1316,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Mixin::set_name(ArgT0&& arg0, ArgT... args) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name) } inline std::string* Mixin::mutable_name() { @@ -1353,15 +1329,15 @@ inline const std::string& Mixin::_internal_name() const { } inline void Mixin::_internal_set_name(const std::string& value) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + name_.Set(value, GetArenaForAllocation()); } inline std::string* Mixin::_internal_mutable_name() { - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return name_.Mutable(GetArenaForAllocation()); } inline std::string* Mixin::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name) - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return name_.Release(); } inline void Mixin::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1369,11 +1345,10 @@ inline void Mixin::set_allocated_name(std::string* name) { } else { } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (name_.IsDefault()) { + name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name) @@ -1391,7 +1366,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Mixin::set_root(ArgT0&& arg0, ArgT... args) { - root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + root_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root) } inline std::string* Mixin::mutable_root() { @@ -1404,15 +1379,15 @@ inline const std::string& Mixin::_internal_root() const { } inline void Mixin::_internal_set_root(const std::string& value) { - root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + root_.Set(value, GetArenaForAllocation()); } inline std::string* Mixin::_internal_mutable_root() { - return root_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return root_.Mutable(GetArenaForAllocation()); } inline std::string* Mixin::release_root() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root) - return root_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return root_.Release(); } inline void Mixin::set_allocated_root(std::string* root) { if (root != nullptr) { @@ -1420,11 +1395,10 @@ inline void Mixin::set_allocated_root(std::string* root) { } else { } - root_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), root, - GetArenaForAllocation()); + root_.SetAllocated(root, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (root_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (root_.IsDefault()) { + root_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root) 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..c3436d4119792 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -37,9 +37,6 @@ #include #include #include -#ifdef max -#undef max // Visual Studio defines this macro -#endif #if defined(_MSC_VER) && !defined(_LIBCPP_STD_VER) && !_HAS_EXCEPTIONS // Work around bugs in MSVC header when _HAS_EXCEPTIONS=0. #include @@ -55,6 +52,7 @@ using type_info = ::type_info; #include #include +// Must be included last. #include #ifdef SWIG @@ -83,10 +81,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 +315,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);`). @@ -397,27 +410,10 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { template class InternalHelper { - public: + private: // Provides access to protected GetOwningArena to generated messages. static Arena* GetOwningArena(const T* p) { return p->GetOwningArena(); } - // Provides access to protected GetArenaForAllocation to generated messages. - static Arena* GetArenaForAllocation(const T* p) { - return GetArenaForAllocationInternal( - p, std::is_convertible()); - } - - // Creates message-owned arena. - static Arena* CreateMessageOwnedArena() { - return new Arena(internal::MessageOwned{}); - } - - // Checks whether the given arena is message-owned. - static bool IsMessageOwnedArena(Arena* arena) { - return arena->IsMessageOwned(); - } - - private: static Arena* GetArenaForAllocationInternal( const T* p, std::true_type /*is_derived_from*/) { return p->GetArenaForAllocation(); @@ -500,6 +496,29 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { friend class TestUtil::ReflectionTester; }; + // Provides access to protected GetOwningArena to generated messages. For + // internal use only. + template + static Arena* InternalGetOwningArena(const T* p) { + return InternalHelper::GetOwningArena(p); + } + + // Provides access to protected GetArenaForAllocation to generated messages. + // For internal use only. + template + static Arena* InternalGetArenaForAllocation(const T* p) { + return InternalHelper::GetArenaForAllocationInternal( + p, std::is_convertible()); + } + + // Creates message-owned arena. For internal use only. + static Arena* InternalCreateMessageOwnedArena() { + return new Arena(internal::MessageOwned{}); + } + + // Checks whether this arena is message-owned. For internal use only. + bool InternalIsMessageOwnedArena() { return IsMessageOwned(); } + // Helper typetraits that indicates support for arenas in a type T at compile // time. This is public only to allow construction of higher-level templated // utilities. @@ -532,6 +551,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 +645,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 +788,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 +810,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 +820,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..e80e0e87495a9 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,16 @@ TEST(ArenaTest, UnsafeArenaSwap) { TestUtil::ExpectAllFieldsSet(*message2); } +TEST(ArenaTest, GetOwningArena) { + Arena arena; + auto* m1 = Arena::CreateMessage(&arena); + EXPECT_EQ(Arena::InternalGetOwningArena(m1), &arena); + EXPECT_EQ(&arena, Arena::InternalGetOwningArena( + m1->mutable_repeated_foreign_message())); + EXPECT_EQ(&arena, + Arena::InternalGetOwningArena(m1->mutable_repeated_int32())); +} + TEST(ArenaTest, SwapBetweenArenasUsingReflection) { Arena arena1; TestAllTypes* arena1_message = Arena::CreateMessage(&arena1); @@ -1465,6 +1477,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..d886ddad66a5c 100644 --- a/src/google/protobuf/arenastring.cc +++ b/src/google/protobuf/arenastring.cc @@ -30,13 +30,14 @@ #include +#include #include #include -#include #include -#include #include #include +#include +#include #include // clang-format off @@ -47,6 +48,27 @@ 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__; +#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900 +constexpr size_t kNewAlign = alignof(::max_align_t); +#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,185 +83,152 @@ const std::string& LazyString::Init() const { return *res; } +namespace { + + +#if defined(NDEBUG) || !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL -std::string* ArenaStringPtr::SetAndReturnNewString() { - std::string* new_string = new std::string(); - tagged_ptr_.Set(new_string); - return new_string; +class ScopedCheckPtrInvariants { + public: + explicit ScopedCheckPtrInvariants(const TaggedStringPtr*) {} +}; + +#endif // NDEBUG || !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL + +// Creates a heap allocated std::string value. +inline TaggedStringPtr CreateString(ConstStringParam value) { + TaggedStringPtr 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. +TaggedStringPtr CreateArenaString(Arena& arena, ConstStringParam s) { + TaggedStringPtr res; + res.SetMutableArena(Arena::Create(&arena, s.data(), s.length())); + return res; } -void ArenaStringPtr::DestroyNoArenaSlowPath() { delete UnsafeMutablePointer(); } +#endif // !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL -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)); +} // namespace + +void ArenaStringPtr::Set(ConstStringParam value, Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + 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, - ::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()) { +void ArenaStringPtr::Set(std::string&& value, Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + 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); } } -void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value, - ::google::protobuf::Arena* arena) { - Set(&GetEmptyStringAlreadyInited(), value, arena); -} - -void ArenaStringPtr::Set(EmptyDefault, std::string&& value, - ::google::protobuf::Arena* arena) { - Set(&GetEmptyStringAlreadyInited(), std::move(value), arena); -} - -void ArenaStringPtr::Set(NonEmptyDefault, ConstStringParam value, - ::google::protobuf::Arena* arena) { - Set(nullptr, value, arena); -} - -void ArenaStringPtr::Set(NonEmptyDefault, std::string&& value, - ::google::protobuf::Arena* arena) { - Set(nullptr, std::move(value), arena); -} - -std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) { - return UnsafeMutablePointer(); +std::string* ArenaStringPtr::Mutable(Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (tagged_ptr_.IsMutable()) { + return tagged_ptr_.Get(); } else { return MutableSlow(arena); } } std::string* ArenaStringPtr::Mutable(const LazyString& default_value, - ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(nullptr)) { - return UnsafeMutablePointer(); + Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (tagged_ptr_.IsMutable()) { + return tagged_ptr_.Get(); } else { return MutableSlow(arena, default_value); } } -std::string* ArenaStringPtr::MutableNoCopy(const std::string* default_value, - ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(default_value)) { - return UnsafeMutablePointer(); +std::string* ArenaStringPtr::MutableNoCopy(Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (tagged_ptr_.IsMutable()) { + return tagged_ptr_.Get(); } 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()); -std::string* ArenaStringPtr::Release(const std::string* default_value, - ::google::protobuf::Arena* arena) { - if (IsDefault(default_value)) { - return nullptr; - } else { - return ReleaseNonDefault(default_value, arena); - } + // For empty defaults, this ends up calling the default constructor which is + // more efficient than a copy construction from + // GetEmptyStringAlreadyInited(). + return NewString(arena, lazy_default.get()...); } -std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value, - ::google::protobuf::Arena* arena) { - GOOGLE_DCHECK(!IsDefault(default_value)); - - if (!IsDonatedString()) { - std::string* released; - if (arena != nullptr) { - released = new std::string; - released->swap(*UnsafeMutablePointer()); - } else { - released = UnsafeMutablePointer(); - } - tagged_ptr_.Set(const_cast(default_value)); - return released; - } else /* IsDonatedString() */ { - GOOGLE_DCHECK(arena != nullptr); - std::string* released = new std::string(Get()); - tagged_ptr_.Set(const_cast(default_value)); - return released; +std::string* ArenaStringPtr::Release() { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (IsDefault()) return nullptr; + + std::string* released = tagged_ptr_.Get(); + if (!tagged_ptr_.IsAllocated()) { + released = tagged_ptr_.IsMutable() ? new std::string(std::move(*released)) + : new std::string(*released); } + InitDefault(); + return released; } -void ArenaStringPtr::SetAllocated(const std::string* default_value, - std::string* value, ::google::protobuf::Arena* arena) { +void ArenaStringPtr::SetAllocated(std::string* value, Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); // Release what we have first. - if (arena == nullptr && !IsDefault(default_value)) { - delete UnsafeMutablePointer(); - } + Destroy(); + if (value == nullptr) { - tagged_ptr_.Set(const_cast(default_value)); + InitDefault(); } 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) { - if (arena == nullptr) { - GOOGLE_DCHECK(!IsDonatedString()); - if (!IsDefault(default_value)) { - delete UnsafeMutablePointer(); - } +void ArenaStringPtr::Destroy() { + if (tagged_ptr_.IsAllocated()) { + delete tagged_ptr_.Get(); } } -void ArenaStringPtr::Destroy(EmptyDefault, ::google::protobuf::Arena* arena) { - Destroy(&GetEmptyStringAlreadyInited(), arena); -} - -void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) { - Destroy(nullptr, arena); -} - void ArenaStringPtr::ClearToEmpty() { - if (IsDefault(&GetEmptyStringAlreadyInited())) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + 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(); @@ -248,34 +237,27 @@ void ArenaStringPtr::ClearToEmpty() { void ArenaStringPtr::ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); (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) { + ScopedCheckPtrInvariants check(&s->tagged_ptr_); GOOGLE_DCHECK(arena != nullptr); 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..b8d31fec015b0 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 { @@ -89,182 +94,222 @@ class PROTOBUF_EXPORT LazyString { const std::string& Init() const; }; -template -class TaggedPtr { +class TaggedStringPtr { public: - TaggedPtr() = default; - explicit constexpr TaggedPtr(const ExplicitlyConstructed* ptr) - : ptr_(const_cast*>(ptr)) {} + // 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, + }; + + TaggedStringPtr() = default; + explicit constexpr TaggedStringPtr(ExplicitlyConstructedArenaString* ptr) + : ptr_(ptr) {} + + // Sets the value to `p`, tagging the value as being a 'default' value. + // See documentation for kDefault for more info. + inline const std::string* SetDefault(const std::string* p) { + return TagAs(kDefault, const_cast(p)); + } + + // 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 std::string* SetAllocated(std::string* p) { + return TagAs(kAllocated, p); + } - void SetTagged(T* p) { - Set(p); - ptr_ = reinterpret_cast(as_int() | 1); + // 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 std::string* SetFixedSizeArena(std::string* p) { + return TagAs(kFixedSizeArena, 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 mutable arena string. + // See documentation for kMutableArena for more info. + // `p` must not be null + inline std::string* SetMutableArena(std::string* 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; } + + // 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; } - bool IsNull() { return ptr_ == nullptr; } + // 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 std::string* 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 std::string* TagAs(Type type, std::string* p) { + GOOGLE_DCHECK(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_; }; -static_assert(std::is_trivial>::value, - "TaggedPtr must be trivial"); +static_assert(std::is_trivial::value, + "TaggedStringPtr 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. +// 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 '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. +// 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. // -// - 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). -// -// 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) + constexpr ArenaStringPtr(ExplicitlyConstructedArenaString* default_value, + ConstantInitialized) : tagged_ptr_(default_value) {} - // Some methods below are overloaded on a `default_value` and on tags. - // The tagged overloads help reduce code size in the callers in generated - // code, while the `default_value` overloads are useful from reflection. - // By-value empty struct arguments are elided in the ABI. - struct EmptyDefault {}; - struct NonEmptyDefault {}; - - void Set(const std::string* default_value, ConstStringParam value, - ::google::protobuf::Arena* arena); - void Set(const std::string* default_value, std::string&& value, - ::google::protobuf::Arena* arena); - void Set(EmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); - void Set(EmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); - void Set(NonEmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); - void Set(NonEmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); - template - void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena) { - Set(p1, ConstStringParam(str), arena); - } - template - void Set(FirstParam p1, const char* str, size_t size, - ::google::protobuf::Arena* arena) { - ConstStringParam sp{str, size}; // for string_view and `const string &` - Set(p1, sp, arena); - } - template - void Set(FirstParam p1, - std::reference_wrapper const_string_ref, + // 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 InitDefault(); + + // Similar to `InitDefault` except that it allows the default value to be + // initialized to an externally owned string. This method is called from + // parsing code. `str` must not be null and outlive this instance. + inline void InitExternal(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); + + void Set(ConstStringParam value, Arena* arena); + void Set(std::string&& value, Arena* arena); + void Set(const char* s, Arena* arena); + void Set(const char* s, size_t n, Arena* arena); + + void SetBytes(ConstStringParam value, Arena* arena); + void SetBytes(std::string&& value, Arena* arena); + void SetBytes(const char* s, Arena* arena); + void SetBytes(const void* p, size_t n, Arena* arena); + + template + void Set(std::reference_wrapper const_string_ref, ::google::protobuf::Arena* arena) { - Set(p1, const_string_ref.get(), arena); + Set(const_string_ref.get(), arena); } - template - void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena) { - Set(p1, static_cast(p2), arena); - } - template - void SetBytes(FirstParam p1, const void* str, size_t size, - ::google::protobuf::Arena* arena) { - // must work whether ConstStringParam is string_view or `const string &` - ConstStringParam sp{static_cast(str), size}; - Set(p1, sp, arena); - } + // Returns a mutable std::string reference. + // The version accepting a `LazyString` value is used in the generated code to + // initialize mutable copies for fields with a non-empty default where the + // default value is lazily initialized. + std::string* Mutable(Arena* arena); + std::string* Mutable(const LazyString& default_value, Arena* arena); + + // Gets a mutable pointer with unspecified contents. + // This function is identical to Mutable(), except it is optimized for the + // case where the caller is not interested in the current contents. For + // example, if the current field is not mutable, it will re-initialize the + // value with an empty string rather than a (non-empty) default value. + // Likewise, if the current value is a fixed size arena string with contents, + // it will be initialized into an empty mutable arena string. + std::string* MutableNoCopy(Arena* arena); // Basic accessors. PROTOBUF_NDEBUG_INLINE const std::string& Get() const { // Unconditionally mask away the tag. return *tagged_ptr_.Get(); } - PROTOBUF_NDEBUG_INLINE const std::string* GetPointer() const { - // Unconditionally mask away the tag. + + // Returns a pointer to the stored contents for this instance. + // This method is for internal debugging and tracking purposes only. + PROTOBUF_NDEBUG_INLINE const std::string* UnsafeGetPointer() const + PROTOBUF_RETURNS_NONNULL { return tagged_ptr_.Get(); } - // For fields with an empty default value. - std::string* Mutable(EmptyDefault, ::google::protobuf::Arena* arena); - // For fields with a non-empty default value. - std::string* Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena); - // Release returns a std::string* instance that is heap-allocated and is not // Own()'d by any arena. If the field is not set, this returns nullptr. The - // caller retains ownership. Clears this field back to nullptr state. Used to - // implement release_() methods on generated classes. - PROTOBUF_NODISCARD std::string* Release(const std::string* default_value, - ::google::protobuf::Arena* arena); - PROTOBUF_NODISCARD std::string* ReleaseNonDefault( - const std::string* default_value, ::google::protobuf::Arena* arena); + // caller retains ownership. Clears this field back to the default state. + // Used to implement release_() methods on generated classes. + PROTOBUF_NODISCARD std::string* Release(); // Takes a std::string that is heap-allocated, and takes ownership. The // std::string's destructor is registered with the arena. Used to implement // set_allocated_ in generated classes. - void SetAllocated(const std::string* default_value, std::string* value, - ::google::protobuf::Arena* arena); - - // Swaps internal pointers. Arena-safety semantics: this is guarded by the - // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is - // 'unsafe' if called directly. - inline PROTOBUF_NDEBUG_INLINE static void InternalSwap( - const std::string* default_value, ArenaStringPtr* rhs, Arena* rhs_arena, - ArenaStringPtr* lhs, Arena* lhs_arena); + void SetAllocated(std::string* value, Arena* arena); // Frees storage (if not on an arena). - void Destroy(const std::string* default_value, ::google::protobuf::Arena* arena); - void Destroy(EmptyDefault, ::google::protobuf::Arena* arena); - void Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena); + void Destroy(); // Clears content, but keeps allocated std::string, to avoid the overhead of // heap operations. After this returns, the content (as seen by the user) will @@ -281,48 +326,40 @@ struct PROTOBUF_EXPORT ArenaStringPtr { // (as seen by the user) will always be equal to |default_value|. 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); - - // Returns a mutable pointer, but doesn't initialize the string to the - // default value. - std::string* MutableNoArenaNoDefault(const std::string* default_value); - - // Get a mutable pointer with unspecified contents. - // Similar to `MutableNoArenaNoDefault`, but also handles the arena case. - // If the value was donated, the contents are discarded. - std::string* MutableNoCopy(const std::string* default_value, - ::google::protobuf::Arena* arena); - - // Destroy the string. Assumes `arena == nullptr`. - void DestroyNoArena(const std::string* default_value); + // Swaps internal pointers. Arena-safety semantics: this is guarded by the + // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is + // 'unsafe' if called directly. + inline PROTOBUF_NDEBUG_INLINE static void InternalSwap(ArenaStringPtr* rhs, + Arena* rhs_arena, + ArenaStringPtr* lhs, + Arena* lhs_arena); // Internal setter used only at parse time to directly set a donated string // value. - void UnsafeSetTaggedPointer(TaggedPtr value) { - tagged_ptr_ = value; - } + void UnsafeSetTaggedPointer(TaggedStringPtr value) { tagged_ptr_ = value; } // Generated code only! An optimization, in certain cases the generated // code is certain we can obtain a std::string with no default checks and // tag tests. std::string* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL; - inline bool IsDefault(const std::string* default_value) const { - // Relies on the fact that kPtrTagString == 0, so if IsString(), ptr_ is the - // actual std::string pointer (and if !IsString(), ptr_ will never be equal - // to any aligned |default_value| pointer). The key is that we want to avoid - // masking in the fastpath const-pointer Get() case for non-arena code. - return tagged_ptr_.UnsafeGet() == default_value; - } + // Returns true if this instances holds an immutable default value. + inline bool IsDefault() const { return tagged_ptr_.IsDefault(); } private: - TaggedPtr tagged_ptr_; + 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); + } + } + + TaggedStringPtr 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,46 +369,81 @@ struct PROTOBUF_EXPORT ArenaStringPtr { } friend class ::google::protobuf::internal::SwapFieldHelper; + friend class TcParser; // Slow paths. // MutableSlow requires that !IsString() || IsDefault - // Variadic to support 0 args for EmptyDefault and 1 arg for LazyString. + // Variadic to support 0 args for empty default and 1 arg for LazyString. template std::string* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default); - // Sets value to a newly allocated string and returns it - std::string* SetAndReturnNewString(); + friend class EpsCopyInputStream; +}; - // Destroys the non-default string value out-of-line - void DestroyNoArenaSlowPath(); +inline void ArenaStringPtr::InitDefault() { + tagged_ptr_ = TaggedStringPtr(&fixed_address_empty_string); +} -}; +inline void ArenaStringPtr::InitExternal(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); + } +} + +inline void ArenaStringPtr::Set(const char* s, Arena* arena) { + Set(ConstStringParam{s}, arena); +} + +inline void ArenaStringPtr::Set(const char* s, size_t n, Arena* arena) { + Set(ConstStringParam{s, n}, arena); +} + +inline void ArenaStringPtr::SetBytes(ConstStringParam value, Arena* arena) { + Set(value, arena); +} + +inline void ArenaStringPtr::SetBytes(std::string&& value, Arena* arena) { + Set(std::move(value), arena); +} + +inline void ArenaStringPtr::SetBytes(const char* s, Arena* arena) { + Set(s, arena); +} -inline void ArenaStringPtr::UnsafeSetDefault(const std::string* value) { - tagged_ptr_.Set(const_cast(value)); +inline void ArenaStringPtr::SetBytes(const void* p, size_t n, Arena* arena) { + Set(ConstStringParam{static_cast(p), n}, arena); } // Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs. inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( // - const std::string* default_value, // 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. @@ -385,29 +457,10 @@ inline void ArenaStringPtr::ClearNonDefaultToEmpty() { tagged_ptr_.Get()->clear(); } -inline std::string* ArenaStringPtr::MutableNoArenaNoDefault( - const std::string* default_value) { - // VERY IMPORTANT for performance and code size: this will reduce to a member - // variable load, a pointer check (against |default_value|, in practice a - // static global) and a branch to the slowpath (which calls operator new and - // the ctor). DO NOT add any tagged-pointer operations here. - if (IsDefault(default_value)) { - return SetAndReturnNewString(); - } else { - return UnsafeMutablePointer(); - } -} - -inline void ArenaStringPtr::DestroyNoArena(const std::string* default_value) { - if (!IsDefault(default_value)) { - 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..0e5ea9b395936 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -54,8 +55,6 @@ namespace protobuf { using internal::ArenaStringPtr; -using EmptyDefault = ArenaStringPtr::EmptyDefault; - const internal::LazyString nonempty_default{{{"default", 7}}, {nullptr}}; const std::string* empty_default = &internal::GetEmptyString(); @@ -72,37 +71,36 @@ INSTANTIATE_TEST_SUITE_P(ArenaString, SingleArena, testing::Bool()); TEST_P(SingleArena, GetSet) { auto arena = GetArena(); ArenaStringPtr field; - field.UnsafeSetDefault(empty_default); + field.InitDefault(); EXPECT_EQ("", field.Get()); - field.Set(empty_default, "Test short", arena.get()); + field.Set("Test short", arena.get()); EXPECT_EQ("Test short", field.Get()); - field.Set(empty_default, "Test long long long long value", arena.get()); + field.Set("Test long long long long value", arena.get()); EXPECT_EQ("Test long long long long value", field.Get()); - field.Set(empty_default, "", arena.get()); - field.Destroy(empty_default, arena.get()); + field.Set("", arena.get()); + field.Destroy(); } TEST_P(SingleArena, MutableAccessor) { auto arena = GetArena(); ArenaStringPtr field; - const std::string* empty_default = &internal::GetEmptyString(); - field.UnsafeSetDefault(empty_default); + field.InitDefault(); - std::string* mut = field.Mutable(EmptyDefault{}, arena.get()); - EXPECT_EQ(mut, field.Mutable(EmptyDefault{}, arena.get())); + std::string* mut = field.Mutable(arena.get()); + EXPECT_EQ(mut, field.Mutable(arena.get())); EXPECT_EQ(mut, &field.Get()); EXPECT_NE(empty_default, mut); EXPECT_EQ("", *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ("Test long long long long value", field.Get()); - field.Destroy(empty_default, arena.get()); + field.Destroy(); } TEST_P(SingleArena, NullDefault) { auto arena = GetArena(); ArenaStringPtr field; - field.UnsafeSetDefault(nullptr); + field.InitDefault(); std::string* mut = field.Mutable(nonempty_default, arena.get()); EXPECT_EQ(mut, field.Mutable(nonempty_default, arena.get())); EXPECT_EQ(mut, &field.Get()); @@ -110,7 +108,7 @@ TEST_P(SingleArena, NullDefault) { EXPECT_EQ("default", *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ("Test long long long long value", field.Get()); - field.Destroy(nullptr, arena.get()); + field.Destroy(); } class DualArena : public testing::TestWithParam> { @@ -131,23 +129,22 @@ INSTANTIATE_TEST_SUITE_P(ArenaString, DualArena, TEST_P(DualArena, Swap) { auto lhs_arena = GetLhsArena(); ArenaStringPtr lhs; - lhs.UnsafeSetDefault(empty_default); + lhs.InitDefault(); ArenaStringPtr rhs; - rhs.UnsafeSetDefault(empty_default); + rhs.InitDefault(); { auto rhs_arena = GetRhsArena(); - lhs.Set(empty_default, "lhs value that has some heft", lhs_arena.get()); - rhs.Set(empty_default, "rhs value that has some heft", rhs_arena.get()); - ArenaStringPtr::InternalSwap(empty_default, // - &lhs, lhs_arena.get(), // + lhs.Set("lhs value that has some heft", lhs_arena.get()); + rhs.Set("rhs value that has some heft", rhs_arena.get()); + ArenaStringPtr::InternalSwap(&lhs, lhs_arena.get(), // &rhs, rhs_arena.get()); EXPECT_EQ("rhs value that has some heft", lhs.Get()); EXPECT_EQ("lhs value that has some heft", rhs.Get()); - lhs.Destroy(empty_default, rhs_arena.get()); + lhs.Destroy(); } EXPECT_EQ("lhs value that has some heft", rhs.Get()); - rhs.Destroy(empty_default, lhs_arena.get()); + rhs.Destroy(); } 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..52e8347ed5184 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -53,10 +53,11 @@ #endif #include #include + #include #include -#include //For PATH_MAX +#include // For PATH_MAX #include @@ -68,7 +69,6 @@ #include #include -#include #include #include #include @@ -81,12 +81,14 @@ #include #include #include +#include #include #include #include #include +// Must be included last. #include namespace google { @@ -195,7 +197,7 @@ bool TryCreateParentDirectory(const std::string& prefix, bool GetProtocAbsolutePath(std::string* path) { #ifdef _WIN32 char buffer[MAX_PATH]; - int len = GetModuleFileNameA(NULL, buffer, MAX_PATH); + int len = GetModuleFileNameA(nullptr, buffer, MAX_PATH); #elif defined(__APPLE__) char buffer[PATH_MAX]; int len = 0; @@ -210,7 +212,7 @@ bool GetProtocAbsolutePath(std::string* path) { char buffer[PATH_MAX]; size_t len = PATH_MAX; int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; - if (sysctl(mib, 4, &buffer, &len, NULL, 0) != 0) { + if (sysctl(mib, 4, &buffer, &len, nullptr, 0) != 0) { len = 0; } #else @@ -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; @@ -1674,8 +1676,9 @@ CommandLineInterface::InterpretArgument(const std::string& name, // On Windows, the shell (typically cmd.exe) does not expand wildcards in // file names (e.g. foo\*.proto), so we do it ourselves. switch (google::protobuf::io::win32::ExpandWildcards( - value, - [this](const string& path) { this->input_files_.push_back(path); })) { + value, [this](const std::string& path) { + this->input_files_.push_back(path); + })) { case google::protobuf::io::win32::ExpandWildcardsResult::kSuccess: break; case google::protobuf::io::win32::ExpandWildcardsResult:: @@ -1946,11 +1949,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 +1982,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 +2139,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")) @@ -2304,7 +2307,7 @@ bool CommandLineInterface::GeneratePluginOutput( if (!output_file.insertion_point().empty()) { std::string filename = output_file.name(); // Open a file for insert. - // We reset current_output to NULL first so that the old file is closed + // We reset current_output to nullptr first so that the old file is closed // before the new one is opened. current_output.reset(); current_output.reset( @@ -2313,11 +2316,11 @@ bool CommandLineInterface::GeneratePluginOutput( output_file.generated_code_info())); } else if (!output_file.name().empty()) { // Starting a new file. Open it. - // We reset current_output to NULL first so that the old file is closed + // We reset current_output to nullptr first so that the old file is closed // 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 +2350,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; } @@ -2586,7 +2589,8 @@ void FormatFreeFieldNumbers(const std::string& name, StringAppendF(&output, " %d", next_free_number); } else { // Range - StringAppendF(&output, " %d-%d", next_free_number, i->first - 1); + StringAppendF(&output, " %d-%d", next_free_number, + i->first - 1); } } next_free_number = i->second; 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..efdd59477907f 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; @@ -1714,7 +1714,7 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFile) { " optional Foo foo = 1;\n" "}\n"); - std::string current_working_directory = getcwd(NULL, 0); + std::string current_working_directory = getcwd(nullptr, 0); SwitchToTempDirectory(); Run("protocol_compiler --dependency_out=manifest --test_out=. " @@ -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..0e832023e24ce 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 { @@ -53,6 +54,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor, (*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options); (*variables)["default"] = Int32ToString(default_value->number()); (*variables)["full_name"] = descriptor->full_name(); + (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); + (*variables)["cached_byte_size_field"] = + MakeVarintCachedSizeFieldName(descriptor); } } // namespace @@ -90,7 +94,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$() const {\n" - " return static_cast< $type$ >($name$_);\n" + " return static_cast< $type$ >($field$);\n" "}\n" "inline $type$ $classname$::$name$() const {\n" "$annotate_get$" @@ -103,7 +107,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions( } format( " $set_hasbit$\n" - " $name$_ = value;\n" + " $field$ = value;\n" "}\n" "inline void $classname$::set_$name$($type$ value) {\n" " _internal_set_$name$(value);\n" @@ -114,7 +118,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions( void EnumFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("$field$ = $default$;\n"); } void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const { @@ -124,18 +128,18 @@ void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const { void EnumFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("swap($name$_, other->$name$_);\n"); + format("swap($field$, other->$field$);\n"); } void EnumFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("$field$ = $default$;\n"); } void EnumFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = from.$name$_;\n"); + format("$field$ = from.$field$;\n"); } void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -143,7 +147,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 +155,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( @@ -178,7 +180,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline $type$ $classname$::_internal_$name$() const {\n" " if (_internal_has_$name$()) {\n" - " return static_cast< $type$ >($field_member$);\n" + " return static_cast< $type$ >($field$);\n" " }\n" " return static_cast< $type$ >($default$);\n" "}\n" @@ -196,7 +198,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions( " clear_$oneof_name$();\n" " set_has_$name$();\n" " }\n" - " $field_member$ = value;\n" + " $field$ = value;\n" "}\n" "inline void $classname$::set_$name$($type$ value) {\n" " _internal_set_$name$(value);\n" @@ -207,7 +209,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions( void EnumOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$field_member$ = $default$;\n"); + format("$field$ = $default$;\n"); } void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { @@ -217,7 +219,7 @@ void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { void EnumOneofFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n"); + format("$ns$::_$classname$_default_instance_.$field$ = $default$;\n"); } // =================================================================== @@ -236,7 +238,7 @@ void RepeatedEnumFieldGenerator::GeneratePrivateMembers( format("::$proto_ns$::RepeatedField $name$_;\n"); if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file(), options_)) { - format("mutable std::atomic _$name$_cached_byte_size_;\n"); + format("mutable std::atomic $cached_byte_size_name$;\n"); } } @@ -265,7 +267,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$(int index) const {\n" - " return static_cast< $type$ >($name$_.Get(index));\n" + " return static_cast< $type$ >($field$.Get(index));\n" "}\n" "inline $type$ $classname$::$name$(int index) const {\n" "$annotate_get$" @@ -277,7 +279,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( format(" assert($type$_IsValid(value));\n"); } format( - " $name$_.Set(index, value);\n" + " $field$.Set(index, value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" @@ -286,7 +288,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( format(" assert($type$_IsValid(value));\n"); } format( - " $name$_.Add(value);\n" + " $field$.Add(value);\n" "}\n" "inline void $classname$::add_$name$($type$ value) {\n" " _internal_add_$name$(value);\n" @@ -297,11 +299,11 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( "$classname$::$name$() const {\n" "$annotate_list$" " // @@protoc_insertion_point(field_list:$full_name$)\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline ::$proto_ns$::RepeatedField*\n" "$classname$::_internal_mutable_$name$() {\n" - " return &$name$_;\n" + " return &$field$;\n" "}\n" "inline ::$proto_ns$::RepeatedField*\n" "$classname$::mutable_$name$() {\n" @@ -314,19 +316,19 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( void RepeatedEnumFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedEnumFieldGenerator::GenerateMergingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("$field$.MergeFrom(from.$field$);\n"); } void RepeatedEnumFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } void RepeatedEnumFieldGenerator::GenerateConstructorCode( @@ -342,17 +344,17 @@ void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "{\n" " int byte_size = " - "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n" + "$cached_byte_size_field$.load(std::memory_order_relaxed);\n" " if (byte_size > 0) {\n" " target = stream->WriteEnumPacked(\n" - " $number$, $name$_, byte_size, target);\n" + " $number$, $field$, byte_size, target);\n" " }\n" "}\n"); } else { 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 +370,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,11 +378,11 @@ 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" - "_$name$_cached_byte_size_.store(cached_size,\n" + "int cached_size = ::_pbi::ToCachedSize(data_size);\n" + "$cached_byte_size_field$.store(cached_size,\n" " std::memory_order_relaxed);\n" "total_size += data_size;\n"); } else { @@ -396,7 +398,7 @@ void RepeatedEnumFieldGenerator::GenerateConstinitInitializer( format("$name$_()"); if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file(), options_)) { - format("\n, _$name$_cached_byte_size_(0)"); + format("\n, $cached_byte_size_name$(0)"); } } 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..90e292b411409 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 { @@ -76,6 +78,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, break; } SetCommonVars(options, &variables_); + SetCommonMessageDataVariables(&variables_); variables_["extendee"] = QualifiedClassName(descriptor_->containing_type(), options_); variables_["type_traits"] = type_traits_; @@ -91,6 +94,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 +180,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..49d62487ecc4a 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 { @@ -81,7 +81,7 @@ std::string GenerateTemplateForOneofString(const FieldDescriptor* descriptor, std::string field_name = google::protobuf::compiler::cpp::FieldName(descriptor); std::string field_pointer = descriptor->options().ctype() == google::protobuf::FieldOptions::STRING - ? "$0.GetPointer()" + ? "$0.UnsafeGetPointer()" : "$0"; if (descriptor->default_value_string().empty()) { @@ -103,7 +103,7 @@ std::string GenerateTemplateForOneofString(const FieldDescriptor* descriptor, return strings::Substitute( StrCat("_internal_has_", field_name, "() ? ", field_pointer, " : ", default_value_pointer), - field_member, MakeDefaultName(descriptor)); + field_member, MakeDefaultFieldName(descriptor)); } std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor, @@ -114,8 +114,8 @@ 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, - MakeDefaultName(descriptor)); + "$0.IsDefault() ? &$1.get() : $0.UnsafeGetPointer()", field_member, + MakeDefaultFieldName(descriptor)); } return StrCat("&", field_member); @@ -150,14 +150,12 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, google::protobuf::FileOptions::LITE_RUNTIME) { return; } - std::string field_member = (*variables)["field_member"]; + std::string field_member = (*variables)["field"]; 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, "; + const std::string substitute_template_prefix = + StrCat(" ", (*variables)["tracker"], ".$1<$0>(this, "); std::string prepared_template; // Flat template is needed if the prepared one is introspecting the values @@ -178,7 +176,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) { @@ -238,13 +236,15 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, std::map* variables, const Options& options) { SetCommonVars(options, variables); + SetCommonMessageDataVariables(variables); + (*variables)["ns"] = Namespace(descriptor, options); (*variables)["name"] = FieldName(descriptor); (*variables)["index"] = StrCat(descriptor->index()); (*variables)["number"] = StrCat(descriptor->number()); (*variables)["classname"] = ClassName(FieldScope(descriptor), false); (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - (*variables)["field_member"] = FieldName(descriptor) + "_"; + (*variables)["field"] = FieldMemberName(descriptor); (*variables)["tag_size"] = StrCat( WireFormat::TagSize(descriptor->number(), descriptor->type())); @@ -254,7 +254,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["clear_hasbit"] = ""; if (HasHasbit(descriptor)) { (*variables)["set_hasbit_io"] = - "_Internal::set_has_" + FieldName(descriptor) + "(&_has_bits_);"; + StrCat("_Internal::set_has_", FieldName(descriptor), "(&", + (*variables)["has_bits"], ");"); } else { (*variables)["set_hasbit_io"] = ""; } @@ -275,10 +276,10 @@ void FieldGenerator::SetHasBitIndex(int32_t has_bit_index) { return; } variables_["set_hasbit"] = StrCat( - "_has_bits_[", has_bit_index / 32, "] |= 0x", + variables_["has_bits"], "[", has_bit_index / 32, "] |= 0x", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); variables_["clear_hasbit"] = StrCat( - "_has_bits_[", has_bit_index / 32, "] &= ~0x", + variables_["has_bits"], "[", has_bit_index / 32, "] &= ~0x", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); } @@ -287,12 +288,17 @@ 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", + "(", variables_["inlined_string_donated_array"], "[", + inlined_string_index / 32, "] & 0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), "u) != 0;"); variables_["donating_states_word"] = - StrCat("_inlined_string_donated_[", inlined_string_index / 32, "]"); + StrCat(variables_["inlined_string_donated_array"], "[", + inlined_string_index / 32, "]"); variables_["mask_for_undonate"] = StrCat( "~0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), "u"); @@ -303,8 +309,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..24f2ccba46c3f 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, @@ -446,8 +486,8 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, // destructor that we need to elide. format( "struct $1$ {\n" - " constexpr $1$()\n" - " : _instance(::$proto_ns$::internal::ConstantInitialized{}) {}\n" + " PROTOBUF_CONSTEXPR $1$()\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,19 +509,21 @@ 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", + "($3$._instance.$4$.Init(), std::true_type{});\n", ClassName(generator->descriptor_), FieldName(field), - DefaultInstanceName(generator->descriptor_, options_)); + DefaultInstanceName(generator->descriptor_, options_), + FieldMemberName(field)); } } 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 +577,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 +591,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 +599,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 +630,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 +640,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 +648,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 +669,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 +686,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 +742,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 +751,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 +792,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 +806,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 +823,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 +879,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 +899,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 +919,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 +937,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 +1118,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 +1229,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..824edc13f6f5d 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 { @@ -82,6 +82,12 @@ bool CppGenerator::Generate(const FileDescriptor* file, // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or // __declspec(dllimport) depending on what is being compiled. // + // If the proto_h option is passed to the compiler, we will generate all + // classes and enums so that they can be forward-declared from files that + // need them from imports. + // + // If the lite option is passed to the compiler, we will generate the + // current files and all transitive dependencies using the LITE runtime. Options file_options; file_options.opensource_runtime = opensource_runtime_; @@ -109,8 +115,10 @@ 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 == "proto_h") { + file_options.proto_h = true; } else if (options[i].first == "annotate_accessor") { file_options.annotate_accessor = true; } else if (options[i].first == "inject_field_listener_events") { @@ -127,14 +135,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 +191,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 +210,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..9545ff078ee1c 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 @@ -229,6 +229,18 @@ void SetCommonVars(const Options& options, (*variables)["string"] = "std::string"; } +void SetCommonMessageDataVariables( + std::map* variables) { + (*variables)["any_metadata"] = "_any_metadata_"; + (*variables)["cached_size"] = "_cached_size_"; + (*variables)["extensions"] = "_extensions_"; + (*variables)["has_bits"] = "_has_bits_"; + (*variables)["inlined_string_donated_array"] = "_inlined_string_donated_"; + (*variables)["oneof_case"] = "_oneof_case_"; + (*variables)["tracker"] = "_tracker_"; + (*variables)["weak_field_map"] = "_weak_field_map_"; +} + void SetUnknownFieldsVariable(const Descriptor* descriptor, const Options& options, std::map* variables) { @@ -453,6 +465,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 +1167,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 +1283,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 +1316,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 +1505,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..d848831794a1a 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"; } @@ -85,6 +87,10 @@ extern const char kThinSeparator[]; void SetCommonVars(const Options& options, std::map* variables); +// Variables to access message data from the message scope. +void SetCommonMessageDataVariables( + std::map* variables); + void SetUnknownFieldsVariable(const Descriptor* descriptor, const Options& options, std::map* variables); @@ -186,6 +192,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 +357,16 @@ 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 +375,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 */, @@ -472,6 +489,43 @@ inline std::string MakeDefaultName(const FieldDescriptor* field) { "_"; } +// Semantically distinct from MakeDefaultName in that it gives the C++ code +// referencing a default field from the message scope, rather than just the +// variable name. +// For example, declarations of default variables should always use just +// MakeDefaultName to produce code like: +// Type _i_give_permission_to_break_this_code_default_field_; +// +// Code that references these should use MakeDefaultFieldName, in case the field +// exists at some nested level like: +// internal_container_._i_give_permission_to_break_this_code_default_field_; +inline std::string MakeDefaultFieldName(const FieldDescriptor* field) { + return MakeDefaultName(field); +} + +inline std::string MakeVarintCachedSizeName(const FieldDescriptor* field) { + return StrCat("_", FieldName(field), "_cached_byte_size_"); +} + +// Semantically distinct from MakeVarintCachedSizeName in that it gives the C++ +// code referencing the object from the message scope, rather than just the +// variable name. +// For example, declarations of default variables should always use just +// MakeVarintCachedSizeName to produce code like: +// Type _field_cached_byte_size_; +// +// Code that references these variables should use +// MakeVarintCachedSizeFieldName, in case the field exists at some nested level +// like: +// internal_container_._field_cached_byte_size_; +inline std::string MakeVarintCachedSizeFieldName(const FieldDescriptor* field) { + return StrCat("_", FieldName(field), "_cached_byte_size_"); +} + +// Note: A lot of libraries detect Any protos based on Descriptor::full_name() +// while the two functions below use FileDescriptor::name(). In a sane world the +// two approaches should be equivalent. But if you are dealing with descriptors +// from untrusted sources, you might need to match semantics across libraries. bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options); bool IsAnyMessage(const Descriptor* descriptor, const Options& options); @@ -955,7 +1009,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..5713fd8e8c492 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: @@ -128,7 +126,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n" "$classname$::_internal_$name$() const {\n" - " return $name$_.GetMap();\n" + " return $field$.GetMap();\n" "}\n" "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n" "$classname$::$name$() const {\n" @@ -138,7 +136,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n" "$classname$::_internal_mutable_$name$() {\n" - " return $name$_.MutableMap();\n" + " return $field$.MutableMap();\n" "}\n" "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n" "$classname$::mutable_$name$() {\n" @@ -150,17 +148,17 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions( void MapFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("$field$.MergeFrom(from.$field$);\n"); } void MapFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } void MapFieldGenerator::GenerateCopyConstructorCode( @@ -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"); @@ -301,7 +267,7 @@ void MapFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { Formatter format(printer, variables_); format( - "if (!::$proto_ns$::internal::AllAreInitialized($name$_)) return " + "if (!::$proto_ns$::internal::AllAreInitialized($field$)) return " "false;\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("$field$.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->$field$.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..8be652b8f2309 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 @@ -109,7 +108,7 @@ void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field, int has_bit_index = has_bit_indices[field->index()]; if (*cached_has_word_index != (has_bit_index / 32)) { *cached_has_word_index = (has_bit_index / 32); - format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", *cached_has_word_index); } const std::string mask = StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); @@ -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; } } @@ -470,6 +411,7 @@ class ColdChunkSkipper { access_info_map_(options.access_info_map), cold_threshold_(cold_threshold) { SetCommonVars(options, &variables_); + SetCommonMessageDataVariables(&variables_); } // May open an external if check for a batch of cold fields. "from" is the @@ -610,6 +552,8 @@ void GenerateExtensionAnnotations( google::protobuf::FileOptions::LITE_RUNTIME) { return; } + StringPiece tracker = (*variables)["tracker"]; + StringPiece extensions = (*variables)["extensions"]; for (const auto& annotation : accessor_annotations_to_hooks) { const std::string& annotation_name = annotation.first; const std::string& listener_call = annotation.second; @@ -619,29 +563,29 @@ void GenerateExtensionAnnotations( // Primitive fields accessors. // "Has" is here as users calling "has" on a repeated field is a mistake. (*variables)[annotation_name] = StrCat( - " _tracker_.", listener_call, - "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), " - "_extensions_, id.default_value_ref()));"); + " ", tracker, ".", listener_call, + "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), ", + extensions, ", id.default_value_ref()));"); } else if (StrContains(annotation_name, "repeated") && !StrContains(annotation_name, "list") && !StrContains(annotation_name, "size")) { // Repeated index accessors. std::string str_index = "index"; if (StrContains(annotation_name, "add")) { - str_index = "_extensions_.ExtensionSize(id.number()) - 1"; + str_index = StrCat(extensions, ".ExtensionSize(id.number()) - 1"); } (*variables)[annotation_name] = - StrCat(" _tracker_.", listener_call, + StrCat(" ", tracker, ".", listener_call, "(this, id.number(), " - "_proto_TypeTraits::GetPtr(id.number(), _extensions_, ", - str_index, "));"); + "_proto_TypeTraits::GetPtr(id.number(), ", + extensions, ", ", str_index, "));"); } else if (StrContains(annotation_name, "list") || StrContains(annotation_name, "size")) { // Repeated full accessors. (*variables)[annotation_name] = StrCat( - " _tracker_.", listener_call, - "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), " - "_extensions_));"); + " ", tracker, ".", listener_call, + "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), ", + extensions, "));"); } else { // Generic accessors such as "clear". // TODO(b/190614678): Generalize clear from both repeated and non repeated @@ -673,6 +617,7 @@ MessageGenerator::MessageGenerator( if (!message_layout_helper_) { message_layout_helper_.reset(new PaddingOptimizer()); } + SetCommonMessageDataVariables(&variables_); // Variables that apply to this class variables_["classname"] = classname_; @@ -688,7 +633,8 @@ MessageGenerator::MessageGenerator( if (options.field_listener_options.inject_field_listener_events && descriptor->file()->options().optimize_for() != google::protobuf::FileOptions::LITE_RUNTIME) { - const std::string injector_template = " _tracker_."; + const std::string injector_template = + StrCat(" ", variables_["tracker"], "."); MaySetAnnotationVariable(options, "serialize", injector_template, "OnSerialize(this);\n", &variables_); @@ -738,6 +684,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 +707,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_)); @@ -903,7 +850,7 @@ inline bool HasExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_extension_has$ - return _extensions_.Has(id.number()); + return $extensions$.Has(id.number()); } template & id) { - _extensions_.ClearExtension(id.number()); + $extensions$.ClearExtension(id.number()); $annotate_extension_clear$ } @@ -923,7 +870,7 @@ inline int ExtensionSize( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_extension_repeated_size$ - return _extensions_.ExtensionSize(id.number()); + return $extensions$.ExtensionSize(id.number()); } template & id) const { $annotate_extension_get$ - return _proto_TypeTraits::Get(id.number(), _extensions_, + return _proto_TypeTraits::Get(id.number(), $extensions$, id.default_value()); } @@ -945,7 +892,7 @@ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { $annotate_extension_mutable$ return _proto_TypeTraits::Mutable(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id, typename _proto_TypeTraits::Singular::ConstType value) { - _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + _proto_TypeTraits::Set(id.number(), _field_type, value, &$extensions$); $annotate_extension_set$ } @@ -967,7 +914,7 @@ inline void SetAllocatedExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, typename _proto_TypeTraits::Singular::MutableType value) { _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, - &_extensions_); + &$extensions$); $annotate_extension_set$ } template & id, typename _proto_TypeTraits::Singular::MutableType value) { _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, - value, &_extensions_); + value, &$extensions$); $annotate_extension_set$ } template & id) { $annotate_extension_release$ return _proto_TypeTraits::Release(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id) { $annotate_extension_release$ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id, int index) const { $annotate_repeated_extension_get$ - return _proto_TypeTraits::Get(id.number(), _extensions_, index); + return _proto_TypeTraits::Get(id.number(), $extensions$, index); } template & id, int index) { $annotate_repeated_extension_mutable$ - return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + return _proto_TypeTraits::Mutable(id.number(), index, &$extensions$); } template & id, int index, typename _proto_TypeTraits::Repeated::ConstType value) { - _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + _proto_TypeTraits::Set(id.number(), index, value, &$extensions$); $annotate_repeated_extension_set$ } @@ -1045,7 +992,7 @@ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { typename _proto_TypeTraits::Repeated::MutableType to_add = - _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + _proto_TypeTraits::Add(id.number(), _field_type, &$extensions$); $annotate_repeated_extension_add_mutable$ return to_add; } @@ -1058,7 +1005,7 @@ inline void AddExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, typename _proto_TypeTraits::Repeated::ConstType value) { _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, - &_extensions_); + &$extensions$); $annotate_repeated_extension_add$ } @@ -1070,7 +1017,7 @@ GetRepeatedExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_repeated_extension_list$ - return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + return _proto_TypeTraits::GetRepeated(id.number(), $extensions$); } template & id) { $annotate_repeated_extension_list_mutable$ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, - _is_packed, &_extensions_); + _is_packed, &$extensions$); } )"); @@ -1119,7 +1066,7 @@ void MessageGenerator::GenerateSingularFieldHasBits( format( "inline bool $classname$::has_$name$() const {\n" "$annotate_has$" - " return _weak_field_map_.Has($number$);\n" + " return $weak_field_map$.Has($number$);\n" "}\n"); return; } @@ -1133,14 +1080,14 @@ void MessageGenerator::GenerateSingularFieldHasBits( format( "inline bool $classname$::_internal_has_$name$() const {\n" " bool value = " - "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"); + "($has_bits$[$has_array_index$] & 0x$has_mask$u) != 0;\n"); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !IsLazy(field, options_, scc_analyzer_)) { // We maintain the invariant that for a submessage x, has_x() returning // true implies that x_ is not null. By giving this information to the // compiler, we allow it to eliminate unnecessary null checks later on. - format(" PROTOBUF_ASSUME(!value || $name$_ != nullptr);\n"); + format(" PROTOBUF_ASSUME(!value || $field$ != nullptr);\n"); } format( @@ -1155,13 +1102,13 @@ void MessageGenerator::GenerateSingularFieldHasBits( if (IsLazy(field, options_, scc_analyzer_)) { format( "inline bool $classname$::_internal_has_$name$() const {\n" - " return !$name$_.IsCleared();\n" + " return !$field$.IsCleared();\n" "}\n"); } else { format( "inline bool $classname$::_internal_has_$name$() const {\n" " return this != internal_default_instance() " - "&& $name$_ != nullptr;\n" + "&& $field$ != nullptr;\n" "}\n"); } format( @@ -1183,7 +1130,7 @@ void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) { " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n" "}\n" "inline void $classname$::clear_has_$oneof_name$() {\n" - " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" + " $oneof_case$[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" "}\n"); } } @@ -1229,7 +1176,7 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, // annotated. format( "inline void $classname$::set_has_$name$() {\n" - " _oneof_case_[$oneof_index$] = k$field_name$;\n" + " $oneof_case$[$oneof_index$] = k$field_name$;\n" "}\n"); } @@ -1264,7 +1211,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, format.Set("has_array_index", has_bit_index / 32); format.Set("has_mask", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); - format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"); + format("$has_bits$[$has_array_index$] &= ~0x$has_mask$u;\n"); } } format("$annotate_clear$"); @@ -1298,12 +1245,13 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { } else { format( "inline int $classname$::_internal_$name$_size() const {\n" - " return $name$_$1$.size();\n" + " return $1$$2$.size();\n" "}\n" "inline int $classname$::$name$_size() const {\n" "$annotate_size$" " return _internal_$name$_size();\n" "}\n", + FieldMemberName(field), IsImplicitWeakField(field, options_, scc_analyzer_) && field->message_type() ? ".weak" @@ -1360,7 +1308,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> " "SuperType;\n" " $classname$();\n" - " explicit constexpr $classname$(\n" + " explicit PROTOBUF_CONSTEXPR $classname$(\n" " ::$proto_ns$::internal::ConstantInitialized);\n" " explicit $classname$(::$proto_ns$::Arena* arena);\n" " void MergeFrom(const $classname$& other);\n" @@ -1432,7 +1380,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "" " ::$proto_ns$::Metadata GetMetadata() const final;\n"); } - format("};\n"); + format( + " friend struct ::$tablename$;\n" + "};\n"); return; } @@ -1444,11 +1394,10 @@ 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" - " CreateMessageOwnedArena(), true) {}\n"); + "::$proto_ns$::Arena::InternalCreateMessageOwnedArena(), true) {}\n"); } else { format("inline $classname$() : $classname$(nullptr) {}\n"); } @@ -1456,7 +1405,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format("~$classname$() override;\n"); } format( - "explicit constexpr " + "explicit PROTOBUF_CONSTEXPR " "$classname$(::$proto_ns$::internal::ConstantInitialized);\n" "\n" "$classname$(const $classname$& from);\n" @@ -1484,14 +1433,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" @@ -1569,16 +1510,16 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { if (HasDescriptorMethods(descriptor_->file(), options_)) { format( "bool PackFrom(const ::$proto_ns$::Message& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "bool PackFrom(const ::$proto_ns$::Message& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);\n" "}\n" "bool UnpackTo(::$proto_ns$::Message* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n" "static bool GetAnyFieldDescriptors(\n" " const ::$proto_ns$::Message& message,\n" @@ -1588,7 +1529,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "!std::is_convertible" "::value>::type>\n" "bool PackFrom(const T& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "template " @@ -1596,36 +1537,36 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);" "}\n" "template " "::value>::type>\n" "bool UnpackTo(T* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n"); } else { format( "template \n" "bool PackFrom(const T& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "template \n" "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);\n" "}\n" "template \n" "bool UnpackTo(T* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n"); } format( "template bool Is() const {\n" - " return _any_metadata_.Is();\n" + " return $any_metadata$.Is();\n" "}\n" "static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url,\n" @@ -1732,7 +1673,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { if (!HasSimpleBaseClass(descriptor_, options_)) { format( - "int GetCachedSize() const final { return _cached_size_.Get(); }" + "int GetCachedSize() const final { return " + "$cached_size$.Get(); }" "\n\nprivate:\n" "void SharedCtor();\n" "void SharedDtor();\n" @@ -1756,13 +1698,32 @@ 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_array$[0] & " + "0x1u) " + "== " + "0) {\n" + " return;\n" + " }\n" + " $inlined_string_donated_array$[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 +1827,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 +1878,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: @@ -2001,73 +1964,12 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) { "inline $classname$::$camel_oneof_name$Case $classname$::" "${1$$oneof_name$_case$}$() const {\n" " return $classname$::$camel_oneof_name$Case(" - "_oneof_case_[$oneof_index$]);\n" + "$oneof_case$[$oneof_index$]);\n" "}\n", oneof); } } -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 +1989,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 +2004,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 +2012,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 +2029,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 +2037,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"); } @@ -2359,7 +2048,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format.Indent(); if (!has_bit_indices_.empty()) { format( - "using HasBits = decltype(std::declval<$classname$>()._has_bits_);\n"); + "using HasBits = " + "decltype(std::declval<$classname$>().$has_bits$);\n"); } for (auto field : FieldRange(descriptor_)) { field_generators_.get(field).GenerateInternalAccessorDeclarations(printer); @@ -2455,20 +2145,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 +2158,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", @@ -2495,234 +2177,40 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { google::protobuf::FileOptions::LITE_RUNTIME) { format( "::$proto_ns$::AccessListener<$classtype$> " - "$1$::_tracker_(&FullMessageName);\n", + "$1$::$tracker$(&FullMessageName);\n", ClassName(descriptor_)); } } -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_); if (!has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $has_bits$),\n"); } else { format("~0u, // no _has_bits_\n"); } format("PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n"); if (descriptor_->extension_range_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $extensions$),\n"); } else { format("~0u, // no _extensions_\n"); } if (descriptor_->real_oneof_decl_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$[0]),\n"); } else { format("~0u, // no _oneof_case_\n"); } if (num_weak_fields_ > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _weak_field_map_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $weak_field_map$),\n"); } else { format("~0u, // no _weak_field_map_\n"); } if (!inlined_string_indices_.empty()) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _inlined_string_donated_),\n"); + format( + "PROTOBUF_FIELD_OFFSET($classtype$, " + "$inlined_string_donated_array$),\n"); } else { format("~0u, // no _inlined_string_donated_\n"); } @@ -2740,9 +2228,9 @@ 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)); + format("PROTOBUF_FIELD_OFFSET($classtype$, $1$)", FieldMemberName(field)); } // Some information about a field is in the pdproto profile. The profile is @@ -2750,11 +2238,6 @@ std::pair MessageGenerator::GenerateOffsets( // offset of the field, so that the information is available when // reflectively accessing the field at run time. // - // Embed whether the field is used to the MSB of the offset. - if (!IsFieldUsed(field, options_)) { - format(" | 0x80000000u // unused\n"); - } - // Embed whether the field is eagerly verified lazy or inlined string to the // LSB of the offset. if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) { @@ -2787,11 +2270,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); } } @@ -2837,7 +2321,7 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { } if (num_weak_fields_) { - format("_weak_field_map_.ClearAll();\n"); + format("$weak_field_map$.ClearAll();\n"); } format.Outdent(); format( @@ -2845,8 +2329,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,56 +2354,33 @@ 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) { Formatter format(printer, variables_); format( - "constexpr $classname$::$classname$(\n" - " ::$proto_ns$::internal::ConstantInitialized)"); + "PROTOBUF_CONSTEXPR $classname$::$classname$(\n" + " ::_pbi::ConstantInitialized)"); format.Indent(); const char* field_sep = ":"; const auto put_sep = [&] { @@ -2953,16 +2426,16 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, std::string pod_template; if (copy_constructor) { pod_template = - "::memcpy(&$first$_, &from.$first$_,\n" - " static_cast(reinterpret_cast(&$last$_) -\n" - " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; + "::memcpy(&$first$, &from.$first$,\n" + " static_cast(reinterpret_cast(&$last$) -\n" + " reinterpret_cast(&$first$)) + sizeof($last$));\n"; } else { pod_template = "::memset(reinterpret_cast(this) + static_cast(\n" - " reinterpret_cast(&$first$_) - " + " reinterpret_cast(&$first$) - " "reinterpret_cast(this)),\n" - " 0, static_cast(reinterpret_cast(&$last$_) -\n" - " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; + " 0, static_cast(reinterpret_cast(&$last$) -\n" + " reinterpret_cast(&$first$)) + sizeof($last$));\n"; } for (int i = 0; i < optimized_order_.size(); ++i) { @@ -2978,9 +2451,9 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, if (it != runs.end() && it->second > 1) { // Use a memset, then skip run_length fields. const size_t run_length = it->second; - const std::string first_field_name = FieldName(field); + const std::string first_field_name = FieldMemberName(field); const std::string last_field_name = - FieldName(optimized_order_[i + run_length - 1]); + FieldMemberName(optimized_order_[i + run_length - 1]); format.Set("first", first_field_name); format.Set("last", last_field_name); @@ -3049,19 +2522,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_array$[0] = ~0u;\n" + " } else {\n" + // We should not register ArenaDtor for MOA. + " $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n" + " }\n"); + } else { + format(" $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n"); } - format(" }\n"); + for (size_t i = 1; i < InlinedStringDonatedSize(); ++i) { + format(" $inlined_string_donated_array$[$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" @@ -3126,8 +2617,8 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "_extensions_.MergeFrom(internal_default_instance(), " - "from._extensions_);\n"); + "$extensions$.MergeFrom(internal_default_instance(), " + "from.$extensions$);\n"); } GenerateConstructorBody(printer, processed, true); @@ -3172,10 +2663,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,13 +2690,15 @@ 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. format( "void $classname$::SetCachedSize(int size) const {\n" - " _cached_size_.Set(size);\n" + " $cached_size$.Set(size);\n" "}\n"); } } @@ -3205,8 +2707,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"); } @@ -3232,7 +2734,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { "(void) cached_has_bits;\n\n"); if (descriptor_->extension_range_count() > 0) { - format("_extensions_.Clear();\n"); + format("$extensions$.Clear();\n"); } // Collect fields into chunks. Each chunk may have an if() condition that @@ -3305,7 +2807,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index); } format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); @@ -3318,10 +2820,10 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { .GenerateMessageClearingCode(printer); } else { format( - "::memset(&$1$_, 0, static_cast(\n" - " reinterpret_cast(&$2$_) -\n" - " reinterpret_cast(&$1$_)) + sizeof($2$_));\n", - FieldName(memset_start), FieldName(memset_end)); + "::memset(&$1$, 0, static_cast(\n" + " reinterpret_cast(&$2$) -\n" + " reinterpret_cast(&$1$)) + sizeof($2$));\n", + FieldMemberName(memset_start), FieldMemberName(memset_end)); } } @@ -3367,14 +2869,14 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { } if (num_weak_fields_) { - format("_weak_field_map_.ClearAll();\n"); + format("$weak_field_map$.ClearAll();\n"); } // We don't clear donated status. if (!has_bit_indices_.empty()) { // Step 5: Everything else. - format("_has_bits_.Clear();\n"); + format("$has_bits$.Clear();\n"); } std::map vars; @@ -3420,7 +2922,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { format.Outdent(); format( "}\n" - "_oneof_case_[$1$] = $2$_NOT_SET;\n", + "$oneof_case$[$1$] = $2$_NOT_SET;\n", i, ToUpper(oneof->name())); format.Outdent(); format( @@ -3440,7 +2942,9 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (HasGeneratedMethods(descriptor_->file(), options_)) { if (descriptor_->extension_range_count() > 0) { - format("_extensions_.InternalSwap(&other->_extensions_);\n"); + format( + "$extensions$.InternalSwap(&other->$extensions$);" + "\n"); } std::map vars; @@ -3455,7 +2959,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (!has_bit_indices_.empty()) { for (int i = 0; i < HasBitsSize(); ++i) { - format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i); + format("swap($has_bits$[$1$], other->$has_bits$[$1$]);\n", i); } } @@ -3475,20 +2979,20 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (it != runs.end() && it->second > 1) { // Use a memswap, then skip run_length fields. const size_t run_length = it->second; - const std::string first_field_name = FieldName(field); + const std::string first_field_name = FieldMemberName(field); const std::string last_field_name = - FieldName(optimized_order_[i + run_length - 1]); + FieldMemberName(optimized_order_[i + run_length - 1]); format.Set("first", first_field_name); format.Set("last", last_field_name); format( "::PROTOBUF_NAMESPACE_ID::internal::memswap<\n" - " PROTOBUF_FIELD_OFFSET($classname$, $last$_)\n" - " + sizeof($classname$::$last$_)\n" - " - PROTOBUF_FIELD_OFFSET($classname$, $first$_)>(\n" - " reinterpret_cast(&$first$_),\n" - " reinterpret_cast(&other->$first$_));\n"); + " PROTOBUF_FIELD_OFFSET($classname$, $last$)\n" + " + sizeof($classname$::$last$)\n" + " - PROTOBUF_FIELD_OFFSET($classname$, $first$)>(\n" + " reinterpret_cast(&$first$),\n" + " reinterpret_cast(&other->$first$));\n"); i += run_length - 1; // ++i at the top of the loop. @@ -3502,11 +3006,25 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { } for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { - format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i); + format( + "swap($oneof_case$[$1$], " + "other->$oneof_case$[$1$]);\n", + i); } if (num_weak_fields_) { - format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n"); + 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_array$[$1$], " + "other->$inlined_string_donated_array$[$1$]);\n", + i); + } } } else { format("GetReflection()->Swap(this, other);"); @@ -3549,7 +3067,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"); } @@ -3619,7 +3137,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = from._has_bits_[$1$];\n", + format("cached_has_bits = from.$has_bits$[$1$];\n", cached_has_word_index); } @@ -3680,7 +3198,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { if (deferred_has_bit_changes) { // Flush the has bits for the primitives we deferred. GOOGLE_CHECK_LE(0, cached_has_word_index); - format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index); + format("$has_bits$[$1$] |= cached_has_bits;\n", cached_has_word_index); } format.Outdent(); @@ -3716,15 +3234,17 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { format("}\n"); } if (num_weak_fields_) { - format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n"); + format( + "$weak_field_map$.MergeFrom(from.$weak_field_map$);" + "\n"); } // Merging of extensions and unknown fields is done last, to maximize // the opportunity for tail calls. if (descriptor_->extension_range_count() > 0) { format( - "_extensions_.MergeFrom(internal_default_instance(), " - "from._extensions_);\n"); + "$extensions$.MergeFrom(internal_default_instance(), " + "from.$extensions$);\n"); } format( @@ -3860,7 +3380,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange( Formatter format(printer, vars); format("// Extension range [$start$, $end$)\n"); format( - "target = _extensions_._InternalSerialize(\n" + "target = $extensions$._InternalSerialize(\n" "internal_default_instance(), $start$, $end$, target, stream);\n\n"); } @@ -3875,14 +3395,14 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray( " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) " "const {\n" "$annotate_serialize$" - " target = _extensions_." + " target = $extensions$." "InternalSerializeMessageSetWithCachedSizesToArray(\n" // "internal_default_instance(), target, stream);\n"); std::map vars; SetUnknownFieldsVariable(descriptor_, options_, &vars); format.AddMap(vars); format( - " target = ::$proto_ns$::internal::" + " target = ::_pbi::" "InternalSerializeUnknownMessageSetItemsToArray(\n" " $unknown_fields$, target, stream);\n"); format( @@ -4077,8 +3597,8 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( ExtensionRangeSorter()); if (num_weak_fields_) { format( - "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" - "_weak_field_map_);\n"); + "::_pbi::WeakFieldMap::FieldWriter field_writer(" + "$weak_field_map$);\n"); } format( @@ -4126,7 +3646,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,8 +3687,8 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( if (num_weak_fields_) { format( - "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" - "_weak_field_map_);\n"); + "::_pbi::WeakFieldMap::FieldWriter field_writer(" + "$weak_field_map$);\n"); } format("for (int i = $1$; i >= 0; i-- ) {\n", num_fields - 1); @@ -4218,7 +3738,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 { @@ -4259,13 +3779,13 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { "size_t $classname$::ByteSizeLong() const {\n" "$annotate_bytesize$" "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" - " size_t total_size = _extensions_.MessageSetByteSize();\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"); @@ -4312,7 +3832,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "total_size += _extensions_.ByteSize();\n" + "total_size += $extensions$.ByteSize();\n" "\n"); } @@ -4393,7 +3913,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index); } format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); @@ -4473,7 +3993,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (num_weak_fields_) { // TagSize + MessageSize - format("total_size += _weak_field_map_.ByteSizeLong();\n"); + format("total_size += $weak_field_map$.ByteSizeLong();\n"); } if (UseUnknownFieldSet(descriptor_->file(), options_)) { @@ -4481,7 +4001,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { // unknown fields in tail position. This allows for better code generation // of this function for simple protos. format( - "return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);\n"); + "return MaybeComputeUnknownFieldsSize(total_size, &$cached_size$);\n"); } else { format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); format(" total_size += $unknown_fields$.size();\n"); @@ -4496,7 +4016,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"); } @@ -4513,14 +4033,14 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "if (!_extensions_.IsInitialized()) {\n" + "if (!$extensions$.IsInitialized()) {\n" " return false;\n" "}\n\n"); } if (num_required_fields_ > 0) { format( - "if (_Internal::MissingRequiredFields(_has_bits_))" + "if (_Internal::MissingRequiredFields($has_bits$))" " return false;\n"); } @@ -4530,7 +4050,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { } if (num_weak_fields_) { // For Weak fields. - format("if (!_weak_field_map_.IsInitialized()) return false;\n"); + format("if (!$weak_field_map$.IsInitialized()) return false;\n"); } // Go through the oneof fields, emitting a switch if any might have required // fields. diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 64af2bf89b52a..5051a97d1bd35 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; @@ -200,7 +200,8 @@ class MessageGenerator { int max_has_bit_index_; // A map from field index to inlined_string index. For non-inlined-string - // fields, the element is -1. + // fields, the element is -1. If there is no inlined string in the message, + // this is empty. std::vector inlined_string_indices_; // The count of inlined_string fields in the message. int max_inlined_string_index_; @@ -209,8 +210,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..809a9e04423a4 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"], implicit_weak); + (*variables)["casted_member_const"] = + ReinterpretCast("const " + (*variables)["type"] + "&", + "*" + (*variables)["field"], 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$_);\n" + " delete reinterpret_cast<::$proto_ns$::MessageLite*>($field$);\n" " }\n"); if (implicit_weak_field_) { format( - " $name$_ = " - "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); + " $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); } else { - format(" $name$_ = $name$;\n"); + format(" $field$ = $name$;\n"); } format( " if ($name$) {\n" @@ -201,7 +206,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_release$" " $clear_hasbit$\n" " $type$* temp = $casted_member$;\n" - " $name$_ = nullptr;\n" + " $field$ = nullptr;\n" "#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n" " auto* old = reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n" " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" @@ -219,7 +224,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "$type_reference_function$" " $clear_hasbit$\n" " $type$* temp = $casted_member$;\n" - " $name$_ = nullptr;\n" + " $field$ = nullptr;\n" " return temp;\n" "}\n"); @@ -227,12 +232,12 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline $type$* $classname$::_internal_mutable_$name$() {\n" "$type_reference_function$" " $set_hasbit$\n" - " if ($name$_ == nullptr) {\n" + " if ($field$ == nullptr) {\n" " auto* p = CreateMaybeMessage<$type$>(GetArenaForAllocation());\n"); if (implicit_weak_field_) { - format(" $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n"); + format(" $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n"); } else { - format(" $name$_ = p;\n"); + format(" $field$ = p;\n"); } format( " }\n" @@ -253,9 +258,9 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( format(" if (message_arena == nullptr) {\n"); if (IsCrossFileMessage(descriptor_)) { format( - " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n"); + " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($field$);\n"); } else { - format(" delete $name$_;\n"); + format(" delete $field$;\n"); } format( " }\n" @@ -265,14 +270,13 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<\n" - " ::$proto_ns$::MessageLite>::GetOwningArena(\n" + " ::$proto_ns$::Arena::InternalGetOwningArena(\n" " reinterpret_cast<::$proto_ns$::MessageLite*>(" "$name$));\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<$type$>::GetOwningArena(" + " ::$proto_ns$::Arena::InternalGetOwningArena(" "$name$);\n"); } format( @@ -285,9 +289,9 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( " $clear_hasbit$\n" " }\n"); if (implicit_weak_field_) { - format(" $name$_ = reinterpret_cast($name$);\n"); + format(" $field$ = reinterpret_cast($name$);\n"); } else { - format(" $name$_ = $name$;\n"); + format(" $field$ = $name$;\n"); } format( "$annotate_set$" @@ -322,14 +326,10 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( format( "const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n" " const $classname$* msg) {\n" - " if (msg->$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$ != nullptr) {\n" + " return *msg->$field$;\n" " } else {\n" - " return " - "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n" + " return *$type_default_instance_ptr$;\n" " }\n" "}\n"); format( @@ -338,20 +338,19 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( if (HasHasbit(descriptor_)) { format(" msg->$set_hasbit$\n"); } + if (descriptor_->real_containing_oneof() == nullptr) { + format(" if (msg->$field$ == 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$ = $type_default_instance_ptr$->New(\n" + " msg->GetArenaForAllocation());\n" " }\n" - " return msg->$name$_;\n" + " return msg->$field$;\n" "}\n"); } else { // This inline accessor directly returns member field and is used in @@ -360,7 +359,7 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( format( "const $type$&\n" "$classname$::_Internal::$name$(const $classname$* msg) {\n" - " return *msg->$field_member$;\n" + " return *msg->$field$;\n" "}\n"); } } @@ -371,14 +370,14 @@ 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" + "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n" + " delete $field$;\n" "}\n" - "$name$_ = nullptr;\n"); + "$field$ = nullptr;\n"); } else { - format("if ($name$_ != nullptr) $name$_->Clear();\n"); + format("if ($field$ != nullptr) $field$->Clear();\n"); } } @@ -389,16 +388,16 @@ 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" + "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n" + " delete $field$;\n" "}\n" - "$name$_ = nullptr;\n"); + "$field$ = nullptr;\n"); } else { format( - "$DCHK$($name$_ != nullptr);\n" - "$name$_->Clear();\n"); + "$DCHK$($field$ != nullptr);\n" + "$field$->Clear();\n"); } } @@ -421,7 +420,7 @@ void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("swap($name$_, other->$name$_);\n"); + format("swap($field$, other->$field$);\n"); } void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { @@ -436,7 +435,7 @@ void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { // care when handling them. format("if (this != internal_default_instance()) "); } - format("delete $name$_;\n"); + format("delete $field$;\n"); } void MessageFieldGenerator::GenerateConstructorCode( @@ -444,7 +443,7 @@ void MessageFieldGenerator::GenerateConstructorCode( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("$name$_ = nullptr;\n"); + format("$field$ = nullptr;\n"); } void MessageFieldGenerator::GenerateCopyConstructorCode( @@ -454,9 +453,9 @@ void MessageFieldGenerator::GenerateCopyConstructorCode( Formatter format(printer, variables_); format( "if (from._internal_has_$name$()) {\n" - " $name$_ = new $type$(*from.$name$_);\n" + " $field$ = new $type$(*from.$field$);\n" "} else {\n" - " $name$_ = nullptr;\n" + " $field$ = nullptr;\n" "}\n"); } @@ -465,11 +464,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 { @@ -479,7 +485,7 @@ void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const { format( "total_size += $tag_size$ +\n" " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" - " *$field_member$);\n"); + " *$field$);\n"); } void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { @@ -490,7 +496,7 @@ void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { Formatter format(printer, variables_); format( "if (_internal_has_$name$()) {\n" - " if (!$name$_->IsInitialized()) return false;\n" + " if (!$field$->IsInitialized()) return false;\n" "}\n"); } @@ -524,15 +530,13 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<\n" - " ::$proto_ns$::MessageLite>::GetOwningArena(\n" + " ::$proto_ns$::Arena::InternalGetOwningArena(\n" " reinterpret_cast<::$proto_ns$::MessageLite*>(" "$name$));\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<" - "$type$>::GetOwningArena($name$);\n"); + " ::$proto_ns$::Arena::InternalGetOwningArena($name$);\n"); } format( " if (message_arena != submessage_arena) {\n" @@ -540,7 +544,7 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( " message_arena, $name$, submessage_arena);\n" " }\n" " set_has_$name$();\n" - " $field_member$ = $name$;\n" + " $field$ = $name$;\n" " }\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" @@ -554,13 +558,14 @@ 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" - " $field_member$ = nullptr;\n" + " $field$ = nullptr;\n" " return temp;\n" " } else {\n" " return nullptr;\n" @@ -569,8 +574,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,10 +588,11 @@ 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" - " $field_member$ = nullptr;\n" + " $type$* temp = $casted_member$;\n" + " $field$ = nullptr;\n" " return temp;\n" " } else {\n" " return nullptr;\n" @@ -598,21 +605,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$ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); + } else { + format(" $field$ = $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$ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>(CreateMaybeMessage< " + "$type$ >(GetArenaForAllocation()));\n"); + } else { + format( + " $field$ = 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" @@ -629,7 +653,7 @@ void MessageOneofFieldGenerator::GenerateClearingCode( Formatter format(printer, variables_); format( "if (GetArenaForAllocation() == nullptr) {\n" - " delete $field_member$;\n" + " delete $field$;\n" "}\n"); } @@ -662,7 +686,7 @@ void MessageOneofFieldGenerator::GenerateIsInitialized( Formatter format(printer, variables_); format( "if (_internal_has_$name$()) {\n" - " if (!$field_member$->IsInitialized()) return false;\n" + " if (!$field$->IsInitialized()) return false;\n" "}\n"); } @@ -741,21 +765,21 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( // TODO(dlj): move insertion points " // @@protoc_insertion_point(field_mutable:$full_name$)\n" "$type_reference_function$" - " return $name$_$weak$.Mutable(index);\n" + " return $field$$weak$.Mutable(index);\n" "}\n" "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n" "$classname$::mutable_$name$() {\n" "$annotate_mutable_list$" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" "$type_reference_function$" - " return &$name$_$weak$;\n" + " return &$field$$weak$;\n" "}\n"); if (options_.safe_boundary_check) { format( "inline const $type$& $classname$::_internal_$name$(int index) const " "{\n" - " return $name$_$weak$.InternalCheckedGet(index,\n" + " return $field$$weak$.InternalCheckedGet(index,\n" " reinterpret_cast($type_default_instance$));\n" "}\n"); } else { @@ -763,7 +787,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$(int index) const " "{\n" "$type_reference_function$" - " return $name$_$weak$.Get(index);\n" + " return $field$$weak$.Get(index);\n" "}\n"); } @@ -774,7 +798,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( " return _internal_$name$(index);\n" "}\n" "inline $type$* $classname$::_internal_add_$name$() {\n" - " return $name$_$weak$.Add();\n" + " return $field$$weak$.Add();\n" "}\n" "inline $type$* $classname$::add_$name$() {\n" " $type$* _add = _internal_add_$name$();\n" @@ -789,7 +813,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_list$" " // @@protoc_insertion_point(field_list:$full_name$)\n" "$type_reference_function$" - " return $name$_$weak$;\n" + " return $field$$weak$;\n" "}\n"); } @@ -798,7 +822,7 @@ void RepeatedMessageFieldGenerator::GenerateClearingCode( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedMessageFieldGenerator::GenerateMergingCode( @@ -806,7 +830,7 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("$field$.MergeFrom(from.$field$);\n"); } void RepeatedMessageFieldGenerator::GenerateSwappingCode( @@ -814,7 +838,7 @@ void RepeatedMessageFieldGenerator::GenerateSwappingCode( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } void RepeatedMessageFieldGenerator::GenerateConstructorCode( @@ -829,23 +853,41 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( Formatter format(printer, variables_); 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"); + "for (auto it = this->$field$.pointer_begin(),\n" + " end = this->$field$.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"); + } } } @@ -856,7 +898,7 @@ void RepeatedMessageFieldGenerator::GenerateByteSize( Formatter format(printer, variables_); format( "total_size += $tag_size$UL * this->_internal_$name$_size();\n" - "for (const auto& msg : this->$name$_) {\n" + "for (const auto& msg : this->$field$) {\n" " total_size +=\n" " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n" "}\n"); @@ -871,11 +913,11 @@ void RepeatedMessageFieldGenerator::GenerateIsInitialized( Formatter format(printer, variables_); if (implicit_weak_field_) { format( - "if (!::$proto_ns$::internal::AllAreInitializedWeak($name$_.weak))\n" + "if (!::$proto_ns$::internal::AllAreInitializedWeak($field$.weak))\n" " return false;\n"); } else { format( - "if (!::$proto_ns$::internal::AllAreInitialized($name$_))\n" + "if (!::$proto_ns$::internal::AllAreInitialized($field$))\n" " return false;\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..c407c0540b3bd 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -57,34 +57,39 @@ 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; + bool force_split = 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..f7dd62946ae82 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; @@ -73,167 +73,351 @@ int TagSize(uint32_t field_number) { return 2; } -const char* CodedTagType(int tag_size) { - return tag_size == 1 ? "uint8_t" : "uint16_t"; -} +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; + } -const char* TagType(const FieldDescriptor* field) { - return CodedTagType(TagSize(field->number())); -} + // We will check for a valid auxiliary index range later. However, we might + // want to change the value we check for inlined string fields. + int aux_idx = entry.aux_idx; -std::string TcParserName(const Options& options) { - return StrCat("::", ProtobufNamespace(options), - "::internal::TcParser::"); -} + switch (field->type()) { + 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_STRING: + case FieldDescriptor::TYPE_BYTES: + if (field->options().ctype() != FieldOptions::STRING) { + return false; + } + if (IsStringInlined(field, options)) { + GOOGLE_CHECK(!field->is_repeated()); + // For inlined strings, the donation state index is stored in the + // `aux_idx` field of the fast parsing info. We need to check the range + // of that value instead of the auxiliary index. + aux_idx = entry.inlined_string_idx; + } + 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), ">"); + default: + break; } - // 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()), ")"); + + 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 (aux_idx > std::numeric_limits::max()) { + return false; + } + + // 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; + // 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; + } + + // 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; + if (IsStringInlined(field, options)) { + GOOGLE_CHECK(!field->is_repeated()); + info.aux_idx = static_cast(entry.inlined_string_idx); } 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; + info.aux_idx = static_cast(entry.aux_idx); } + } + return result; +} - // Determine the name of the fastpath parse function to use for this field. - std::string name; +// 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; + for (const auto* field : fields) { + bool handled = false; switch (field->type()) { - case FieldDescriptor::TYPE_MESSAGE: - name = MessageTcParseFunctionName(field, options); - break; - - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_SFIXED64: - case FieldDescriptor::TYPE_SFIXED32: 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_BYTES: - if (field->options().ctype() == FieldOptions::STRING && - field->default_value_string().empty() && - !IsStringInlined(field, options)) { - name = FieldParseFunctionName(field, options); + 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; + + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_STRING: + if (IsStringInlined(field, options)) { + // TODO(b/198211897): support InilnedStringField. + handled = false; + } else { + handled = true; + } + break; + + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_GROUP: + // 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, + const std::vector& inlined_string_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_)}")); + } + + // If this message has any inlined string fields, store the donation state + // offset in the second auxiliary entry. + if (!inlined_string_indices.empty()) { + aux_entries.resize(2); // pad if necessary + aux_entries[1] = + StrCat("_fl::Offset{offsetof(", ClassName(descriptor), + ", _inlined_string_donated_)}"); + } + + // 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, contiguous 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")); + } + } else if ((field->type() == FieldDescriptor::TYPE_STRING || + field->type() == FieldDescriptor::TYPE_BYTES) && + IsStringInlined(field, options)) { + GOOGLE_CHECK(!field->is_repeated()); + // Inlined strings have an extra marker to represent their donation state. + int idx = inlined_string_indices[field->index()]; + // For mini parsing, the donation state index is stored as an `offset` + // auxiliary entry. + entry.aux_idx = aux_entries.size(); + aux_entries.push_back(StrCat("_fl::Offset{", idx, "}")); + // For fast table parsing, the donation state index is stored instead of + // the aux_idx (this will limit the range to 8 bits). + entry.inlined_string_idx = idx; + } + } + + // 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; } - // 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; } + // 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,12 +436,15 @@ 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, + inlined_string_indices, scc_analyzer)); } SetCommonVars(options_, &variables_); + SetCommonMessageDataVariables(&variables_); SetUnknownFieldsVariable(descriptor_, options_, &variables_); variables_["classname"] = ClassName(descriptor, false); } @@ -265,45 +452,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,9 +478,15 @@ 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$" - " return _extensions_.ParseMessageSet(ptr, \n" + " ::_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 +505,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 +527,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 +549,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,62 +567,30 @@ 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); +struct SkipEntry16 { + uint16_t skipmap; + uint16_t field_entry_offset; +}; +struct SkipEntryBlock { + uint32_t first_fnum; + std::vector entries; +}; +struct NumToEntryTable { + uint32_t skipmap32; // for fields #1 - #32 + std::vector blocks; + // Compute the number of uint16_t required to represent this table. + int size16() const { + int size = 2; // for the termination field# + for (const auto& block : blocks) { + // 2 for the field#, 1 for a count of skip entries, 2 for each entry. + size += 3 + block.entries.size() * 2; + } + return size; } -} +}; + +static NumToEntryTable MakeNumToEntryTable( + const std::vector& field_descriptors); void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { if (!should_generate_tctable()) { @@ -468,10 +602,13 @@ void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); format.Indent(); } + auto field_num_to_entry_table = MakeNumToEntryTable(ordered_fields_); 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$, $5$> _table_;\n", + tc_table_info_->table_size_log2, ordered_fields_.size(), + tc_table_info_->aux_entries.size(), CalculateFieldNamesSize(), + field_num_to_entry_table.size16()); if (should_generate_guarded_tctable()) { format.Outdent(); format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); @@ -496,7 +633,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 +655,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"); @@ -537,6 +676,68 @@ void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) { "}\n"); } +static NumToEntryTable MakeNumToEntryTable( + const std::vector& field_descriptors) { + NumToEntryTable num_to_entry_table; + num_to_entry_table.skipmap32 = static_cast(-1); + + // skip_entry_block is the current block of SkipEntries that we're + // appending to. cur_block_first_fnum is the number of the first + // field represented by the block. + uint16_t field_entry_index = 0; + uint16_t N = field_descriptors.size(); + // First, handle field numbers 1-32, which affect only the initial + // skipmap32 and don't generate additional skip-entry blocks. + for (; field_entry_index != N; ++field_entry_index) { + auto* field_descriptor = field_descriptors[field_entry_index]; + if (field_descriptor->number() > 32) break; + auto skipmap32_index = field_descriptor->number() - 1; + num_to_entry_table.skipmap32 -= 1 << skipmap32_index; + } + // If all the field numbers were less than or equal to 32, we will have + // no further entries to process, and we are already done. + if (field_entry_index == N) return num_to_entry_table; + + SkipEntryBlock* block = nullptr; + bool start_new_block = true; + // To determine sparseness, track the field number corresponding to + // the start of the most recent skip entry. + uint32_t last_skip_entry_start = 0; + for (; field_entry_index != N; ++field_entry_index) { + auto* field_descriptor = field_descriptors[field_entry_index]; + uint32_t fnum = field_descriptor->number(); + GOOGLE_CHECK_GT(fnum, last_skip_entry_start); + if (start_new_block == false) { + // If the next field number is within 15 of the last_skip_entry_start, we + // continue writing just to that entry. If it's between 16 and 31 more, + // then we just extend the current block by one. If it's more than 31 + // more, we have to add empty skip entries in order to continue using the + // existing block. Obviously it's just 32 more, it doesn't make sense to + // start a whole new block, since new blocks mean having to write out + // their starting field number, which is 32 bits, as well as the size of + // the additional block, which is 16... while an empty SkipEntry16 only + // costs 32 bits. So if it was 48 more, it's a slight space win; we save + // 16 bits, but probably at the cost of slower run time. We're choosing + // 96 for now. + if (fnum - last_skip_entry_start > 96) start_new_block = true; + } + if (start_new_block) { + num_to_entry_table.blocks.push_back(SkipEntryBlock{fnum}); + block = &num_to_entry_table.blocks.back(); + start_new_block = false; + } + + auto skip_entry_num = (fnum - block->first_fnum) / 16; + auto skip_entry_index = (fnum - block->first_fnum) % 16; + while (skip_entry_num >= block->entries.size()) + block->entries.push_back({0xFFFF, field_entry_index}); + block->entries[skip_entry_num].skipmap -= 1 << (skip_entry_index); + + last_skip_entry_start = fnum - skip_entry_index; + } + return num_to_entry_table; +} + void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { GOOGLE_CHECK(should_generate_tctable()); // All entries without a fast-path parsing function need a fallback. @@ -544,7 +745,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"; @@ -558,10 +759,15 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { // maps, weak fields, lazy, more than 1 extension range. In the cases // the table is sufficient we can use a generic routine, that just handles // unknown fields and potentially an extension range. + auto field_num_to_entry_table = MakeNumToEntryTable(ordered_fields_); 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$, $5$> " + "$classname$::_table_ = " + "{\n", + tc_table_info_->table_size_log2, ordered_fields_.size(), + tc_table_info_->aux_entries.size(), CalculateFieldNamesSize(), + field_num_to_entry_table.size16()); { auto table_scope = format.ScopedIndent(); format("{\n"); @@ -574,86 +780,364 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { } if (descriptor_->extension_range_count() == 1) { format( - "PROTOBUF_FIELD_OFFSET($classname$, _extensions_),\n" + "PROTOBUF_FIELD_OFFSET($classname$, $extensions$),\n" "$1$, $2$, // extension_range_{low,high}\n", descriptor_->extension_range(0)->start, descriptor_->extension_range(0)->end); } 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)); + format( + "offsetof(decltype(_table_), field_lookup_table),\n" + "$1$, // skipmap\n", + field_num_to_entry_table.skipmap32); + if (ordered_fields_.empty()) { + format( + "offsetof(decltype(_table_), field_names), // no field_entries\n"); + } else { + format("offsetof(decltype(_table_), field_entries),\n"); + } + + 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"); + { + // field_lookup_table[] + auto field_lookup_scope = format.ScopedIndent(); + int line_entries = 0; + for (int i = 0, N = field_num_to_entry_table.blocks.size(); i < N; ++i) { + SkipEntryBlock& entry_block = field_num_to_entry_table.blocks[i]; + format("$1$, $2$, $3$,\n", entry_block.first_fnum & 65535, + entry_block.first_fnum / 65536, entry_block.entries.size()); + for (auto se16 : entry_block.entries) { + if (line_entries == 0) { + format("$1$, $2$,", se16.skipmap, se16.field_entry_offset); + ++line_entries; + } else if (line_entries < 5) { + format(" $1$, $2$,", se16.skipmap, se16.field_entry_offset); + ++line_entries; + } else { + format(" $1$, $2$,\n", se16.skipmap, se16.field_entry_offset); + line_entries = 0; + } + } + } + if (line_entries) format("\n"); + format("65535, 65535\n"); + } + 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_entries, or aux_entries\n" + "{{\n"); + } else { + 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_name_scope = format.ScopedIndent(); + GenerateFieldNames(format); } - format("},\n"); // entries[] + 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, + FieldMemberName(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(" | ::_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 { - format("{}"); + 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)) { format("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); } - std::string default_string = - field->default_value_string().empty() - ? "::" + ProtobufNamespace(options_) + - "::internal::GetEmptyStringAlreadyInited()" - : QualifiedClassName(field->containing_type(), options_) + - "::" + MakeDefaultName(field) + ".get()"; format( "if (arena != nullptr) {\n" - " ptr = ctx->ReadArenaString(ptr, &$msg$$name$_, arena"); + " ptr = ctx->ReadArenaString(ptr, &$msg$$field$, arena"); 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); - format( - ", $msg$_internal_$name$_donated()" - ", &$msg$_inlined_string_donated_[$1$]" - ", ~0x$2$u", - inlined_string_index / 32, - strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8)); + GOOGLE_DCHECK_GT(inlined_string_index, 0); + format(", &$msg$$inlined_string_donated_array$[0], $1$, $this$", + inlined_string_index); } else { GOOGLE_DCHECK(field->default_value_string().empty()); } format( ");\n" "} else {\n" - " ptr = ::$proto_ns$::internal::InlineGreedyStringParser(" - "$msg$$name$_.MutableNoArenaNoDefault(&$1$), ptr, ctx);\n" + " ptr = ::_pbi::InlineGreedyStringParser(" + "$msg$$field$.MutableNoCopy(nullptr), ptr, ctx);\n" "}\n" - "const std::string* str = &$msg$$name$_.Get(); (void)str;\n", - default_string); + "const std::string* str = &$msg$$field$.Get(); (void)str;\n"); } void ParseFunctionGenerator::GenerateStrings(Formatter& format, @@ -685,11 +1169,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 +1194,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 +1227,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,48 +1239,64 @@ 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)) { format( "auto object = " "::$proto_ns$::internal::InitEnumParseWrapper<" - "$unknown_fields_type$>(&$msg$$name$_, $1$_IsValid, " + "$unknown_fields_type$>(&$msg$$field$, $1$_IsValid, " "$2$, &$msg$_internal_metadata_);\n" "ptr = ctx->ParseMessage(&object, ptr);\n", QualifiedClassName(val->enum_type(), options_), field->number()); } else { - format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); + format("ptr = ctx->ParseMessage(&$msg$$field$, 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" " $msg$clear_$1$();\n" - " $msg$$1$_.$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" + " $msg$$field$ = ::$proto_ns$::Arena::CreateMessage<\n" " ::$proto_ns$::internal::LazyField>(" "$msg$GetArenaForAllocation());\n" " $msg$set_has_$name$();\n" "}\n" - "auto* lazy_field = $msg$$1$_.$name$_;\n", + "auto* lazy_field = $msg$$field$;\n", field->containing_oneof()->name()); } else if (HasHasbit(field)) { format( "_Internal::set_has_$name$(&$has_bits$);\n" - "auto* lazy_field = &$msg$$name$_;\n"); + "auto* lazy_field = &$msg$$field$;\n"); } else { - format("auto* lazy_field = &$msg$$name$_;\n"); + format("auto* lazy_field = &$msg$$field$;\n"); } 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( @@ -800,7 +1304,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, "ptr);\n"); } else { format( - "ptr = ctx->ParseMessage($msg$$name$_.AddWeak(" + "ptr = ctx->ParseMessage($msg$$field$.AddWeak(" "reinterpret_cast($1$ptr_)" "), ptr);\n", QualifiedDefaultInstanceName(field->message_type(), options_)); @@ -809,7 +1313,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, format( "{\n" " auto* default_ = &reinterpret_cast($1$);\n" - " ptr = ctx->ParseMessage($msg$_weak_field_map_.MutableMessage(" + " ptr = ctx->ParseMessage($msg$$weak_field_map$.MutableMessage(" "$2$, default_), ptr);\n" "}\n", QualifiedDefaultInstanceName(field->message_type(), options_), @@ -819,6 +1323,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, "ptr = ctx->ParseMessage($msg$_internal_$mutable_field$(), " "ptr);\n"); } + format("CHK_(ptr);\n"); break; } default: @@ -898,7 +1403,7 @@ void ParseFunctionGenerator::GenerateFieldBody( format("_Internal::set_has_$name$(&$has_bits$);\n"); } format( - "$msg$$name$_ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n" + "$msg$$field$ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n" "CHK_(ptr);\n", zigzag, size); } @@ -917,7 +1422,7 @@ void ParseFunctionGenerator::GenerateFieldBody( format("_Internal::set_has_$name$(&$has_bits$);\n"); } format( - "$msg$$name$_ = " + "$msg$$field$ = " "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr);\n" "ptr += sizeof($primitive_type$);\n"); } @@ -925,7 +1430,6 @@ void ParseFunctionGenerator::GenerateFieldBody( } case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { GenerateLengthDelim(format, field); - format("CHK_(ptr);\n"); break; } case WireFormatLite::WIRETYPE_START_GROUP: { @@ -983,13 +1487,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. @@ -1028,7 +1528,7 @@ void ParseFunctionGenerator::GenerateParseIterationBody( } format( ") {\n" - " ptr = $msg$_extensions_.ParseField(tag, ptr, " + " ptr = $msg$$extensions$.ParseField(tag, ptr, " "internal_default_instance(), &$msg$_internal_metadata_, ctx);\n" " CHK_(ptr != nullptr);\n" " $next_tag$;\n" @@ -1045,12 +1545,12 @@ 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) { + format.Set("field", FieldMemberName(field)); PrintFieldComment(format, field); format("case $1$:\n", field->number()); format.Indent(); @@ -1104,199 +1604,111 @@ 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"); + if (IsStringInlined(field, options)) { + name.append("i"); + } 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: " << static_cast(GetUtf8CheckMode(field, options)); return ""; } + if (IsStringInlined(field, options)) { + name.append("i"); + } 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; - - 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; - - case TypeFormat::kVar32: - case TypeFormat::kFixed32: - name.append("uint32_t, "); - break; - - case TypeFormat::kSInt32: - name.append("int32_t, "); + case FieldDescriptor::TYPE_MESSAGE: + name.append("M"); break; - - case TypeFormat::kBool: - name.append("bool, "); + case FieldDescriptor::TYPE_GROUP: + name.append("G"); break; default: - break; + GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString(); + return ""; } - 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; + // The field implementation functions are prefixed by cardinality: + // `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"); - default: - break; - } + // Append the tag length. Fast parsing only handles 1- or 2-byte tags. + name.append(TagSize(field->number()) == 1 ? "1" : "2"); - 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..d98f085e30598 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,36 @@ 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, + const std::vector& inlined_string_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; + int inlined_string_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 +127,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 +156,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 +168,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..cef623c991837 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 { @@ -104,6 +104,9 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type()); (*variables)["default"] = DefaultValue(options, descriptor); + (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); + (*variables)["cached_byte_size_field"] = + MakeVarintCachedSizeFieldName(descriptor); (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor)); int fixed_size = FixedSize(descriptor->type()); if (fixed_size != -1) { @@ -150,7 +153,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$() const {\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline $type$ $classname$::$name$() const {\n" "$annotate_get$" @@ -159,7 +162,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline void $classname$::_internal_set_$name$($type$ value) {\n" " $set_hasbit$\n" - " $name$_ = value;\n" + " $field$ = value;\n" "}\n" "inline void $classname$::set_$name$($type$ value) {\n" " _internal_set_$name$(value);\n" @@ -170,7 +173,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( void PrimitiveFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("$field$ = $default$;\n"); } void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) const { @@ -180,19 +183,19 @@ void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) const { void PrimitiveFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("swap($name$_, other->$name$_);\n"); + format("swap($field$, other->$field$);\n"); } void PrimitiveFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("$field$ = $default$;\n"); } void PrimitiveFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = from.$name$_;\n"); + format("$field$ = from.$field$;\n"); } void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -201,7 +204,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 +217,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 { @@ -249,7 +252,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline $type$ $classname$::_internal_$name$() const {\n" " if (_internal_has_$name$()) {\n" - " return $field_member$;\n" + " return $field$;\n" " }\n" " return $default$;\n" "}\n" @@ -258,7 +261,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions( " clear_$oneof_name$();\n" " set_has_$name$();\n" " }\n" - " $field_member$ = value;\n" + " $field$ = value;\n" "}\n" "inline $type$ $classname$::$name$() const {\n" "$annotate_get$" @@ -275,7 +278,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions( void PrimitiveOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$field_member$ = $default$;\n"); + format("$field$ = $default$;\n"); } void PrimitiveOneofFieldGenerator::GenerateSwappingCode( @@ -286,7 +289,7 @@ void PrimitiveOneofFieldGenerator::GenerateSwappingCode( void PrimitiveOneofFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n"); + format("$ns$::_$classname$_default_instance_.$field$ = $default$;\n"); } // =================================================================== @@ -313,7 +316,7 @@ void RepeatedPrimitiveFieldGenerator::GeneratePrivateMembers( format("::$proto_ns$::RepeatedField< $type$ > $name$_;\n"); if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && HasGeneratedMethods(descriptor_->file(), options_)) { - format("mutable std::atomic _$name$_cached_byte_size_;\n"); + format("mutable std::atomic $cached_byte_size_name$;\n"); } } @@ -344,7 +347,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$(int index) const {\n" - " return $name$_.Get(index);\n" + " return $field$.Get(index);\n" "}\n" "inline $type$ $classname$::$name$(int index) const {\n" "$annotate_get$" @@ -353,11 +356,11 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline void $classname$::set_$name$(int index, $type$ value) {\n" "$annotate_set$" - " $name$_.Set(index, value);\n" + " $field$.Set(index, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "inline void $classname$::_internal_add_$name$($type$ value) {\n" - " $name$_.Add(value);\n" + " $field$.Add(value);\n" "}\n" "inline void $classname$::add_$name$($type$ value) {\n" " _internal_add_$name$(value);\n" @@ -366,7 +369,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline const ::$proto_ns$::RepeatedField< $type$ >&\n" "$classname$::_internal_$name$() const {\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline const ::$proto_ns$::RepeatedField< $type$ >&\n" "$classname$::$name$() const {\n" @@ -376,7 +379,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline ::$proto_ns$::RepeatedField< $type$ >*\n" "$classname$::_internal_mutable_$name$() {\n" - " return &$name$_;\n" + " return &$field$;\n" "}\n" "inline ::$proto_ns$::RepeatedField< $type$ >*\n" "$classname$::mutable_$name$() {\n" @@ -389,30 +392,19 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( void RepeatedPrimitiveFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedPrimitiveFieldGenerator::GenerateMergingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("$field$.MergeFrom(from.$field$);\n"); } void RepeatedPrimitiveFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); -} - -void RepeatedPrimitiveFieldGenerator::GenerateConstructorCode( - io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedPrimitiveFieldGenerator::GenerateCopyConstructorCode( - io::Printer* printer) const { - Formatter format(printer, variables_); - format("$name$_.CopyFrom(from.$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -423,7 +415,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "{\n" " int byte_size = " - "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n" + "$cached_byte_size_field$.load(std::memory_order_relaxed);\n" " if (byte_size > 0) {\n" " target = stream->Write$declared_type$Packed(\n" " $number$, _internal_$name$(), byte_size, target);\n" @@ -440,7 +432,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,8 +447,8 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize( int fixed_size = FixedSize(descriptor_->type()); if (fixed_size == -1) { format( - "size_t data_size = ::$proto_ns$::internal::WireFormatLite::\n" - " $declared_type$Size(this->$name$_);\n"); + "size_t data_size = ::_pbi::WireFormatLite::\n" + " $declared_type$Size(this->$field$);\n"); } else { format( "unsigned int count = static_cast 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" - "_$name$_cached_byte_size_.store(cached_size,\n" + "int cached_size = ::_pbi::ToCachedSize(data_size);\n" + "$cached_byte_size_field$.store(cached_size,\n" " std::memory_order_relaxed);\n"); } format("total_size += data_size;\n"); @@ -482,7 +473,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(); @@ -495,7 +486,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateConstinitInitializer( format("$name$_()"); if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && HasGeneratedMethods(descriptor_->file(), options_)) { - format("\n, _$name$_cached_byte_size_(0)"); + format("\n, $cached_byte_size_name$(0)"); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h index ff7c208ff2941..77ac598e905ae 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; @@ -97,8 +98,8 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { void GenerateClearingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; - void GenerateConstructorCode(io::Printer* printer) const override; - void GenerateCopyConstructorCode(io::Printer* printer) const override; + void GenerateConstructorCode(io::Printer* printer) const override {} + void GenerateCopyConstructorCode(io::Printer* printer) const override {} void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(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..41daed221f01c 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,30 @@ 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"; + (*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; + (*variables)["default_variable_name"] = MakeDefaultName(descriptor); + (*variables)["default_variable_field"] = MakeDefaultFieldName(descriptor); - if (!descriptor->default_value_string().empty()) { + if (descriptor->default_value_string().empty()) { + (*variables)["default_string"] = kNS + "GetEmptyStringAlreadyInited()"; + (*variables)["default_value"] = "&" + (*variables)["default_string"]; + (*variables)["lazy_variable_args"] = ""; + } else { (*variables)["lazy_variable"] = - QualifiedClassName(descriptor->containing_type(), options) + - "::" + default_variable_string; - } - - (*variables)["default_string"] = - descriptor->default_value_string().empty() - ? "::" + (*variables)["proto_ns"] + - "::internal::GetEmptyStringAlreadyInited()" - : (*variables)["lazy_variable"] + ".get()"; - (*variables)["init_value"] = - descriptor->default_value_string().empty() - ? "&::" + (*variables)["proto_ns"] + - "::internal::GetEmptyStringAlreadyInited()" - : "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"]; + StrCat(QualifiedClassName(descriptor->containing_type(), options), + "::", MakeDefaultFieldName(descriptor)); + + (*variables)["default_string"] = (*variables)["lazy_variable"] + ".get()"; + (*variables)["default_value"] = "nullptr"; + (*variables)["lazy_variable_args"] = (*variables)["lazy_variable"] + ", "; + } + (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; (*variables)["setter"] = @@ -116,9 +111,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,8 +204,8 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " // @@protoc_insertion_point(field_get:$full_name$)\n"); if (!descriptor_->default_value_string().empty()) { format( - " if ($name$_.IsDefault(nullptr)) return " - "$default_variable_name$.get();\n"); + " if ($field$.IsDefault()) return " + "$default_variable_field$.get();\n"); } format( " return _internal_$name$();\n" @@ -216,7 +216,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "inline PROTOBUF_ALWAYS_INLINE\n" "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" " $set_hasbit$\n" - " $name$_.$setter$($default_value_tag$, static_cast(arg0)," + " $field$.$setter$(static_cast(arg0)," " args..., GetArenaForAllocation());\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -227,9 +227,9 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "inline PROTOBUF_ALWAYS_INLINE\n" "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" " $set_hasbit$\n" - " $name$_.$setter$(nullptr, static_cast(arg0)," + " $field$.$setter$(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" @@ -246,20 +246,20 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " return _s;\n" "}\n" "inline const std::string& $classname$::_internal_$name$() const {\n" - " return $name$_.Get();\n" + " return $field$.Get();\n" "}\n" "inline void $classname$::_internal_set_$name$(const std::string& " "value) {\n" " $set_hasbit$\n"); if (!inlined_) { format( - " $name$_.Set($default_value_tag$, value, GetArenaForAllocation());\n" + " $field$.Set(value, GetArenaForAllocation());\n" "}\n"); } else { format( - " $name$_.Set(nullptr, value, GetArenaForAllocation(),\n" + " $field$.Set(value, GetArenaForAllocation(),\n" " _internal_$name$_donated(), &$donating_states_word$, " - "$mask_for_undonate$);\n" + "$mask_for_undonate$, this);\n" "}\n"); } format( @@ -267,14 +267,14 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " $set_hasbit$\n"); if (!inlined_) { format( - " return $name$_.Mutable($default_variable_or_tag$, " + " return $field$.Mutable($lazy_variable_args$" "GetArenaForAllocation());\n" "}\n"); } else { format( - " return $name$_.Mutable($default_variable_or_tag$, " + " return $field$.Mutable($lazy_variable_args$" "GetArenaForAllocation(), _internal_$name$_donated(), " - "&$donating_states_word$, $mask_for_undonate$);\n" + "&$donating_states_word$, $mask_for_undonate$, this);\n" "}\n"); } format( @@ -289,26 +289,23 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " }\n" " $clear_hasbit$\n"); if (!inlined_) { - format( - " auto* p = $name$_.ReleaseNonDefault($init_value$, " - "GetArenaForAllocation());\n"); + format(" auto* p = $field$.Release();\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 ($field$.IsDefault()) {\n" + " $field$.Set(\"\", GetArenaForAllocation());\n" " }\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } format(" return p;\n"); } else { format( - " return $name$_.Release(nullptr, GetArenaForAllocation(), " + " return $field$.Release(GetArenaForAllocation(), " "_internal_$name$_donated());\n"); } } else { - format( - " return $name$_.Release($init_value$, GetArenaForAllocation());\n"); + format(" return $field$.Release();\n"); } format( @@ -320,23 +317,21 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " $clear_hasbit$\n" " }\n"); if (!inlined_) { - format( - " $name$_.SetAllocated($init_value$, $name$,\n" - " GetArenaForAllocation());\n"); + format(" $field$.SetAllocated($name$, 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 ($field$.IsDefault()) {\n" + " $field$.Set(\"\", GetArenaForAllocation());\n" " }\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } } else { // Currently, string fields with default value can't be inlined. format( - " $name$_.SetAllocated(nullptr, $name$, GetArenaForAllocation(), " + " $field$.SetAllocated(nullptr, $name$, GetArenaForAllocation(), " "_internal_$name$_donated(), &$donating_states_word$, " - "$mask_for_undonate$);\n"); + "$mask_for_undonate$, this);\n"); } format( "$annotate_set$" @@ -350,7 +345,7 @@ void StringFieldGenerator::GenerateNonInlineAccessorDefinitions( if (!descriptor_->default_value_string().empty()) { format( "const ::$proto_ns$::internal::LazyString " - "$classname$::$default_variable_name$" + "$classname$::$default_variable_field$" "{{{$default$, $default_length$}}, {nullptr}};\n"); } } @@ -358,11 +353,11 @@ void StringFieldGenerator::GenerateNonInlineAccessorDefinitions( void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmpty();\n"); + format("$field$.ClearToEmpty();\n"); } else { GOOGLE_DCHECK(!inlined_); format( - "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n"); + "$field$.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n"); } } @@ -388,20 +383,20 @@ 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$(!$field$.IsDefault());\n"); } if (descriptor_->default_value_string().empty()) { if (must_be_present) { - format("$name$_.ClearNonDefaultToEmpty();\n"); + format("$field$.ClearNonDefaultToEmpty();\n"); } else { - format("$name$_.ClearToEmpty();\n"); + format("$field$.ClearToEmpty();\n"); } } else { // Clear to a non-empty default is more involved, as we try to use the // Arena if one is present and may need to reallocate the string. format( - "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n "); + "$field$.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n "); } } @@ -416,34 +411,31 @@ void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { if (!inlined_) { format( "::$proto_ns$::internal::ArenaStringPtr::InternalSwap(\n" - " $init_value$,\n" - " &$name$_, lhs_arena,\n" - " &other->$name$_, rhs_arena\n" + " &$field$, lhs_arena,\n" + " &other->$field$, 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" + " &$field$, lhs_arena, " + "($inlined_string_donated_array$[0] & 0x1u) == 0, this,\n" + " &other->$field$, rhs_arena, " + "(other->$inlined_string_donated_array$[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("$field$.InitDefault();\n"); if (IsString(descriptor_, options_) && descriptor_->default_value_string().empty()) { format( "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" - " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + " $field$.Set(\"\", GetArenaForAllocation());\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } } @@ -452,6 +444,9 @@ void StringFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); GenerateConstructorCode(printer); + if (inlined_) { + format("new (&$field$) ::_pbi::InlinedStringField();\n"); + } if (HasHasbit(descriptor_)) { format("if (from._internal_has_$name$()) {\n"); @@ -463,13 +458,13 @@ void StringFieldGenerator::GenerateCopyConstructorCode( if (!inlined_) { format( - "$name$_.Set($default_value_tag$, from._internal_$name$(), \n" + "$field$.Set(from._internal_$name$(), \n" " GetArenaForAllocation());\n"); } else { format( - "$name$_.Set(nullptr, from._internal_$name$(),\n" + "$field$.Set(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 +473,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("$field$.Destroy();\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("$field$.~InlinedStringField();\n"); +} - format("$name$_.DestroyNoArena($init_value$);\n"); +ArenaDtorNeeds StringFieldGenerator::NeedsArenaDestructor() const { + return inlined_ ? ArenaDtorNeeds::kOnDemand : ArenaDtorNeeds::kNone; +} + +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->$field$.~InlinedStringField();\n" + "}\n"); } void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -517,9 +530,11 @@ void StringFieldGenerator::GenerateConstinitInitializer( return; } if (descriptor_->default_value_string().empty()) { - format("$name$_(&::$proto_ns$::internal::fixed_address_empty_string)"); + format( + "$name$_(&::_pbi::fixed_address_empty_string, " + "::_pbi::ConstantInitialized{})"); } else { - format("$name$_(nullptr)"); + format("$name$_(nullptr, ::_pbi::ConstantInitialized{})"); } } @@ -550,9 +565,9 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field$.InitDefault();\n" " }\n" - " $field_member$.$setter$($default_value_tag$," + " $field$.$setter$(" " static_cast(arg0), args..., GetArenaForAllocation());\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -565,7 +580,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline const std::string& $classname$::_internal_$name$() const {\n" " if (_internal_has_$name$()) {\n" - " return $field_member$.Get();\n" + " return $field$.Get();\n" " }\n" " return $default_string$;\n" "}\n" @@ -574,28 +589,26 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field$.InitDefault();\n" " }\n" - " $field_member$.Set($default_value_tag$, value, " - "GetArenaForAllocation());\n" + " $field$.Set(value, GetArenaForAllocation());\n" "}\n"); format( "inline std::string* $classname$::_internal_mutable_$name$() {\n" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field$.InitDefault();\n" " }\n" - " return $field_member$.Mutable(\n" - " $default_variable_or_tag$, GetArenaForAllocation());\n" + " return $field$.Mutable($lazy_variable_args$" + " GetArenaForAllocation());\n" "}\n" "inline std::string* $classname$::$release_name$() {\n" "$annotate_release$" " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " return $field_member$.ReleaseNonDefault($init_value$, " - "GetArenaForAllocation());\n" + " return $field$.Release();\n" " } else {\n" " return nullptr;\n" " }\n" @@ -606,11 +619,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$.InitAllocated($name$, GetArenaForAllocation());\n" " }\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" @@ -620,9 +629,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( void StringOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format( - "$field_member$.Destroy($default_value_tag$, " - "GetArenaForAllocation());\n"); + format("$field$.Destroy();\n"); } void StringOneofFieldGenerator::GenerateMessageClearingCode( @@ -737,14 +744,14 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const std::string& $classname$::_internal_$name$(int index) " "const {\n" - " return $name$_.InternalCheckedGet(\n" + " return $field$.InternalCheckedGet(\n" " index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n" "}\n"); } else { format( "inline const std::string& $classname$::_internal_$name$(int index) " "const {\n" - " return $name$_.Get(index);\n" + " return $field$.Get(index);\n" "}\n"); } format( @@ -756,23 +763,23 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( "inline std::string* $classname$::mutable_$name$(int index) {\n" "$annotate_mutable$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_.Mutable(index);\n" + " return $field$.Mutable(index);\n" "}\n" "inline void $classname$::set_$name$(int index, const std::string& " "value) " "{\n" - " $name$_.Mutable(index)->assign(value);\n" + " $field$.Mutable(index)->assign(value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "inline void $classname$::set_$name$(int index, std::string&& value) {\n" - " $name$_.Mutable(index)->assign(std::move(value));\n" + " $field$.Mutable(index)->assign(std::move(value));\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "inline void $classname$::set_$name$(int index, const char* value) {\n" " $null_check$" - " $name$_.Mutable(index)->assign(value);\n" + " $field$.Mutable(index)->assign(value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); @@ -780,7 +787,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline void " "$classname$::set_$name$(int index, StringPiece value) {\n" - " $name$_.Mutable(index)->assign(value.data(), value.size());\n" + " $field$.Mutable(index)->assign(value.data(), value.size());\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); @@ -789,34 +796,34 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( "inline void " "$classname$::set_$name$" "(int index, const $pointer_type$* value, size_t size) {\n" - " $name$_.Mutable(index)->assign(\n" + " $field$.Mutable(index)->assign(\n" " reinterpret_cast(value), size);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" "inline std::string* $classname$::_internal_add_$name$() {\n" - " return $name$_.Add();\n" + " return $field$.Add();\n" "}\n" "inline void $classname$::add_$name$(const std::string& value) {\n" - " $name$_.Add()->assign(value);\n" + " $field$.Add()->assign(value);\n" "$annotate_add$" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" "inline void $classname$::add_$name$(std::string&& value) {\n" - " $name$_.Add(std::move(value));\n" + " $field$.Add(std::move(value));\n" "$annotate_add$" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" "inline void $classname$::add_$name$(const char* value) {\n" " $null_check$" - " $name$_.Add()->assign(value);\n" + " $field$.Add()->assign(value);\n" "$annotate_add$" " // @@protoc_insertion_point(field_add_char:$full_name$)\n" "}\n"); if (!options_.opensource_runtime) { format( "inline void $classname$::add_$name$(StringPiece value) {\n" - " $name$_.Add()->assign(value.data(), value.size());\n" + " $field$.Add()->assign(value.data(), value.size());\n" "$annotate_add$" " // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n" "}\n"); @@ -824,7 +831,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline void " "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n" - " $name$_.Add()->assign(reinterpret_cast(value), size);\n" + " $field$.Add()->assign(reinterpret_cast(value), size);\n" "$annotate_add$" " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n" "}\n" @@ -832,43 +839,32 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( "$classname$::$name$() const {\n" "$annotate_list$" " // @@protoc_insertion_point(field_list:$full_name$)\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline ::$proto_ns$::RepeatedPtrField*\n" "$classname$::mutable_$name$() {\n" "$annotate_mutable_list$" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" - " return &$name$_;\n" + " return &$field$;\n" "}\n"); } void RepeatedStringFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedStringFieldGenerator::GenerateMergingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("$field$.MergeFrom(from.$field$);\n"); } void RepeatedStringFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); -} - -void RepeatedStringFieldGenerator::GenerateConstructorCode( - io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedStringFieldGenerator::GenerateCopyConstructorCode( - io::Printer* printer) const { - Formatter format(printer, variables_); - format("$name$_.CopyFrom(from.$name$_);"); + format("$field$.InternalSwap(&other->$field$);\n"); } void RepeatedStringFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -895,11 +891,11 @@ void RepeatedStringFieldGenerator::GenerateByteSize( Formatter format(printer, variables_); format( "total_size += $tag_size$ *\n" - " ::$proto_ns$::internal::FromIntSize($name$_.size());\n" - "for (int i = 0, n = $name$_.size(); i < n; i++) {\n" + " ::$proto_ns$::internal::FromIntSize($field$.size());\n" + "for (int i = 0, n = $field$.size(); i < n; i++) {\n" " total_size += " "::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" - " $name$_.Get(i));\n" + " $field$.Get(i));\n" "}\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..845bf073a93f1 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; @@ -108,8 +111,8 @@ class RepeatedStringFieldGenerator : public FieldGenerator { void GenerateClearingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; - void GenerateConstructorCode(io::Printer* printer) const override; - void GenerateCopyConstructorCode(io::Printer* printer) const override; + void GenerateConstructorCode(io::Printer* printer) const override {} + void GenerateCopyConstructorCode(io::Printer* printer) const override {} void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(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..f1e26f8bdd1d3 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( @@ -498,12 +498,12 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( #if defined(_WIN32) if (ret == 0 && sb.st_mode & S_IFDIR) { last_error_message_ = "Input file is a directory."; - return NULL; + return nullptr; } #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..2fb88b923ea2c 100644 --- a/src/google/protobuf/compiler/importer.h +++ b/src/google/protobuf/compiler/importer.h @@ -41,10 +41,12 @@ #include #include #include + #include #include #include +// Must be included last. #include namespace google { @@ -85,7 +87,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 +126,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 +243,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_field.h b/src/google/protobuf/compiler/java/java_field.h index a7c995c4ef14f..6ac01b99ff29d 100644 --- a/src/google/protobuf/compiler/java/java_field.h +++ b/src/google/protobuf/compiler/java/java_field.h @@ -156,7 +156,7 @@ template <> FieldGeneratorMap::~FieldGeneratorMap(); -// Field information used in FieldGeneartors. +// Field information used in FieldGenerators. struct FieldGeneratorInfo { std::string name; std::string capitalized_name; 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..f75f8b3165a1f 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -37,6 +37,9 @@ #include +#include +#include +#include #include #include #include @@ -44,8 +47,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..3d9dc4001d886 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -40,13 +40,13 @@ #include #include +#include +#include #include +#include #include #include #include -#include -#include -#include #include // for hash namespace google { @@ -66,15 +66,27 @@ namespace { const char* kDefaultPackage = ""; -// Names that should be avoided as field names. -// Using them will cause the compiler to generate accessors whose names are -// colliding with methods defined in base classes. +// Names that should be avoided (in UpperCamelCase format). +// Using them will cause the compiler to generate accessors whose names +// collide with methods defined in base classes. +// Keep this list in sync with specialFieldNames in +// java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java const char* kForbiddenWordList[] = { - // message base class: - "cached_size", - "serialized_size", // java.lang.Object: - "class", + "Class", + // com.google.protobuf.MessageLiteOrBuilder: + "DefaultInstanceForType", + // com.google.protobuf.MessageLite: + "ParserForType", + "SerializedSize", + // com.google.protobuf.MessageOrBuilder: + "AllFields", + "DescriptorForType", + "InitializationErrorString", + // TODO(b/219045204): re-enable + // "UnknownFields", + // obsolete. kept for backwards compatibility of generated code + "CachedSize", }; const std::unordered_set* kReservedNames = @@ -93,7 +105,7 @@ const std::unordered_set* kReservedNames = bool IsForbidden(const std::string& field_name) { for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { - if (field_name == kForbiddenWordList[i]) { + if (UnderscoresToCamelCase(field_name, true) == kForbiddenWordList[i]) { return true; } } @@ -1049,8 +1061,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..9918abc04f525 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,24 @@ 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_presence() && 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 +1525,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 +1541,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 +1570,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 +1613,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 +1622,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 +1632,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 +1643,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 +1653,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..694218c1d49cf 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"); @@ -1426,7 +1438,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "add(value: $kt_type$) {\n" " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); @@ -1438,7 +1450,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(value: $kt_type$) {\n" " add(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -1449,7 +1461,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -1462,7 +1474,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" " addAll(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, /* builder */ false); @@ -1474,7 +1486,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "set(index: kotlin.Int, value: $kt_type$) {\n" " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, /* builder */ false); @@ -1485,7 +1497,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "clear() {\n" " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" - "}"); + "}\n\n"); } } // namespace java 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..4f4265fdf8ceb 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( @@ -816,7 +825,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "add(value: $kt_type$) {\n" " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); @@ -828,7 +837,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(value: $kt_type$) {\n" " add(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -839,7 +848,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -852,7 +861,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" " addAll(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, /* builder */ false); @@ -864,7 +873,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "set(index: kotlin.Int, value: $kt_type$) {\n" " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, /* builder */ false); @@ -875,7 +884,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "clear() {\n" " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" - "}"); + "}\n"); } } // namespace java 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..8073bac09026f 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,26 @@ 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_presence() && 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 +846,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 +862,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 +891,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 +934,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 +943,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 +953,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 +964,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 +974,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 1a0959e408bc9..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 { @@ -992,7 +992,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers( // List += String WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); - printer->Print(variables_, + printer->Print(variables_, "@kotlin.jvm.JvmSynthetic\n" "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" 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 1833903316137..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 { diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index d2dac2f606f62..2cee9da597bd7 100644 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -3625,23 +3625,19 @@ void Generator::GenerateFile(const GeneratorOptions& options, if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { printer->Print("var proto = {};\n\n"); } else { - // 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): + // 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('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() {\n" - " if (this) { return this; }\n" - " if (typeof window !== 'undefined') { return window; }\n" - " if (typeof global !== 'undefined') { return global; }\n" - " if (typeof self !== 'undefined') { return self; }\n" - " return Function('return this')();\n" - "}.call(null));\n\n"); + "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..08d77a639ca99 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."); + // Python 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_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index ff69f39f484ff..1e55f3d95eec4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -65,9 +65,8 @@ void SetEnumVariables(const FieldDescriptor* descriptor, } } // namespace -EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); } @@ -116,12 +115,16 @@ void EnumFieldGenerator::GenerateCFunctionImplementations( } void EnumFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // If it is an enum defined in a different file, then we'll need a forward - // declaration for it. When it is in our file, all the enums are output - // before the message, so it will be declared before it is needed. - if (descriptor_->file() != descriptor_->enum_type()->file()) { + std::set* fwd_decls, + bool include_external_types) const { + SingleFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // If it is an enum defined in a different file (and not a WKT), then we'll + // need a forward declaration for it. When it is in our file, all the enums + // are output before the message, so it will be declared before it is needed. + if (include_external_types && + descriptor_->file() != descriptor_->enum_type()->file() && + !IsProtobufLibraryBundledProtoFile(descriptor_->enum_type()->file())) { // Enum name is already in "storage_type". const std::string& name = variable("storage_type"); fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); @@ -129,8 +132,8 @@ void EnumFieldGenerator::DetermineForwardDeclarations( } RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); variables_["array_storage_type"] = "GPBEnumArray"; } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 3fb0a9fd11fee..138be31142840 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class EnumFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); EnumFieldGenerator(const EnumFieldGenerator&) = delete; EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; @@ -53,23 +52,22 @@ class EnumFieldGenerator : public SingleFieldGenerator { virtual void GenerateCFunctionImplementations( io::Printer* printer) const override; virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; protected: - EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + EnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~EnumFieldGenerator(); }; class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization() override; protected: - RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedEnumFieldGenerator(); }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc index eb23fee19f800..f16dd4b9b697c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -118,40 +118,39 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } // namespace -FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options) { +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { FieldGenerator* result = NULL; if (field->is_repeated()) { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { if (field->is_map()) { - result = new MapFieldGenerator(field, options); + result = new MapFieldGenerator(field); } else { - result = new RepeatedMessageFieldGenerator(field, options); + result = new RepeatedMessageFieldGenerator(field); } break; } case OBJECTIVECTYPE_ENUM: - result = new RepeatedEnumFieldGenerator(field, options); + result = new RepeatedEnumFieldGenerator(field); break; default: - result = new RepeatedPrimitiveFieldGenerator(field, options); + result = new RepeatedPrimitiveFieldGenerator(field); break; } } else { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { - result = new MessageFieldGenerator(field, options); + result = new MessageFieldGenerator(field); break; } case OBJECTIVECTYPE_ENUM: - result = new EnumFieldGenerator(field, options); + result = new EnumFieldGenerator(field); break; default: if (IsReferenceType(field)) { - result = new PrimitiveObjFieldGenerator(field, options); + result = new PrimitiveObjFieldGenerator(field); } else { - result = new PrimitiveFieldGenerator(field, options); + result = new PrimitiveFieldGenerator(field); } break; } @@ -160,8 +159,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, return result; } -FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, - const Options& options) +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) : descriptor_(descriptor) { SetCommonFieldVariables(descriptor, &variables_); } @@ -185,7 +183,8 @@ void FieldGenerator::GenerateCFunctionImplementations( } void FieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls, + bool include_external_types) const { // Nothing } @@ -266,9 +265,8 @@ void FieldGenerator::FinishInitialization(void) { } } -SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : FieldGenerator(descriptor, options) { +SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor) + : FieldGenerator(descriptor) { // Nothing } @@ -310,9 +308,8 @@ bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { return true; } -ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { variables_["property_storage_attribute"] = "strong"; if (IsRetainedName(variables_["name"])) { variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -353,8 +350,8 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration( } RepeatedFieldGenerator::RepeatedFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { // Default to no comment and let the cases needing it fill it in. variables_["array_comment"] = ""; } @@ -407,19 +404,18 @@ bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { return false; // The array (or map/dict) having anything is what is used. } -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, - const Options& options) +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) : descriptor_(descriptor), field_generators_(descriptor->field_count()), extension_generators_(descriptor->extension_count()) { // Construct all the FieldGenerators. for (int i = 0; i < descriptor->field_count(); i++) { field_generators_[i].reset( - FieldGenerator::Make(descriptor->field(i), options)); + FieldGenerator::Make(descriptor->field(i))); } for (int i = 0; i < descriptor->extension_count(); i++) { extension_generators_[i].reset( - FieldGenerator::Make(descriptor->extension(i), options)); + FieldGenerator::Make(descriptor->extension(i))); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h index ad8e55aeb228a..e1e906deff4ef 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -44,8 +43,7 @@ namespace objectivec { class FieldGenerator { public: - static FieldGenerator* Make(const FieldDescriptor* field, - const Options& options); + static FieldGenerator* Make(const FieldDescriptor* field); virtual ~FieldGenerator(); @@ -66,7 +64,8 @@ class FieldGenerator { // Exposed for subclasses, should always call it on the parent class also. virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const; + std::set* fwd_decls, + bool include_external_types) const; virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const; @@ -96,7 +95,7 @@ class FieldGenerator { std::string raw_field_name() const { return variable("raw_field_name"); } protected: - FieldGenerator(const FieldDescriptor* descriptor, const Options& options); + FieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void); bool WantsHasProperty(void) const; @@ -120,8 +119,7 @@ class SingleFieldGenerator : public FieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + SingleFieldGenerator(const FieldDescriptor* descriptor); }; // Subclass with common support for when the field ends up as an ObjC Object. @@ -136,8 +134,7 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator { virtual void GeneratePropertyDeclaration(io::Printer* printer) const override; protected: - ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + ObjCObjFieldGenerator(const FieldDescriptor* descriptor); }; class RepeatedFieldGenerator : public ObjCObjFieldGenerator { @@ -155,15 +152,14 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - RepeatedFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedFieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void) override; }; // Convenience class which constructs FieldGenerators for a Descriptor. class FieldGeneratorMap { public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + FieldGeneratorMap(const Descriptor* descriptor); ~FieldGeneratorMap(); FieldGeneratorMap(const FieldGeneratorMap&) = delete; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index d9f43a55c73c4..84a75d83d5bc1 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,10 @@ const int32_t GOOGLE_PROTOBUF_OBJC_VERSION = 30004; const char* kHeaderExtension = ".pbobjc.h"; +std::string BundledFileName(const FileDescriptor* file) { + return "GPB" + FilePathBasename(file) + kHeaderExtension; +} + // Checks if a message contains any enums definitions (on the message or // a nested message under it). bool MessageContainsEnums(const Descriptor* message) { @@ -185,18 +190,19 @@ bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { } // namespace -FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) +FileGenerator::FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options) : file_(file), + generation_options_(generation_options), root_class_name_(FileClassName(file)), - is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)), - options_(options) { + is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) { for (int i = 0; i < file_->enum_type_count(); i++) { EnumGenerator* generator = new EnumGenerator(file_->enum_type(i)); enum_generators_.emplace_back(generator); } for (int i = 0; i < file_->message_type_count(); i++) { MessageGenerator* generator = - new MessageGenerator(root_class_name_, file_->message_type(i), options_); + new MessageGenerator(root_class_name_, file_->message_type(i)); message_generators_.emplace_back(generator); } for (int i = 0; i < file_->extension_count(); i++) { @@ -216,6 +222,10 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { headers.push_back("GPBDescriptor.h"); headers.push_back("GPBMessage.h"); headers.push_back("GPBRootObject.h"); + for (int i = 0; i < file_->dependency_count(); i++) { + const std::string header_name = BundledFileName(file_->dependency(i)); + headers.push_back(header_name); + } } else { headers.push_back("GPBProtocolBuffers.h"); } @@ -237,16 +247,26 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { "\n", "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION)); - // #import any headers for "public imports" in the proto file. + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; + { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const std::string header_extension(kHeaderExtension); - for (int i = 0; i < file_->public_dependency_count(); i++) { - import_writer.AddFile(file_->public_dependency(i), header_extension); + if (headers_use_forward_declarations) { + // #import any headers for "public imports" in the proto file. + for (int i = 0; i < file_->public_dependency_count(); i++) { + import_writer.AddFile(file_->public_dependency(i), header_extension); + } + } else { + for (int i = 0; i < file_->dependency_count(); i++) { + import_writer.AddFile(file_->dependency(i), header_extension); + } } import_writer.Print(printer); } @@ -266,7 +286,9 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { std::set fwd_decls; for (const auto& generator : message_generators_) { - generator->DetermineForwardDeclarations(&fwd_decls); + generator->DetermineForwardDeclarations( + &fwd_decls, + /* include_external_types = */ headers_use_forward_declarations); } for (std::set::const_iterator i(fwd_decls.begin()); i != fwd_decls.end(); ++i) { @@ -340,6 +362,9 @@ void FileGenerator::GenerateSource(io::Printer* printer) { // #import the runtime support. std::vector headers; headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); + if (is_bundled_proto_) { + headers.push_back(BundledFileName(file_)); + } PrintFileRuntimePreamble(printer, headers); // Enums use atomic in the generated code, so add the system import as needed. @@ -352,28 +377,34 @@ void FileGenerator::GenerateSource(io::Printer* printer) { std::vector deps_with_extensions; CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; + { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const std::string header_extension(kHeaderExtension); // #import the header for this proto file. import_writer.AddFile(file_, header_extension); - // #import the headers for anything that a plain dependency of this proto - // file (that means they were just an include, not a "public" include). - std::set public_import_names; - for (int i = 0; i < file_->public_dependency_count(); i++) { - public_import_names.insert(file_->public_dependency(i)->name()); - } - for (int i = 0; i < file_->dependency_count(); i++) { - const FileDescriptor *dep = file_->dependency(i); - bool public_import = (public_import_names.count(dep->name()) != 0); - if (!public_import) { - import_writer.AddFile(dep, header_extension); + if (headers_use_forward_declarations) { + // #import the headers for anything that a plain dependency of this proto + // file (that means they were just an include, not a "public" include). + std::set public_import_names; + for (int i = 0; i < file_->public_dependency_count(); i++) { + public_import_names.insert(file_->public_dependency(i)->name()); + } + for (int i = 0; i < file_->dependency_count(); i++) { + const FileDescriptor *dep = file_->dependency(i); + bool public_import = (public_import_names.count(dep->name()) != 0); + if (!public_import) { + import_writer.AddFile(dep, header_extension); + } } } @@ -599,8 +630,26 @@ void FileGenerator::PrintFileRuntimePreamble( "// source: $filename$\n" "\n", "filename", file_->name()); - ImportWriter::PrintRuntimeImports( - printer, headers_to_import, options_.runtime_import_prefix, true); + + if (is_bundled_proto_) { + // This is basically a clone of ImportWriter::PrintRuntimeImports() but + // without the CPP symbol gate, since within the bundled files, that isn't + // needed. + std::string import_prefix = generation_options_.runtime_import_prefix; + if (!import_prefix.empty()) { + import_prefix += "/"; + } + for (const auto& header : headers_to_import) { + printer->Print( + "#import \"$import_prefix$$header$\"\n", + "import_prefix", import_prefix, + "header", header); + } + } else { + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, generation_options_.runtime_import_prefix, true); + } + printer->Print("\n"); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h index 87258a39fe06f..64c833bd7f862 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -49,7 +48,19 @@ class MessageGenerator; class FileGenerator { public: - FileGenerator(const FileDescriptor* file, const Options& options); + struct GenerationOptions { + GenerationOptions() + // TODO(thomasvl): Eventually flip this default to false for better + // interop with Swift if proto usages span modules made from ObjC sources. + : headers_use_forward_declarations(true) {} + std::string generate_for_named_framework; + std::string named_framework_to_proto_path_mappings_path; + std::string runtime_import_prefix; + bool headers_use_forward_declarations; + }; + + FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options); ~FileGenerator(); FileGenerator(const FileGenerator&) = delete; @@ -60,6 +71,7 @@ class FileGenerator { private: const FileDescriptor* file_; + const GenerationOptions& generation_options_; std::string root_class_name_; bool is_bundled_proto_; @@ -67,8 +79,6 @@ class FileGenerator { std::vector> message_generators_; std::vector> extension_generators_; - const Options options_; - void PrintFileRuntimePreamble( io::Printer* printer, const std::vector& headers_to_import) const; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index a03b8604fca12..f61f34f465d36 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -94,7 +94,8 @@ bool ObjectiveCGenerator::GenerateAll( // // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework - Options generation_options; + Options validation_options; + FileGenerator::GenerationOptions generation_options; std::vector > options; ParseGeneratorParameter(parameter, &options); @@ -110,17 +111,20 @@ 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. - generation_options.expected_prefixes_path = options[i].second; + validation_options.expected_prefixes_path = options[i].second; } else if (options[i].first == "expected_prefixes_suppressions") { // A semicolon delimited string that lists the paths of .proto files to // exclude from the package prefix validations (expected_prefixes_path). // This is provided as an "out", to skip some files being checked. for (StringPiece split_piece : Split( options[i].second, ";", true)) { - generation_options.expected_prefixes_suppressions.push_back( + validation_options.expected_prefixes_suppressions.push_back( std::string(split_piece)); } } else if (options[i].first == "prefixes_must_be_registered") { @@ -132,7 +136,7 @@ bool ObjectiveCGenerator::GenerateAll( // tried to use a prefix that isn't registered. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.prefixes_must_be_registered)) { + &validation_options.prefixes_must_be_registered)) { *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second; return false; } @@ -144,7 +148,7 @@ bool ObjectiveCGenerator::GenerateAll( // raised if a files doesn't have one. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.require_prefixes)) { + &validation_options.require_prefixes)) { *error = "error: Unknown value for require_prefixes: " + options[i].second; return false; } @@ -185,8 +189,22 @@ bool ObjectiveCGenerator::GenerateAll( // generated files. When integrating ObjC protos into a build system, // this can be used to avoid having to add the runtime directory to the // header search path since the generate #import will be more complete. - generation_options.runtime_import_prefix = - StripSuffixString(options[i].second, "/"); + generation_options.runtime_import_prefix = StripSuffixString(options[i].second, "/"); + } else if (options[i].first == "package_to_prefix_mappings_path") { + // Path to use for when loading the objc class prefix mappings to use. + // The `objc_class_prefix` file option is always honored first if one is present. + // This option also has precedent over the use_package_as_prefix option. + // + // The format of the file is: + // - An entry is a line of "package=prefix". + // - 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. + // + SetPackageToPrefixMappingsPath(options[i].second); } else if (options[i].first == "use_package_as_prefix") { // Controls how the symbols should be prefixed to avoid symbols // collisions. The objc_class_prefix file option is always honored, this @@ -212,6 +230,12 @@ bool ObjectiveCGenerator::GenerateAll( // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "some.proto.package # comment") SetProtoPackagePrefixExceptionList(options[i].second); + } else if (options[i].first == "headers_use_forward_declarations") { + if (!StringToBool(options[i].second, + &generation_options.headers_use_forward_declarations)) { + *error = "error: Unknown value for headers_use_forward_declarations: " + options[i].second; + return false; + } } else { *error = "error: Unknown generator option: " + options[i].first; return false; @@ -240,7 +264,7 @@ bool ObjectiveCGenerator::GenerateAll( // ----------------------------------------------------------------- // Validate the objc prefix/package pairings. - if (!ValidateObjCClassPrefixes(files, generation_options, error)) { + if (!ValidateObjCClassPrefixes(files, validation_options, error)) { // *error will have been filled in. return false; } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 5f4b7f60fa252..b15f58095454f 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) @@ -87,10 +95,31 @@ class SimpleLineCollector : public LineConsumer { std::unordered_set* set_; }; +class PackageToPrefixesCollector : public LineConsumer { + public: + PackageToPrefixesCollector(const std::string &usage, + std::map* inout_package_to_prefix_map) + : usage_(usage), prefix_map_(inout_package_to_prefix_map) {} + + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override; + + private: + const std::string usage_; + std::map* prefix_map_; +}; + class PrefixModeStorage { public: PrefixModeStorage(); + const std::string package_to_prefix_mappings_path() const { return package_to_prefix_mappings_path_; } + void set_package_to_prefix_mappings_path(const std::string& path) { + package_to_prefix_mappings_path_ = path; + package_to_prefix_map_.clear(); + } + + std::string prefix_from_proto_package_mappings(const FileDescriptor* file); + bool use_package_name() const { return use_package_name_; } void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; } @@ -102,9 +131,16 @@ 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::map package_to_prefix_map_; + std::string package_to_prefix_mappings_path_; std::string exception_path_; + std::string forced_prefix_; std::unordered_set exceptions_; }; @@ -112,14 +148,57 @@ 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; + } +} + +std::string PrefixModeStorage::prefix_from_proto_package_mappings(const FileDescriptor* file) { + if (!file) { + return ""; + } + + if (package_to_prefix_map_.empty() && !package_to_prefix_mappings_path_.empty()) { + std::string error_str; + // Re use the same collector as we use for expected_prefixes_path since the file + // format is the same. + PackageToPrefixesCollector collector("Package to prefixes", &package_to_prefix_map_); + if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector, &error_str)) { + if (error_str.empty()) { + error_str = std::string("protoc:0: warning: Failed to parse") + + std::string(" prefix to proto package mappings file: ") + + package_to_prefix_mappings_path_; + } + std::cerr << error_str << std::endl; + std::cerr.flush(); + package_to_prefix_map_.clear(); + } + } + + 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; + + std::map::const_iterator prefix_lookup = + package_to_prefix_map_.find(lookup_key); + + if (prefix_lookup != package_to_prefix_map_.end()) { + return prefix_lookup->second; + } + + return ""; } bool PrefixModeStorage::is_package_exempted(const std::string& package) { @@ -151,6 +230,14 @@ PrefixModeStorage g_prefix_mode; } // namespace +std::string GetPackageToPrefixMappingsPath() { + return g_prefix_mode.package_to_prefix_mappings_path(); +} + +void SetPackageToPrefixMappingsPath(const std::string& file_path) { + g_prefix_mode.set_package_to_prefix_mappings_path(file_path); +} + bool UseProtoPackageAsDefaultPrefix() { return g_prefix_mode.use_package_name(); } @@ -168,7 +255,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 +267,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 +442,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 +600,14 @@ 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 is specified in an prefix to proto mappings file then use that. + std::string objc_class_prefix = g_prefix_mode.prefix_from_proto_package_mappings(file); + if (!objc_class_prefix.empty()) { + return objc_class_prefix; + } + + // If package prefix isn't enabled, done. + if (!g_prefix_mode.use_package_name()) { return ""; } @@ -538,7 +634,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) { @@ -1184,23 +1280,11 @@ void RemoveComment(StringPiece* input) { namespace { -class ExpectedPrefixesCollector : public LineConsumer { - public: - ExpectedPrefixesCollector(std::map* inout_package_to_prefix_map) - : prefix_map_(inout_package_to_prefix_map) {} - - virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override; - - private: - std::map* prefix_map_; -}; - -bool ExpectedPrefixesCollector::ConsumeLine( +bool PackageToPrefixesCollector::ConsumeLine( const StringPiece& line, std::string* out_error) { int offset = line.find('='); if (offset == StringPiece::npos) { - *out_error = std::string("Expected prefixes file line without equal sign: '") + - std::string(line) + "'."; + *out_error = usage_ + " file line without equal sign: '" + StrCat(line) + "'."; return false; } StringPiece package = line.substr(0, offset); @@ -1214,16 +1298,16 @@ bool ExpectedPrefixesCollector::ConsumeLine( return true; } -bool LoadExpectedPackagePrefixes(const Options& generation_options, +bool LoadExpectedPackagePrefixes(const std::string& expected_prefixes_path, std::map* prefix_map, std::string* out_error) { - if (generation_options.expected_prefixes_path.empty()) { + if (expected_prefixes_path.empty()) { return true; } - ExpectedPrefixesCollector collector(prefix_map); + PackageToPrefixesCollector collector("Expected prefixes", prefix_map); return ParseSimpleFile( - generation_options.expected_prefixes_path, &collector, out_error); + expected_prefixes_path, &collector, out_error); } bool ValidateObjCClassPrefix( @@ -1240,6 +1324,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 +1336,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 +1345,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 +1378,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 +1392,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 +1434,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(); } @@ -1378,6 +1454,13 @@ bool ValidateObjCClassPrefix( } // namespace +bool ValidateObjCClassPrefixes(const std::vector& files, + std::string* out_error) { + // Options's ctor load from the environment. + Options options; + return ValidateObjCClassPrefixes(files, options, out_error); +} + bool ValidateObjCClassPrefixes(const std::vector& files, const Options& generation_options, std::string* out_error) { @@ -1389,7 +1472,7 @@ bool ValidateObjCClassPrefixes(const std::vector& files, // Load the expected package prefixes, if available, to validate against. std::map expected_package_prefixes; - if (!LoadExpectedPackagePrefixes(generation_options, + if (!LoadExpectedPackagePrefixes(generation_options.expected_prefixes_path, &expected_package_prefixes, out_error)) { return false; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 13a105240662b..d21fed215aa89 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -47,6 +47,10 @@ namespace protobuf { namespace compiler { namespace objectivec { +// Get/Set the path to a file to load for objc class prefix lookups. +std::string PROTOC_EXPORT GetPackageToPrefixMappingsPath(); +void PROTOC_EXPORT SetPackageToPrefixMappingsPath( + const std::string& file_path); // Get/Set if the proto package should be used to make the default prefix for // symbols. This will then impact most of the type naming apis below. It is done // as a global to not break any other generator reusing the methods since they @@ -54,20 +58,18 @@ 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); -// Generator options (see objectivec_generator.cc for a description of each): +// Generator Prefix Validation Options (see objectivec_generator.cc for a +// description of each): struct Options { Options(); std::string expected_prefixes_path; std::vector expected_prefixes_suppressions; - std::string generate_for_named_framework; - std::string named_framework_to_proto_path_mappings_path; - std::string runtime_import_prefix; bool prefixes_must_be_registered; bool require_prefixes; }; @@ -251,7 +253,11 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); // and the result is false. bool PROTOC_EXPORT ValidateObjCClassPrefixes( const std::vector& files, - const Options& generation_options, std::string* out_error); + const Options& validation_options, std::string* out_error); +// Same was the other ValidateObjCClassPrefixes() calls, but the options all +// come from the environment variables. +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector& files, std::string* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. 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..99d7581533a20 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -81,14 +81,13 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) { } // namespace -MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : RepeatedFieldGenerator(descriptor, options) { +MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { const FieldDescriptor* key_descriptor = descriptor->message_type()->map_key(); const FieldDescriptor* value_descriptor = descriptor->message_type()->map_value(); - value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options)); + value_field_generator_.reset(FieldGenerator::Make(value_descriptor)); // Pull over some variables_ from the value. variables_["field_type"] = value_field_generator_->variable("field_type"); @@ -153,7 +152,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"; @@ -161,11 +160,19 @@ void MapFieldGenerator::FinishInitialization(void) { } void MapFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); + std::set* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); - if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { + descriptor_->message_type()->map_value(); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE && + ((include_external_types && + !IsProtobufLibraryBundledProtoFile(value_descriptor->file())) || + descriptor_->file() == value_descriptor->file())) { const std::string& value_storage_type = value_field_generator_->variable("storage_type"); fwd_decls->insert("@class " + value_storage_type); @@ -176,7 +183,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/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index 84eac6183a29a..36abf0e38c5cc 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class MapFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization(void) override; @@ -51,13 +50,14 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; protected: - MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + MapFieldGenerator(const FieldDescriptor* descriptor); virtual ~MapFieldGenerator(); virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const override; virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; private: std::unique_ptr value_field_generator_; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 3a00113f32629..1cebdd339b988 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -171,11 +171,10 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { } // namespace MessageGenerator::MessageGenerator(const std::string& root_classname, - const Descriptor* descriptor, - const Options& options) + const Descriptor* descriptor) : root_classname_(root_classname), descriptor_(descriptor), - field_generators_(descriptor, options), + field_generators_(descriptor), class_name_(ClassName(descriptor_)), deprecated_attribute_(GetOptionalDeprecatedAttribute( descriptor, descriptor->file(), false, true)) { @@ -197,8 +196,7 @@ MessageGenerator::MessageGenerator(const std::string& root_classname, for (int i = 0; i < descriptor_->nested_type_count(); i++) { MessageGenerator* generator = new MessageGenerator(root_classname_, - descriptor_->nested_type(i), - options); + descriptor_->nested_type(i)); nested_message_generators_.emplace_back(generator); } } @@ -217,17 +215,18 @@ void MessageGenerator::GenerateStaticVariablesInitialization( } void MessageGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) { + std::set* fwd_decls, + bool include_external_types) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); field_generators_.get(fieldDescriptor) - .DetermineForwardDeclarations(fwd_decls); + .DetermineForwardDeclarations(fwd_decls, include_external_types); } } for (const auto& generator : nested_message_generators_) { - generator->DetermineForwardDeclarations(fwd_decls); + generator->DetermineForwardDeclarations(fwd_decls, include_external_types); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h index 01108d29e75ae..9d1443098181c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -51,7 +50,7 @@ class EnumGenerator; class MessageGenerator { public: MessageGenerator(const std::string& root_classname, - const Descriptor* descriptor, const Options& options); + const Descriptor* descriptor); ~MessageGenerator(); MessageGenerator(const MessageGenerator&) = delete; @@ -63,7 +62,8 @@ class MessageGenerator { void GenerateSource(io::Printer* printer); void GenerateExtensionRegistrationSource(io::Printer* printer); void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); - void DetermineForwardDeclarations(std::set* fwd_decls); + void DetermineForwardDeclarations(std::set* fwd_decls, + bool include_external_types); // Checks if the message or a nested message includes a oneof definition. bool IncludesOneOfDefinition() const; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index 299a20b152eeb..1aa61f1266349 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -58,19 +58,27 @@ void SetMessageVariables(const FieldDescriptor* descriptor, } // namespace -MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); } MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set* fwd_decls, + bool include_external_types) const { + ObjCObjFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( @@ -79,8 +87,8 @@ void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( } RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); variables_["array_storage_type"] = "NSMutableArray"; variables_["array_property_type"] = @@ -90,10 +98,19 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index 01799a120b3ff..bab150f865693 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class MessageFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + MessageFieldGenerator(const FieldDescriptor* descriptor); MessageFieldGenerator(const MessageFieldGenerator&) = delete; MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; @@ -55,18 +53,17 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const override; }; class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedMessageFieldGenerator(); RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; @@ -74,7 +71,8 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const override; }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index e198c5c182ca3..5a89f45c0d4f0 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -125,8 +125,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } // namespace PrimitiveFieldGenerator::PrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : SingleFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); } @@ -159,8 +159,8 @@ void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { } PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); variables_["property_storage_attribute"] = "copy"; } @@ -168,8 +168,8 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); std::string base_name = PrimitiveArrayTypeName(descriptor); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h index a9f30f6419541..291d11a2e30f1 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class PrimitiveFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveFieldGenerator(); PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; @@ -59,12 +57,10 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator { }; class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveObjFieldGenerator(); PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; @@ -73,12 +69,10 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { }; class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedPrimitiveFieldGenerator(); RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 49ddfceb1aa92..0bb96ac80ed6d 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 #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) { @@ -221,12 +221,8 @@ bool Parser::Consume(const char* text, const char* error) { } bool Parser::Consume(const char* text) { - if (TryConsume(text)) { - return true; - } else { - AddError("Expected \"" + std::string(text) + "\"."); - return false; - } + std::string error = "Expected \"" + std::string(text) + "\"."; + return Consume(text, error.c_str()); } bool Parser::ConsumeIdentifier(std::string* output, const char* error) { @@ -347,7 +343,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 +376,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 +469,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 +512,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 +530,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 +624,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 +640,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 +660,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 +702,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 +858,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 +883,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")) { @@ -945,7 +941,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, const FileDescriptorProto* containing_file) { { FieldDescriptorProto::Label label; - if (ParseLabel(&label, field_location, containing_file)) { + if (ParseLabel(&label, field_location)) { field->set_label(label); if (label == FieldDescriptorProto::LABEL_OPTIONAL && syntax_identifier_ == "proto3") { @@ -1458,7 +1454,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 +1902,7 @@ bool Parser::ParseExtend(RepeatedPtrField* extensions, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -1970,7 +1966,7 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -2003,7 +1999,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 +2018,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 +2116,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 +2135,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 +2173,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 +2193,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 +2220,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); @@ -2251,8 +2245,7 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, // ------------------------------------------------------------------- bool Parser::ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { + const LocationRecorder& field_location) { if (!LookingAt("optional") && !LookingAt("repeated") && !LookingAt("required")) { return false; @@ -2396,7 +2389,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..7b426772e7be4 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -42,9 +42,9 @@ #include #include +#include #include #include -#include #include // Must be included last. @@ -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, @@ -444,8 +440,7 @@ class PROTOBUF_EXPORT Parser { // Parse "required", "optional", or "repeated" and fill in "label" // with the value. Returns true if such a label is consumed. bool ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file); + const LocationRecorder& field_location); // Parse a type name and fill in "type" (if it is a primitive) or // "type_name" (if it is not) with the type parsed. diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 6973bc993dd51..9027891ec10d5 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. @@ -2466,13 +2466,15 @@ TEST_F(ParseDescriptorDebugTest, TestMaps) { // *output_field to the descriptor of the field, and *output_index to -1. // Returns true if the path was valid, false otherwise. A gTest failure is // recorded before returning false. -bool FollowPath(const Message& root, const int* path_begin, const int* path_end, +bool FollowPath(const Message& root, + RepeatedField::const_iterator path_begin, + RepeatedField::const_iterator path_end, const Message** output_message, const FieldDescriptor** output_field, int* output_index) { 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 +2484,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 +2575,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 +2603,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 +2612,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 +2627,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 +2637,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 +2650,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 +2688,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 +3498,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 +3574,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 +3657,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..b9110440f9dba 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -48,28 +48,29 @@ const std::string kDescriptorMetadataFile = const std::string kDescriptorDirName = "Google/Protobuf/Internal"; const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal"; 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", - "global", "goto", "if", "implements", "include", - "include_once", "instanceof", "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"}; + "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", + "global", "goto", "if", "implements", "include", + "include_once", "instanceof", "insteadof", "interface", "isset", + "list", "match", "namespace", "new", "or", + "parent", "print", "private", "protected", "public", + "require", "require_once", "return", "self", "static", + "switch", "throw", "trait", "try", "unset", + "use", "var", "while", "xor", "yield", + "int", "float", "bool", "string", "true", + "false", "null", "void", "iterable"}; const char* const kValidConstantNames[] = { "int", "float", "bool", "string", "true", - "false", "null", "void", "iterable", + "false", "null", "void", "iterable", "parent", + "self" }; -const int kReservedNamesSize = 77; -const int kValidConstantNamesSize = 9; +const int kReservedNamesSize = 79; +const int kValidConstantNamesSize = 11; const int kFieldSetter = 1; const int kFieldGetter = 2; const int kFieldProperty = 3; @@ -83,14 +84,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 +431,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 +742,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 +890,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", @@ -1114,7 +1115,7 @@ void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, std::map dependency_count; std::set nodes_without_dependency; FileDescriptorSet sorted_file_set; - + AnalyzeDependencyForFile( file, &nodes_without_dependency, &deps, &dependency_count); @@ -1869,44 +1870,45 @@ void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) { "\n" "PHP_METHOD($c_name$, name) {\n" " $file_c_name$_AddDescriptor();\n" - " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" - " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" - " const char *name;\n" + " const upb_DefPool *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n" " zend_long value;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"l\", &value) ==\n" " FAILURE) {\n" " return;\n" " }\n" - " name = upb_enumdef_iton(e, value);\n" - " if (!name) {\n" + " const upb_EnumValueDef* ev =\n" + " upb_EnumDef_FindValueByNumber(e, value);\n" + " if (!ev) {\n" " zend_throw_exception_ex(NULL, 0,\n" " \"$php_name$ has no name \"\n" " \"defined for value \" ZEND_LONG_FMT \".\",\n" " value);\n" " return;\n" " }\n" - " RETURN_STRING(name);\n" + " RETURN_STRING(upb_EnumValueDef_Name(ev));\n" "}\n" "\n" "PHP_METHOD($c_name$, value) {\n" " $file_c_name$_AddDescriptor();\n" - " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" - " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" + " const upb_DefPool *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n" " char *name = NULL;\n" " size_t name_len;\n" - " int32_t num;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"s\", &name,\n" " &name_len) == FAILURE) {\n" " return;\n" " }\n" - " if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n" + " const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize(\n" + " e, name, name_len);\n" + " if (!ev) {\n" " zend_throw_exception_ex(NULL, 0,\n" " \"$php_name$ has no value \"\n" " \"defined for name %s.\",\n" " name);\n" " return;\n" " }\n" - " RETURN_LONG(num);\n" + " RETURN_LONG(upb_EnumValueDef_Number(ev));\n" "}\n" "\n" "static zend_function_entry $c_name$_phpmethods[] = {\n" @@ -1965,8 +1967,8 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { printer->Print( "static PHP_METHOD($c_name$, get$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" - " \"$name$\");\n" + " const upb_FieldDef *f = upb_MessageDef_FindFieldByName(\n" + " intern->desc->msgdef, \"$name$\");\n" " zval ret;\n" " Message_get(intern, f, &ret);\n" " RETURN_COPY_VALUE(&ret);\n" @@ -1974,8 +1976,8 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { "\n" "static PHP_METHOD($c_name$, set$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" - " \"$name$\");\n" + " const upb_FieldDef *f = upb_MessageDef_FindFieldByName(\n" + " intern->desc->msgdef, \"$name$\");\n" " zval *val;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"z\", &val)\n" " == FAILURE) {\n" @@ -1995,10 +1997,11 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { printer->Print( "static PHP_METHOD($c_name$, get$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n" - " \"$name$\");\n" - " const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n" - " RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n" + " const upb_OneofDef *oneof = upb_MessageDef_FindOneofByName(\n" + " intern->desc->msgdef, \"$name$\");\n" + " const upb_FieldDef *field = \n" + " upb_Message_WhichOneof(intern->msg, oneof);\n" + " RETURN_STRING(field ? upb_FieldDef_Name(field) : \"\");\n" "}\n", "c_name", c_name, "name", oneof->name(), @@ -2065,7 +2068,7 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { break; default: break; - } + } printer->Print( " ZEND_FE_END\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..61a6700cfc746 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) - : suffix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) +PROTOBUF_CONSTEXPR Version::Version( + ::_pbi::ConstantInitialized) + : suffix_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , major_(0) , minor_(0) , patch_(0){} struct VersionDefaultTypeInternal { - constexpr VersionDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR VersionDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~VersionDefaultTypeInternal() {} union { Version _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT VersionDefaultTypeInternal _Version_default_instance_; -constexpr CodeGeneratorRequest::CodeGeneratorRequest( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 VersionDefaultTypeInternal _Version_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorRequest::CodeGeneratorRequest( + ::_pbi::ConstantInitialized) : file_to_generate_() , proto_file_() - , parameter_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , parameter_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , compiler_version_(nullptr){} struct CodeGeneratorRequestDefaultTypeInternal { - constexpr CodeGeneratorRequestDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorRequestDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorRequestDefaultTypeInternal() {} union { CodeGeneratorRequest _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; -constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File( - ::PROTOBUF_NAMESPACE_ID::internal::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) +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorResponse_File::CodeGeneratorResponse_File( + ::_pbi::ConstantInitialized) + : name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , insertion_point_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , content_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , generated_code_info_(nullptr){} struct CodeGeneratorResponse_FileDefaultTypeInternal { - constexpr CodeGeneratorResponse_FileDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorResponse_FileDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponse_FileDefaultTypeInternal() {} union { CodeGeneratorResponse_File _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; -constexpr CodeGeneratorResponse::CodeGeneratorResponse( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorResponse::CodeGeneratorResponse( + ::_pbi::ConstantInitialized) : file_() - , error_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , error_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , supported_features_(uint64_t{0u}){} struct CodeGeneratorResponseDefaultTypeInternal { - constexpr CodeGeneratorResponseDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorResponseDefaultTypeInternal() + : _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,21 +244,18 @@ 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()); + suffix_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_suffix()) { - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_suffix(), + suffix_.Set(from._internal_suffix(), GetArenaForAllocation()); } ::memcpy(&major_, &from.major_, @@ -262,9 +265,9 @@ 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()); + suffix_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING ::memset(reinterpret_cast(this) + static_cast( reinterpret_cast(&major_) - reinterpret_cast(this)), @@ -274,22 +277,18 @@ ::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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - suffix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + suffix_.Destroy(); } -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()); } } @@ -518,7 +517,6 @@ void Version::InternalSwap(Version* other) { _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &suffix_, lhs_arena, &other->suffix_, rhs_arena ); @@ -531,7 +529,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 +561,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,12 +569,12 @@ 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()); + parameter_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_parameter()) { - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_parameter(), + parameter_.Set(from._internal_parameter(), GetArenaForAllocation()); } if (from._internal_has_compiler_version()) { @@ -591,32 +586,28 @@ 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()); + parameter_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING 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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - parameter_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + parameter_.Destroy(); 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 +634,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 +648,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 +662,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 +744,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) @@ -873,7 +863,6 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { file_to_generate_.InternalSwap(&other->file_to_generate_); proto_file_.InternalSwap(&other->proto_file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ¶meter_, lhs_arena, &other->parameter_, rhs_arena ); @@ -881,7 +870,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,37 +907,34 @@ 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()); + name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_name()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + name_.Set(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()); + insertion_point_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_insertion_point()) { - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_insertion_point(), + insertion_point_.Set(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()); + content_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_content()) { - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_content(), + content_.Set(from._internal_content(), GetArenaForAllocation()); } if (from._internal_has_generated_code_info()) { @@ -960,42 +946,38 @@ 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()); + name_.Set("", 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()); + insertion_point_.Set("", 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()); + content_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING 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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - content_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.Destroy(); + insertion_point_.Destroy(); + content_.Destroy(); 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 +1008,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 +1031,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 +1043,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 +1122,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) @@ -1251,17 +1232,14 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &name_, lhs_arena, &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &insertion_point_, lhs_arena, &other->insertion_point_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &content_, lhs_arena, &other->content_, rhs_arena ); @@ -1269,7 +1247,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 +1270,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,12 +1277,12 @@ 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()); + error_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_error()) { - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_error(), + error_.Set(from._internal_error(), GetArenaForAllocation()); } supported_features_ = from.supported_features_; @@ -1315,31 +1290,27 @@ 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()); + error_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING 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() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - error_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + error_.Destroy(); } -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 +1331,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 +1416,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 +1461,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()); } } @@ -1549,7 +1520,6 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { swap(_has_bits_[0], other->_has_bits_[0]); file_.InternalSwap(&other->file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &error_, lhs_arena, &other->error_, rhs_arena ); @@ -1557,7 +1527,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 +1536,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 d558f5b7a3381..4da9a9aed4a3f 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3019000 +#if PROTOBUF_VERSION < 3020000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3019004 < PROTOBUF_MIN_PROTOC_VERSION +#if 3020000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -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; @@ -116,7 +107,7 @@ class PROTOC_EXPORT Version final : public: inline Version() : Version(nullptr) {} ~Version() override; - explicit constexpr Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Version(const Version& from); Version(Version&& from) noexcept @@ -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_; @@ -324,7 +312,7 @@ class PROTOC_EXPORT CodeGeneratorRequest final : public: inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {} ~CodeGeneratorRequest() override; - explicit constexpr CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorRequest(const CodeGeneratorRequest& from); CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept @@ -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_; @@ -553,7 +538,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : public: inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {} ~CodeGeneratorResponse_File() override; - explicit constexpr CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept @@ -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_; @@ -776,7 +758,7 @@ class PROTOC_EXPORT CodeGeneratorResponse final : public: inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {} ~CodeGeneratorResponse() override; - explicit constexpr CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse(const CodeGeneratorResponse& from); CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept @@ -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_; @@ -1114,7 +1093,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Version::set_suffix(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + suffix_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix) } inline std::string* Version::mutable_suffix() { @@ -1127,11 +1106,11 @@ inline const std::string& Version::_internal_suffix() const { } inline void Version::_internal_set_suffix(const std::string& value) { _has_bits_[0] |= 0x00000001u; - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + suffix_.Set(value, GetArenaForAllocation()); } inline std::string* Version::_internal_mutable_suffix() { _has_bits_[0] |= 0x00000001u; - return suffix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return suffix_.Mutable(GetArenaForAllocation()); } inline std::string* Version::release_suffix() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix) @@ -1139,10 +1118,10 @@ inline std::string* Version::release_suffix() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = suffix_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (suffix_.IsDefault()) { + suffix_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1153,11 +1132,10 @@ inline void Version::set_allocated_suffix(std::string* suffix) { } else { _has_bits_[0] &= ~0x00000001u; } - suffix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), suffix, - GetArenaForAllocation()); + suffix_.SetAllocated(suffix, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (suffix_.IsDefault()) { + suffix_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix) @@ -1262,7 +1240,7 @@ template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorRequest::set_parameter(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + parameter_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline std::string* CodeGeneratorRequest::mutable_parameter() { @@ -1275,11 +1253,11 @@ inline const std::string& CodeGeneratorRequest::_internal_parameter() const { } inline void CodeGeneratorRequest::_internal_set_parameter(const std::string& value) { _has_bits_[0] |= 0x00000001u; - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + parameter_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() { _has_bits_[0] |= 0x00000001u; - return parameter_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return parameter_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorRequest::release_parameter() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1287,10 +1265,10 @@ inline std::string* CodeGeneratorRequest::release_parameter() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = parameter_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (parameter_.IsDefault()) { + parameter_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1301,11 +1279,10 @@ inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter } else { _has_bits_[0] &= ~0x00000001u; } - parameter_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), parameter, - GetArenaForAllocation()); + parameter_.SetAllocated(parameter, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (parameter_.IsDefault()) { + parameter_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1425,7 +1402,7 @@ inline void CodeGeneratorRequest::set_allocated_compiler_version(::PROTOBUF_NAME } if (compiler_version) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::compiler::Version>::GetOwningArena(compiler_version); + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(compiler_version); if (message_arena != submessage_arena) { compiler_version = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, compiler_version, submessage_arena); @@ -1462,7 +1439,7 @@ template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_name(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline std::string* CodeGeneratorResponse_File::mutable_name() { @@ -1475,11 +1452,11 @@ inline const std::string& CodeGeneratorResponse_File::_internal_name() const { } inline void CodeGeneratorResponse_File::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + name_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return name_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1487,10 +1464,10 @@ inline std::string* CodeGeneratorResponse_File::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = name_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (name_.IsDefault()) { + name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1501,11 +1478,10 @@ inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) { } else { _has_bits_[0] &= ~0x00000001u; } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (name_.IsDefault()) { + name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1531,7 +1507,7 @@ template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_insertion_point(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + insertion_point_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() { @@ -1544,11 +1520,11 @@ inline const std::string& CodeGeneratorResponse_File::_internal_insertion_point( } inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const std::string& value) { _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + insertion_point_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_point() { _has_bits_[0] |= 0x00000002u; - return insertion_point_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return insertion_point_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::release_insertion_point() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1556,10 +1532,10 @@ inline std::string* CodeGeneratorResponse_File::release_insertion_point() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - auto* p = insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = insertion_point_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (insertion_point_.IsDefault()) { + insertion_point_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1570,11 +1546,10 @@ inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::strin } else { _has_bits_[0] &= ~0x00000002u; } - insertion_point_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), insertion_point, - GetArenaForAllocation()); + insertion_point_.SetAllocated(insertion_point, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (insertion_point_.IsDefault()) { + insertion_point_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1600,7 +1575,7 @@ template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_content(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000004u; - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + content_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline std::string* CodeGeneratorResponse_File::mutable_content() { @@ -1613,11 +1588,11 @@ inline const std::string& CodeGeneratorResponse_File::_internal_content() const } inline void CodeGeneratorResponse_File::_internal_set_content(const std::string& value) { _has_bits_[0] |= 0x00000004u; - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + content_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() { _has_bits_[0] |= 0x00000004u; - return content_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return content_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::release_content() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1625,10 +1600,10 @@ inline std::string* CodeGeneratorResponse_File::release_content() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - auto* p = content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = content_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (content_.IsDefault()) { + content_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1639,11 +1614,10 @@ inline void CodeGeneratorResponse_File::set_allocated_content(std::string* conte } else { _has_bits_[0] &= ~0x00000004u; } - content_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), content, - GetArenaForAllocation()); + content_.SetAllocated(content, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (content_.IsDefault()) { + content_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1722,8 +1696,7 @@ inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(::PROT } if (generated_code_info) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< - ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena( reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info)); if (message_arena != submessage_arena) { generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( @@ -1761,7 +1734,7 @@ template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse::set_error(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + error_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error) } inline std::string* CodeGeneratorResponse::mutable_error() { @@ -1774,11 +1747,11 @@ inline const std::string& CodeGeneratorResponse::_internal_error() const { } inline void CodeGeneratorResponse::_internal_set_error(const std::string& value) { _has_bits_[0] |= 0x00000001u; - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + error_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse::_internal_mutable_error() { _has_bits_[0] |= 0x00000001u; - return error_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return error_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse::release_error() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error) @@ -1786,10 +1759,10 @@ inline std::string* CodeGeneratorResponse::release_error() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = error_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (error_.IsDefault()) { + error_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1800,11 +1773,10 @@ inline void CodeGeneratorResponse::set_allocated_error(std::string* error) { } else { _has_bits_[0] &= ~0x00000001u; } - error_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error, - GetArenaForAllocation()); + error_.SetAllocated(error, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (error_.IsDefault()) { + error_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error) diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index 9ad7a33b2e710..8f70925a70e2b 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -54,13 +54,15 @@ #include #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)); - } - } -} - -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()); + PrintEnum(*descriptor.enum_type(i)); } - 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)); } } @@ -1463,7 +1284,7 @@ void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { if (value_options != "None") { PrintDescriptorOptionsFixingCode( StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), - value_descriptor.name().c_str()), + value_descriptor.name().c_str()), value_options, printer_); } } 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_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index 46e60f587474c..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'"; } 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..46d98a141b67f 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; @@ -73,15 +73,15 @@ static void CloseHandleOrDie(HANDLE handle) { Subprocess::Subprocess() : process_start_error_(ERROR_SUCCESS), - child_handle_(NULL), - child_stdin_(NULL), - child_stdout_(NULL) {} + child_handle_(nullptr), + child_stdin_(nullptr), + child_stdout_(nullptr) {} Subprocess::~Subprocess() { - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { CloseHandleOrDie(child_stdin_); } - if (child_stdout_ != NULL) { + if (child_stdout_ != nullptr) { CloseHandleOrDie(child_stdout_); } } @@ -93,10 +93,10 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { HANDLE stdout_pipe_read; HANDLE stdout_pipe_write; - if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) { + if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, nullptr, 0)) { GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); } - if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) { + if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, nullptr, 0)) { GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); } @@ -134,14 +134,14 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { // Create the process. PROCESS_INFORMATION process_info; - if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(), - (search_mode == SEARCH_PATH) ? command_line : NULL, - NULL, // process security attributes - NULL, // thread security attributes - TRUE, // inherit handles? - 0, // obscure creation flags - NULL, // environment (inherit from parent) - NULL, // current directory (inherit from parent) + if (CreateProcessA((search_mode == SEARCH_PATH) ? nullptr : program.c_str(), + (search_mode == SEARCH_PATH) ? command_line : nullptr, + nullptr, // process security attributes + nullptr, // thread security attributes + TRUE, // inherit handles? + 0, // obscure creation flags + nullptr, // environment (inherit from parent) + nullptr, // current directory (inherit from parent) &startup_info, &process_info)) { child_handle_ = process_info.hProcess; CloseHandleOrDie(process_info.hThread); @@ -165,28 +165,28 @@ bool Subprocess::Communicate(const Message& input, Message* output, return false; } - GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first."; + GOOGLE_CHECK(child_handle_ != nullptr) << "Must call Start() first."; std::string input_data = input.SerializeAsString(); std::string output_data; int input_pos = 0; - while (child_stdout_ != NULL) { + while (child_stdout_ != nullptr) { HANDLE handles[2]; int handle_count = 0; - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { handles[handle_count++] = child_stdin_; } - if (child_stdout_ != NULL) { + if (child_stdout_ != nullptr) { handles[handle_count++] = child_stdout_; } DWORD wait_result = WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE); - HANDLE signaled_handle = NULL; + HANDLE signaled_handle = nullptr; if (wait_result >= WAIT_OBJECT_0 && wait_result < WAIT_OBJECT_0 + handle_count) { signaled_handle = handles[wait_result - WAIT_OBJECT_0]; @@ -201,7 +201,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, if (signaled_handle == child_stdin_) { DWORD n; if (!WriteFile(child_stdin_, input_data.data() + input_pos, - input_data.size() - input_pos, &n, NULL)) { + input_data.size() - input_pos, &n, nullptr)) { // Child closed pipe. Presumably it will report an error later. // Pretend we're done for now. input_pos = input_data.size(); @@ -212,27 +212,27 @@ bool Subprocess::Communicate(const Message& input, Message* output, if (input_pos == input_data.size()) { // We're done writing. Close. CloseHandleOrDie(child_stdin_); - child_stdin_ = NULL; + child_stdin_ = nullptr; } } else if (signaled_handle == child_stdout_) { char buffer[4096]; DWORD n; - if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) { + if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, nullptr)) { // We're done reading. Close. CloseHandleOrDie(child_stdout_); - child_stdout_ = NULL; + child_stdout_ = nullptr; } else { output_data.append(buffer, n); } } } - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { // Child did not finish reading input before it closed the output. // Presumably it exited with an error. CloseHandleOrDie(child_stdin_); - child_stdin_ = NULL; + child_stdin_ = nullptr; } DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE); @@ -252,7 +252,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, } CloseHandleOrDie(child_handle_); - child_handle_ = NULL; + child_handle_ = nullptr; if (exit_code != 0) { *error = strings::Substitute("Plugin failed with status code $0.", exit_code); @@ -273,9 +273,10 @@ std::string Subprocess::Win32ErrorMessage(DWORD error_code) { // WTF? FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error_code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + nullptr, error_code, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPSTR)&message, // NOT A BUG! - 0, NULL); + 0, nullptr); std::string result = message; LocalFree(message); @@ -309,7 +310,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 +387,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..0524fd46226e6 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -42,29 +42,30 @@ #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 #include #include -#include -#include -#include -#include #include #include #include @@ -72,11 +73,493 @@ #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) {} + +template +constexpr size_t RoundUpTo(size_t n) { + static_assert((R & (R - 1)) == 0, "Must be power of two"); + return (n + (R - 1)) & ~(R - 1); +} + +constexpr size_t Max(size_t a, size_t b) { return a > b ? a : b; } +template +constexpr size_t Max(T a, Ts... b) { + return Max(a, Max(b...)); +} + +template +constexpr size_t EffectiveAlignof() { + // `char` is special in that it gets aligned to 8. It is where we drop the + // trivial structs. + return std::is_same::value ? 8 : alignof(T); +} + +template +using AppendIfAlign = + typename std::conditional() == align, void (*)(T..., U), + void (*)(T...)>::type; + +// Metafunction to sort types in descending order of alignment. +// Useful for the flat allocator to ensure proper alignment of all elements +// without having to add padding. +// Instead of implementing a proper sort metafunction we just do a +// filter+merge, which is much simpler to write as a metafunction. +// We have a fixed set of alignments we can filter on. +// For simplicity we use a function pointer as a type list. +template +struct TypeListSortImpl; + +template +struct TypeListSortImpl { + using type = void (*)(T16..., T8..., T4..., T2..., T1...); +}; + +template +struct TypeListSortImpl { + using type = typename TypeListSortImpl< + void (*)(Rest...), AppendIfAlign<16, First, T16...>, + AppendIfAlign<8, First, T8...>, AppendIfAlign<4, First, T4...>, + AppendIfAlign<2, First, T2...>, AppendIfAlign<1, First, T1...>>::type; +}; + +template +using SortByAlignment = + typename TypeListSortImpl::type; + +template