diff --git a/BUILD b/BUILD index 92e4091db3a0..1124321602b5 100644 --- a/BUILD +++ b/BUILD @@ -164,6 +164,7 @@ cc_library( # AUTOGEN(protobuf_lite_srcs) "src/google/protobuf/any_lite.cc", "src/google/protobuf/arena.cc", + "src/google/protobuf/arenastring.cc", "src/google/protobuf/extension_set.cc", "src/google/protobuf/generated_enum_util.cc", "src/google/protobuf/generated_message_table_driven_lite.cc", diff --git a/CHANGES.txt b/CHANGES.txt index 511d84e88258..da3e51bc534d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,12 +1,15 @@ -Unreleased Changes +2020-11-11 version 3.14.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) Protocol Compiler * The proto compiler no longer requires a .proto filename when it is not generating code. + * Added flag `--deterministic_output` to `protoc --encode=...`. + * Fixed deadlock when using google.protobuf.Any embedded in aggregate options. C++ * Arenas are now unconditionally enabled. cc_enable_arenas no longer has any effect. + * Removed inlined string support, which is incompatible with arenas. * Fix a memory corruption bug in reflection when mixing optional and non-optional fields. * Make SpaceUsed() calculation more thorough for map fields. @@ -20,18 +23,55 @@ Unreleased Changes * When running under ASAN, skip a test that makes huge allocations. * Fixed a crash that could happen when creating more than 256 extensions in a single message. + * Fix a crash in BuildFile when passing in invalid descriptor proto. + * Parser security fix when operating with CodedInputStream. + * Warn against the use of AllowUnknownExtension. + * Migrated to C++11 for-range loops instead of index-based loops where + possible. This fixes a lot of warnings when compiling with -Wsign-compare. + * Fix segment fault for proto3 optional (#7805) + * Adds a CMake option to build `libprotoc` separately (#7949) Java * Bugfix in mergeFrom() when a oneof has multiple message fields. + * Fix RopeByteString.RopeInputStream.read() returning -1 when told to read + 0 bytes when not at EOF. + * Redefine remove(Object) on primitive repeated field Lists to avoid + autoboxing. + * Support "\u" escapes in textformat string literals. + * Trailing empty spaces are no longer ignored for FieldMask. + * Fix FieldMaskUtil.subtract to recursively remove mask. + * Mark enums with `@java.lang.Deprecated` if the proto enum has option + `deprecated = true;`. + * Adding forgotten duration.proto to the lite library (#7738) Python * Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is used outside WKT Value/Struct. * Fix bug occurring when attempting to deep copy an enum type in python 3. + * Add a setuptools extension for generating Python protobufs (#7783) + * Remove uses of pkg_resources in non-namespace packages. (#7902) + * [bazel/py] Omit google/__init__.py from the Protobuf runtime. (#7908) + * Removed the unnecessary setuptools package dependency for Python package (#7511) + * Fix PyUnknownFields memory leak (#7928) + + PHP + * Added support for "==" to the PHP C extension (#7883) + * Added `==` operators for Map and Array. (#7900) + * Native C well-known types (#7944) + * Optimized away hex2bin() call in generated code (#8006) + * New version of upb, and a new hash function wyhash in third_party. (#8000) + * add missing hasOneof method to check presence of oneof fields (#8003) Go: * Update go_package options to reference google.golang.org/protobuf module. + C#: + * annotate ByteString.CopyFrom(ReadOnlySpan) as SecuritySafeCritical (#7701) + * Fix C# optional field reflection when there are regular fields too (#7705) + * Fix parsing negative Int32Value that crosses segment boundary (#8035) + + Javascript: + * JS: parse (un)packed fields conditionally (#7379) 2020-07-14 version 3.13.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) diff --git a/Protobuf.podspec b/Protobuf.podspec index 22e7ce3003a3..7a7363aaf0fa 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -5,7 +5,7 @@ # dependent projects use the :git notation to refer to the library. Pod::Spec.new do |s| s.name = 'Protobuf' - s.version = '3.13.0' + s.version = '3.14.0' s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.' s.homepage = 'https://github.com/protocolbuffers/protobuf' s.license = '3-Clause BSD License' @@ -34,7 +34,7 @@ Pod::Spec.new do |s| s.user_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' } s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' } - s.ios.deployment_target = '7.0' + s.ios.deployment_target = '9.0' s.osx.deployment_target = '10.9' s.tvos.deployment_target = '9.0' s.watchos.deployment_target = '2.0' diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 65364116a765..52661f522d99 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -44,6 +44,7 @@ option(protobuf_BUILD_TESTS "Build tests" ON) option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF) option(protobuf_BUILD_EXAMPLES "Build examples" OFF) option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON) +option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF) if (BUILD_SHARED_LIBS) set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON) else (BUILD_SHARED_LIBS) @@ -64,8 +65,6 @@ include(protobuf-options.cmake) # Overrides for option dependencies if (protobuf_BUILD_PROTOC_BINARIES OR protobuf_BUILD_TESTS) set(protobuf_BUILD_LIBPROTOC ON) -else() - set(protobuf_BUILD_LIBPROTOC OFF) endif () # Path to main configure script set(protobuf_CONFIGURE_SCRIPT "../configure.ac") diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index f8fc0e9813e3..5c5799efa1e8 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -87,7 +87,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" i copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h diff --git a/cmake/install.cmake b/cmake/install.cmake index be47c54a1e21..4091bc8af986 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -6,9 +6,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/protobuf-lite.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc @ONLY) set(_protobuf_libraries libprotobuf-lite libprotobuf) -if (protobuf_BUILD_PROTOC_BINARIES) +if (protobuf_BUILD_LIBPROTOC) list(APPEND _protobuf_libraries libprotoc) -endif (protobuf_BUILD_PROTOC_BINARIES) +endif (protobuf_BUILD_LIBPROTOC) foreach(_library ${_protobuf_libraries}) set_property(TARGET ${_library} diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index 75d8d71ce97a..6d325d5dcad4 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -69,6 +69,9 @@ target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT}) if(protobuf_LINK_LIBATOMIC) target_link_libraries(libprotobuf-lite atomic) endif() +if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + target_link_libraries(libprotobuf-lite log) +endif() target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src) if(MSVC AND protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf-lite diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index d7d077067aa3..a5be494fb702 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -2,7 +2,6 @@ set(libprotobuf_files ${protobuf_source_dir}/src/google/protobuf/any.cc ${protobuf_source_dir}/src/google/protobuf/any.pb.cc ${protobuf_source_dir}/src/google/protobuf/api.pb.cc - ${protobuf_source_dir}/src/google/protobuf/arenastring.cc ${protobuf_source_dir}/src/google/protobuf/compiler/importer.cc ${protobuf_source_dir}/src/google/protobuf/compiler/parser.cc ${protobuf_source_dir}/src/google/protobuf/descriptor.cc @@ -122,6 +121,9 @@ endif() if(protobuf_LINK_LIBATOMIC) target_link_libraries(libprotobuf atomic) endif() +if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + target_link_libraries(libprotobuf log) +endif() target_include_directories(libprotobuf PUBLIC ${protobuf_source_dir}/src) if(MSVC AND protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in index 74c5488729a1..810256e54cfb 100644 --- a/cmake/protobuf-module.cmake.in +++ b/cmake/protobuf-module.cmake.in @@ -97,6 +97,10 @@ function(_protobuf_find_libraries name filename) else() get_target_property(${name}_LIBRARY_RELEASE protobuf::lib${filename} LOCATION_RELEASE) + get_target_property(${name}_LIBRARY_RELWITHDEBINFO protobuf::lib${filename} + LOCATION_RELWITHDEBINFO) + get_target_property(${name}_LIBRARY_MINSIZEREL protobuf::lib${filename} + LOCATION_MINSIZEREL) get_target_property(${name}_LIBRARY_DEBUG protobuf::lib${filename} LOCATION_DEBUG) @@ -146,6 +150,14 @@ get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf # Set the protoc Executable get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc IMPORTED_LOCATION_RELEASE) +if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_RELWITHDEBINFO) +endif() +if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_MINSIZEREL) +endif() if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc IMPORTED_LOCATION_DEBUG) diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 6815c733a522..5b82a4241e69 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -333,7 +333,7 @@ conformance-php-c: # Targets for actually running tests. test_cpp: protoc_middleman conformance-test-runner conformance-cpp - ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt ./conformance-cpp + ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt --text_format_failure_list text_format_failure_list_cpp.txt ./conformance-cpp test_java: protoc_middleman conformance-test-runner conformance-java ./conformance-test-runner --enforce_recommended --failure_list failure_list_java.txt --text_format_failure_list text_format_failure_list_java.txt ./conformance-java @@ -359,10 +359,24 @@ test_php_c_32: protoc_middleman conformance-test-runner conformance-php-c $(othe # These depend on library paths being properly set up. The easiest way to # run them is to just use "tox" from the python dir. test_python: protoc_middleman conformance-test-runner - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py + VERSION="$(shell python --version 2>&1)"; \ + if [[ "$$VERSION" == "Python 2.7"* ]]; then \ + echo "Using Python 2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python_2.7.txt ./conformance_python.py; \ + else \ + echo "Using Python >2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py; \ + fi test_python_cpp: protoc_middleman conformance-test-runner - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py + VERSION="$(shell python --version 2>&1)"; \ + if [[ "$$VERSION" == "Python 2.7"* ]]; then \ + echo "Using Python 2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp_2.7.txt ./conformance_python.py; \ + else \ + echo "Using Python >2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py; \ + fi test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc index 1cdfdae45736..9546518bf553 100644 --- a/conformance/conformance_cpp.cc +++ b/conformance/conformance_cpp.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include "conformance.pb.h" #include #include @@ -125,9 +126,9 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) { options.ignore_unknown_fields = (request.test_category() == conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST); - Status status = JsonToBinaryString(type_resolver, *type_url, - request.json_payload(), &proto_binary, - options); + util::Status status = + JsonToBinaryString(type_resolver, *type_url, request.json_payload(), + &proto_binary, options); if (!status.ok()) { response->set_parse_error(string("Parse error: ") + std::string(status.error_message())); @@ -179,8 +180,9 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) { case conformance::JSON: { string proto_binary; GOOGLE_CHECK(test_message->SerializeToString(&proto_binary)); - Status status = BinaryToJsonString(type_resolver, *type_url, proto_binary, - response->mutable_json_payload()); + util::Status status = + BinaryToJsonString(type_resolver, *type_url, proto_binary, + response->mutable_json_payload()); if (!status.ok()) { response->set_serialize_error( string("Failed to serialize JSON output: ") + diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt index 2fc03dee730f..63c7e8a024cc 100644 --- a/conformance/failure_list_php_c.txt +++ b/conformance/failure_list_php_c.txt @@ -1,4 +1,2 @@ Recommended.Proto2.JsonInput.FieldNameExtension.Validator -Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator -Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator diff --git a/conformance/failure_list_php_c_32.txt b/conformance/failure_list_php_c_32.txt deleted file mode 100644 index 2fc03dee730f..000000000000 --- a/conformance/failure_list_php_c_32.txt +++ /dev/null @@ -1,4 +0,0 @@ -Recommended.Proto2.JsonInput.FieldNameExtension.Validator -Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator -Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator -Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index 78462c4763ca..4c9dc7dbe051 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -259,8 +259,7 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { "optional_float: 18446744073709551616"); // String literals x {Strings, Bytes} - for (const auto& field_type : - std::vector{"String", "Bytes"}) { + for (const auto& field_type : std::vector{"String", "Bytes"}) { const std::string field_name = field_type == "String" ? "optional_string" : "optional_bytes"; RunValidTextFormatTest( diff --git a/conformance/text_format_failure_list_python_2.7.txt b/conformance/text_format_failure_list_python_2.7.txt new file mode 100644 index 000000000000..cada2bc03b2e --- /dev/null +++ b/conformance/text_format_failure_list_python_2.7.txt @@ -0,0 +1,36 @@ +# This is the list of text format conformance tests that are known to fail right +# now. +# TODO: These should be fixed. +Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput +Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput + +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString diff --git a/conformance/text_format_failure_list_python_cpp_2.7.txt b/conformance/text_format_failure_list_python_cpp_2.7.txt new file mode 100644 index 000000000000..ba2089bcaad3 --- /dev/null +++ b/conformance/text_format_failure_list_python_cpp_2.7.txt @@ -0,0 +1,30 @@ +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 019f054472e8..0fb4b15093bd 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -5,7 +5,7 @@ Google Protocol Buffers tools Tools for Protocol Buffers - Google's data interchange format. See project site for more info. - 3.13.0 + 3.14.0 Google Inc. protobuf-packages https://github.com/protocolbuffers/protobuf/blob/master/LICENSE diff --git a/php/ext/google/protobuf/bundled_php.h b/csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs similarity index 57% rename from php/ext/google/protobuf/bundled_php.h rename to csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs index 76147677a177..a755850a66e1 100644 --- a/php/ext/google/protobuf/bundled_php.h +++ b/csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs @@ -1,6 +1,7 @@ +#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/ +// Copyright 2019 Google Inc. All rights reserved. +// https://github.com/protocolbuffers/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -27,20 +28,45 @@ // 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 -#ifndef PHP_PROTOBUF_BUNDLED_PHP_H_ -#define PHP_PROTOBUF_BUNDLED_PHP_H_ +using BenchmarkDotNet.Attributes; -// We embed PHP source code into the binary for things we don't want to -// implement in C. This struct serves as a table of contents for all of -// the embedded files. -typedef struct { - const char *filename; - const char *contents; -} BundledPhp_File; +namespace Google.Protobuf.Benchmarks +{ + /// + /// Benchmarks using ByteString. + /// + [MemoryDiagnoser] + public class ByteStringBenchmark + { + private const int Zero = 0; + private const int Kilobyte = 1024; + private const int _128Kilobytes = 1024 * 128; + private const int Megabyte = 1024 * 1024; + private const int _10Megabytes = 1024 * 1024 * 10; -// An array of all the embedded file structs. This array is terminated with a -// {NULL, NULL} entry. -extern BundledPhp_File *bundled_files; + byte[] byteBuffer; -#endif // PHP_PROTOBUF_BUNDLED_PHP_H_ + [GlobalSetup] + public void GlobalSetup() + { + byteBuffer = new byte[PayloadSize]; + } + + [Params(Zero, Kilobyte, _128Kilobytes, Megabyte, _10Megabytes)] + public int PayloadSize { get; set; } + + [Benchmark] + public ByteString CopyFrom() + { + return ByteString.CopyFrom(byteBuffer); + } + + [Benchmark] + public ByteString UnsafeWrap() + { + return UnsafeByteOperations.UnsafeWrap(byteBuffer); + } + } +} diff --git a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs index 0ef8d8f4e798..d9f607448d9c 100644 --- a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs +++ b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs @@ -34,6 +34,13 @@ using System.Text; using NUnit.Framework; using System.IO; +using System.Collections.Generic; +using System.Collections; +using System.Linq; +using System.Buffers; +using System.Runtime.InteropServices; +using System.Threading; +using System.Runtime.CompilerServices; #if !NET35 using System.Threading.Tasks; #endif @@ -54,6 +61,7 @@ public void Equality() EqualityTester.AssertInequality(b1, b3); EqualityTester.AssertInequality(b1, b4); EqualityTester.AssertInequality(b1, null); + EqualityTester.AssertEquality(ByteString.Empty, ByteString.Empty); #pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1) Assert.IsTrue(b1 == b1); Assert.IsTrue(b1 == b2); @@ -63,6 +71,7 @@ public void Equality() Assert.IsTrue((ByteString) null == null); Assert.IsFalse(b1 != b1); Assert.IsFalse(b1 != b2); + Assert.IsTrue(ByteString.Empty == ByteString.Empty); #pragma warning disable 1718 Assert.IsTrue(b1 != b3); Assert.IsTrue(b1 != b4); @@ -110,6 +119,18 @@ public void CopyFromByteArrayCopiesContents() Assert.AreEqual(10, bs[0]); } + [Test] + public void CopyFromReadOnlySpanCopiesContents() + { + byte[] data = new byte[1]; + data[0] = 10; + ReadOnlySpan byteSpan = data; + var bs = ByteString.CopyFrom(byteSpan); + Assert.AreEqual(10, bs[0]); + data[0] = 5; + Assert.AreEqual(10, bs[0]); + } + [Test] public void ToByteArrayCopiesContents() { @@ -142,6 +163,84 @@ public void CopyFromPortion() Assert.AreEqual(3, bs[1]); } + [Test] + public void CopyTo() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = ByteString.CopyFrom(data); + + byte[] dest = new byte[data.Length]; + bs.CopyTo(dest, 0); + + CollectionAssert.AreEqual(data, dest); + } + + [Test] + public void GetEnumerator() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = ByteString.CopyFrom(data); + + IEnumerator genericEnumerator = bs.GetEnumerator(); + Assert.IsTrue(genericEnumerator.MoveNext()); + Assert.AreEqual(0, genericEnumerator.Current); + + IEnumerator enumerator = ((IEnumerable)bs).GetEnumerator(); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(0, enumerator.Current); + + // Call via LINQ + CollectionAssert.AreEqual(bs.Span.ToArray(), bs.ToArray()); + } + + [Test] + public void UnsafeWrap() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3)); + ReadOnlySpan s = bs.Span; + + Assert.AreEqual(3, s.Length); + Assert.AreEqual(2, s[0]); + Assert.AreEqual(3, s[1]); + Assert.AreEqual(4, s[2]); + + // Check that the value is not a copy + data[2] = byte.MaxValue; + Assert.AreEqual(byte.MaxValue, s[0]); + } + + [Test] + public void WriteToStream() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = ByteString.CopyFrom(data); + + MemoryStream ms = new MemoryStream(); + bs.WriteTo(ms); + + CollectionAssert.AreEqual(data, ms.ToArray()); + } + + [Test] + public void WriteToStream_Stackalloc() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world"); + Span s = stackalloc byte[data.Length]; + data.CopyTo(s); + + MemoryStream ms = new MemoryStream(); + + using (UnmanagedMemoryManager manager = new UnmanagedMemoryManager(s)) + { + ByteString bs = ByteString.AttachBytes(manager.Memory); + + bs.WriteTo(ms); + } + + CollectionAssert.AreEqual(data, ms.ToArray()); + } + [Test] public void ToStringUtf8() { @@ -156,6 +255,21 @@ public void ToStringWithExplicitEncoding() Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode)); } + [Test] + public void ToString_Stackalloc() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world"); + Span s = stackalloc byte[data.Length]; + data.CopyTo(s); + + using (UnmanagedMemoryManager manager = new UnmanagedMemoryManager(s)) + { + ByteString bs = ByteString.AttachBytes(manager.Memory); + + Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8)); + } + } + [Test] public void FromBase64_WithText() { @@ -172,6 +286,29 @@ public void FromBase64_Empty() Assert.AreSame(ByteString.Empty, ByteString.FromBase64("")); } + [Test] + public void ToBase64_Array() + { + ByteString bs = ByteString.CopyFrom(Encoding.UTF8.GetBytes("Hello world")); + + Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); + } + + [Test] + public void ToBase64_Stackalloc() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world"); + Span s = stackalloc byte[data.Length]; + data.CopyTo(s); + + using (UnmanagedMemoryManager manager = new UnmanagedMemoryManager(s)) + { + ByteString bs = ByteString.AttachBytes(manager.Memory); + + Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); + } + } + [Test] public void FromStream_Seekable() { @@ -249,5 +386,38 @@ public void GetContentsAsReadOnlyMemory() var copied = byteString.Memory.ToArray(); CollectionAssert.AreEqual(byteString, copied); } + + // Create Memory from non-array source. + // Use by ByteString tests that have optimized path for array backed Memory. + private sealed unsafe class UnmanagedMemoryManager : MemoryManager where T : unmanaged + { + private readonly T* _pointer; + private readonly int _length; + + public UnmanagedMemoryManager(Span span) + { + fixed (T* ptr = &MemoryMarshal.GetReference(span)) + { + _pointer = ptr; + _length = span.Length; + } + } + + public override Span GetSpan() => new Span(_pointer, _length); + + public override MemoryHandle Pin(int elementIndex = 0) + { + if (elementIndex < 0 || elementIndex >= _length) + { + throw new ArgumentOutOfRangeException(nameof(elementIndex)); + } + + return new MemoryHandle(_pointer + elementIndex); + } + + public override void Unpin() { } + + protected override void Dispose(bool disposing) { } + } } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs index 1fb3bb503908..0ad286f3787f 100644 --- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs +++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs @@ -343,6 +343,25 @@ public void ReadWholeMessage_VaryingBlockSizes_FromSequence() } } + [Test] + public void ReadInt32Wrapper_VariableBlockSizes() + { + byte[] rawBytes = new byte[] { 202, 1, 11, 8, 254, 255, 255, 255, 255, 255, 255, 255, 255, 1 }; + + for (int blockSize = 1; blockSize <= rawBytes.Length; blockSize++) + { + ReadOnlySequence data = ReadOnlySequenceFactory.CreateWithContent(rawBytes, blockSize); + AssertReadFromParseContext(data, (ref ParseContext ctx) => + { + ctx.ReadTag(); + + var value = ParsingPrimitivesWrappers.ReadInt32Wrapper(ref ctx); + + Assert.AreEqual(-2, value); + }, true); + } + } + [Test] public void ReadHugeBlob() { diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj index 1a7953d6b786..89fe5d4febbc 100644 --- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj +++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj @@ -6,6 +6,7 @@ true true False + True diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs index 94c4746a80dc..5b0e5e8fc1cb 100644 --- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs +++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs @@ -87,6 +87,28 @@ public void NonDefaultSingleValues() }); } + [Test] + public void NegativeSingleValues() + { + var message = new TestWellKnownTypes + { + FloatField = -12.5f, + DoubleField = -12.25d, + Int32Field = -1, + Int64Field = -2 + }; + + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed => + { + Assert.AreEqual(-12.5f, parsed.FloatField); + Assert.AreEqual(-12.25d, parsed.DoubleField); + Assert.AreEqual(-1, parsed.Int32Field); + Assert.AreEqual(-2L, parsed.Int64Field); + }); + } + [Test] public void NonNullDefaultIsPreservedThroughSerialization() { diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs index 2a52ae58be5b..7828658672fe 100644 --- a/csharp/src/Google.Protobuf/ByteString.cs +++ b/csharp/src/Google.Protobuf/ByteString.cs @@ -34,6 +34,7 @@ using System.Collections; using System.Collections.Generic; using System.IO; +using System.Runtime.InteropServices; using System.Security; using System.Text; #if !NET35 @@ -49,40 +50,36 @@ namespace Google.Protobuf /// /// Immutable array of bytes. /// + [SecuritySafeCritical] public sealed class ByteString : IEnumerable, IEquatable { private static readonly ByteString empty = new ByteString(new byte[0]); - private readonly byte[] bytes; + private readonly ReadOnlyMemory bytes; /// - /// Unsafe operations that can cause IO Failure and/or other catastrophic side-effects. + /// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. /// - internal static class Unsafe + internal static ByteString AttachBytes(ReadOnlyMemory bytes) { - /// - /// Constructs a new ByteString from the given byte array. The array is - /// *not* copied, and must not be modified after this constructor is called. - /// - internal static ByteString FromBytes(byte[] bytes) - { - return new ByteString(bytes); - } + return new ByteString(bytes); } /// - /// Internal use only. Ensure that the provided array is not mutated and belongs to this instance. + /// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. + /// This method encapsulates converting array to memory. Reduces need for SecuritySafeCritical + /// in .NET Framework. /// internal static ByteString AttachBytes(byte[] bytes) { - return new ByteString(bytes); + return AttachBytes(bytes.AsMemory()); } /// - /// Constructs a new ByteString from the given byte array. The array is + /// Constructs a new ByteString from the given memory. The memory is /// *not* copied, and must not be modified after this constructor is called. /// - private ByteString(byte[] bytes) + private ByteString(ReadOnlyMemory bytes) { this.bytes = bytes; } @@ -111,18 +108,13 @@ public bool IsEmpty get { return Length == 0; } } -#if GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY /// /// Provides read-only access to the data of this . /// No data is copied so this is the most efficient way of accessing. /// public ReadOnlySpan Span { - [SecuritySafeCritical] - get - { - return new ReadOnlySpan(bytes); - } + get { return bytes.Span; } } /// @@ -131,13 +123,8 @@ public ReadOnlySpan Span /// public ReadOnlyMemory Memory { - [SecuritySafeCritical] - get - { - return new ReadOnlyMemory(bytes); - } + get { return bytes; } } -#endif /// /// Converts this into a byte array. @@ -146,7 +133,7 @@ public ReadOnlyMemory Memory /// A byte array with the same data as this ByteString. public byte[] ToByteArray() { - return (byte[]) bytes.Clone(); + return bytes.ToArray(); } /// @@ -155,7 +142,16 @@ public byte[] ToByteArray() /// A base64 representation of this ByteString. public string ToBase64() { - return Convert.ToBase64String(bytes); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment)) + { + // Fast path. ByteString was created with an array, so pass the underlying array. + return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count); + } + else + { + // Slow path. BytesString is not an array. Convert memory and pass result to ToBase64String. + return Convert.ToBase64String(bytes.ToArray()); + } } /// @@ -199,21 +195,10 @@ public static ByteString FromStream(Stream stream) /// The stream to copy into a ByteString. /// The cancellation token to use when reading from the stream, if any. /// A ByteString with content read from the given stream. - public async static Task FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) + public static Task FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { ProtoPreconditions.CheckNotNull(stream, nameof(stream)); - int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0; - var memoryStream = new MemoryStream(capacity); - // We have to specify the buffer size here, as there's no overload accepting the cancellation token - // alone. But it's documented to use 81920 by default if not specified. - await stream.CopyToAsync(memoryStream, 81920, cancellationToken); -#if NETSTANDARD1_1 || NETSTANDARD2_0 - byte[] bytes = memoryStream.ToArray(); -#else - // Avoid an extra copy if we can. - byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray(); -#endif - return AttachBytes(bytes); + return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken); } #endif @@ -239,7 +224,6 @@ public static ByteString CopyFrom(byte[] bytes, int offset, int count) return new ByteString(portion); } -#if GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY /// /// Constructs a from a read only span. The contents /// are copied, so further modifications to the span will not @@ -249,7 +233,6 @@ public static ByteString CopyFrom(ReadOnlySpan bytes) { return new ByteString(bytes.ToArray()); } -#endif /// /// Creates a new by encoding the specified text with @@ -273,7 +256,7 @@ public static ByteString CopyFromUtf8(string text) /// public byte this[int index] { - get { return bytes[index]; } + get { return bytes.Span[index]; } } /// @@ -287,7 +270,18 @@ public byte this[int index] /// The result of decoding the binary data with the given decoding. public string ToString(Encoding encoding) { - return encoding.GetString(bytes, 0, bytes.Length); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment)) + { + // Fast path. ByteString was created with an array. + return encoding.GetString(segment.Array, segment.Offset, segment.Count); + } + else + { + // Slow path. BytesString is not an array. Convert memory and pass result to GetString. + // TODO: Consider using GetString overload that takes a pointer. + byte[] array = bytes.ToArray(); + return encoding.GetString(array, 0, array.Length); + } } /// @@ -307,9 +301,10 @@ public string ToStringUtf8() /// Returns an iterator over the bytes in this . /// /// An iterator over the bytes in this object. + [SecuritySafeCritical] public IEnumerator GetEnumerator() { - return ((IEnumerable) bytes).GetEnumerator(); + return MemoryMarshal.ToEnumerable(bytes).GetEnumerator(); } /// @@ -327,7 +322,17 @@ IEnumerator IEnumerable.GetEnumerator() public CodedInputStream CreateCodedInput() { // We trust CodedInputStream not to reveal the provided byte array or modify it - return new CodedInputStream(bytes); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment) && segment.Count == bytes.Length) + { + // Fast path. ByteString was created with a complete array. + return new CodedInputStream(segment.Array); + } + else + { + // Slow path. BytesString is not an array, or is a slice of an array. + // Convert memory and pass result to WriteRawBytes. + return new CodedInputStream(bytes.ToArray()); + } } /// @@ -346,18 +351,8 @@ public CodedInputStream CreateCodedInput() { return false; } - if (lhs.bytes.Length != rhs.bytes.Length) - { - return false; - } - for (int i = 0; i < lhs.Length; i++) - { - if (rhs.bytes[i] != lhs.bytes[i]) - { - return false; - } - } - return true; + + return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span); } /// @@ -376,6 +371,7 @@ public CodedInputStream CreateCodedInput() /// /// The object to compare this with. /// true if refers to an equal ; false otherwise. + [SecuritySafeCritical] public override bool Equals(object obj) { return this == (obj as ByteString); @@ -386,12 +382,15 @@ public override bool Equals(object obj) /// will return the same hash code. /// /// A hash code for this object. + [SecuritySafeCritical] public override int GetHashCode() { + ReadOnlySpan b = bytes.Span; + int ret = 23; - foreach (byte b in bytes) + for (int i = 0; i < b.Length; i++) { - ret = (ret * 31) + b; + ret = (ret * 31) + b[i]; } return ret; } @@ -406,20 +405,12 @@ public bool Equals(ByteString other) return this == other; } - /// - /// Used internally by CodedOutputStream to avoid creating a copy for the write - /// - internal void WriteRawBytesTo(CodedOutputStream outputStream) - { - outputStream.WriteRawBytes(bytes, 0, bytes.Length); - } - /// /// Copies the entire byte array to the destination array provided at the offset specified. /// public void CopyTo(byte[] array, int position) { - ByteArray.Copy(bytes, 0, array, position, bytes.Length); + bytes.CopyTo(array.AsMemory(position)); } /// @@ -427,7 +418,17 @@ public void CopyTo(byte[] array, int position) /// public void WriteTo(Stream outputStream) { - outputStream.Write(bytes, 0, bytes.Length); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment)) + { + // Fast path. ByteString was created with an array, so pass the underlying array. + outputStream.Write(segment.Array, segment.Offset, segment.Count); + } + else + { + // Slow path. BytesString is not an array. Convert memory and pass result to WriteRawBytes. + var array = bytes.ToArray(); + outputStream.Write(array, 0, array.Length); + } } } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/ByteStringAsync.cs b/csharp/src/Google.Protobuf/ByteStringAsync.cs new file mode 100644 index 000000000000..3465cc67b40f --- /dev/null +++ b/csharp/src/Google.Protobuf/ByteStringAsync.cs @@ -0,0 +1,64 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Google.Protobuf +{ + /// + /// SecuritySafeCritical attribute can not be placed on types with async methods. + /// This class has ByteString's async methods so it can be marked with SecuritySafeCritical. + /// + internal static class ByteStringAsync + { +#if !NET35 + internal static async Task FromStreamAsyncCore(Stream stream, CancellationToken cancellationToken) + { + int capacity = stream.CanSeek ? checked((int)(stream.Length - stream.Position)) : 0; + var memoryStream = new MemoryStream(capacity); + // We have to specify the buffer size here, as there's no overload accepting the cancellation token + // alone. But it's documented to use 81920 by default if not specified. + await stream.CopyToAsync(memoryStream, 81920, cancellationToken); +#if NETSTANDARD1_1 + byte[] bytes = memoryStream.ToArray(); +#else + // Avoid an extra copy if we can. + byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray(); +#endif + return ByteString.AttachBytes(bytes); + } +#endif + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index 706d836a3d08..45541c537a8b 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.13.0 + 3.14.0 7.2 Google Inc. @@ -19,7 +19,6 @@ https://github.com/protocolbuffers/protobuf/blob/master/LICENSE git https://github.com/protocolbuffers/protobuf.git - $(DefineConstants);GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY True $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb diff --git a/csharp/src/Google.Protobuf/IBufferMessage.cs b/csharp/src/Google.Protobuf/IBufferMessage.cs index c99a7d79fc02..05c15db4c62a 100644 --- a/csharp/src/Google.Protobuf/IBufferMessage.cs +++ b/csharp/src/Google.Protobuf/IBufferMessage.cs @@ -32,7 +32,6 @@ namespace Google.Protobuf { -#if GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY /// /// Interface for a Protocol Buffers message, supporting /// parsing from and writing to . @@ -51,5 +50,4 @@ public interface IBufferMessage : IMessage /// void InternalWriteTo(ref WriteContext ctx); } -#endif } diff --git a/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs b/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs index 126306490a09..629ec32bd81e 100644 --- a/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs +++ b/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs @@ -160,8 +160,11 @@ internal static class ParsingPrimitivesWrappers internal static uint? ReadUInt32Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) { - // length:1 + tag:1 + value:5(varint32-max) = 7 bytes - if (state.bufferPos + 7 <= state.bufferSize) + // field=1, type=varint = tag of 8 + const int expectedTag = 8; + // length:1 + tag:1 + value:10(varint64-max) = 12 bytes + // Value can be 64 bits for negative integers + if (state.bufferPos + 12 <= state.bufferSize) { // The entire wrapper message is already contained in `buffer`. int pos0 = state.bufferPos; @@ -177,8 +180,7 @@ internal static class ParsingPrimitivesWrappers return ReadUInt32WrapperSlow(ref buffer, ref state); } int finalBufferPos = state.bufferPos + length; - // field=1, type=varint = tag of 8 - if (buffer[state.bufferPos++] != 8) + if (buffer[state.bufferPos++] != expectedTag) { state.bufferPos = pos0; return ReadUInt32WrapperSlow(ref buffer, ref state); diff --git a/csharp/src/Google.Protobuf/UnsafeByteOperations.cs b/csharp/src/Google.Protobuf/UnsafeByteOperations.cs new file mode 100644 index 000000000000..865ea067b8c8 --- /dev/null +++ b/csharp/src/Google.Protobuf/UnsafeByteOperations.cs @@ -0,0 +1,81 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Security; + +namespace Google.Protobuf +{ + /// + /// Provides a number of unsafe byte operations to be used by advanced applications with high performance + /// requirements. These methods are referred to as "unsafe" due to the fact that they potentially expose + /// the backing buffer of a to the application. + /// + /// + /// + /// The methods in this class should only be called if it is guaranteed that the buffer backing the + /// will never change! Mutation of a can lead to unexpected + /// and undesirable consequences in your application, and will likely be difficult to debug. Proceed with caution! + /// + /// + /// This can have a number of significant side affects that have spooky-action-at-a-distance-like behavior. In + /// particular, if the bytes value changes out from under a Protocol Buffer: + /// + /// + /// + /// serialization may throw + /// + /// + /// serialization may succeed but the wrong bytes may be written out + /// + /// + /// objects that are normally immutable (such as ByteString) are no longer immutable + /// + /// + /// hashCode may be incorrect + /// + /// + /// + [SecuritySafeCritical] + public static class UnsafeByteOperations + { + /// + /// Constructs a new from the given bytes. The bytes are not copied, + /// and must not be modified while the is in use. + /// This API is experimental and subject to change. + /// + public static ByteString UnsafeWrap(ReadOnlyMemory bytes) + { + return ByteString.AttachBytes(bytes); + } + } +} diff --git a/docs/options.md b/docs/options.md index f64b9ea8e11c..3aee3921852a 100644 --- a/docs/options.md +++ b/docs/options.md @@ -93,8 +93,8 @@ with info about your project (name and website) so we can add an entry for you. * Website: https://github.com/protobuf-c/protobuf-c * Extensions: 1019 -1. ScalePB - * Website: http://trueaccord.github.io/ScalaPB/ +1. ScalaPB + * Website: https://scalapb.github.io/ * Extensions: 1020 1. protoc-gen-bq-schema diff --git a/editors/proto.vim b/editors/proto.vim index 7f1aeb730a17..bdc60ce7f8ee 100644 --- a/editors/proto.vim +++ b/editors/proto.vim @@ -69,10 +69,10 @@ syn keyword pbBool true false syn match pbInt /-\?\<\d\+\>/ syn match pbInt /\<0[xX]\x+\>/ syn match pbFloat /\<-\?\d*\(\.\d*\)\?/ -syn region pbComment start="\/\*" end="\*\/" contains=@pbCommentGrp -syn region pbComment start="//" skip="\\$" end="$" keepend contains=@pbCommentGrp -syn region pbString start=/"/ skip=/\\./ end=/"/ -syn region pbString start=/'/ skip=/\\./ end=/'/ +syn region pbComment start="\/\*" end="\*\/" contains=@pbCommentGrp,@Spell +syn region pbComment start="//" skip="\\$" end="$" keepend contains=@pbCommentGrp,@Spell +syn region pbString start=/"/ skip=/\\./ end=/"/ contains=@Spell +syn region pbString start=/'/ skip=/\\./ end=/'/ contains=@Spell if version >= 508 || !exists("did_proto_syn_inits") if version < 508 diff --git a/java/bom/pom.xml b/java/bom/pom.xml index 3642783f6a8c..209a4b555b2e 100644 --- a/java/bom/pom.xml +++ b/java/bom/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-bom - 3.13.0 + 3.14.0 pom Protocol Buffers [BOM] diff --git a/java/core/pom.xml b/java/core/pom.xml index 3509163b0811..6c0732a358bd 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.13.0 + 3.14.0 protobuf-java diff --git a/java/core/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java index d52aede95803..1d8592f7527c 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java @@ -119,7 +119,6 @@ boolean isEmpty() { } /** Make this FieldSet immutable from this point forward. */ - @SuppressWarnings("unchecked") public void makeImmutable() { if (isImmutable) { return; @@ -286,11 +285,11 @@ public void setField(final T descriptor, Object value) { final List newList = new ArrayList(); newList.addAll((List) value); for (final Object element : newList) { - verifyType(descriptor.getLiteType(), element); + verifyType(descriptor, element); } value = newList; } else { - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); } if (value instanceof LazyField) { @@ -354,7 +353,7 @@ public void setRepeatedField(final T descriptor, final int index, final Object v throw new IndexOutOfBoundsException(); } - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); ((List) list).set(index, value); } @@ -369,7 +368,7 @@ public void addRepeatedField(final T descriptor, final Object value) { "addRepeatedField() can only be called on repeated fields."); } - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); final Object existingValue = getField(descriptor); List list; @@ -390,8 +389,8 @@ public void addRepeatedField(final T descriptor, final Object value) { * * @throws IllegalArgumentException The value is not of the right type. */ - private void verifyType(final WireFormat.FieldType type, final Object value) { - if (!isValidType(type, value)) { + private void verifyType(final T descriptor, final Object value) { + if (!isValidType(descriptor.getLiteType(), value)) { // TODO(kenton): When chaining calls to setField(), it can be hard to // tell from the stack trace which exact call failed, since the whole // chain is considered one line of code. It would be nice to print @@ -400,10 +399,16 @@ private void verifyType(final WireFormat.FieldType type, final Object value) { // isn't a big deal, though, since it would only really apply when using // reflection and generally people don't chain reflection setters. throw new IllegalArgumentException( - "Wrong object type used with protocol message reflection."); + String.format( + "Wrong object type used with protocol message reflection.\n" + + "Field number: %d, field java type: %s, value type: %s\n", + descriptor.getNumber(), + descriptor.getLiteType().getJavaType(), + value.getClass().getName())); } } + private static boolean isValidType(final WireFormat.FieldType type, final Object value) { checkNotNull(value); switch (type.getJavaType()) { @@ -1081,12 +1086,12 @@ public void setField(final T descriptor, Object value) { final List newList = new ArrayList(); newList.addAll((List) value); for (final Object element : newList) { - verifyType(descriptor.getLiteType(), element); + verifyType(descriptor, element); hasNestedBuilders = hasNestedBuilders || element instanceof MessageLite.Builder; } value = newList; } else { - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); } if (value instanceof LazyField) { @@ -1172,7 +1177,7 @@ public void setRepeatedField(final T descriptor, final int index, final Object v throw new IndexOutOfBoundsException(); } - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); ((List) list).set(index, value); } @@ -1190,7 +1195,7 @@ public void addRepeatedField(final T descriptor, final Object value) { hasNestedBuilders = hasNestedBuilders || value instanceof MessageLite.Builder; - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); final Object existingValue = getField(descriptor); List list; @@ -1211,15 +1216,20 @@ public void addRepeatedField(final T descriptor, final Object value) { * * @throws IllegalArgumentException The value is not of the right type. */ - private static void verifyType(final WireFormat.FieldType type, final Object value) { - if (!FieldSet.isValidType(type, value)) { + private void verifyType(final T descriptor, final Object value) { + if (!FieldSet.isValidType(descriptor.getLiteType(), value)) { // Builder can accept Message.Builder values even though FieldSet will reject. - if (type.getJavaType() == WireFormat.JavaType.MESSAGE + if (descriptor.getLiteType().getJavaType() == WireFormat.JavaType.MESSAGE && value instanceof MessageLite.Builder) { return; } throw new IllegalArgumentException( - "Wrong object type used with protocol message reflection."); + String.format( + "Wrong object type used with protocol message reflection.\n" + + "Field number: %d, field java type: %s, value type: %s\n", + descriptor.getNumber(), + descriptor.getLiteType().getJavaType(), + value.getClass().getName())); } } diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index bbc0f8dd94fe..e781df333d10 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -61,6 +61,7 @@ private TextFormat() {} private static final Logger logger = Logger.getLogger(TextFormat.class.getName()); + /** * Outputs a textual representation of the Protocol Message supplied into the parameter output. * (This representation is the new version of the classic "ProtocolPrinter" output from the @@ -727,9 +728,9 @@ private void printSingleField( // Groups must be serialized with their original capitalization. generator.print(field.getMessageType().getName()); } else { - generator.print(field.getName()); + generator.print(field.getName()); + } } - } if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { generator.print(" {"); @@ -1811,16 +1812,16 @@ private void mergeField( extension = target.findExtensionByName(extensionRegistry, name.toString()); if (extension == null) { - String message = - (tokenizer.getPreviousLine() + 1) - + ":" - + (tokenizer.getPreviousColumn() + 1) - + ":\t" - + type.getFullName() - + ".[" - + name - + "]"; - unknownFields.add(new UnknownField(message, UnknownField.Type.EXTENSION)); + String message = + (tokenizer.getPreviousLine() + 1) + + ":" + + (tokenizer.getPreviousColumn() + 1) + + ":\t" + + type.getFullName() + + ".[" + + name + + "]"; + unknownFields.add(new UnknownField(message, UnknownField.Type.EXTENSION)); } else { if (extension.descriptor.getContainingType() != type) { throw tokenizer.parseExceptionPreviousToken( diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java index 471238ae4325..b9b32af15823 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -388,7 +388,7 @@ private static boolean supportsUnsafeByteBufferOperations() { } if (Android.isOnAndroidDevice()) { - return true; + return false; } clazz.getMethod("getByte", long.class); clazz.getMethod("putByte", long.class, byte.class); diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java index 9994ad067a1e..4de09cd1619a 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java @@ -184,17 +184,17 @@ private void assertMapValuesUpdated(TestMap message) { } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -226,13 +226,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java index b995802b4f0c..d2565ca15701 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -128,35 +128,35 @@ private void copyMapValues(TestMap source, TestMap.Builder destination) { } private void assertMapValuesSet(TestMapOrBuilder message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); - - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { @@ -268,17 +268,17 @@ private void assertMapValuesUpdated(TestMap message) { } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -293,13 +293,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { @@ -874,8 +874,8 @@ public void testRecursiveMap() throws Exception { ByteString data = builder.build().toByteString(); TestRecursiveMap message = TestRecursiveMap.parseFrom(data); - assertEquals(2, message.getRecursiveMapField().get(1).getValue()); - assertEquals(4, message.getRecursiveMapField().get(3).getValue()); + assertEquals(2, message.getRecursiveMapFieldMap().get(1).getValue()); + assertEquals(4, message.getRecursiveMapFieldMap().get(3).getValue()); } public void testIterationOrder() throws Exception { 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 40bb7893b313..33282add80d0 100644 --- a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java @@ -191,17 +191,17 @@ private void assertMapValuesUpdated(TestMap message) { } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -232,13 +232,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { 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 f3458dd23595..2f55328b5105 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -271,17 +271,17 @@ private void assertMapValuesUpdated(TestMap message) { } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -296,13 +296,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java index 22c0be25226c..d3f0b0eda968 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java @@ -260,8 +260,8 @@ private TestUtil() {} TestRequired.newBuilder().setA(1).setB(2).setC(3).build(); /** Helper to convert a String to ByteString. */ - static ByteString toBytes(String str) { - return ByteString.copyFrom(str.getBytes(Internal.UTF_8)); + public static ByteString toBytes(String str) { + return ByteString.copyFromUtf8(str); } // BEGIN FULL-RUNTIME diff --git a/java/core/src/test/java/com/google/protobuf/TestUtilLite.java b/java/core/src/test/java/com/google/protobuf/TestUtilLite.java index 31565fc40a64..993dd9defb2c 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtilLite.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtilLite.java @@ -142,8 +142,8 @@ public final class TestUtilLite { private TestUtilLite() {} /** Helper to convert a String to ByteString. */ - static ByteString toBytes(String str) { - return ByteString.copyFrom(str.getBytes(Internal.UTF_8)); + public static ByteString toBytes(String str) { + return ByteString.copyFromUtf8(str); } /** diff --git a/java/lite/pom.xml b/java/lite/pom.xml index 779eacc6371f..104c5c1676ac 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.13.0 + 3.14.0 protobuf-javalite diff --git a/java/pom.xml b/java/pom.xml index 80e76add8af3..3283268afcb4 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.13.0 + 3.14.0 pom Protocol Buffers [Parent] diff --git a/java/util/pom.xml b/java/util/pom.xml index 54dcc869078b..75457fbc8ea7 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.13.0 + 3.14.0 protobuf-java-util diff --git a/java/util/src/main/java/com/google/protobuf/util/Durations.java b/java/util/src/main/java/com/google/protobuf/util/Durations.java index 1edc8f0af259..747096082176 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Durations.java +++ b/java/util/src/main/java/com/google/protobuf/util/Durations.java @@ -44,6 +44,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.Duration; +import java.io.Serializable; import java.text.ParseException; import java.util.Comparator; @@ -72,23 +73,25 @@ public final class Durations { private Durations() {} - private static final Comparator COMPARATOR = - new Comparator() { - @Override - public int compare(Duration d1, Duration d2) { - checkValid(d1); - checkValid(d2); - int secDiff = Long.compare(d1.getSeconds(), d2.getSeconds()); - return (secDiff != 0) ? secDiff : Integer.compare(d1.getNanos(), d2.getNanos()); - } - }; + private static enum DurationComparator implements Comparator, Serializable { + INSTANCE; + + @Override + public int compare(Duration d1, Duration d2) { + checkValid(d1); + checkValid(d2); + int secDiff = Long.compare(d1.getSeconds(), d2.getSeconds()); + return (secDiff != 0) ? secDiff : Integer.compare(d1.getNanos(), d2.getNanos()); + } + } /** * Returns a {@link Comparator} for {@link Duration}s which sorts in increasing chronological - * order. Nulls and invalid {@link Duration}s are not allowed (see {@link #isValid}). + * order. Nulls and invalid {@link Duration}s are not allowed (see {@link #isValid}). The returned + * comparator is serializable. */ public static Comparator comparator() { - return COMPARATOR; + return DurationComparator.INSTANCE; } /** @@ -99,7 +102,7 @@ public static Comparator comparator() { * and a value greater than {@code 0} if {@code x > y} */ public static int compare(Duration x, Duration y) { - return COMPARATOR.compare(x, y); + return DurationComparator.INSTANCE.compare(x, y); } /** diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java index 12cd0500fb33..fe9b9a50b838 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java +++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java @@ -39,6 +39,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.Duration; import com.google.protobuf.Timestamp; +import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Comparator; @@ -100,24 +101,25 @@ private static SimpleDateFormat createTimestampFormat() { private Timestamps() {} - private static final Comparator COMPARATOR = - new Comparator() { - @Override - public int compare(Timestamp t1, Timestamp t2) { - checkValid(t1); - checkValid(t2); - int secDiff = Long.compare(t1.getSeconds(), t2.getSeconds()); - return (secDiff != 0) ? secDiff : Integer.compare(t1.getNanos(), t2.getNanos()); - } - }; + private static enum TimestampComparator implements Comparator, Serializable { + INSTANCE; + + @Override + public int compare(Timestamp t1, Timestamp t2) { + checkValid(t1); + checkValid(t2); + int secDiff = Long.compare(t1.getSeconds(), t2.getSeconds()); + return (secDiff != 0) ? secDiff : Integer.compare(t1.getNanos(), t2.getNanos()); + } + } /** * Returns a {@link Comparator} for {@link Timestamp Timestamps} which sorts in increasing * chronological order. Nulls and invalid {@link Timestamp Timestamps} are not allowed (see - * {@link #isValid}). + * {@link #isValid}). The returned comparator is serializable. */ public static Comparator comparator() { - return COMPARATOR; + return TimestampComparator.INSTANCE; } /** @@ -128,7 +130,7 @@ public static Comparator comparator() { * and a value greater than {@code 0} if {@code x > y} */ public static int compare(Timestamp x, Timestamp y) { - return COMPARATOR.compare(x, y); + return TimestampComparator.INSTANCE.compare(x, y); } /** diff --git a/js/binary/reader.js b/js/binary/reader.js index 6fdbd6f4dc96..31bbfda43885 100644 --- a/js/binary/reader.js +++ b/js/binary/reader.js @@ -207,6 +207,15 @@ jspb.BinaryReader.prototype.getWireType = function() { }; +/** + * @return {boolean} Whether the current wire type is a delimited field. Used to + * conditionally parse packed repeated fields. + */ +jspb.BinaryReader.prototype.isDelimited = function() { + return this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED; +}; + + /** * @return {boolean} Whether the current wire type is an end-group tag. Used as * an exit condition in decoder loops in generated code. diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index 7b1263fde9ea..20ae9aee989c 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -71,6 +71,8 @@ @interface GPBMessage () { @package GPBUnknownFieldSet *unknownFields_; NSMutableDictionary *extensionMap_; + // Readonly access to autocreatedExtensionMap_ is protected via + // readOnlySemaphore_. NSMutableDictionary *autocreatedExtensionMap_; // If the object was autocreated, we remember the creator so that if we get @@ -79,10 +81,10 @@ @interface GPBMessage () { GPBFieldDescriptor *autocreatorField_; GPBExtensionDescriptor *autocreatorExtension_; - // A lock to provide mutual exclusion from internal data that can be modified - // by *read* operations such as getters (autocreation of message fields and - // message extensions, not setting of values). Used to guarantee thread safety - // for concurrent reads on the message. + // Message can only be mutated from one thread. But some *readonly* operations + // modifify internal state because they autocreate things. The + // autocreatedExtensionMap_ is one such structure. Access during readonly + // operations is protected via this semaphore. // NOTE: OSSpinLock may seem like a good fit here but Apple engineers have // pointed out that they are vulnerable to live locking on iOS in cases of // priority inversion: @@ -583,19 +585,30 @@ static id GetOrCreateArrayIvarWithField(GPBMessage *self, // This is like GPBGetObjectIvarWithField(), but for arrays, it should // only be used to wire the method into the class. static id GetArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { - id array = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!array) { - // Check again after getting the lock. - GPBPrepareReadOnlySemaphore(self); - dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); - array = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!array) { - array = CreateArrayForField(field, self); - GPBSetAutocreatedRetainedObjectIvarWithField(self, field, array); - } - dispatch_semaphore_signal(self->readOnlySemaphore_); + uint8_t *storage = (uint8_t *)self->messageStorage_; + _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset]; + id array = atomic_load(typePtr); + if (array) { + return array; } - return array; + + id expected = nil; + id autocreated = CreateArrayForField(field, self); + if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) { + // Value was set, return it. + return autocreated; + } + + // Some other thread set it, release the one created and return what got set. + if (GPBFieldDataTypeIsObject(field)) { + GPBAutocreatedArray *autoArray = autocreated; + autoArray->_autocreator = nil; + } else { + GPBInt32Array *gpbArray = autocreated; + gpbArray->_autocreator = nil; + } + [autocreated release]; + return expected; } static id GetOrCreateMapIvarWithField(GPBMessage *self, @@ -613,19 +626,31 @@ static id GetOrCreateMapIvarWithField(GPBMessage *self, // This is like GPBGetObjectIvarWithField(), but for maps, it should // only be used to wire the method into the class. static id GetMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { - id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!dict) { - // Check again after getting the lock. - GPBPrepareReadOnlySemaphore(self); - dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); - dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!dict) { - dict = CreateMapForField(field, self); - GPBSetAutocreatedRetainedObjectIvarWithField(self, field, dict); - } - dispatch_semaphore_signal(self->readOnlySemaphore_); + uint8_t *storage = (uint8_t *)self->messageStorage_; + _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset]; + id dict = atomic_load(typePtr); + if (dict) { + return dict; } - return dict; + + id expected = nil; + id autocreated = CreateMapForField(field, self); + if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) { + // Value was set, return it. + return autocreated; + } + + // Some other thread set it, release the one created and return what got set. + if ((field.mapKeyDataType == GPBDataTypeString) && + GPBFieldDataTypeIsObject(field)) { + GPBAutocreatedDictionary *autoDict = autocreated; + autoDict->_autocreator = nil; + } else { + GPBInt32Int32Dictionary *gpbDict = autocreated; + gpbDict->_autocreator = nil; + } + [autocreated release]; + return expected; } #endif // !defined(__clang_analyzer__) @@ -3337,30 +3362,34 @@ id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) { id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { NSCAssert(!GPBFieldIsMapOrArray(field), @"Shouldn't get here"); - if (GPBGetHasIvarField(self, field)) { - uint8_t *storage = (uint8_t *)self->messageStorage_; - id *typePtr = (id *)&storage[field->description_->offset]; - return *typePtr; - } - // Not set... - - // Non messages (string/data), get their default. if (!GPBFieldDataTypeIsMessage(field)) { + if (GPBGetHasIvarField(self, field)) { + uint8_t *storage = (uint8_t *)self->messageStorage_; + id *typePtr = (id *)&storage[field->description_->offset]; + return *typePtr; + } + // Not set...non messages (string/data), get their default. return field.defaultValue.valueMessage; } - GPBPrepareReadOnlySemaphore(self); - dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); - GPBMessage *result = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!result) { - // For non repeated messages, create the object, set it and return it. - // This object will not initially be visible via GPBGetHasIvar, so - // we save its creator so it can become visible if it's mutated later. - result = GPBCreateMessageWithAutocreator(field.msgClass, self, field); - GPBSetAutocreatedRetainedObjectIvarWithField(self, field, result); - } - dispatch_semaphore_signal(self->readOnlySemaphore_); - return result; + uint8_t *storage = (uint8_t *)self->messageStorage_; + _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset]; + id msg = atomic_load(typePtr); + if (msg) { + return msg; + } + + id expected = nil; + id autocreated = GPBCreateMessageWithAutocreator(field.msgClass, self, field); + if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) { + // Value was set, return it. + return autocreated; + } + + // Some other thread set it, release the one created and return what got set. + GPBClearMessageAutocreator(autocreated); + [autocreated release]; + return expected; } #pragma clang diagnostic pop diff --git a/objectivec/GPBUtilities.m b/objectivec/GPBUtilities.m index e13210210da6..08dd358225fb 100644 --- a/objectivec/GPBUtilities.m +++ b/objectivec/GPBUtilities.m @@ -504,15 +504,6 @@ static void GPBMaybeClearOneofPrivate(GPBMessage *self, // Object types are handled slightly differently, they need to be released // and retained. -void GPBSetAutocreatedRetainedObjectIvarWithField( - GPBMessage *self, GPBFieldDescriptor *field, - id __attribute__((ns_consumed)) value) { - uint8_t *storage = (uint8_t *)self->messageStorage_; - id *typePtr = (id *)&storage[field->description_->offset]; - NSCAssert(*typePtr == NULL, @"Can't set autocreated object more than once."); - *typePtr = value; -} - void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { if (GPBGetHasIvarField(self, field)) { diff --git a/objectivec/GPBUtilities_PackagePrivate.h b/objectivec/GPBUtilities_PackagePrivate.h index a620288267f2..3d3d7349ec78 100644 --- a/objectivec/GPBUtilities_PackagePrivate.h +++ b/objectivec/GPBUtilities_PackagePrivate.h @@ -289,10 +289,6 @@ void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self, GPBFieldDescriptor *field); -void GPBSetAutocreatedRetainedObjectIvarWithField( - GPBMessage *self, GPBFieldDescriptor *field, - id __attribute__((ns_consumed)) value); - // Clears and releases the autocreated message ivar, if it's autocreated. If // it's not set as autocreated, this method does nothing. void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework index 913a289b8ec1..e0ee90551452 100644 --- a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework +++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework @@ -1,5 +1,5 @@ source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' +platform :ios, '9.0' install! 'cocoapods', :deterministic_uuids => false diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static index e9b3c235dd16..1bb8cb2e1aa4 100644 --- a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static +++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static @@ -1,5 +1,5 @@ source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' +platform :ios, '9.0' install! 'cocoapods', :deterministic_uuids => false diff --git a/php/ext/google/protobuf/config.m4 b/php/ext/google/protobuf/config.m4 index 3fdcb00480d4..c09c03af0a5b 100644 --- a/php/ext/google/protobuf/config.m4 +++ b/php/ext/google/protobuf/config.m4 @@ -4,7 +4,7 @@ if test "$PHP_PROTOBUF" != "no"; then PHP_NEW_EXTENSION( protobuf, - arena.c array.c bundled_php.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c, - $ext_shared) + arena.c array.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c, + $ext_shared, , -std=gnu99) fi diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 37dd50c1824a..3f7590ca44dc 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -772,6 +772,7 @@ upb_symtab *DescriptorPool_GetSymbolTable() { return intern->symtab; } + /* * DescriptorPool::getGeneratedPool() * @@ -906,13 +907,38 @@ static void add_name_mappings(const upb_filedef *file) { } } +static void add_descriptor(DescriptorPool *pool, + const google_protobuf_FileDescriptorProto *file) { + upb_strview name = google_protobuf_FileDescriptorProto_name(file); + upb_status status; + const upb_filedef *file_def; + upb_status_clear(&status); + + if (upb_symtab_lookupfile2(pool->symtab, name.data, name.size)) { + // Already added. + fprintf(stderr, "WARNING: file was already added\n"); + return; + } + + // The PHP code generator currently special-cases descriptor.proto. It + // doesn't add it as a dependency even if the proto file actually does + // depend on it. + if (depends_on_descriptor(file)) { + google_protobuf_FileDescriptorProto_getmsgdef(pool->symtab); + } + + file_def = upb_symtab_addfile(pool->symtab, file, &status); + CheckUpbStatus(&status, "Unable to load descriptor"); + add_name_mappings(file_def); +} + /* - * add_name_mappings() + * add_descriptor() * * Adds the given descriptor data to this DescriptorPool. */ -static void add_descriptor(DescriptorPool *pool, const char *data, - int data_len, upb_arena *arena) { +static void add_descriptor_set(DescriptorPool *pool, const char *data, + int data_len, upb_arena *arena) { size_t i, n; google_protobuf_FileDescriptorSet *set; const google_protobuf_FileDescriptorProto* const* files; @@ -928,27 +954,28 @@ static void add_descriptor(DescriptorPool *pool, const char *data, for (i = 0; i < n; i++) { const google_protobuf_FileDescriptorProto* file = files[i]; - upb_strview name = google_protobuf_FileDescriptorProto_name(file); - upb_status status; - const upb_filedef *file_def; - upb_status_clear(&status); - - if (upb_symtab_lookupfile2(pool->symtab, name.data, name.size)) { - // Already added. - continue; - } + add_descriptor(pool, file); + } +} - // The PHP code generator currently special-cases descriptor.proto. It - // doesn't add it as a dependency even if the proto file actually does - // depend on it. - if (depends_on_descriptor(file)) { - google_protobuf_FileDescriptorProto_getmsgdef(pool->symtab); - } +bool DescriptorPool_HasFile(const char *filename) { + DescriptorPool *intern = GetPool(get_generated_pool()); + return upb_symtab_lookupfile(intern->symtab, filename) != NULL; +} + +void DescriptorPool_AddDescriptor(const char *filename, const char *data, + int size) { + upb_arena *arena = upb_arena_new(); + const google_protobuf_FileDescriptorProto *file = + google_protobuf_FileDescriptorProto_parse(data, size, arena); - file_def = upb_symtab_addfile(pool->symtab, file, &status); - CheckUpbStatus(&status, "Unable to load descriptor"); - add_name_mappings(file_def); + if (!file) { + zend_error(E_ERROR, "Failed to parse binary descriptor for %s\n", filename); + return; } + + add_descriptor(GetPool(get_generated_pool()), file); + upb_arena_free(arena); } /* @@ -969,7 +996,7 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { } arena = upb_arena_new(); - add_descriptor(intern, data, data_len, arena); + add_descriptor_set(intern, data, data_len, arena); upb_arena_free(arena); } @@ -983,6 +1010,35 @@ static zend_function_entry DescriptorPool_methods[] = { ZEND_FE_END }; +// ----------------------------------------------------------------------------- +// InternalDescriptorPool +// ----------------------------------------------------------------------------- + +// For the C extension, Google\Protobuf\Internal\DescriptorPool is not a +// separate instantiable object, it just returns a +// Google\Protobuf\DescriptorPool. + +zend_class_entry *InternalDescriptorPool_class_entry; + +/* + * InternalDescriptorPool::getGeneratedPool() + * + * Returns the generated DescriptorPool. Note that this is identical to + * DescriptorPool::getGeneratedPool(), and in fact returns a DescriptorPool + * instance. + */ +PHP_METHOD(InternalDescriptorPool, getGeneratedPool) { + zval ret; + ZVAL_COPY(&ret, get_generated_pool()); + RETURN_ZVAL(&ret, 0, 1); +} + +static zend_function_entry InternalDescriptorPool_methods[] = { + PHP_ME(InternalDescriptorPool, getGeneratedPool, NULL, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_FE_END +}; + // ----------------------------------------------------------------------------- // GPBType // ----------------------------------------------------------------------------- @@ -1044,7 +1100,7 @@ void Def_ModuleInit() { h = &FieldDescriptor_object_handlers; memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); - INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\DescriptorPool", + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\DescriptorPool", DescriptorPool_methods); DescriptorPool_class_entry = zend_register_internal_class(&tmp_ce); DescriptorPool_class_entry->ce_flags |= ZEND_ACC_FINAL; @@ -1053,6 +1109,10 @@ void Def_ModuleInit() { memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); h->dtor_obj = DescriptorPool_destructor; + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\DescriptorPool", + InternalDescriptorPool_methods); + InternalDescriptorPool_class_entry = zend_register_internal_class(&tmp_ce); + // GPBType. #define STR(str) (str), strlen(str) zend_class_entry class_type; diff --git a/php/ext/google/protobuf/def.h b/php/ext/google/protobuf/def.h index 515a83eca7da..2a89cd0fd4e6 100644 --- a/php/ext/google/protobuf/def.h +++ b/php/ext/google/protobuf/def.h @@ -49,6 +49,12 @@ upb_symtab *DescriptorPool_Steal(zval *zv); upb_symtab *DescriptorPool_GetSymbolTable(); +// Returns true if the global descriptor pool already has the given filename. +bool DescriptorPool_HasFile(const char *filename); + +// Adds the given descriptor with the given filename to the global pool. +void DescriptorPool_AddDescriptor(const char *filename, const char *data, int size); + typedef struct Descriptor { zend_object std; const upb_msgdef *msgdef; diff --git a/php/ext/google/protobuf/make-preload.php b/php/ext/google/protobuf/make-preload.php deleted file mode 100644 index 4b1ce7f676fa..000000000000 --- a/php/ext/google/protobuf/make-preload.php +++ /dev/null @@ -1,62 +0,0 @@ - Google\\Protobuf\\BoolValue - $ret = stripSuffix($filename, ".php"); - return str_replace("/", "\\\\", $ret); -} - -function toCSymbolName($filename) { - # Google/Protobuf/BoolValue.php -> Google__Protobuf__BoolValue - $ret = stripSuffix($filename, ".php"); - return str_replace("/", "__", $ret); -} - -$f = fopen($output, "w"); - -fwrite($f, "#include \"bundled_php.h\"\n"); -fwrite($f, "#include \"stdlib.h\"\n"); - -foreach ($filenames as $filename) { - print("Reading $filename...\n"); - $contents = file_get_contents($filename); - $contents = substr($contents, 5); // Strip diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 7cd16699c7c7..f15b8ac1b466 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -36,6 +36,7 @@ // This is not self-contained: it must be after other Zend includes. #include +#include #include "arena.h" #include "array.h" @@ -108,6 +109,43 @@ 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); + + if (upb_fielddef_ismap(f)) { + upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); + MapField_GetPhpWrapper(rv, msgval.map, f, &intern->arena); + } else if (upb_fielddef_isseq(f)) { + upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); + RepeatedField_GetPhpWrapper(rv, msgval.array, f, &intern->arena); + } else { + upb_msgval msgval = upb_msg_get(intern->msg, f); + const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); + Convert_UpbToPhp(msgval, rv, upb_fielddef_type(f), subdesc, &intern->arena); + } +} + +static bool Message_set(Message *intern, const upb_fielddef *f, zval *val) { + upb_arena *arena = Arena_Get(&intern->arena); + upb_msgval msgval; + + if (upb_fielddef_ismap(f)) { + msgval.map_val = MapField_GetUpbMap(val, f, arena); + if (!msgval.map_val) return false; + } else if (upb_fielddef_isseq(f)) { + msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); + if (!msgval.array_val) return false; + } else { + upb_fieldtype_t type = upb_fielddef_type(f); + const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); + bool ok = Convert_PhpToUpb(val, &msgval, type, subdesc, arena); + if (!ok) return false; + } + + upb_msg_set(intern->msg, f, msgval, arena); + return true; +} + static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m); /** @@ -271,6 +309,7 @@ static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member, upb_msg_clearfield(intern->msg, f); } + /** * Message_read_property() * @@ -293,22 +332,9 @@ static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member, int type, void **cache_slot, zval *rv) { Message* intern = PROTO_MSG_P(obj); const upb_fielddef *f = get_field(intern, member); - upb_arena *arena = Arena_Get(&intern->arena); if (!f) return NULL; - - if (upb_fielddef_ismap(f)) { - upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); - MapField_GetPhpWrapper(rv, msgval.map, f, &intern->arena); - } else if (upb_fielddef_isseq(f)) { - upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); - RepeatedField_GetPhpWrapper(rv, msgval.array, f, &intern->arena); - } else { - upb_msgval msgval = upb_msg_get(intern->msg, f); - const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); - Convert_UpbToPhp(msgval, rv, upb_fielddef_type(f), subdesc, &intern->arena); - } - + Message_get(intern, f, rv); return rv; } @@ -337,37 +363,20 @@ static PROTO_RETURN_VAL Message_write_property( PROTO_VAL *obj, PROTO_STR *member, zval *val, void **cache_slot) { Message* intern = PROTO_MSG_P(obj); const upb_fielddef *f = get_field(intern, member); - upb_arena *arena = Arena_Get(&intern->arena); - upb_msgval msgval; - - if (!f) goto error; - - if (upb_fielddef_ismap(f)) { - msgval.map_val = MapField_GetUpbMap(val, f, arena); - if (!msgval.map_val) goto error; - } else if (upb_fielddef_isseq(f)) { - msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); - if (!msgval.array_val) goto error; - } else { - upb_fieldtype_t type = upb_fielddef_type(f); - const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); - bool ok = Convert_PhpToUpb(val, &msgval, type, subdesc, arena); - if (!ok) goto error; - } - upb_msg_set(intern->msg, f, msgval, arena); + if (f && Message_set(intern, f, val)) { #if PHP_VERSION_ID < 70400 - return; + return; #else - return val; + return val; #endif - -error: + } else { #if PHP_VERSION_ID < 70400 - return; + return; #else - return &EG(error_zval); + return &EG(error_zval); #endif + } } /** @@ -531,6 +540,12 @@ 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)); + ObjCache_Add(intern->msg, &intern->std); +} + /** * Message::__construct() * @@ -540,13 +555,10 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, PHP_METHOD(Message, __construct) { Message* intern = (Message*)Z_OBJ_P(getThis()); const Descriptor* desc = Descriptor_GetFromClassEntry(Z_OBJCE_P(getThis())); - const upb_msgdef *msgdef = desc->msgdef; upb_arena *arena = Arena_Get(&intern->arena); zval *init_arr = NULL; - intern->desc = desc; - intern->msg = upb_msg_new(msgdef, arena); - ObjCache_Add(intern->msg, &intern->std); + Message_Initialize(intern, desc); if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &init_arr) == FAILURE) { return; @@ -892,6 +904,39 @@ PHP_METHOD(Message, whichOneof) { RETURN_STRING(field ? upb_fielddef_name(field) : ""); } +/** + * Message::hasOneof() + * + * Returns the presence of the given oneof field, given a field number. Called + * from generated code methods such as: + * + * public function hasDoubleValueOneof() + * { + * return $this->hasOneof(10); + * } + * + * @return boolean + */ +PHP_METHOD(Message, hasOneof) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + zend_long field_num; + const upb_fielddef* f; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &field_num) == FAILURE) { + return; + } + + f = upb_msgdef_itof(intern->desc->msgdef, field_num); + + 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)); +} + /** * Message::readOneof() * @@ -1002,6 +1047,7 @@ static zend_function_entry Message_methods[] = { PHP_ME(Message, mergeFrom, arginfo_mergeFrom, ZEND_ACC_PUBLIC) PHP_ME(Message, readWrapperValue, arginfo_read, ZEND_ACC_PROTECTED) PHP_ME(Message, writeWrapperValue, arginfo_write, ZEND_ACC_PROTECTED) + PHP_ME(Message, hasOneof, arginfo_read, ZEND_ACC_PROTECTED) PHP_ME(Message, readOneof, arginfo_read, ZEND_ACC_PROTECTED) PHP_ME(Message, writeOneof, arginfo_write, ZEND_ACC_PROTECTED) PHP_ME(Message, whichOneof, arginfo_read, ZEND_ACC_PROTECTED) @@ -1009,6 +1055,260 @@ static zend_function_entry Message_methods[] = { ZEND_FE_END }; +// Well-known types //////////////////////////////////////////////////////////// + +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); + PBPHP_ASSERT(f); + return upb_msg_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); + PBPHP_ASSERT(f); + return upb_msg_set(intern->msg, f, val, Arena_Get(&intern->arena)); +} + +static upb_msgval StringVal(upb_strview view) { + upb_msgval ret; + ret.str_val = view; + return ret; +} + +static bool TryStripUrlPrefix(upb_strview *str) { + size_t size = strlen(TYPE_URL_PREFIX); + if (str->size < size || memcmp(TYPE_URL_PREFIX, str->data, size) != 0) { + return false; + } + str->data += size; + str->size -= size; + return true; +} + +static bool StrViewEq(upb_strview 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; + Descriptor *desc; + zval ret; + + // Ensure that type_url has TYPE_URL_PREFIX as a prefix. + if (!TryStripUrlPrefix(&type_url)) { + zend_throw_exception( + NULL, "Type url needs to be type.googleapis.com/fully-qualified", + 0 TSRMLS_CC); + return; + } + + m = upb_symtab_lookupmsg2(symtab, type_url.data, type_url.size); + + if (m == NULL) { + zend_throw_exception( + NULL, "Specified message in any hasn't been added to descriptor pool", + 0 TSRMLS_CC); + return; + } + + desc = Descriptor_GetFromMessageDef(m); + PBPHP_ASSERT(desc->class_entry->create_object == Message_create); + zend_object *obj = Message_create(desc->class_entry); + Message *msg = (Message*)obj; + Message_Initialize(msg, desc); + ZVAL_OBJ(&ret, obj); + + // Get value. + if (!upb_decode(value.data, value.size, msg->msg, + upb_msgdef_layout(desc->msgdef), Arena_Get(&msg->arena))) { + zend_throw_exception_ex(NULL, 0, "Error occurred during parsing"); + return; + } + + // Fuse since the parsed message could alias "value". + upb_arena_fuse(Arena_Get(&intern->arena), Arena_Get(&msg->arena)); + + RETURN_ZVAL(&ret, 1, 0); +} + +PHP_METHOD(google_protobuf_Any, pack) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); + zval *val; + Message *msg; + upb_strview value; + upb_strview type_url; + const char *full_name; + char *buf; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &val) == + FAILURE) { + return; + } + + if (!instanceof_function(Z_OBJCE_P(val), message_ce)) { + zend_error(E_USER_ERROR, "Given value is not an instance of Message."); + return; + } + + 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); + Message_setval(intern, "value", StringVal(value)); + + // Set type url: type_url_prefix + fully_qualified_name + full_name = upb_msgdef_fullname(msg->desc->msgdef); + type_url.size = strlen(TYPE_URL_PREFIX) + strlen(full_name); + buf = upb_arena_malloc(arena, type_url.size + 1); + memcpy(buf, TYPE_URL_PREFIX, strlen(TYPE_URL_PREFIX)); + memcpy(buf + strlen(TYPE_URL_PREFIX), full_name, strlen(full_name)); + type_url.data = buf; + Message_setval(intern, "type_url", StringVal(type_url)); +} + +PHP_METHOD(google_protobuf_Any, is) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_strview type_url = Message_getval(intern, "type_url").str_val; + zend_class_entry *klass = NULL; + const upb_msgdef *m; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "C", &klass) == + FAILURE) { + return; + } + + m = NameMap_GetMessage(klass); + + if (m == NULL) { + RETURN_BOOL(false); + } + + RETURN_BOOL(TryStripUrlPrefix(&type_url) && + StrViewEq(type_url, upb_msgdef_fullname(m))); +} + +PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + zval* datetime; + const char *classname = "\\DatetimeInterface"; + zend_string *classname_str = zend_string_init(classname, strlen(classname), 0); + zend_class_entry *date_interface_ce = zend_lookup_class(classname_str); + + if (date_interface_ce == NULL) { + zend_error(E_ERROR, "Make sure date extension is enabled."); + return; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &datetime, + date_interface_ce) == FAILURE) { + zend_error(E_USER_ERROR, "Expect DatetimeInterface."); + return; + } + + upb_msgval timestamp_seconds; + { + zval retval; + zval function_name; + + ZVAL_STRING(&function_name, "date_timestamp_get"); + + if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1, + datetime) == FAILURE || + !Convert_PhpToUpb(&retval, ×tamp_seconds, UPB_TYPE_INT64, NULL, + NULL)) { + zend_error(E_ERROR, "Cannot get timestamp from DateTime."); + return; + } + + zval_dtor(&retval); + zval_dtor(&function_name); + } + + upb_msgval timestamp_nanos; + { + zval retval; + zval function_name; + zval format_string; + + ZVAL_STRING(&function_name, "date_format"); + ZVAL_STRING(&format_string, "u"); + + zval params[2] = { + *datetime, + format_string, + }; + + if (call_user_function(EG(function_table), NULL, &function_name, &retval, 2, + params) == FAILURE || + !Convert_PhpToUpb(&retval, ×tamp_nanos, UPB_TYPE_INT32, NULL, + NULL)) { + zend_error(E_ERROR, "Cannot format DateTime."); + return; + } + + timestamp_nanos.int32_val *= 1000; + + zval_dtor(&retval); + zval_dtor(&function_name); + zval_dtor(&format_string); + } + + Message_setval(intern, "seconds", timestamp_seconds); + Message_setval(intern, "nanos", timestamp_nanos); + + RETURN_NULL(); +} + +PHP_METHOD(google_protobuf_Timestamp, toDateTime) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_msgval seconds = Message_getval(intern, "seconds"); + upb_msgval nanos = Message_getval(intern, "nanos"); + + // Get formatted time string. + char formatted_time[32]; + snprintf(formatted_time, sizeof(formatted_time), "%" PRId64 ".%06" PRId32, + seconds.int64_val, nanos.int32_val / 1000); + + // Create Datetime object. + zval datetime; + zval function_name; + zval format_string; + zval formatted_time_php; + + ZVAL_STRING(&function_name, "date_create_from_format"); + ZVAL_STRING(&format_string, "U.u"); + ZVAL_STRING(&formatted_time_php, formatted_time); + + zval params[2] = { + format_string, + formatted_time_php, + }; + + if (call_user_function(EG(function_table), NULL, &function_name, &datetime, 2, + params) == FAILURE) { + zend_error(E_ERROR, "Cannot create DateTime."); + return; + } + + zval_dtor(&function_name); + zval_dtor(&format_string); + zval_dtor(&formatted_time_php); + + ZVAL_OBJ(return_value, Z_OBJ(datetime)); +} + +#include "wkt.inc" + /** * Message_ModuleInit() * @@ -1033,4 +1333,6 @@ void Message_ModuleInit() { h->unset_property = Message_unset_property; h->get_properties = Message_get_properties; h->get_property_ptr_ptr = Message_get_property_ptr_ptr; + + WellKnownTypes_ModuleInit(); /* From wkt.inc. */ } diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index e0d25c87c5db..557f8ffc23a7 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -10,18 +10,18 @@ protobuf-opensource@google.com yes - 2020-10-08 - + 2020-11-12 + - 3.13.0.1 - 3.13.0.1 + 3.14.0 + 3.14.0 stable stable 3-Clause BSD License - GA release. + PHP protobuf @@ -29,8 +29,6 @@ - - @@ -45,6 +43,9 @@ + + + @@ -689,5 +690,65 @@ G A release. 3-Clause BSD License GA release. + + + 3.14.0RC1 + 3.14.0 + + + beta + beta + + 2020-11-05 + + 3-Clause BSD License + + + + + + 3.14.0RC2 + 3.14.0 + + + beta + beta + + 2020-11-10 + + 3-Clause BSD License + + + + + + 3.14.0RC3 + 3.14.0 + + + beta + beta + + 2020-11-11 + + 3-Clause BSD License + + + + + + 3.14.0 + 3.14.0 + + + stable + stable + + 2020-11-12 + + 3-Clause BSD License + + + diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index d1fc36663dfc..738386890bb1 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -22,6 +22,15 @@ * * This file is private and must not be included by users! */ + +#if !(__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L) +#error upb requires C99 or C++11 +#endif + +#if (defined(_MSC_VER) && _MSC_VER < 1900) +#error upb requires MSVC >= 2015. +#endif + #include #include @@ -70,66 +79,21 @@ #define UPB_UNLIKELY(x) (x) #endif -/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler - * doesn't provide these preprocessor symbols. */ -#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define UPB_BIG_ENDIAN -#endif - /* Macros for function attributes on compilers that support them. */ #ifdef __GNUC__ #define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) #define UPB_NOINLINE __attribute__((noinline)) #define UPB_NORETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE +#define UPB_NORETURN __declspec(noreturn) #else /* !defined(__GNUC__) */ #define UPB_FORCEINLINE #define UPB_NOINLINE #define UPB_NORETURN #endif -#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L -/* C99/C++11 versions. */ -#include -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined(_MSC_VER) -/* Microsoft C/C++ versions. */ -#include -#include -#if _MSC_VER < 1900 -int msvc_snprintf(char* s, size_t n, const char* format, ...); -int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); -#define UPB_MSVC_VSNPRINTF -#define _upb_snprintf msvc_snprintf -#define _upb_vsnprintf msvc_vsnprintf -#else -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#endif -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined __GNUC__ -/* A few hacky workarounds for functions not in C89. - * For internal use only! - * TODO(haberman): fix these by including our own implementations, or finding - * another workaround. - */ -#define _upb_snprintf __builtin_snprintf -#define _upb_vsnprintf __builtin_vsnprintf -#define _upb_va_copy(a, b) __va_copy(a, b) -#else -#error Need implementations of [v]snprintf and va_copy -#endif - -#ifdef __cplusplus -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) -/* C++11 is present */ -#else -#error upb requires C++11 for C++ support -#endif -#endif - #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -143,7 +107,7 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #elif defined _MSC_VER #define UPB_ASSUME(expr) if (!(expr)) __assume(0) #else -#define UPB_ASSUME(expr) do {} if (false && (expr)) +#define UPB_ASSUME(expr) do {} while (false && (expr)) #endif #else #define UPB_ASSUME(expr) assert(expr) @@ -157,55 +121,62 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_ASSERT(expr) assert(expr) #endif -/* UPB_ASSERT_DEBUGVAR(): assert that uses functions or variables that only - * exist in debug mode. This turns into regular assert. */ -#define UPB_ASSERT_DEBUGVAR(expr) assert(expr) - #if defined(__GNUC__) || defined(__clang__) #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0) #else #define UPB_UNREACHABLE() do { assert(0); } while(0) #endif -/* UPB_INFINITY representing floating-point positive infinity. */ -#include -#ifdef INFINITY -#define UPB_INFINITY INFINITY -#else -#define UPB_INFINITY (1.0 / 0.0) +#if defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#ifdef __cplusplus +extern "C" { #endif -#ifdef NAN -#define UPB_NAN NAN -#else -#define UPB_NAN (0.0 / 0.0) +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#ifdef __cplusplus +} /* extern "C" */ #endif +#define UPB_POISON_MEMORY_REGION(addr, size) \ + __asan_poison_memory_region((addr), (size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) +#else +#define UPB_ASAN 0 +#define UPB_POISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#endif + #include #include +/* Must be last. */ -/* Maps descriptor type -> upb field type. */ -static const uint8_t desctype_to_fieldtype[] = { +/* Maps descriptor type -> elem_size_lg2. */ +static const uint8_t desctype_to_elem_size_lg2[] = { -1, /* invalid descriptor type */ - UPB_TYPE_DOUBLE, /* DOUBLE */ - UPB_TYPE_FLOAT, /* FLOAT */ - UPB_TYPE_INT64, /* INT64 */ - UPB_TYPE_UINT64, /* UINT64 */ - UPB_TYPE_INT32, /* INT32 */ - UPB_TYPE_UINT64, /* FIXED64 */ - UPB_TYPE_UINT32, /* FIXED32 */ - UPB_TYPE_BOOL, /* BOOL */ - UPB_TYPE_STRING, /* STRING */ - UPB_TYPE_MESSAGE, /* GROUP */ - UPB_TYPE_MESSAGE, /* MESSAGE */ - UPB_TYPE_BYTES, /* BYTES */ - UPB_TYPE_UINT32, /* UINT32 */ - UPB_TYPE_ENUM, /* ENUM */ - UPB_TYPE_INT32, /* SFIXED32 */ - UPB_TYPE_INT64, /* SFIXED64 */ - UPB_TYPE_INT32, /* SINT32 */ - UPB_TYPE_INT64, /* SINT64 */ + 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. */ @@ -314,20 +285,22 @@ static const int8_t delim_ops[37] = { /* Data pertaining to the parse. */ typedef struct { - const char *limit; /* End of delimited region or end of buffer. */ - upb_arena *arena; + const char *end; /* Can read up to 16 bytes slop beyond this. */ + const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */ + int limit; /* Submessage limit relative to end. */ int depth; uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ + bool alias; + char patch[32]; + upb_arena arena; jmp_buf err; } upb_decstate; typedef union { bool bool_val; - int32_t int32_val; - int64_t int64_val; uint32_t uint32_val; uint64_t uint64_val; - upb_strview str_val; + uint32_t size; } wireval; static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, @@ -371,47 +344,54 @@ void decode_verifyutf8(upb_decstate *d, const char *buf, int len) { static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) { bool need_realloc = arr->size - arr->len < elem; - if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) { + if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) { decode_err(d); } return need_realloc; } -UPB_NOINLINE -static const char *decode_longvarint64(upb_decstate *d, const char *ptr, - const char *limit, uint64_t *val) { - uint8_t byte; - int bitpos = 0; - uint64_t out = 0; - - do { - if (bitpos >= 70 || ptr == limit) decode_err(d); - byte = *ptr; - out |= (uint64_t)(byte & 0x7F) << bitpos; - ptr++; - bitpos += 7; - } while (byte & 0x80); +typedef struct { + const char *ptr; + uint64_t val; +} decode_vret; - *val = out; - return ptr; +UPB_NOINLINE +static decode_vret decode_longvarint64(const char *ptr, uint64_t val) { + decode_vret ret = {NULL, 0}; + uint64_t byte; + int i; + for (i = 1; i < 10; i++) { + byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + ret.ptr = ptr + i + 1; + ret.val = val; + return ret; + } + } + return ret; } UPB_FORCEINLINE static const char *decode_varint64(upb_decstate *d, const char *ptr, - const char *limit, uint64_t *val) { - if (UPB_LIKELY(ptr < limit && (*ptr & 0x80) == 0)) { - *val = (uint8_t)*ptr; + uint64_t *val) { + uint64_t byte = (uint8_t)*ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; return ptr + 1; } else { - return decode_longvarint64(d, ptr, limit, val); + decode_vret res = decode_longvarint64(ptr, byte); + if (!res.ptr) decode_err(d); + *val = res.val; + return res.ptr; } } UPB_FORCEINLINE static const char *decode_varint32(upb_decstate *d, const char *ptr, - const char *limit, uint32_t *val) { + uint32_t *val) { uint64_t u64; - ptr = decode_varint64(d, ptr, limit, &u64); + ptr = decode_varint64(d, ptr, &u64); if (u64 > UINT32_MAX) decode_err(d); *val = (uint32_t)u64; return ptr; @@ -424,14 +404,21 @@ static void decode_munge(int type, wireval *val) { break; case UPB_DESCRIPTOR_TYPE_SINT32: { uint32_t n = val->uint32_val; - val->int32_val = (n >> 1) ^ -(int32_t)(n & 1); + val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1); break; } case UPB_DESCRIPTOR_TYPE_SINT64: { uint64_t n = val->uint64_val; - val->int64_val = (n >> 1) ^ -(int64_t)(n & 1); + val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1); break; } + case UPB_DESCRIPTOR_TYPE_INT32: + case UPB_DESCRIPTOR_TYPE_UINT32: + if (!_upb_isle()) { + /* The next stage will memcpy(dst, &val, 4) */ + val->uint32_val = val->uint64_val; + } + break; } } @@ -454,20 +441,85 @@ static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout, const upb_msglayout_field *field) { const upb_msglayout *subl = layout->submsgs[field->submsg_index]; - return _upb_msg_new(subl, d->arena); + return _upb_msg_new_inl(subl, &d->arena); +} + +static int decode_pushlimit(upb_decstate *d, const char *ptr, int size) { + int limit = size + (int)(ptr - d->end); + int delta = d->limit - limit; + d->limit = limit; + d->limit_ptr = d->end + UPB_MIN(0, limit); + return delta; +} + +static void decode_poplimit(upb_decstate *d, int saved_delta) { + d->limit += saved_delta; + d->limit_ptr = d->end + UPB_MIN(0, d->limit); +} + +typedef struct { + bool ok; + const char *ptr; +} decode_doneret; + +UPB_NOINLINE +static const char *decode_isdonefallback(upb_decstate *d, const char *ptr, + int overrun) { + if (overrun < d->limit) { + /* Need to copy remaining data into patch buffer. */ + UPB_ASSERT(overrun < 16); + memset(d->patch + 16, 0, 16); + memcpy(d->patch, d->end, 16); + ptr = &d->patch[0] + overrun; + d->end = &d->patch[16]; + d->limit -= 16; + d->limit_ptr = d->end + d->limit; + d->alias = false; + UPB_ASSERT(ptr < d->limit_ptr); + return ptr; + } else { + decode_err(d); + } } -static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg, - const upb_msglayout *layout, - const upb_msglayout_field *field, upb_strview val) { +UPB_FORCEINLINE +static bool decode_isdone(upb_decstate *d, const char **ptr) { + int overrun = *ptr - d->end; + if (UPB_LIKELY(*ptr < d->limit_ptr)) { + return false; + } else if (UPB_LIKELY(overrun == d->limit)) { + return true; + } else { + *ptr = decode_isdonefallback(d, *ptr, overrun); + return false; + } +} + +static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, + upb_strview *str) { + if (d->alias) { + str->data = ptr; + } else { + char *data = upb_arena_malloc(&d->arena, size); + if (!data) decode_err(d); + memcpy(data, ptr, size); + str->data = data; + } + str->size = size; + return ptr + size; +} + +static const char *decode_tosubmsg(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *layout, + const upb_msglayout_field *field, int size) { const upb_msglayout *subl = layout->submsgs[field->submsg_index]; - const char *saved_limit = d->limit; + int saved_delta = decode_pushlimit(d, ptr, size); if (--d->depth < 0) decode_err(d); - d->limit = val.data + val.size; - decode_msg(d, val.data, submsg, subl); - d->limit = saved_limit; + ptr = decode_msg(d, ptr, submsg, subl); + decode_poplimit(d, saved_delta); if (d->end_group != 0) decode_err(d); d->depth++; + return ptr; } static const char *decode_group(upb_decstate *d, const char *ptr, @@ -496,15 +548,15 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, upb_array *arr = *arrp; void *mem; - if (!arr) { - upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype]; - arr = _upb_array_new(d->arena, type); + if (arr) { + decode_reserve(d, arr, 1); + } else { + size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype]; + arr = _upb_array_new(&d->arena, 4, lg2); if (!arr) decode_err(d); *arrp = arr; } - decode_reserve(d, arr, 1); - switch (op) { case OP_SCALAR_LG2(0): case OP_SCALAR_LG2(2): @@ -515,15 +567,14 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, memcpy(mem, &val, 1 << op); return ptr; case OP_STRING: - decode_verifyutf8(d, val.str_val.data, val.str_val.size); + decode_verifyutf8(d, ptr, val.size); /* Fallthrough. */ - case OP_BYTES: + case OP_BYTES: { /* Append bytes. */ - mem = - UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void); + upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len; arr->len++; - memcpy(mem, &val, sizeof(upb_strview)); - return ptr; + return decode_readstr(d, ptr, val.size, str); + } case OP_SUBMSG: { /* Append submessage / group. */ upb_msg *submsg = decode_newsubmsg(d, layout, field); @@ -531,26 +582,25 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, submsg; arr->len++; if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) { - ptr = decode_togroup(d, ptr, submsg, layout, field); + return decode_togroup(d, ptr, submsg, layout, field); } else { - decode_tosubmsg(d, submsg, layout, field, val.str_val); + return decode_tosubmsg(d, ptr, submsg, layout, field, val.size); } - return ptr; } case OP_FIXPCK_LG2(2): case OP_FIXPCK_LG2(3): { /* Fixed packed. */ int lg2 = op - OP_FIXPCK_LG2(0); int mask = (1 << lg2) - 1; - size_t count = val.str_val.size >> lg2; - if ((val.str_val.size & mask) != 0) { + 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, val.str_val.data, val.str_val.size); - return ptr; + memcpy(mem, ptr, val.size); /* XXX: ptr boundary. */ + return ptr + val.size; } case OP_VARPCK_LG2(0): case OP_VARPCK_LG2(2): @@ -558,12 +608,11 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, /* Varint packed. */ int lg2 = op - OP_VARPCK_LG2(0); int scale = 1 << lg2; - const char *ptr = val.str_val.data; - const char *end = ptr + val.str_val.size; + int saved_limit = decode_pushlimit(d, ptr, val.size); char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); - while (ptr < end) { + while (!decode_isdone(d, &ptr)) { wireval elem; - ptr = decode_varint64(d, ptr, end, &elem.uint64_val); + 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); @@ -572,7 +621,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, memcpy(out, &elem, scale); out += scale; } - if (ptr != end) decode_err(d); + decode_poplimit(d, saved_limit); return ptr; } default: @@ -580,9 +629,9 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, } } -static void decode_tomap(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, - const upb_msglayout_field *field, wireval val) { +static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val) { upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *); upb_map *map = *map_p; upb_map_entry ent; @@ -597,7 +646,7 @@ static void decode_tomap(upb_decstate *d, upb_msg *msg, char val_size = desctype_to_mapsize[val_field->descriptortype]; UPB_ASSERT(key_field->offset == 0); UPB_ASSERT(val_field->offset == sizeof(upb_strview)); - map = _upb_map_new(d->arena, key_size, val_size); + map = _upb_map_new(&d->arena, key_size, val_size); *map_p = map; } @@ -607,13 +656,12 @@ static void decode_tomap(upb_decstate *d, upb_msg *msg, if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) { /* Create proactively to handle the case where it doesn't appear. */ - ent.v.val.val = (uint64_t)_upb_msg_new(entry->submsgs[0], d->arena); + ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena)); } - decode_tosubmsg(d, &ent.k, layout, field, val.str_val); - - /* Insert into map. */ - _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena); + ptr = decode_tosubmsg(d, ptr, &ent.k, layout, field, val.size); + _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena); + return ptr; } static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, @@ -647,16 +695,15 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) { ptr = decode_togroup(d, ptr, submsg, layout, field); } else { - decode_tosubmsg(d, submsg, layout, field, val.str_val); + ptr = decode_tosubmsg(d, ptr, submsg, layout, field, val.size); } break; } case OP_STRING: - decode_verifyutf8(d, val.str_val.data, val.str_val.size); + decode_verifyutf8(d, ptr, val.size); /* Fallthrough. */ case OP_BYTES: - memcpy(mem, &val, sizeof(upb_strview)); - break; + return decode_readstr(d, ptr, val.size, mem); case OP_SCALAR_LG2(3): memcpy(mem, &val, 8); break; @@ -675,7 +722,7 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, const upb_msglayout *layout) { - while (ptr < d->limit) { + while (!decode_isdone(d, &ptr)) { uint32_t tag; const upb_msglayout_field *field; int field_number; @@ -684,7 +731,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, wireval val; int op; - ptr = decode_varint32(d, ptr, d->limit, &tag); + ptr = decode_varint32(d, ptr, &tag); field_number = tag >> 3; wire_type = tag & 7; @@ -692,40 +739,37 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, switch (wire_type) { case UPB_WIRE_TYPE_VARINT: - ptr = decode_varint64(d, ptr, d->limit, &val.uint64_val); + ptr = decode_varint64(d, ptr, &val.uint64_val); op = varint_ops[field->descriptortype]; decode_munge(field->descriptortype, &val); break; case UPB_WIRE_TYPE_32BIT: - if (d->limit - ptr < 4) decode_err(d); - memcpy(&val, ptr, 4); + 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: - if (d->limit - ptr < 8) decode_err(d); - memcpy(&val, ptr, 8); + 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: { - uint32_t size; int ndx = field->descriptortype; if (_upb_isrepeated(field)) ndx += 18; - ptr = decode_varint32(d, ptr, d->limit, &size); - if (size >= INT32_MAX || (size_t)(d->limit - ptr) < size) { + ptr = decode_varint32(d, ptr, &val.size); + if (val.size >= INT32_MAX || + ptr - d->end + (int32_t)val.size > d->limit) { decode_err(d); /* Length overflow. */ } - val.str_val.data = ptr; - val.str_val.size = size; - ptr += size; op = delim_ops[ndx]; break; } case UPB_WIRE_TYPE_START_GROUP: - val.int32_val = field_number; + val.uint32_val = field_number; op = OP_SUBMSG; if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown; break; @@ -744,7 +788,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, ptr = decode_toarray(d, ptr, msg, layout, field, val, op); break; case _UPB_LABEL_MAP: - decode_tomap(d, msg, layout, field, val); + ptr = decode_tomap(d, ptr, msg, layout, field, val); break; default: ptr = decode_tomsg(d, ptr, msg, layout, field, val, op); @@ -758,32 +802,55 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, ptr = decode_group(d, ptr, NULL, NULL, field_number); } if (msg) { + if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size; if (!_upb_msg_addunknown(msg, field_start, ptr - field_start, - d->arena)) { + &d->arena)) { decode_err(d); } } } } - if (ptr != d->limit) decode_err(d); return ptr; } bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, upb_arena *arena) { + bool ok; upb_decstate state; - state.limit = buf + size; - state.arena = arena; + + if (size == 0) { + return true; + } else if (size < 16) { + memset(&state.patch, 0, 32); + memcpy(&state.patch, buf, size); + buf = state.patch; + state.end = buf + size; + state.limit = 0; + state.alias = false; + } else { + state.end = buf + size - 16; + state.limit = 16; + state.alias = true; + } + + state.limit_ptr = state.end; state.depth = 64; state.end_group = 0; + state.arena.head = arena->head; + state.arena.last_size = arena->last_size; + state.arena.parent = arena; - if (setjmp(state.err)) return false; - - if (size == 0) return true; - decode_msg(&state, buf, msg, l); + if (UPB_UNLIKELY(setjmp(state.err))) { + ok = false; + } else { + decode_msg(&state, buf, msg, l); + ok = state.end_group == 0; + } - return state.end_group == 0; + arena->head.ptr = state.arena.head.ptr; + arena->head.end = state.arena.head.end; + return ok; } #undef OP_SCALAR_LG2 @@ -794,30 +861,30 @@ bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */ +#include #include #define UPB_PB_VARINT_MAX_LEN 10 -#define CHK(x) do { if (!(x)) { return false; } } while(0) -static size_t upb_encode_varint(uint64_t val, char *buf) { - size_t i; - if (val < 128) { buf[0] = val; return 1; } - i = 0; - while (val) { +UPB_NOINLINE +static size_t encode_varint64(uint64_t val, char *buf) { + size_t i = 0; + do { uint8_t byte = val & 0x7fU; val >>= 7; if (val) byte |= 0x80U; buf[i++] = byte; - } + } while (val); return i; } -static uint32_t upb_zzencode_32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); } -static uint64_t upb_zzencode_64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); } +static uint32_t encode_zz32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); } +static uint64_t encode_zz64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); } typedef struct { + jmp_buf err; upb_alloc *alloc; char *buf, *ptr, *limit; } upb_encstate; @@ -830,11 +897,15 @@ static size_t upb_roundup_pow2(size_t bytes) { return ret; } -static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) { +UPB_NORETURN static void encode_err(upb_encstate *e) { longjmp(e->err, 1); } + +UPB_NOINLINE +static void encode_growbuffer(upb_encstate *e, size_t bytes) { size_t old_size = e->limit - e->buf; size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr)); char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size); - CHK(new_buf); + + if (!new_buf) encode_err(e); /* We want previous data at the end, realloc() put it at the beginning. */ if (old_size > 0) { @@ -844,99 +915,115 @@ static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) { e->ptr = new_buf + new_size - (e->limit - e->ptr); e->limit = new_buf + new_size; e->buf = new_buf; - return true; + + e->ptr -= bytes; } /* Call to ensure that at least "bytes" bytes are available for writing at * e->ptr. Returns false if the bytes could not be allocated. */ -static bool upb_encode_reserve(upb_encstate *e, size_t bytes) { - CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) || - upb_encode_growbuffer(e, bytes)); +UPB_FORCEINLINE +static void encode_reserve(upb_encstate *e, size_t bytes) { + if ((size_t)(e->ptr - e->buf) < bytes) { + encode_growbuffer(e, bytes); + return; + } e->ptr -= bytes; - return true; } /* Writes the given bytes to the buffer, handling reserve/advance. */ -static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) { - if (len == 0) return true; - CHK(upb_encode_reserve(e, len)); +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); - return true; } -static bool upb_put_fixed64(upb_encstate *e, uint64_t val) { - /* TODO(haberman): byte-swap for big endian. */ - return upb_put_bytes(e, &val, sizeof(uint64_t)); +static void encode_fixed64(upb_encstate *e, uint64_t val) { + val = _upb_be_swap64(val); + encode_bytes(e, &val, sizeof(uint64_t)); } -static bool upb_put_fixed32(upb_encstate *e, uint32_t val) { - /* TODO(haberman): byte-swap for big endian. */ - return upb_put_bytes(e, &val, sizeof(uint32_t)); +static void encode_fixed32(upb_encstate *e, uint32_t val) { + val = _upb_be_swap32(val); + encode_bytes(e, &val, sizeof(uint32_t)); } -static bool upb_put_varint(upb_encstate *e, uint64_t val) { +UPB_NOINLINE +static void encode_longvarint(upb_encstate *e, uint64_t val) { size_t len; char *start; - CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN)); - len = upb_encode_varint(val, e->ptr); + + encode_reserve(e, UPB_PB_VARINT_MAX_LEN); + len = encode_varint64(val, e->ptr); start = e->ptr + UPB_PB_VARINT_MAX_LEN - len; memmove(start, e->ptr, len); e->ptr = start; - return true; } -static bool upb_put_double(upb_encstate *e, double d) { +UPB_FORCEINLINE +static void encode_varint(upb_encstate *e, uint64_t val) { + if (val < 128 && e->ptr != e->buf) { + --e->ptr; + *e->ptr = val; + } else { + encode_longvarint(e, val); + } +} + +static void encode_double(upb_encstate *e, double d) { uint64_t u64; UPB_ASSERT(sizeof(double) == sizeof(uint64_t)); memcpy(&u64, &d, sizeof(uint64_t)); - return upb_put_fixed64(e, u64); + encode_fixed64(e, u64); } -static bool upb_put_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)); - return upb_put_fixed32(e, u32); + encode_fixed32(e, u32); } -static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) { - return upb_put_varint(e, (field_number << 3) | wire_type); +static void encode_tag(upb_encstate *e, int field_number, int wire_type) { + encode_varint(e, (field_number << 3) | wire_type); } -static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr, +static void encode_fixedarray(upb_encstate *e, const upb_array *arr, size_t elem_size, uint32_t tag) { size_t bytes = arr->len * elem_size; const char* data = _upb_array_constptr(arr); const char* ptr = data + bytes - elem_size; if (tag) { while (true) { - CHK(upb_put_bytes(e, ptr, elem_size) && upb_put_varint(e, tag)); + encode_bytes(e, ptr, elem_size); + encode_varint(e, tag); if (ptr == data) break; ptr -= elem_size; } - return true; } else { - return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes); + encode_bytes(e, data, bytes); } } -bool upb_encode_message(upb_encstate *e, const char *msg, - const upb_msglayout *m, size_t *size); +static void encode_message(upb_encstate *e, const char *msg, + const upb_msglayout *m, size_t *size); -static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem, - const upb_msglayout *m, - const upb_msglayout_field *f, - bool skip_zero_value) { +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; -#define CASE(ctype, type, wire_type, encodeval) do { \ - ctype val = *(ctype*)field_mem; \ - if (skip_zero_value && val == 0) { \ - return true; \ - } \ - return upb_put_ ## type(e, encodeval) && \ - upb_put_tag(e, f->number, wire_type); \ -} while(0) + int wire_type; + +#define CASE(ctype, type, wtype, encodeval) \ + { \ + ctype val = *(ctype *)field_mem; \ + if (skip_zero_value && val == 0) { \ + return; \ + } \ + encode_##type(e, encodeval); \ + wire_type = wtype; \ + break; \ + } switch (f->descriptortype) { case UPB_DESCRIPTOR_TYPE_DOUBLE: @@ -960,90 +1047,91 @@ static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem, case UPB_DESCRIPTOR_TYPE_BOOL: CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val); case UPB_DESCRIPTOR_TYPE_SINT32: - CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val)); + CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz32(val)); case UPB_DESCRIPTOR_TYPE_SINT64: - CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val)); + 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 true; + return; } - return upb_put_bytes(e, view.data, view.size) && - upb_put_varint(e, view.size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + encode_bytes(e, view.data, view.size); + encode_varint(e, view.size); + wire_type = UPB_WIRE_TYPE_DELIMITED; + break; } case UPB_DESCRIPTOR_TYPE_GROUP: { size_t size; void *submsg = *(void **)field_mem; const upb_msglayout *subm = m->submsgs[f->submsg_index]; if (submsg == NULL) { - return true; + return; } - return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) && - upb_encode_message(e, submsg, subm, &size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); + encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_message(e, submsg, subm, &size); + wire_type = UPB_WIRE_TYPE_START_GROUP; + break; } case UPB_DESCRIPTOR_TYPE_MESSAGE: { size_t size; void *submsg = *(void **)field_mem; const upb_msglayout *subm = m->submsgs[f->submsg_index]; if (submsg == NULL) { - return true; + return; } - return upb_encode_message(e, submsg, subm, &size) && - upb_put_varint(e, size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + encode_message(e, submsg, subm, &size); + encode_varint(e, size); + wire_type = UPB_WIRE_TYPE_DELIMITED; + break; } + default: + UPB_UNREACHABLE(); } #undef CASE - UPB_UNREACHABLE(); + + encode_tag(e, f->number, wire_type); } -static bool upb_encode_array(upb_encstate *e, const char *field_mem, - const upb_msglayout *m, - const upb_msglayout_field *f) { +static void encode_array(upb_encstate *e, const char *field_mem, + const upb_msglayout *m, const upb_msglayout_field *f) { const upb_array *arr = *(const upb_array**)field_mem; bool packed = f->label == _UPB_LABEL_PACKED; + size_t pre_len = e->limit - e->ptr; if (arr == NULL || arr->len == 0) { - return true; + return; } #define VARINT_CASE(ctype, encode) \ { \ const ctype *start = _upb_array_constptr(arr); \ const ctype *ptr = start + arr->len; \ - size_t pre_len = e->limit - e->ptr; \ uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \ do { \ ptr--; \ - CHK(upb_put_varint(e, encode)); \ - if (tag) CHK(upb_put_varint(e, tag)); \ + encode_varint(e, encode); \ + if (tag) encode_varint(e, tag); \ } while (ptr != start); \ - if (!tag) CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \ } \ - break; \ - do { \ - ; \ - } while (0) + break; #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type)) switch (f->descriptortype) { case UPB_DESCRIPTOR_TYPE_DOUBLE: - CHK(upb_put_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT))); + encode_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT)); break; case UPB_DESCRIPTOR_TYPE_FLOAT: - CHK(upb_put_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT))); + encode_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT)); break; case UPB_DESCRIPTOR_TYPE_SFIXED64: case UPB_DESCRIPTOR_TYPE_FIXED64: - CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT))); + encode_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT)); break; case UPB_DESCRIPTOR_TYPE_FIXED32: case UPB_DESCRIPTOR_TYPE_SFIXED32: - CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT))); + encode_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT)); break; case UPB_DESCRIPTOR_TYPE_INT64: case UPB_DESCRIPTOR_TYPE_UINT64: @@ -1056,20 +1144,20 @@ static bool upb_encode_array(upb_encstate *e, const char *field_mem, case UPB_DESCRIPTOR_TYPE_BOOL: VARINT_CASE(bool, *ptr); case UPB_DESCRIPTOR_TYPE_SINT32: - VARINT_CASE(int32_t, upb_zzencode_32(*ptr)); + VARINT_CASE(int32_t, encode_zz32(*ptr)); case UPB_DESCRIPTOR_TYPE_SINT64: - VARINT_CASE(int64_t, upb_zzencode_64(*ptr)); + VARINT_CASE(int64_t, encode_zz64(*ptr)); case UPB_DESCRIPTOR_TYPE_STRING: case UPB_DESCRIPTOR_TYPE_BYTES: { const upb_strview *start = _upb_array_constptr(arr); const upb_strview *ptr = start + arr->len; do { ptr--; - CHK(upb_put_bytes(e, ptr->data, ptr->size) && - upb_put_varint(e, ptr->size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + encode_bytes(e, ptr->data, ptr->size); + encode_varint(e, ptr->size); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); } while (ptr != start); - return true; + return; } case UPB_DESCRIPTOR_TYPE_GROUP: { const void *const*start = _upb_array_constptr(arr); @@ -1078,11 +1166,11 @@ static bool upb_encode_array(upb_encstate *e, const char *field_mem, do { size_t size; ptr--; - CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) && - upb_encode_message(e, *ptr, subm, &size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP)); + encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_message(e, *ptr, subm, &size); + encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); } while (ptr != start); - return true; + return; } case UPB_DESCRIPTOR_TYPE_MESSAGE: { const void *const*start = _upb_array_constptr(arr); @@ -1091,31 +1179,30 @@ static bool upb_encode_array(upb_encstate *e, const char *field_mem, do { size_t size; ptr--; - CHK(upb_encode_message(e, *ptr, subm, &size) && - upb_put_varint(e, size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + encode_message(e, *ptr, subm, &size); + encode_varint(e, size); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); } while (ptr != start); - return true; + return; } } #undef VARINT_CASE if (packed) { - CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + encode_varint(e, e->limit - e->ptr - pre_len); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); } - return true; } -static bool upb_encode_map(upb_encstate *e, const char *field_mem, - const upb_msglayout *m, - const upb_msglayout_field *f) { +static void encode_map(upb_encstate *e, const char *field_mem, + const upb_msglayout *m, const upb_msglayout_field *f) { const upb_map *map = *(const upb_map**)field_mem; const upb_msglayout *entry = m->submsgs[f->submsg_index]; const upb_msglayout_field *key_field = &entry->fields[0]; const upb_msglayout_field *val_field = &entry->fields[1]; upb_strtable_iter i; if (map == NULL) { - return true; + return; } upb_strtable_begin(&i, &map->table); @@ -1127,59 +1214,57 @@ static bool upb_encode_map(upb_encstate *e, const char *field_mem, upb_map_entry ent; _upb_map_fromkey(key, &ent.k, map->key_size); _upb_map_fromvalue(val, &ent.v, map->val_size); - CHK(upb_encode_scalarfield(e, &ent.v, entry, val_field, false)); - CHK(upb_encode_scalarfield(e, &ent.k, entry, key_field, false)); + encode_scalar(e, &ent.v, entry, val_field, false); + encode_scalar(e, &ent.k, entry, key_field, false); size = (e->limit - e->ptr) - pre_len; - CHK(upb_put_varint(e, size)); - CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + encode_varint(e, size); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); } - - return true; } +static void encode_scalarfield(upb_encstate *e, const char *msg, + const upb_msglayout *m, + const upb_msglayout_field *f) { + bool skip_empty = false; + if (f->presence == 0) { + /* Proto3 presence. */ + skip_empty = true; + } else if (f->presence > 0) { + /* Proto2 presence: hasbit. */ + if (!_upb_hasbit_field(msg, f)) return; + } else { + /* Field is in a oneof. */ + if (_upb_getoneofcase_field(msg, f) != f->number) return; + } + encode_scalar(e, msg + f->offset, m, f, skip_empty); +} -bool upb_encode_message(upb_encstate *e, const char *msg, - const upb_msglayout *m, size_t *size) { - int i; +static void encode_message(upb_encstate *e, const char *msg, + const upb_msglayout *m, size_t *size) { size_t pre_len = e->limit - e->ptr; const char *unknown; size_t unknown_size; + const upb_msglayout_field *f = &m->fields[m->field_count]; + const upb_msglayout_field *first = &m->fields[0]; unknown = upb_msg_getunknown(msg, &unknown_size); if (unknown) { - upb_put_bytes(e, unknown, unknown_size); + encode_bytes(e, unknown, unknown_size); } - for (i = m->field_count - 1; i >= 0; i--) { - const upb_msglayout_field *f = &m->fields[i]; - + while (f != first) { + f--; if (_upb_isrepeated(f)) { - CHK(upb_encode_array(e, msg + f->offset, m, f)); + encode_array(e, msg + f->offset, m, f); } else if (f->label == _UPB_LABEL_MAP) { - CHK(upb_encode_map(e, msg + f->offset, m, f)); + encode_map(e, msg + f->offset, m, f); } else { - bool skip_empty = false; - if (f->presence == 0) { - /* Proto3 presence. */ - skip_empty = true; - } else if (f->presence > 0) { - /* Proto2 presence: hasbit. */ - if (!_upb_hasbit_field(msg, f)) { - continue; - } - } else { - /* Field is in a oneof. */ - if (_upb_getoneofcase_field(msg, f) != f->number) { - continue; - } - } - CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty)); + encode_scalarfield(e, msg, m, f); } } *size = (e->limit - e->ptr) - pre_len; - return true; } char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, @@ -1190,11 +1275,13 @@ char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, e.limit = NULL; e.ptr = NULL; - if (!upb_encode_message(&e, msg, m, size)) { + if (setjmp(e.err)) { *size = 0; return NULL; } + encode_message(&e, msg, m, size); + *size = e.limit - e.ptr; if (*size == 0) { @@ -1206,113 +1293,72 @@ char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, } } -#undef CHK - /** upb_msg *******************************************************************/ -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 uintptr_t tag_arrptr(void* ptr, int elem_size_lg2) { - UPB_ASSERT(elem_size_lg2 <= 4); - return (uintptr_t)ptr | elem_size_lg2; -} - -static int upb_msg_internalsize(const upb_msglayout *l) { - return sizeof(upb_msg_internal) - l->extendable * sizeof(void *); -} - -static size_t upb_msg_sizeof(const upb_msglayout *l) { - return l->size + upb_msg_internalsize(l); -} +static const size_t overhead = sizeof(upb_msg_internal); static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) { ptrdiff_t size = sizeof(upb_msg_internal); - return UPB_PTR_AT(msg, -size, upb_msg_internal); + return (upb_msg_internal*)((char*)msg - size); } -static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) { - return (upb_msg_internal*)upb_msg_getinternal_const(msg); +upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) { + return _upb_msg_new_inl(l, a); } void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) { - ptrdiff_t internal = upb_msg_internalsize(l); - void *mem = UPB_PTR_AT(msg, -internal, char); - memset(mem, 0, l->size + internal); -} - -upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) { - void *mem = upb_arena_malloc(a, upb_msg_sizeof(l)); - upb_msg *msg; - - if (!mem) { - return NULL; - } - - msg = UPB_PTR_AT(mem, upb_msg_internalsize(l), upb_msg); - _upb_msg_clear(msg, l); - return msg; + void *mem = UPB_PTR_AT(msg, -sizeof(upb_msg_internal), char); + memset(mem, 0, upb_msg_sizeof(l)); } bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, upb_arena *arena) { + upb_msg_internal *in = upb_msg_getinternal(msg); - if (len > in->unknown_size - in->unknown_len) { - upb_alloc *alloc = upb_arena_alloc(arena); - size_t need = in->unknown_size + len; - size_t newsize = UPB_MAX(in->unknown_size * 2, need); - void *mem = upb_realloc(alloc, in->unknown, in->unknown_size, newsize); - if (!mem) return false; - in->unknown = mem; - in->unknown_size = newsize; - } - memcpy(in->unknown + in->unknown_len, data, len); - in->unknown_len += len; + if (!in->unknown) { + size_t size = 128; + while (size < len) size *= 2; + in->unknown = upb_arena_malloc(arena, size + overhead); + if (!in->unknown) return false; + in->unknown->size = size; + in->unknown->len = 0; + } else if (in->unknown->size - in->unknown->len < len) { + size_t need = in->unknown->len + len; + size_t size = in->unknown->size; + while (size < need) size *= 2; + in->unknown = upb_arena_realloc( + arena, in->unknown, in->unknown->size + overhead, size + overhead); + if (!in->unknown) return false; + in->unknown->size = size; + } + memcpy(UPB_PTR_AT(in->unknown + 1, in->unknown->len, char), data, len); + in->unknown->len += len; return true; } void _upb_msg_discardunknown_shallow(upb_msg *msg) { upb_msg_internal *in = upb_msg_getinternal(msg); - in->unknown_len = 0; + if (in->unknown) { + in->unknown->len = 0; + } } const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { const upb_msg_internal *in = upb_msg_getinternal_const(msg); - *len = in->unknown_len; - return in->unknown; -} - -/** upb_array *****************************************************************/ - -upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type) { - upb_array *arr = upb_arena_malloc(a, sizeof(upb_array)); - - if (!arr) { + if (in->unknown) { + *len = in->unknown->len; + return (char*)(in->unknown + 1); + } else { + *len = 0; return NULL; } - - arr->data = tag_arrptr(NULL, _upb_fieldtype_to_sizelg2[type]); - arr->len = 0; - arr->size = 0; - - return arr; } +/** upb_array *****************************************************************/ + bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { size_t new_size = UPB_MAX(arr->size, 4); int elem_size_lg2 = arr->data & 7; @@ -1330,16 +1376,16 @@ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { return false; } - arr->data = tag_arrptr(ptr, elem_size_lg2); + arr->data = _upb_tag_arrptr(ptr, elem_size_lg2); arr->size = new_size; return true; } -static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type, +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, type); + arr = _upb_array_new(arena, 4, elem_size_lg2); if (!arr) return NULL; *arr_ptr = arr; } @@ -1347,22 +1393,25 @@ static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type, } void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, - upb_fieldtype_t type, upb_arena *arena) { - upb_array *arr = getorcreate_array(arr_ptr, type, arena); - return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr) : NULL; + 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, - upb_fieldtype_t type, upb_arena *arena) { - upb_array *arr = getorcreate_array(arr_ptr, type, arena); - size_t elem = arr->len; - int lg2 = _upb_fieldtype_to_sizelg2[type]; - char *data; + int elem_size_lg2, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena); + if (!arr) return false; - if (!arr || !_upb_array_resize(arr, elem + 1, arena)) return false; + size_t elems = arr->len; - data = _upb_array_ptr(arr); - memcpy(data + (elem << lg2), value, 1 << lg2); + if (!_upb_array_resize(arr, elems + 1, arena)) { + return false; + } + + char *data = _upb_array_ptr(arr); + memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2); return true; } @@ -1375,7 +1424,7 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { return NULL; } - upb_strtable_init2(&map->table, UPB_CTYPE_INT32, upb_arena_alloc(a)); + upb_strtable_init2(&map->table, UPB_CTYPE_INT32, 4, upb_arena_alloc(a)); map->key_size = key_size; map->val_size = value_size; @@ -1387,9 +1436,11 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { ** Implementation is heavily inspired by Lua's ltable.c. */ - #include +#include "third_party/wyhash/wyhash.h" + +/* Must be last. */ #define UPB_MAXARRSIZE 16 /* 64k. */ @@ -1468,11 +1519,7 @@ static upb_tabent *mutable_entries(upb_table *t) { } static bool isfull(upb_table *t) { - if (upb_table_size(t) == 0) { - return true; - } else { - return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD; - } + return t->count == t->max_count; } static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) { @@ -1481,6 +1528,7 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) { t->count = 0; t->size_lg2 = size_lg2; t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0; + t->max_count = upb_table_size(t) * MAX_LOAD; bytes = upb_table_size(t) * sizeof(upb_tabent); if (bytes > 0) { t->entries = upb_malloc(a, bytes); @@ -1496,9 +1544,17 @@ static void uninit(upb_table *t, upb_alloc *a) { upb_free(a, mutable_entries(t)); } -static upb_tabent *emptyent(upb_table *t) { - upb_tabent *e = mutable_entries(t) + upb_table_size(t); - while (1) { if (upb_tabent_isempty(--e)) return e; UPB_ASSERT(e > t->entries); } +static upb_tabent *emptyent(upb_table *t, upb_tabent *e) { + upb_tabent *begin = mutable_entries(t); + upb_tabent *end = begin + upb_table_size(t); + for (e = e + 1; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + for (e = begin; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + UPB_ASSERT(false); + return NULL; } static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) { @@ -1554,7 +1610,7 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, our_e->next = NULL; } else { /* Collision. */ - upb_tabent *new_e = emptyent(t); + upb_tabent *new_e = emptyent(t, mainpos_e); /* Head of collider's chain. */ upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key)); if (chain == mainpos_e) { @@ -1649,10 +1705,14 @@ static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) { return (uintptr_t)str; } +static uint32_t table_hash(const char *p, size_t n) { + return wyhash(p, n, 0, _wyp); +} + static uint32_t strhash(upb_tabkey key) { uint32_t len; char *str = upb_tabstr(key, &len); - return upb_murmur_hash2(str, len, 0); + return table_hash(str, len); } static bool streql(upb_tabkey k1, lookupkey_t k2) { @@ -1661,9 +1721,14 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) { return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0); } -bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) { +bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, + size_t expected_size, upb_alloc *a) { UPB_UNUSED(ctype); /* TODO(haberman): rm */ - return init(&t->t, 2, 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); + return init(&t->t, size_lg2, a); } void upb_strtable_clear(upb_strtable *t) { @@ -1714,20 +1779,20 @@ bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len, tabkey = strcopy(key, a); if (tabkey == 0) return false; - hash = upb_murmur_hash2(key.str.str, key.str.len, 0); + hash = table_hash(key.str.str, key.str.len); insert(&t->t, key, tabkey, v, hash, &strhash, &streql); return true; } bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, upb_value *v) { - uint32_t hash = upb_murmur_hash2(key, len, 0); + uint32_t hash = table_hash(key, len); return lookup(&t->t, strkey2(key, len), v, hash, &streql); } bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, upb_value *val, upb_alloc *alloc) { - uint32_t hash = upb_murmur_hash2(key, len, 0); + uint32_t hash = table_hash(key, len); upb_tabkey tabkey; if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) { if (alloc) { @@ -2081,234 +2146,55 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, i1->array_part == i2->array_part; } -#if defined(UPB_UNALIGNED_READS_OK) || defined(__s390x__) -/* ----------------------------------------------------------------------------- - * MurmurHash2, by Austin Appleby (released as public domain). - * Reformatted and C99-ified by Joshua Haberman. - * Note - This code makes a few assumptions about how your machine behaves - - * 1. We can read a 4-byte value from any address without crashing - * 2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t - * And it has a few limitations - - * 1. It will not work incrementally. - * 2. It will not produce the same results on little-endian and big-endian - * machines. */ -uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) { - /* 'm' and 'r' are mixing constants generated offline. - * They're not really 'magic', they just happen to work well. */ - const uint32_t m = 0x5bd1e995; - const int32_t r = 24; - - /* Initialize the hash to a 'random' value */ - uint32_t h = seed ^ len; - - /* Mix 4 bytes at a time into the hash */ - const uint8_t * data = (const uint8_t *)key; - while(len >= 4) { - uint32_t k; - memcpy(&k, data, sizeof(k)); - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - /* Handle the last few bytes of the input array */ - switch(len) { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; h *= m; - }; - - /* Do a few final mixes of the hash to ensure the last few - * bytes are well-incorporated. */ - h ^= h >> 13; - h *= m; - h ^= h >> 15; - return h; -} +#include +#include +#include +#include +#include +#include +#include -#else /* !UPB_UNALIGNED_READS_OK */ -/* ----------------------------------------------------------------------------- - * MurmurHashAligned2, by Austin Appleby - * Same algorithm as MurmurHash2, but only does aligned reads - should be safer - * on certain platforms. - * Performance will be lower than MurmurHash2 */ +/* upb_status *****************************************************************/ -#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; } +void upb_status_clear(upb_status *status) { + if (!status) return; + status->ok = true; + status->msg[0] = '\0'; +} -uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed) { - const uint32_t m = 0x5bd1e995; - const int32_t r = 24; - const uint8_t * data = (const uint8_t *)key; - uint32_t h = (uint32_t)(seed ^ len); - uint8_t align = (uintptr_t)data & 3; +bool upb_ok(const upb_status *status) { return status->ok; } - if(align && (len >= 4)) { - /* Pre-load the temp registers */ - uint32_t t = 0, d = 0; - int32_t sl; - int32_t sr; +const char *upb_status_errmsg(const upb_status *status) { return status->msg; } - switch(align) { - case 1: t |= data[2] << 16; /* fallthrough */ - case 2: t |= data[1] << 8; /* fallthrough */ - case 3: t |= data[0]; - } +void upb_status_seterrmsg(upb_status *status, const char *msg) { + if (!status) return; + status->ok = false; + strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; +} - t <<= (8 * align); +void upb_status_seterrf(upb_status *status, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + upb_status_vseterrf(status, fmt, args); + va_end(args); +} - data += 4-align; - len -= 4-align; - - sl = 8 * (4-align); - sr = 8 * align; - - /* Mix */ - - while(len >= 4) { - uint32_t k; - - d = *(uint32_t *)data; - t = (t >> sr) | (d << sl); - - k = t; - - MIX(h,k,m); - - t = d; - - data += 4; - len -= 4; - } - - /* Handle leftover data in temp registers */ - - d = 0; - - if(len >= align) { - uint32_t k; - - switch(align) { - case 3: d |= data[2] << 16; /* fallthrough */ - case 2: d |= data[1] << 8; /* fallthrough */ - case 1: d |= data[0]; /* fallthrough */ - } - - k = (t >> sr) | (d << sl); - MIX(h,k,m); - - data += align; - len -= align; - - /* ---------- - * Handle tail bytes */ - - switch(len) { - case 3: h ^= data[2] << 16; /* fallthrough */ - case 2: h ^= data[1] << 8; /* fallthrough */ - case 1: h ^= data[0]; h *= m; /* fallthrough */ - }; - } else { - switch(len) { - case 3: d |= data[2] << 16; /* fallthrough */ - case 2: d |= data[1] << 8; /* fallthrough */ - case 1: d |= data[0]; /* fallthrough */ - case 0: h ^= (t >> sr) | (d << sl); h *= m; - } - } - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; - } else { - while(len >= 4) { - uint32_t k = *(uint32_t *)data; - - MIX(h,k,m); - - data += 4; - len -= 4; - } - - /* ---------- - * Handle tail bytes */ - - switch(len) { - case 3: h ^= data[2] << 16; /* fallthrough */ - case 2: h ^= data[1] << 8; /* fallthrough */ - case 1: h ^= data[0]; h *= m; - }; - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; - } -} -#undef MIX - -#endif /* UPB_UNALIGNED_READS_OK */ - - -#include -#include -#include -#include -#include -#include -#include - - -/* upb_status *****************************************************************/ - -void upb_status_clear(upb_status *status) { - if (!status) return; - status->ok = true; - status->msg[0] = '\0'; -} - -bool upb_ok(const upb_status *status) { return status->ok; } - -const char *upb_status_errmsg(const upb_status *status) { return status->msg; } - -void upb_status_seterrmsg(upb_status *status, const char *msg) { - if (!status) return; - status->ok = false; - strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1); - status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; -} - -void upb_status_seterrf(upb_status *status, const char *fmt, ...) { - va_list args; - va_start(args, fmt); - upb_status_vseterrf(status, fmt, args); - va_end(args); -} - -void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { - if (!status) return; - status->ok = false; - _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args); - status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; -} +void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { + if (!status) return; + status->ok = false; + vsnprintf(status->msg, sizeof(status->msg), fmt, args); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; +} void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) { size_t len; if (!status) return; status->ok = false; len = strlen(status->msg); - _upb_vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args); + vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args); status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; } @@ -2332,37 +2218,18 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc}; /* Be conservative and choose 16 in case anyone is using SSE. */ -typedef struct mem_block { +struct mem_block { struct mem_block *next; uint32_t size; uint32_t cleanups; /* Data follows. */ -} mem_block; +}; typedef struct cleanup_ent { upb_cleanup_func *cleanup; void *ud; } cleanup_ent; -struct upb_arena { - _upb_arena_head head; - uint32_t *cleanups; - - /* Allocator to allocate arena blocks. We are responsible for freeing these - * when we are destroyed. */ - upb_alloc *block_alloc; - uint32_t last_size; - - /* When multiple arenas are fused together, each arena points to a parent - * arena (root points to itself). The root tracks how many live arenas - * reference it. */ - uint32_t refcount; /* Only used when a->parent == a */ - struct upb_arena *parent; - - /* Linked list of blocks to free/cleanup. */ - mem_block *freelist, *freelist_tail; -}; - static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16); static upb_arena *arena_findroot(upb_arena *a) { @@ -2376,9 +2243,9 @@ static upb_arena *arena_findroot(upb_arena *a) { return a; } -static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) { +static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr, + size_t size) { mem_block *block = ptr; - upb_arena *root = arena_findroot(a); /* The block is for arena |a|, but should appear in the freelist of |root|. */ block->next = root->freelist; @@ -2392,26 +2259,22 @@ static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) { a->head.end = UPB_PTR_AT(block, size, char); a->cleanups = &block->cleanups; - /* TODO(haberman): ASAN poison. */ + UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr); } static bool upb_arena_allocblock(upb_arena *a, size_t size) { + upb_arena *root = arena_findroot(a); size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve; - mem_block *block = upb_malloc(a->block_alloc, block_size); + mem_block *block = upb_malloc(root->block_alloc, block_size); if (!block) return false; - upb_arena_addblock(a, block, block_size); + upb_arena_addblock(a, root, block, block_size); return true; } -static bool arena_has(upb_arena *a, size_t size) { - _upb_arena_head *h = (_upb_arena_head*)a; - return (size_t)(h->end - h->ptr) >= size; -} - void *_upb_arena_slowmalloc(upb_arena *a, size_t size) { if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */ - UPB_ASSERT(arena_has(a, size)); + UPB_ASSERT(_upb_arenahas(a, size)); return upb_arena_malloc(a, size); } @@ -2443,7 +2306,7 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { a->freelist = NULL; a->freelist_tail = NULL; - upb_arena_addblock(a, mem, n); + upb_arena_addblock(a, a, mem, n); return a; } @@ -2506,14 +2369,15 @@ void upb_arena_free(upb_arena *a) { bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { cleanup_ent *ent; - if (!a->cleanups || !arena_has(a, sizeof(cleanup_ent))) { + if (!a->cleanups || !_upb_arenahas(a, sizeof(cleanup_ent))) { if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */ - UPB_ASSERT(arena_has(a, sizeof(cleanup_ent))); + UPB_ASSERT(_upb_arenahas(a, sizeof(cleanup_ent))); } a->head.end -= sizeof(cleanup_ent); ent = (cleanup_ent*)a->head.end; (*a->cleanups)++; + UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent)); ent->cleanup = func; ent->ud = ud; @@ -2599,7 +2463,7 @@ const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { UPB_SIZE(64, 128), 12, false, }; -static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = { +static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = { &google_protobuf_DescriptorProto_msginit, &google_protobuf_DescriptorProto_ExtensionRange_msginit, &google_protobuf_DescriptorProto_ReservedRange_msginit, @@ -2674,23 +2538,23 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1 }; static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = { - {1, UPB_SIZE(36, 40), 6, 0, 12, 1}, - {2, UPB_SIZE(44, 56), 7, 0, 12, 1}, - {3, UPB_SIZE(24, 24), 3, 0, 5, 1}, - {4, UPB_SIZE(8, 8), 1, 0, 14, 1}, - {5, UPB_SIZE(16, 16), 2, 0, 14, 1}, - {6, UPB_SIZE(52, 72), 8, 0, 12, 1}, - {7, UPB_SIZE(60, 88), 9, 0, 12, 1}, - {8, UPB_SIZE(76, 120), 11, 0, 11, 1}, - {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, - {10, UPB_SIZE(68, 104), 10, 0, 12, 1}, - {17, UPB_SIZE(32, 32), 5, 0, 8, 1}, + {1, UPB_SIZE(24, 24), 6, 0, 12, 1}, + {2, UPB_SIZE(32, 40), 7, 0, 12, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 5, 1}, + {4, UPB_SIZE(4, 4), 1, 0, 14, 1}, + {5, UPB_SIZE(8, 8), 2, 0, 14, 1}, + {6, UPB_SIZE(40, 56), 8, 0, 12, 1}, + {7, UPB_SIZE(48, 72), 9, 0, 12, 1}, + {8, UPB_SIZE(64, 104), 11, 0, 11, 1}, + {9, UPB_SIZE(16, 16), 4, 0, 5, 1}, + {10, UPB_SIZE(56, 88), 10, 0, 12, 1}, + {17, UPB_SIZE(20, 20), 5, 0, 8, 1}, }; const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { &google_protobuf_FieldDescriptorProto_submsgs[0], &google_protobuf_FieldDescriptorProto__fields[0], - UPB_SIZE(80, 128), 11, false, + UPB_SIZE(72, 112), 11, false, }; static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { @@ -2796,33 +2660,33 @@ static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = { }; static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { - {1, UPB_SIZE(28, 32), 11, 0, 12, 1}, - {8, UPB_SIZE(36, 48), 12, 0, 12, 1}, - {9, UPB_SIZE(8, 8), 1, 0, 14, 1}, - {10, UPB_SIZE(16, 16), 2, 0, 8, 1}, - {11, UPB_SIZE(44, 64), 13, 0, 12, 1}, - {16, UPB_SIZE(17, 17), 3, 0, 8, 1}, - {17, UPB_SIZE(18, 18), 4, 0, 8, 1}, - {18, UPB_SIZE(19, 19), 5, 0, 8, 1}, - {20, UPB_SIZE(20, 20), 6, 0, 8, 1}, - {23, UPB_SIZE(21, 21), 7, 0, 8, 1}, - {27, UPB_SIZE(22, 22), 8, 0, 8, 1}, - {31, UPB_SIZE(23, 23), 9, 0, 8, 1}, - {36, UPB_SIZE(52, 80), 14, 0, 12, 1}, - {37, UPB_SIZE(60, 96), 15, 0, 12, 1}, - {39, UPB_SIZE(68, 112), 16, 0, 12, 1}, - {40, UPB_SIZE(76, 128), 17, 0, 12, 1}, - {41, UPB_SIZE(84, 144), 18, 0, 12, 1}, - {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, - {44, UPB_SIZE(92, 160), 19, 0, 12, 1}, - {45, UPB_SIZE(100, 176), 20, 0, 12, 1}, - {999, UPB_SIZE(108, 192), 0, 0, 11, 3}, + {1, UPB_SIZE(20, 24), 11, 0, 12, 1}, + {8, UPB_SIZE(28, 40), 12, 0, 12, 1}, + {9, UPB_SIZE(4, 4), 1, 0, 14, 1}, + {10, UPB_SIZE(8, 8), 2, 0, 8, 1}, + {11, UPB_SIZE(36, 56), 13, 0, 12, 1}, + {16, UPB_SIZE(9, 9), 3, 0, 8, 1}, + {17, UPB_SIZE(10, 10), 4, 0, 8, 1}, + {18, UPB_SIZE(11, 11), 5, 0, 8, 1}, + {20, UPB_SIZE(12, 12), 6, 0, 8, 1}, + {23, UPB_SIZE(13, 13), 7, 0, 8, 1}, + {27, UPB_SIZE(14, 14), 8, 0, 8, 1}, + {31, UPB_SIZE(15, 15), 9, 0, 8, 1}, + {36, UPB_SIZE(44, 72), 14, 0, 12, 1}, + {37, UPB_SIZE(52, 88), 15, 0, 12, 1}, + {39, UPB_SIZE(60, 104), 16, 0, 12, 1}, + {40, UPB_SIZE(68, 120), 17, 0, 12, 1}, + {41, UPB_SIZE(76, 136), 18, 0, 12, 1}, + {42, UPB_SIZE(16, 16), 10, 0, 8, 1}, + {44, UPB_SIZE(84, 152), 19, 0, 12, 1}, + {45, UPB_SIZE(92, 168), 20, 0, 12, 1}, + {999, UPB_SIZE(100, 184), 0, 0, 11, 3}, }; const upb_msglayout google_protobuf_FileOptions_msginit = { &google_protobuf_FileOptions_submsgs[0], &google_protobuf_FileOptions__fields[0], - UPB_SIZE(112, 208), 21, false, + UPB_SIZE(104, 192), 21, false, }; static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = { @@ -2848,19 +2712,19 @@ static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = { }; static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { - {1, UPB_SIZE(8, 8), 1, 0, 14, 1}, - {2, UPB_SIZE(24, 24), 3, 0, 8, 1}, - {3, UPB_SIZE(25, 25), 4, 0, 8, 1}, - {5, UPB_SIZE(26, 26), 5, 0, 8, 1}, - {6, UPB_SIZE(16, 16), 2, 0, 14, 1}, - {10, UPB_SIZE(27, 27), 6, 0, 8, 1}, - {999, UPB_SIZE(28, 32), 0, 0, 11, 3}, + {1, UPB_SIZE(4, 4), 1, 0, 14, 1}, + {2, UPB_SIZE(12, 12), 3, 0, 8, 1}, + {3, UPB_SIZE(13, 13), 4, 0, 8, 1}, + {5, UPB_SIZE(14, 14), 5, 0, 8, 1}, + {6, UPB_SIZE(8, 8), 2, 0, 14, 1}, + {10, UPB_SIZE(15, 15), 6, 0, 8, 1}, + {999, UPB_SIZE(16, 16), 0, 0, 11, 3}, }; const upb_msglayout google_protobuf_FieldOptions_msginit = { &google_protobuf_FieldOptions_submsgs[0], &google_protobuf_FieldOptions__fields[0], - UPB_SIZE(32, 40), 7, false, + UPB_SIZE(20, 24), 7, false, }; static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = { @@ -2928,15 +2792,15 @@ static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = { }; static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { - {33, UPB_SIZE(16, 16), 2, 0, 8, 1}, - {34, UPB_SIZE(8, 8), 1, 0, 14, 1}, - {999, UPB_SIZE(20, 24), 0, 0, 11, 3}, + {33, UPB_SIZE(8, 8), 2, 0, 8, 1}, + {34, UPB_SIZE(4, 4), 1, 0, 14, 1}, + {999, UPB_SIZE(12, 16), 0, 0, 11, 3}, }; const upb_msglayout google_protobuf_MethodOptions_msginit = { &google_protobuf_MethodOptions_submsgs[0], &google_protobuf_MethodOptions__fields[0], - UPB_SIZE(24, 32), 3, false, + UPB_SIZE(16, 24), 3, false, }; static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = { @@ -3093,7 +2957,7 @@ static const upb_msglayout *layouts[27] = { &google_protobuf_GeneratedCodeInfo_Annotation_msginit, }; -static const char descriptor[7619] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', +static const char descriptor[7601] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n', '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', @@ -3391,13 +3255,13 @@ static const char descriptor[7619] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', ' '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', '\217', -'\001', '\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', 'i', 't', 'h', 'u', 'b', -'.', 'c', 'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'p', 'r', 'o', 't', -'o', 'c', '-', 'g', 'e', 'n', '-', 'g', 'o', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', ';', 'd', 'e', 's', 'c', -'r', 'i', 'p', 't', 'o', 'r', '\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', +'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] = { @@ -3408,12 +3272,13 @@ upb_def_init google_protobuf_descriptor_proto_upbdefinit = { deps, layouts, "google/protobuf/descriptor.proto", - UPB_STRVIEW_INIT(descriptor, 7619) + UPB_STRVIEW_INIT(descriptor, 7601) }; #include #include +#include #include #include @@ -3423,15 +3288,6 @@ typedef struct { char str[1]; /* Null-terminated string data follows. */ } str_t; -static str_t *newstr(upb_alloc *alloc, const char *data, size_t len) { - str_t *ret = upb_malloc(alloc, sizeof(*ret) + len); - if (!ret) return NULL; - ret->len = len; - if (len) memcpy(ret->str, data, len); - ret->str[len] = '\0'; - return ret; -} - struct upb_fielddef { const upb_filedef *file; const upb_msgdef *msgdef; @@ -3498,7 +3354,9 @@ struct upb_enumdef { struct upb_oneofdef { const upb_msgdef *parent; const char *full_name; - uint32_t index; + int field_count; + bool synthetic; + const upb_fielddef **fields; upb_strtable ntof; upb_inttable itof; }; @@ -3525,6 +3383,7 @@ struct upb_symtab { upb_arena *arena; upb_strtable syms; /* full_name -> packed def ptr */ upb_strtable files; /* file_name -> upb_filedef* */ + size_t bytes_loaded; }; /* Inside a symtab we store tagged pointers to specific def types. */ @@ -3563,38 +3422,6 @@ static bool upb_isalphanum(char c) { return upb_isletter(c) || upb_isbetween(c, '0', '9'); } -static bool upb_isident(upb_strview name, bool full, upb_status *s) { - const char *str = name.data; - size_t len = name.size; - bool start = true; - size_t i; - for (i = 0; i < len; i++) { - char c = str[i]; - if (c == '.') { - if (start || !full) { - upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str); - return false; - } - start = true; - } else if (start) { - if (!upb_isletter(c)) { - upb_status_seterrf( - s, "invalid name: path components must start with a letter (%s)", - str); - return false; - } - start = false; - } else { - if (!upb_isalphanum(c)) { - upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)", - str); - return false; - } - } - } - return !start; -} - static const char *shortdefname(const char *fullname) { const char *p; @@ -3654,85 +3481,6 @@ static void upb_status_setoom(upb_status *status) { upb_status_seterrmsg(status, "out of memory"); } -static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { - /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the - * lowest indexes, but we do not publicly guarantee this. */ - upb_msg_field_iter j; - int i; - uint32_t selector; - int n = upb_msgdef_numfields(m); - upb_fielddef **fields; - - if (n == 0) { - m->selector_count = UPB_STATIC_SELECTOR_COUNT; - m->submsg_field_count = 0; - return true; - } - - fields = upb_gmalloc(n * sizeof(*fields)); - if (!fields) { - upb_status_setoom(s); - return false; - } - - m->submsg_field_count = 0; - for(i = 0, upb_msg_field_begin(&j, m); - !upb_msg_field_done(&j); - upb_msg_field_next(&j), i++) { - upb_fielddef *f = upb_msg_iter_field(&j); - UPB_ASSERT(f->msgdef == m); - if (upb_fielddef_issubmsg(f)) { - m->submsg_field_count++; - } - fields[i] = f; - } - - qsort(fields, n, sizeof(*fields), cmp_fields); - - selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count; - for (i = 0; i < n; i++) { - upb_fielddef *f = fields[i]; - f->index_ = i; - f->selector_base = selector + upb_handlers_selectorbaseoffset(f); - selector += upb_handlers_selectorcount(f); - } - m->selector_count = selector; - - upb_gfree(fields); - return true; -} - -static bool check_oneofs(upb_msgdef *m, upb_status *s) { - int i; - int first_synthetic = -1; - upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs; - - for (i = 0; i < m->oneof_count; i++) { - mutable_oneofs[i].index = i; - - if (upb_oneofdef_issynthetic(&mutable_oneofs[i])) { - if (first_synthetic == -1) { - first_synthetic = i; - } - } else { - if (first_synthetic != -1) { - upb_status_seterrf( - s, "Synthetic oneofs must be after all other oneofs: %s", - upb_oneofdef_name(&mutable_oneofs[i])); - return false; - } - } - } - - if (first_synthetic == -1) { - m->real_oneof_count = m->oneof_count; - } else { - m->real_oneof_count = first_synthetic; - } - - return true; -} - static void assign_msg_wellknowntype(upb_msgdef *m) { const char *name = upb_msgdef_fullname(m); if (name == NULL) { @@ -4135,15 +3883,32 @@ int upb_msgdef_numrealoneofs(const upb_msgdef *m) { return m->real_oneof_count; } +int upb_msgdef_fieldcount(const upb_msgdef *m) { + return m->field_count; +} + +int upb_msgdef_oneofcount(const upb_msgdef *m) { + return m->oneof_count; +} + +int upb_msgdef_realoneofcount(const upb_msgdef *m) { + return m->real_oneof_count; +} + const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) { return m->layout; } -const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i) { - if (i >= m->field_count) return NULL; +const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i) { + UPB_ASSERT(i >= 0 && i < m->field_count); return &m->fields[i]; } +const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i) { + UPB_ASSERT(i >= 0 && i < m->oneof_count); + return &m->oneofs[i]; +} + bool upb_msgdef_mapentry(const upb_msgdef *m) { return m->map_entry; } @@ -4231,22 +3996,25 @@ const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { return o->parent; } +int upb_oneofdef_fieldcount(const upb_oneofdef *o) { + return o->field_count; +} + +const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i) { + UPB_ASSERT(i < o->field_count); + return o->fields[i]; +} + int upb_oneofdef_numfields(const upb_oneofdef *o) { - return (int)upb_strtable_count(&o->ntof); + return o->field_count; } uint32_t upb_oneofdef_index(const upb_oneofdef *o) { - return o->index; + return o - o->parent->oneofs; } bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { - upb_inttable_iter iter; - const upb_fielddef *f; - upb_inttable_begin(&iter, &o->itof); - if (upb_oneofdef_numfields(o) != 1) return false; - f = upb_value_getptr(upb_inttable_iter_value(&iter)); - UPB_ASSERT(f); - return f->proto3_optional_; + return o->synthetic; } const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, @@ -4282,7 +4050,185 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) { upb_inttable_iter_setdone(iter); } -/* Dynamic Layout Generation. *************************************************/ +/* upb_filedef ****************************************************************/ + +const char *upb_filedef_name(const upb_filedef *f) { + return f->name; +} + +const char *upb_filedef_package(const upb_filedef *f) { + return f->package; +} + +const char *upb_filedef_phpprefix(const upb_filedef *f) { + return f->phpprefix; +} + +const char *upb_filedef_phpnamespace(const upb_filedef *f) { + return f->phpnamespace; +} + +upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { + return f->syntax; +} + +int upb_filedef_msgcount(const upb_filedef *f) { + return f->msg_count; +} + +int upb_filedef_depcount(const upb_filedef *f) { + return f->dep_count; +} + +int upb_filedef_enumcount(const upb_filedef *f) { + return f->enum_count; +} + +const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { + return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; +} + +const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { + return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; +} + +const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { + return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; +} + +void upb_symtab_free(upb_symtab *s) { + upb_arena_free(s->arena); + upb_gfree(s); +} + +upb_symtab *upb_symtab_new(void) { + upb_symtab *s = upb_gmalloc(sizeof(*s)); + upb_alloc *alloc; + + if (!s) { + return NULL; + } + + s->arena = upb_arena_new(); + s->bytes_loaded = 0; + alloc = upb_arena_alloc(s->arena); + + if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, 32, alloc) || + !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, 4, alloc)) { + upb_arena_free(s->arena); + upb_gfree(s); + s = NULL; + } + return s; +} + +const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { + upb_value v; + return upb_strtable_lookup(&s->syms, sym, &v) ? + unpack_def(v, UPB_DEFTYPE_MSG) : NULL; +} + +const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, + size_t len) { + upb_value v; + return upb_strtable_lookup2(&s->syms, sym, len, &v) ? + unpack_def(v, UPB_DEFTYPE_MSG) : NULL; +} + +const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { + upb_value v; + return upb_strtable_lookup(&s->syms, sym, &v) ? + unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; +} + +const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) { + upb_value v; + return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) + : NULL; +} + +const upb_filedef *upb_symtab_lookupfile2( + const upb_symtab *s, const char *name, size_t len) { + upb_value v; + return upb_strtable_lookup2(&s->files, name, len, &v) ? + upb_value_getconstptr(v) : NULL; +} + +int upb_symtab_filecount(const upb_symtab *s) { + return (int)upb_strtable_count(&s->files); +} + +/* Code to build defs from descriptor protos. *********************************/ + +/* There is a question of how much validation to do here. It will be difficult + * to perfectly match the amount of validation performed by proto2. But since + * this code is used to directly build defs from Ruby (for example) we do need + * to validate important constraints like uniqueness of names and numbers. */ + +#define CHK_OOM(x) if (!(x)) { symtab_oomerr(ctx); } + +typedef struct { + upb_symtab *symtab; + upb_filedef *file; /* File we are building. */ + upb_arena *file_arena; /* Allocate defs here. */ + upb_alloc *alloc; /* Alloc of file_arena, for tables. */ + const upb_msglayout **layouts; /* NULL if we should build layouts. */ + upb_status *status; /* Record errors here. */ + jmp_buf err; /* longjmp() on error. */ +} symtab_addctx; + +UPB_NORETURN UPB_NOINLINE +static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + upb_status_vseterrf(ctx->status, fmt, argp); + va_end(argp); + longjmp(ctx->err, 1); +} + +UPB_NORETURN UPB_NOINLINE +static void symtab_oomerr(symtab_addctx *ctx) { + upb_status_setoom(ctx->status); + longjmp(ctx->err, 1); +} + +void *symtab_alloc(symtab_addctx *ctx, size_t bytes) { + void *ret = upb_arena_malloc(ctx->file_arena, bytes); + if (!ret) symtab_oomerr(ctx); + return ret; +} + +static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) { + const char *str = name.data; + size_t len = name.size; + bool start = true; + size_t i; + for (i = 0; i < len; i++) { + char c = str[i]; + if (c == '.') { + if (start || !full) { + symtab_errf(ctx, "invalid name: unexpected '.' (%.*s)", (int)len, str); + } + start = true; + } else if (start) { + if (!upb_isletter(c)) { + symtab_errf( + ctx, + "invalid name: path components must start with a letter (%.*s)", + (int)len, str); + } + start = false; + } else { + if (!upb_isalphanum(c)) { + symtab_errf(ctx, "invalid name: non-alphanumeric character (%.*s)", + (int)len, str); + } + } + } + if (start) { + symtab_errf(ctx, "invalid name: empty part (%.*s)", (int)len, str); + } +} static size_t div_round_up(size_t n, size_t d) { return (n + d - 1) / d; @@ -4349,7 +4295,7 @@ static void assign_layout_indices(const upb_msgdef *m, upb_msglayout_field *fiel /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc. * It computes a dynamic layout for all of the fields in |m|. */ -static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) { +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; @@ -4357,18 +4303,11 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) { size_t submsg_count = m->submsg_field_count; const upb_msglayout **submsgs; upb_msglayout_field *fields; - upb_alloc *alloc = upb_arena_alloc(symtab->arena); memset(l, 0, sizeof(*l)); - fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields)); - submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs)); - - if ((!fields && upb_msgdef_numfields(m)) || - (!submsgs && submsg_count)) { - /* OOM. */ - return false; - } + fields = symtab_alloc(ctx, upb_msgdef_numfields(m) * sizeof(*fields)); + submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs)); l->field_count = upb_msgdef_numfields(m); l->fields = fields; @@ -4398,7 +4337,7 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) { l->field_count = 2; l->size = 2 * sizeof(upb_strview); l->size = UPB_ALIGN_UP(l->size, 8); - return true; + return; } /* Allocate data offsets in three stages: @@ -4510,31 +4449,52 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) { /* Sort fields by number. */ qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp); assign_layout_indices(m, fields); - - return true; } -/* Code to build defs from descriptor protos. *********************************/ +static void assign_msg_indices(symtab_addctx *ctx, upb_msgdef *m) { + /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the + * lowest indexes, but we do not publicly guarantee this. */ + upb_msg_field_iter j; + int i; + uint32_t selector; + int n = upb_msgdef_numfields(m); + upb_fielddef **fields; -/* There is a question of how much validation to do here. It will be difficult - * to perfectly match the amount of validation performed by proto2. But since - * this code is used to directly build defs from Ruby (for example) we do need - * to validate important constraints like uniqueness of names and numbers. */ + if (n == 0) { + m->selector_count = UPB_STATIC_SELECTOR_COUNT; + m->submsg_field_count = 0; + return; + } -#define CHK(x) if (!(x)) { return false; } -#define CHK_OOM(x) if (!(x)) { upb_status_setoom(ctx->status); return false; } + fields = upb_gmalloc(n * sizeof(*fields)); -typedef struct { - const upb_symtab *symtab; - upb_filedef *file; /* File we are building. */ - upb_alloc *alloc; /* Allocate defs here. */ - upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */ - upb_strtable *addtab; /* full_name -> packed def ptr for new defs */ - const upb_msglayout **layouts; /* NULL if we should build layouts. */ - upb_status *status; /* Record errors here. */ -} symtab_addctx; + m->submsg_field_count = 0; + for(i = 0, upb_msg_field_begin(&j, m); + !upb_msg_field_done(&j); + upb_msg_field_next(&j), i++) { + upb_fielddef *f = upb_msg_iter_field(&j); + UPB_ASSERT(f->msgdef == m); + if (upb_fielddef_issubmsg(f)) { + m->submsg_field_count++; + } + fields[i] = f; + } + + qsort(fields, n, sizeof(*fields), cmp_fields); + + selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count; + for (i = 0; i < n; i++) { + upb_fielddef *f = fields[i]; + f->index_ = i; + f->selector_base = selector + upb_handlers_selectorbaseoffset(f); + selector += upb_handlers_selectorcount(f); + } + m->selector_count = selector; + + upb_gfree(fields); +} -static char* strviewdup(const symtab_addctx *ctx, upb_strview view) { +static char *strviewdup(symtab_addctx *ctx, upb_strview view) { return upb_strdup2(view.data, view.size, ctx->alloc); } @@ -4546,13 +4506,12 @@ static bool streql_view(upb_strview view, const char *b) { return streql2(view.data, view.size, b); } -static const char *makefullname(const symtab_addctx *ctx, const char *prefix, +static const char *makefullname(symtab_addctx *ctx, const char *prefix, upb_strview name) { if (prefix) { /* ret = prefix + '.' + name; */ size_t n = strlen(prefix); - char *ret = upb_malloc(ctx->alloc, n + name.size + 2); - CHK_OOM(ret); + char *ret = symtab_alloc(ctx, n + name.size + 2); strcpy(ret, prefix); ret[n] = '.'; memcpy(&ret[n + 1], name.data, name.size); @@ -4563,6 +4522,41 @@ static const char *makefullname(const symtab_addctx *ctx, const char *prefix, } } +static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) { + int i; + int synthetic_count = 0; + upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs; + + for (i = 0; i < m->oneof_count; i++) { + upb_oneofdef *o = &mutable_oneofs[i]; + + if (o->synthetic && o->field_count != 1) { + symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s", + o->field_count, upb_oneofdef_name(o)); + } + + if (o->synthetic) { + synthetic_count++; + } else if (synthetic_count != 0) { + symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s", + upb_oneofdef_name(o)); + } + + o->fields = symtab_alloc(ctx, sizeof(upb_fielddef *) * o->field_count); + o->field_count = 0; + } + + for (i = 0; i < m->field_count; i++) { + const upb_fielddef *f = &m->fields[i]; + upb_oneofdef *o = (upb_oneofdef*)f->oneof; + if (o) { + o->fields[o->field_count++] = f; + } + } + + m->real_oneof_count = m->oneof_count - synthetic_count; +} + size_t getjsonname(const char *name, char *buf, size_t len) { size_t src, dst = 0; bool ucase_next = false; @@ -4601,76 +4595,57 @@ size_t getjsonname(const char *name, char *buf, size_t len) { #undef WRITE } -static char* makejsonname(const char* name, upb_alloc *alloc) { +static char* makejsonname(symtab_addctx *ctx, const char* name) { size_t size = getjsonname(name, NULL, 0); - char* json_name = upb_malloc(alloc, size); + char* json_name = symtab_alloc(ctx, size); getjsonname(name, json_name, size); return json_name; } -static bool symtab_add(const symtab_addctx *ctx, const char *name, - upb_value v) { - upb_value tmp; - if (upb_strtable_lookup(ctx->addtab, name, &tmp) || - upb_strtable_lookup(&ctx->symtab->syms, name, &tmp)) { - upb_status_seterrf(ctx->status, "duplicate symbol '%s'", name); - return false; +static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) { + if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) { + symtab_errf(ctx, "duplicate symbol '%s'", name); } - - CHK_OOM(upb_strtable_insert3(ctx->addtab, name, strlen(name), v, ctx->tmp)); - return true; + upb_alloc *alloc = upb_arena_alloc(ctx->symtab->arena); + size_t len = strlen(name); + CHK_OOM(upb_strtable_insert3(&ctx->symtab->syms, name, len, v, alloc)); } /* Given a symbol and the base symbol inside which it is defined, find the * symbol's definition in t. */ -static bool resolvename(const upb_strtable *t, const upb_fielddef *f, - const char *base, upb_strview sym, - upb_deftype_t type, upb_status *status, - const void **def) { - if(sym.size == 0) return false; +static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f, + const char *base, upb_strview sym, + upb_deftype_t type) { + const upb_strtable *t = &ctx->symtab->syms; + if(sym.size == 0) goto notfound; if(sym.data[0] == '.') { /* Symbols starting with '.' are absolute, so we do a single lookup. * Slice to omit the leading '.' */ upb_value v; if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) { - return false; + goto notfound; } - *def = unpack_def(v, type); - - if (!*def) { - upb_status_seterrf(status, - "type mismatch when resolving field %s, name %s", - f->full_name, sym.data); - return false; + 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 true; + 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); - return false; + goto notfound; } -} -const void *symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f, - const char *base, upb_strview sym, - upb_deftype_t type) { - const void *ret; - if (!resolvename(ctx->addtab, f, base, sym, type, ctx->status, &ret) && - !resolvename(&ctx->symtab->syms, f, base, sym, type, ctx->status, &ret)) { - if (upb_ok(ctx->status)) { - upb_status_seterrf(ctx->status, "couldn't resolve name '%s'", sym.data); - } - return false; - } - return ret; +notfound: + symtab_errf(ctx, "couldn't resolve name '%s'", sym.data); } -static bool create_oneofdef( - const symtab_addctx *ctx, upb_msgdef *m, +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); @@ -4679,18 +4654,27 @@ static bool create_oneofdef( o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; o->parent = m; o->full_name = makefullname(ctx, m->full_name, name); + o->field_count = 0; + o->synthetic = false; v = pack_def(o, UPB_DEFTYPE_ONEOF); - CHK_OOM(symtab_add(ctx, o->full_name, v)); + symtab_add(ctx, o->full_name, v); CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc)); CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); - CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, 4, ctx->alloc)); +} - return true; +static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) { + str_t *ret = symtab_alloc(ctx, sizeof(*ret) + len); + if (!ret) return NULL; + ret->len = len; + if (len) memcpy(ret->str, data, len); + ret->str[len] = '\0'; + return ret; } -static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, +static void parse_default(symtab_addctx *ctx, const char *str, size_t len, upb_fielddef *f) { char *end; char nullz[64]; @@ -4705,7 +4689,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, case UPB_TYPE_FLOAT: /* Standard C number parsing functions expect null-terminated strings. */ if (len >= sizeof(nullz) - 1) { - return false; + symtab_errf(ctx, "Default too long: %.*s", (int)len, str); } memcpy(nullz, str, len); nullz[len] = '\0'; @@ -4718,47 +4702,61 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, switch (upb_fielddef_type(f)) { case UPB_TYPE_INT32: { long val = strtol(str, &end, 0); - CHK(val <= INT32_MAX && val >= INT32_MIN && errno != ERANGE && !*end); + if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) { + goto invalid; + } f->defaultval.sint = val; break; } case UPB_TYPE_ENUM: { const upb_enumdef *e = f->sub.enumdef; int32_t val; - CHK(upb_enumdef_ntoi(e, str, len, &val)); + if (!upb_enumdef_ntoi(e, str, len, &val)) { + goto invalid; + } f->defaultval.sint = val; break; } case UPB_TYPE_INT64: { /* XXX: Need to write our own strtoll, since it's not available in c89. */ int64_t val = strtol(str, &end, 0); - CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end); + if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) { + goto invalid; + } f->defaultval.sint = val; break; } case UPB_TYPE_UINT32: { unsigned long val = strtoul(str, &end, 0); - CHK(val <= UINT32_MAX && errno != ERANGE && !*end); + if (val > UINT32_MAX || errno == ERANGE || *end) { + goto invalid; + } f->defaultval.uint = val; break; } case UPB_TYPE_UINT64: { /* XXX: Need to write our own strtoull, since it's not available in c89. */ uint64_t val = strtoul(str, &end, 0); - CHK(val <= UINT64_MAX && errno != ERANGE && !*end); + if (val > UINT64_MAX || errno == ERANGE || *end) { + goto invalid; + } f->defaultval.uint = val; break; } case UPB_TYPE_DOUBLE: { double val = strtod(str, &end); - CHK(errno != ERANGE && !*end); + if (errno == ERANGE || *end) { + goto invalid; + } f->defaultval.dbl = val; break; } case UPB_TYPE_FLOAT: { /* XXX: Need to write our own strtof, since it's not available in c89. */ float val = strtod(str, &end); - CHK(errno != ERANGE && !*end); + if (errno == ERANGE || *end) { + goto invalid; + } f->defaultval.flt = val; break; } @@ -4768,25 +4766,30 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, } else if (streql2(str, len, "true")) { f->defaultval.boolean = true; } else { - return false; } break; } case UPB_TYPE_STRING: - f->defaultval.str = newstr(ctx->alloc, str, len); + 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->alloc, str, len); + f->defaultval.str = newstr(ctx, str, len); break; case UPB_TYPE_MESSAGE: /* Should not have a default value. */ - return false; + symtab_errf(ctx, "Message should not have a default (%s)", + upb_fielddef_fullname(f)); } - return true; + + return; + +invalid: + symtab_errf(ctx, "Invalid default '%.*s' for field %f", (int)len, str, + upb_fielddef_fullname(f)); } -static void set_default_default(const symtab_addctx *ctx, upb_fielddef *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: @@ -4803,7 +4806,7 @@ static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) { break; case UPB_TYPE_STRING: case UPB_TYPE_BYTES: - f->defaultval.str = newstr(ctx->alloc, NULL, 0); + f->defaultval.str = newstr(ctx, NULL, 0); break; case UPB_TYPE_BOOL: f->defaultval.boolean = false; @@ -4813,8 +4816,8 @@ static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) { } } -static bool create_fielddef( - const symtab_addctx *ctx, const char *prefix, upb_msgdef *m, +static void create_fielddef( + symtab_addctx *ctx, const char *prefix, upb_msgdef *m, const google_protobuf_FieldDescriptorProto *field_proto) { upb_alloc *alloc = ctx->alloc; upb_fielddef *f; @@ -4826,12 +4829,11 @@ static bool create_fielddef( uint32_t field_number; if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { - upb_status_seterrmsg(ctx->status, "field has no name"); - return false; + symtab_errf(ctx, "field has no name (%s)", upb_msgdef_fullname(m)); } name = google_protobuf_FieldDescriptorProto_name(field_proto); - CHK(upb_isident(name, false, ctx->status)); + check_ident(ctx, name, false); full_name = makefullname(ctx, prefix, name); shortname = shortdefname(full_name); @@ -4839,14 +4841,13 @@ static bool create_fielddef( json_name = strviewdup( ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto)); } else { - json_name = makejsonname(shortname, ctx->alloc); + json_name = makejsonname(ctx, shortname); } field_number = google_protobuf_FieldDescriptorProto_number(field_proto); if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) { - upb_status_seterrf(ctx->status, "invalid field number (%u)", field_number); - return false; + symtab_errf(ctx, "invalid field number (%u)", field_number); } if (m) { @@ -4859,19 +4860,15 @@ static bool create_fielddef( f->is_extension_ = false; if (upb_strtable_lookup(&m->ntof, shortname, NULL)) { - upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname); - return false; + symtab_errf(ctx, "duplicate field name (%s)", shortname); } if (upb_strtable_lookup(&m->ntof, json_name, NULL)) { - upb_status_seterrf(ctx->status, "duplicate json_name (%s)", json_name); - return false; + symtab_errf(ctx, "duplicate json_name (%s)", json_name); } if (upb_inttable_lookup(&m->itof, field_number, NULL)) { - upb_status_seterrf(ctx->status, "duplicate field number (%u)", - field_number); - return false; + symtab_errf(ctx, "duplicate field number (%u)", field_number); } field_v = pack_def(f, UPB_DEFTYPE_FIELD); @@ -4905,7 +4902,7 @@ static bool create_fielddef( /* extension field. */ f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++]; f->is_extension_ = true; - CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD))); + symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)); } f->full_name = full_name; @@ -4924,9 +4921,7 @@ static bool create_fielddef( f->sub.unresolved = field_proto; if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) { - upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)", - f->full_name); - return false; + symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name); } if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { @@ -4936,32 +4931,34 @@ static bool create_fielddef( upb_value v = upb_value_constptr(f); if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { - upb_status_seterrf(ctx->status, - "fields in oneof must have OPTIONAL label (%s)", - f->full_name); - return false; + symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)", + f->full_name); } if (!m) { - upb_status_seterrf(ctx->status, - "oneof_index provided for extension field (%s)", - f->full_name); - return false; + symtab_errf(ctx, "oneof_index provided for extension field (%s)", + f->full_name); } if (oneof_index >= m->oneof_count) { - upb_status_seterrf(ctx->status, "oneof_index out of range (%s)", - f->full_name); - return false; + symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name); } oneof = (upb_oneofdef*)&m->oneofs[oneof_index]; f->oneof = oneof; - CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc)); - CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc)); + oneof->field_count++; + if (f->proto3_optional_) { + oneof->synthetic = true; + } + CHK_OOM(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc)); + CHK_OOM(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc)); } else { f->oneof = NULL; + if (f->proto3_optional_) { + symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)", + f->full_name); + } } options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ? @@ -4980,12 +4977,10 @@ static bool create_fielddef( } else { f->lazy_ = false; } - - return true; } -static bool create_enumdef( - const symtab_addctx *ctx, const char *prefix, +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; @@ -4993,25 +4988,22 @@ static bool create_enumdef( size_t i, n; name = google_protobuf_EnumDescriptorProto_name(enum_proto); - CHK(upb_isident(name, false, ctx->status)); + check_ident(ctx, name, false); e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++]; e->full_name = makefullname(ctx, prefix, name); - CHK_OOM(symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM))); + symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM)); - CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc)); + values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); + CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, n, ctx->alloc)); CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc)); e->file = ctx->file; e->defaultval = 0; - values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); - if (n == 0) { - upb_status_seterrf(ctx->status, - "enums must contain at least one value (%s)", - e->full_name); - return false; + symtab_errf(ctx, "enums must contain at least one value (%s)", + e->full_name); } for (i = 0; i < n; i++) { @@ -5022,15 +5014,12 @@ static bool create_enumdef( upb_value v = upb_value_int32(num); if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) { - upb_status_seterrf(ctx->status, - "for proto3, the first enum value must be zero (%s)", - e->full_name); - return false; + symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)", + e->full_name); } if (upb_strtable_lookup(&e->ntoi, name2, NULL)) { - upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2); - return false; + symtab_errf(ctx, "duplicate enum label '%s'", name2); } CHK_OOM(name2) @@ -5044,11 +5033,9 @@ static bool create_enumdef( } upb_inttable_compact2(&e->iton, ctx->alloc); - - return true; } -static bool create_msgdef(symtab_addctx *ctx, const char *prefix, +static void create_msgdef(symtab_addctx *ctx, const char *prefix, const google_protobuf_DescriptorProto *msg_proto) { upb_msgdef *m; const google_protobuf_MessageOptions *options; @@ -5056,18 +5043,22 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix, const google_protobuf_FieldDescriptorProto *const *fields; const google_protobuf_EnumDescriptorProto *const *enums; const google_protobuf_DescriptorProto *const *msgs; - size_t i, n; + size_t i, n_oneof, n_field, n; upb_strview name; name = google_protobuf_DescriptorProto_name(msg_proto); - CHK(upb_isident(name, false, ctx->status)); + check_ident(ctx, name, false); m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++]; m->full_name = makefullname(ctx, prefix, name); - CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG))); + symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG)); + + oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof); + fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field); CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); - CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, n_oneof + n_field, + ctx->alloc)); m->file = ctx->file; m->map_entry = false; @@ -5083,25 +5074,23 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix, ctx->layouts++; } else { /* Allocate now (to allow cross-linking), populate later. */ - m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout)); + m->layout = symtab_alloc(ctx, sizeof(*m->layout)); } - oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n); m->oneof_count = 0; - m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n); - for (i = 0; i < n; i++) { - CHK(create_oneofdef(ctx, m, oneofs[i])); + m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof); + for (i = 0; i < n_oneof; i++) { + create_oneofdef(ctx, m, oneofs[i]); } - fields = google_protobuf_DescriptorProto_field(msg_proto, &n); m->field_count = 0; - m->fields = upb_malloc(ctx->alloc, sizeof(*m->fields) * n); - for (i = 0; i < n; i++) { - CHK(create_fielddef(ctx, m->full_name, m, fields[i])); + 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]); } - CHK(assign_msg_indices(m, ctx->status)); - CHK(check_oneofs(m, ctx->status)); + assign_msg_indices(ctx, m); + finalize_oneofs(ctx, m); assign_msg_wellknowntype(m); upb_inttable_compact2(&m->itof, ctx->alloc); @@ -5109,93 +5098,78 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix, enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n); for (i = 0; i < n; i++) { - CHK(create_enumdef(ctx, m->full_name, enums[i])); + create_enumdef(ctx, m->full_name, enums[i]); } msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); for (i = 0; i < n; i++) { - CHK(create_msgdef(ctx, m->full_name, msgs[i])); + create_msgdef(ctx, m->full_name, msgs[i]); } - - return true; } -typedef struct { - int msg_count; - int enum_count; - int ext_count; -} decl_counts; - static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, - decl_counts *counts) { + upb_filedef *file) { const google_protobuf_DescriptorProto *const *msgs; size_t i, n; - counts->msg_count++; + file->msg_count++; msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); for (i = 0; i < n; i++) { - count_types_in_msg(msgs[i], counts); + count_types_in_msg(msgs[i], file); } google_protobuf_DescriptorProto_enum_type(msg_proto, &n); - counts->enum_count += n; + file->enum_count += n; google_protobuf_DescriptorProto_extension(msg_proto, &n); - counts->ext_count += n; + file->ext_count += n; } static void count_types_in_file( const google_protobuf_FileDescriptorProto *file_proto, - decl_counts *counts) { + 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], counts); + count_types_in_msg(msgs[i], file); } google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); - counts->enum_count += n; + file->enum_count += n; google_protobuf_FileDescriptorProto_extension(file_proto, &n); - counts->ext_count += n; + file->ext_count += n; } -static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, +static void resolve_fielddef(symtab_addctx *ctx, const char *prefix, upb_fielddef *f) { upb_strview name; const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved; if (f->is_extension_) { if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { - upb_status_seterrf(ctx->status, - "extension for field '%s' had no extendee", - f->full_name); - return false; + symtab_errf(ctx, "extension for field '%s' had no extendee", + f->full_name); } name = google_protobuf_FieldDescriptorProto_extendee(field_proto); f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); - CHK(f->msgdef); } if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) && !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) { - upb_status_seterrf(ctx->status, "field '%s' is missing type name", - f->full_name); - return false; + symtab_errf(ctx, "field '%s' is missing type name", f->full_name); } name = google_protobuf_FieldDescriptorProto_type_name(field_proto); if (upb_fielddef_issubmsg(f)) { f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); - CHK(f->sub.msgdef); } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) { f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM); - CHK(f->sub.enumdef); } /* Have to delay resolving of the default value until now because of the enum @@ -5205,54 +5179,36 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, google_protobuf_FieldDescriptorProto_default_value(field_proto); if (f->file->syntax == UPB_SYNTAX_PROTO3) { - upb_status_seterrf(ctx->status, - "proto3 fields cannot have explicit defaults (%s)", - f->full_name); - return false; + symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)", + f->full_name); } if (upb_fielddef_issubmsg(f)) { - upb_status_seterrf(ctx->status, - "message fields cannot have explicit defaults (%s)", - f->full_name); - return false; + symtab_errf(ctx, "message fields cannot have explicit defaults (%s)", + f->full_name); } - if (!parse_default(ctx, defaultval.data, defaultval.size, f)) { - upb_status_seterrf(ctx->status, - "couldn't parse default '" UPB_STRVIEW_FORMAT - "' for field (%s)", - UPB_STRVIEW_ARGS(defaultval), f->full_name); - return false; - } + parse_default(ctx, defaultval.data, defaultval.size, f); } else { set_default_default(ctx, f); } - - return true; } -static bool build_filedef( +static void build_filedef( symtab_addctx *ctx, upb_filedef *file, const google_protobuf_FileDescriptorProto *file_proto) { - upb_alloc *alloc = ctx->alloc; const google_protobuf_FileOptions *file_options_proto; const google_protobuf_DescriptorProto *const *msgs; const google_protobuf_EnumDescriptorProto *const *enums; const google_protobuf_FieldDescriptorProto *const *exts; const upb_strview* strs; size_t i, n; - decl_counts counts = {0, 0, 0}; - count_types_in_file(file_proto, &counts); + count_types_in_file(file_proto, file); - file->msgs = upb_malloc(alloc, sizeof(*file->msgs) * counts.msg_count); - file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count); - file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count); - - CHK_OOM(counts.msg_count == 0 || file->msgs); - CHK_OOM(counts.enum_count == 0 || file->enums); - CHK_OOM(counts.ext_count == 0 || file->exts); + file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count); + file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count); + file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count); /* We increment these as defs are added. */ file->msg_count = 0; @@ -5260,8 +5216,7 @@ static bool build_filedef( file->ext_count = 0; if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) { - upb_status_seterrmsg(ctx->status, "File has no name"); - return false; + symtab_errf(ctx, "File has no name"); } file->name = @@ -5272,7 +5227,7 @@ static bool build_filedef( if (google_protobuf_FileDescriptorProto_has_package(file_proto)) { upb_strview package = google_protobuf_FileDescriptorProto_package(file_proto); - CHK(upb_isident(package, true, ctx->status)); + check_ident(ctx, package, true); file->package = strviewdup(ctx, package); } else { file->package = NULL; @@ -5287,9 +5242,8 @@ static bool build_filedef( } else if (streql_view(syntax, "proto3")) { file->syntax = UPB_SYNTAX_PROTO3; } else { - upb_status_seterrf(ctx->status, "Invalid syntax '" UPB_STRVIEW_FORMAT "'", - UPB_STRVIEW_ARGS(syntax)); - return false; + symtab_errf(ctx, "Invalid syntax '" UPB_STRVIEW_FORMAT "'", + UPB_STRVIEW_ARGS(syntax)); } } else { file->syntax = UPB_SYNTAX_PROTO2; @@ -5311,19 +5265,17 @@ static bool build_filedef( /* Verify dependencies. */ strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); - file->deps = upb_malloc(alloc, sizeof(*file->deps) * n) ; - CHK_OOM(n == 0 || file->deps); + 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_status_seterrf(ctx->status, - "Depends on file '" UPB_STRVIEW_FORMAT - "', but it has not been loaded", - UPB_STRVIEW_ARGS(dep_name)); - return false; + symtab_errf(ctx, + "Depends on file '" UPB_STRVIEW_FORMAT + "', but it has not been loaded", + UPB_STRVIEW_ARGS(dep_name)); } file->deps[i] = upb_value_getconstptr(v); } @@ -5331,194 +5283,98 @@ static bool build_filedef( /* Create messages. */ msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); for (i = 0; i < n; i++) { - CHK(create_msgdef(ctx, file->package, msgs[i])); + create_msgdef(ctx, file->package, msgs[i]); } /* Create enums. */ enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); for (i = 0; i < n; i++) { - CHK(create_enumdef(ctx, file->package, enums[i])); + create_enumdef(ctx, file->package, enums[i]); } /* Create extensions. */ exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); - file->exts = upb_malloc(alloc, sizeof(*file->exts) * n); - CHK_OOM(n == 0 || file->exts); + file->exts = symtab_alloc(ctx, sizeof(*file->exts) * n); for (i = 0; i < n; i++) { - CHK(create_fielddef(ctx, file->package, NULL, exts[i])); + create_fielddef(ctx, file->package, NULL, exts[i]); } /* Now that all names are in the table, build layouts and resolve refs. */ for (i = 0; i < (size_t)file->ext_count; i++) { - CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i])); + resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]); } for (i = 0; i < (size_t)file->msg_count; i++) { const upb_msgdef *m = &file->msgs[i]; int j; for (j = 0; j < m->field_count; j++) { - CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j])); + resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]); } } if (!ctx->layouts) { for (i = 0; i < (size_t)file->msg_count; i++) { const upb_msgdef *m = &file->msgs[i]; - make_layout(ctx->symtab, m); + make_layout(ctx, m); } } +} - return true; - } - -static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx) { - const upb_filedef *file = ctx->file; +static void remove_filedef(upb_symtab *s, upb_filedef *file) { upb_alloc *alloc = upb_arena_alloc(s->arena); - upb_strtable_iter iter; - - CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name), - upb_value_constptr(file), alloc)); - - upb_strtable_begin(&iter, ctx->addtab); - for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { - upb_strview key = upb_strtable_iter_key(&iter); - upb_value value = upb_strtable_iter_value(&iter); - CHK_OOM(upb_strtable_insert3(&s->syms, key.data, key.size, value, alloc)); + int i; + for (i = 0; i < file->msg_count; i++) { + const char *name = file->msgs[i].full_name; + upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc); } - - return true; -} - -/* upb_filedef ****************************************************************/ - -const char *upb_filedef_name(const upb_filedef *f) { - return f->name; -} - -const char *upb_filedef_package(const upb_filedef *f) { - return f->package; -} - -const char *upb_filedef_phpprefix(const upb_filedef *f) { - return f->phpprefix; -} - -const char *upb_filedef_phpnamespace(const upb_filedef *f) { - return f->phpnamespace; -} - -upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { - return f->syntax; -} - -int upb_filedef_msgcount(const upb_filedef *f) { - return f->msg_count; -} - -int upb_filedef_depcount(const upb_filedef *f) { - return f->dep_count; -} - -int upb_filedef_enumcount(const upb_filedef *f) { - return f->enum_count; -} - -const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { - return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; -} - -const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { - return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; -} - -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { - return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; -} - -void upb_symtab_free(upb_symtab *s) { - upb_arena_free(s->arena); - upb_gfree(s); -} - -upb_symtab *upb_symtab_new(void) { - upb_symtab *s = upb_gmalloc(sizeof(*s)); - upb_alloc *alloc; - - if (!s) { - return NULL; + for (i = 0; i < file->enum_count; i++) { + const char *name = file->enums[i].full_name; + upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc); } - - s->arena = upb_arena_new(); - alloc = upb_arena_alloc(s->arena); - - if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) || - !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) { - upb_arena_free(s->arena); - upb_gfree(s); - s = NULL; + for (i = 0; i < file->ext_count; i++) { + const char *name = file->exts[i].full_name; + upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc); } - return s; -} - -const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { - upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_MSG) : NULL; -} - -const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, - size_t len) { - upb_value v; - return upb_strtable_lookup2(&s->syms, sym, len, &v) ? - unpack_def(v, UPB_DEFTYPE_MSG) : NULL; -} - -const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { - upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; -} - -const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) { - upb_value v; - return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) - : NULL; -} - -const upb_filedef *upb_symtab_lookupfile2( - const upb_symtab *s, const char *name, size_t len) { - upb_value v; - return upb_strtable_lookup2(&s->files, name, len, &v) ? - upb_value_getconstptr(v) : NULL; -} - -int upb_symtab_filecount(const upb_symtab *s) { - return (int)upb_strtable_count(&s->files); } static const upb_filedef *_upb_symtab_addfile( upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, const upb_msglayout **layouts, upb_status *status) { - upb_arena *tmparena = upb_arena_new(); - upb_strtable addtab; - upb_alloc *alloc = upb_arena_alloc(s->arena); - upb_filedef *file = upb_malloc(alloc, sizeof(*file)); - bool ok; + upb_arena *file_arena = upb_arena_new(); + upb_filedef *file; symtab_addctx ctx; + if (!file_arena) return NULL; + + file = upb_arena_malloc(file_arena, sizeof(*file)); + if (!file) goto done; + ctx.file = file; ctx.symtab = s; - ctx.alloc = alloc; - ctx.tmp = upb_arena_alloc(tmparena); - ctx.addtab = &addtab; + ctx.file_arena = file_arena; + ctx.alloc = upb_arena_alloc(file_arena); ctx.layouts = layouts; ctx.status = status; - ok = file && upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) && - build_filedef(&ctx, file, file_proto) && upb_symtab_addtotabs(s, &ctx); + file->msg_count = 0; + file->enum_count = 0; + file->ext_count = 0; + + if (UPB_UNLIKELY(setjmp(ctx.err))) { + UPB_ASSERT(!upb_ok(status)); + remove_filedef(s, file); + file = NULL; + } else { + build_filedef(&ctx, file, file_proto); + upb_strtable_insert3(&s->files, file->name, strlen(file->name), + upb_value_constptr(file), ctx.alloc); + UPB_ASSERT(upb_ok(status)); + upb_arena_fuse(s->arena, file_arena); + } - upb_arena_free(tmparena); - return ok ? file : NULL; +done: + upb_arena_free(file_arena); + return file; } const upb_filedef *upb_symtab_addfile( @@ -5552,6 +5408,7 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { file = google_protobuf_FileDescriptorProto_parse( init->descriptor.data, init->descriptor.size, arena); + s->bytes_loaded += init->descriptor.size; if (!file) { upb_status_seterrf( @@ -5574,7 +5431,10 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { return false; } -#undef CHK +size_t _upb_symtab_bytesloaded(const upb_symtab *s) { + return s->bytes_loaded; +} + #undef CHK_OOM @@ -5622,6 +5482,21 @@ static char _upb_fieldtype_to_mapsize[12] = { 0, /* UPB_TYPE_BYTES */ }; +static const char _upb_fieldtype_to_sizelg2[12] = { + 0, + 0, /* UPB_TYPE_BOOL */ + 2, /* UPB_TYPE_FLOAT */ + 2, /* UPB_TYPE_INT32 */ + 2, /* UPB_TYPE_UINT32 */ + 2, /* UPB_TYPE_ENUM */ + UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */ + 3, /* UPB_TYPE_DOUBLE */ + 3, /* UPB_TYPE_INT64 */ + 3, /* UPB_TYPE_UINT64 */ + UPB_SIZE(3, 4), /* UPB_TYPE_STRING */ + UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */ +}; + /** upb_msg *******************************************************************/ upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) { @@ -5655,24 +5530,17 @@ bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) { const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg, const upb_oneofdef *o) { - upb_oneof_iter i; - const upb_fielddef *f; - const upb_msglayout_field *field; - const upb_msgdef *m = upb_oneofdef_containingtype(o); - uint32_t oneof_case; - - /* This is far from optimal. */ - upb_oneof_begin(&i, o); - if (upb_oneof_done(&i)) return false; - f = upb_oneof_iter_field(&i); - field = upb_fielddef_layout(f); - if (in_oneof(field)) { - oneof_case = _upb_getoneofcase_field(msg, field); + const upb_fielddef *f = upb_oneofdef_field(o, 0); + if (upb_oneofdef_issynthetic(o)) { + UPB_ASSERT(upb_oneofdef_fieldcount(o) == 1); + return upb_msg_has(msg, f) ? f : NULL; } else { - return _upb_hasbit_field(msg, field) ? f : NULL; + const upb_msglayout_field *field = upb_fielddef_layout(f); + uint32_t oneof_case = _upb_getoneofcase_field(msg, field); + f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL; + UPB_ASSERT((f != NULL) == (oneof_case != 0)); + return f; } - - return oneof_case ? upb_msgdef_itof(m, oneof_case) : NULL; } upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) { @@ -5785,11 +5653,12 @@ void upb_msg_clear(upb_msg *msg, const upb_msgdef *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) { - size_t i = *iter; + int i = *iter; + int n = upb_msgdef_fieldcount(m); const upb_msgval zero = {0}; - const upb_fielddef *f; UPB_UNUSED(ext_pool); - while ((f = _upb_msgdef_field(m, (int)++i)) != NULL) { + while (++i < n) { + const upb_fielddef *f = upb_msgdef_field(m, i); upb_msgval val = _upb_msg_getraw(msg, f); /* Skip field if unset or empty. */ @@ -5874,7 +5743,7 @@ bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) { /** upb_array *****************************************************************/ upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) { - return _upb_array_new(a, type); + return _upb_array_new(a, 4, _upb_fieldtype_to_sizelg2[type]); } size_t upb_array_size(const upb_array *arr) { @@ -5998,6 +5867,7 @@ int msvc_snprintf(char* s, size_t n, const char* format, ...) { #include #include #include +#include #include #include #include @@ -6032,6 +5902,19 @@ static bool jsondec_streql(upb_strview str, const char *lit) { return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0; } +static bool jsondec_isnullvalue(const upb_fielddef *f) { + return upb_fielddef_type(f) == UPB_TYPE_ENUM && + strcmp(upb_enumdef_fullname(upb_fielddef_enumsubdef(f)), + "google.protobuf.NullValue") == 0; +} + +static bool jsondec_isvalue(const upb_fielddef *f) { + return (upb_fielddef_type(f) == UPB_TYPE_MESSAGE && + upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(f)) == + UPB_WELLKNOWN_VALUE) || + jsondec_isnullvalue(f); +} + UPB_NORETURN static void jsondec_err(jsondec *d, const char *msg) { upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: %s", d->line, (int)(d->ptr - d->line_begin), msg); @@ -6372,6 +6255,8 @@ static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) { size_t size = UPB_MAX(8, 2 * oldsize); *buf = upb_arena_realloc(d->arena, *buf, len, size); + if (!*buf) jsondec_err(d, "Out of memory"); + *end = *buf + len; *buf_end = *buf + size; } @@ -6724,11 +6609,11 @@ static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) { case JD_STRING: str = jsondec_string(d); if (jsondec_streql(str, "NaN")) { - val.double_val = UPB_NAN; + val.double_val = NAN; } else if (jsondec_streql(str, "Infinity")) { - val.double_val = UPB_INFINITY; + val.double_val = INFINITY; } else if (jsondec_streql(str, "-Infinity")) { - val.double_val = -UPB_INFINITY; + val.double_val = -INFINITY; } else { val.double_val = strtod(str.data, NULL); } @@ -6738,7 +6623,7 @@ static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) { } if (upb_fielddef_type(f) == UPB_TYPE_FLOAT) { - if (val.double_val != UPB_INFINITY && val.double_val != -UPB_INFINITY && + 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"); } @@ -6759,21 +6644,32 @@ static upb_msgval jsondec_strfield(jsondec *d, const upb_fielddef *f) { } static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *f) { - if (jsondec_peek(d) == 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) { + switch (jsondec_peek(d)) { + case JD_STRING: { + const upb_enumdef *e = upb_fielddef_enumsubdef(f); + upb_strview str = jsondec_string(d); + upb_msgval val; + if (!upb_enumdef_ntoi(e, str.data, str.size, &val.int32_val)) { + if (d->options & UPB_JSONDEC_IGNOREUNKNOWN) { + val.int32_val = 0; + } else { + jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'", + UPB_STRVIEW_ARGS(str)); + } + } + return val; + } + case JD_NULL: { + if (jsondec_isnullvalue(f)) { + upb_msgval val; + jsondec_null(d); val.int32_val = 0; - } else { - jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'", - UPB_STRVIEW_ARGS(str)); + return val; } } - return val; - } else { - return jsondec_int(d, f); + /* Fallthrough. */ + default: + return jsondec_int(d, f); } } @@ -6857,12 +6753,6 @@ static upb_msgval jsondec_msg(jsondec *d, const upb_fielddef *f) { return val; } -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 void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) { upb_strview name; const upb_fielddef *f; @@ -7068,6 +6958,7 @@ static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) { upb_strview str = jsondec_string(d); const char *ptr = str.data; const char *end = ptr + str.size; + const int64_t max = (uint64_t)3652500 * 86400; /* "3.000000001s", "3s", etc. */ ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val); @@ -7077,7 +6968,7 @@ static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) { jsondec_err(d, "Malformed duration"); } - if (seconds.int64_val < -315576000000LL || seconds.int64_val > 315576000000LL) { + if (seconds.int64_val < -max || seconds.int64_val > max) { jsondec_err(d, "Duration out of range"); } @@ -7414,12 +7305,14 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg, #include #include #include +#include +#include #include #include #include -#include +/* Must be last. */ typedef struct { char *buf, *ptr, *end; @@ -7483,7 +7376,7 @@ static void jsonenc_printf(jsonenc *e, const char *fmt, ...) { va_list args; va_start(args, fmt); - n = _upb_vsnprintf(e->ptr, have, fmt, args); + n = vsnprintf(e->ptr, have, fmt, args); va_end(args); if (UPB_LIKELY(have > n)) { @@ -7574,12 +7467,17 @@ static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m static void jsonenc_enum(int32_t val, const upb_fielddef *f, jsonenc *e) { const upb_enumdef *e_def = upb_fielddef_enumsubdef(f); - const char *name = upb_enumdef_iton(e_def, val); - if (name) { - jsonenc_printf(e, "\"%s\"", name); + if (strcmp(upb_enumdef_fullname(e_def), "google.protobuf.NullValue") == 0) { + jsonenc_putstr(e, "null"); } else { - jsonenc_printf(e, "%" PRId32, val); + const char *name = upb_enumdef_iton(e_def, val); + + if (name) { + jsonenc_printf(e, "\"%s\"", name); + } else { + jsonenc_printf(e, "%" PRId32, val); + } } } @@ -7670,9 +7568,9 @@ static void jsonenc_string(jsonenc *e, upb_strview str) { } static void jsonenc_double(jsonenc *e, const char *fmt, double val) { - if (val == UPB_INFINITY) { + if (val == INFINITY) { jsonenc_putstr(e, "\"Infinity\""); - } else if (val == -UPB_INFINITY) { + } else if (val == -INFINITY) { jsonenc_putstr(e, "\"-Infinity\""); } else if (val != val) { jsonenc_putstr(e, "\"NaN\""); @@ -8055,10 +7953,10 @@ static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg, if (e->options & UPB_JSONENC_EMITDEFAULTS) { /* Iterate over all fields. */ - upb_msg_field_iter i; - for (upb_msg_field_begin(&i, m); !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - f = upb_msg_iter_field(&i); + int i = 0; + int n = upb_msgdef_fieldcount(m); + for (i = 0; i < n; i++) { + f = upb_msgdef_field(m, i); jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first); } } else { @@ -8127,11 +8025,7 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, #undef UPB_UNUSED #undef UPB_ASSUME #undef UPB_ASSERT -#undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE -#undef UPB_INFINITY -#undef UPB_NAN -#undef UPB_MSVC_VSNPRINTF -#undef _upb_snprintf -#undef _upb_vsnprintf -#undef _upb_va_copy +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index 666ec76d05e5..d22b4aa0e0e1 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -21,6 +21,15 @@ * * This file is private and must not be included by users! */ + +#if !(__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L) +#error upb requires C99 or C++11 +#endif + +#if (defined(_MSC_VER) && _MSC_VER < 1900) +#error upb requires MSVC >= 2015. +#endif + #include #include @@ -69,66 +78,21 @@ #define UPB_UNLIKELY(x) (x) #endif -/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler - * doesn't provide these preprocessor symbols. */ -#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define UPB_BIG_ENDIAN -#endif - /* Macros for function attributes on compilers that support them. */ #ifdef __GNUC__ #define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) #define UPB_NOINLINE __attribute__((noinline)) #define UPB_NORETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE +#define UPB_NORETURN __declspec(noreturn) #else /* !defined(__GNUC__) */ #define UPB_FORCEINLINE #define UPB_NOINLINE #define UPB_NORETURN #endif -#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L -/* C99/C++11 versions. */ -#include -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined(_MSC_VER) -/* Microsoft C/C++ versions. */ -#include -#include -#if _MSC_VER < 1900 -int msvc_snprintf(char* s, size_t n, const char* format, ...); -int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); -#define UPB_MSVC_VSNPRINTF -#define _upb_snprintf msvc_snprintf -#define _upb_vsnprintf msvc_vsnprintf -#else -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#endif -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined __GNUC__ -/* A few hacky workarounds for functions not in C89. - * For internal use only! - * TODO(haberman): fix these by including our own implementations, or finding - * another workaround. - */ -#define _upb_snprintf __builtin_snprintf -#define _upb_vsnprintf __builtin_vsnprintf -#define _upb_va_copy(a, b) __va_copy(a, b) -#else -#error Need implementations of [v]snprintf and va_copy -#endif - -#ifdef __cplusplus -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) -/* C++11 is present */ -#else -#error upb requires C++11 for C++ support -#endif -#endif - #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -142,7 +106,7 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #elif defined _MSC_VER #define UPB_ASSUME(expr) if (!(expr)) __assume(0) #else -#define UPB_ASSUME(expr) do {} if (false && (expr)) +#define UPB_ASSUME(expr) do {} while (false && (expr)) #endif #else #define UPB_ASSUME(expr) assert(expr) @@ -156,28 +120,33 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_ASSERT(expr) assert(expr) #endif -/* UPB_ASSERT_DEBUGVAR(): assert that uses functions or variables that only - * exist in debug mode. This turns into regular assert. */ -#define UPB_ASSERT_DEBUGVAR(expr) assert(expr) - #if defined(__GNUC__) || defined(__clang__) #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0) #else #define UPB_UNREACHABLE() do { assert(0); } while(0) #endif -/* UPB_INFINITY representing floating-point positive infinity. */ -#include -#ifdef INFINITY -#define UPB_INFINITY INFINITY -#else -#define UPB_INFINITY (1.0 / 0.0) +#if defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#ifdef __cplusplus +extern "C" { #endif -#ifdef NAN -#define UPB_NAN NAN -#else -#define UPB_NAN (0.0 / 0.0) +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#ifdef __cplusplus +} /* extern "C" */ #endif +#define UPB_POISON_MEMORY_REGION(addr, size) \ + __asan_poison_memory_region((addr), (size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) +#else +#define UPB_ASAN 0 +#define UPB_POISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#endif /* ** upb_decode: parsing into a upb_msg using a upb_msglayout. */ @@ -384,17 +353,35 @@ void *_upb_arena_slowmalloc(upb_arena *a, size_t size); UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; } +UPB_INLINE bool _upb_arenahas(upb_arena *a, size_t size) { + _upb_arena_head *h = (_upb_arena_head*)a; + return (size_t)(h->end - h->ptr) >= size; +} + UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { _upb_arena_head *h = (_upb_arena_head*)a; void* ret; size = UPB_ALIGN_MALLOC(size); - if (UPB_UNLIKELY((size_t)(h->end - h->ptr) < size)) { + if (UPB_UNLIKELY(!_upb_arenahas(a, size))) { return _upb_arena_slowmalloc(a, size); } ret = h->ptr; h->ptr += size; + UPB_UNPOISON_MEMORY_REGION(ret, size); + +#if UPB_ASAN + { + size_t guard_size = 32; + if (_upb_arenahas(a, guard_size)) { + h->ptr += guard_size; + } else { + h->ptr = h->end; + } + } +#endif + return ret; } @@ -496,6 +483,39 @@ typedef enum { #define UPB_MAP_BEGIN ((size_t)-1) +UPB_INLINE bool _upb_isle(void) { + int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t _upb_be_swap32(uint32_t val) { + if (_upb_isle()) { + return val; + } else { + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); + } +} + +UPB_INLINE uint64_t _upb_be_swap64(uint64_t val) { + if (_upb_isle()) { + return val; + } else { + return ((uint64_t)_upb_be_swap32(val) << 32) | _upb_be_swap32(val >> 32); + } +} + +UPB_INLINE int _upb_lg2ceil(int x) { + if (x <= 1) return 0; +#ifdef __GNUC__ + return 32 - __builtin_clz(x - 1); +#else + int lg2 = 0; + while (1 << lg2 < x) lg2++; + return lg2; +#endif +} + #ifdef __cplusplus } /* extern "C" */ @@ -649,7 +669,8 @@ typedef struct _upb_tabent { typedef struct { size_t count; /* Number of entries in the hash part. */ - size_t mask; /* Mask to turn hash value -> bucket. */ + uint32_t mask; /* Mask to turn hash value -> bucket. */ + uint32_t max_count; /* Max count before we hit our load limit. */ uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */ /* Hash table entries. @@ -708,7 +729,8 @@ UPB_INLINE bool upb_arrhas(upb_tabval key) { /* Initialize and uninitialize a table, respectively. If memory allocation * failed, false is returned that the table is uninitialized. */ bool upb_inttable_init2(upb_inttable *table, upb_ctype_t ctype, upb_alloc *a); -bool upb_strtable_init2(upb_strtable *table, upb_ctype_t ctype, upb_alloc *a); +bool upb_strtable_init2(upb_strtable *table, upb_ctype_t ctype, + size_t expected_size, upb_alloc *a); void upb_inttable_uninit2(upb_inttable *table, upb_alloc *a); void upb_strtable_uninit2(upb_strtable *table, upb_alloc *a); @@ -717,7 +739,7 @@ UPB_INLINE bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype) { } UPB_INLINE bool upb_strtable_init(upb_strtable *table, upb_ctype_t ctype) { - return upb_strtable_init2(table, ctype, &upb_alloc_global); + return upb_strtable_init2(table, ctype, 4, &upb_alloc_global); } UPB_INLINE void upb_inttable_uninit(upb_inttable *table) { @@ -989,25 +1011,42 @@ typedef struct upb_msglayout { * compatibility. We put these before the user's data. The user's upb_msg* * points after the upb_msg_internal. */ -/* Used when a message is not extendable. */ typedef struct { - char *unknown; - size_t unknown_len; - size_t unknown_size; -} upb_msg_internal; + uint32_t len; + uint32_t size; + /* Data follows. */ +} upb_msg_unknowndata; -/* Used when a message is extendable. */ +/* Used when a message is not extendable. */ typedef struct { - upb_inttable *extdict; - upb_msg_internal base; -} upb_msg_internal_withext; + upb_msg_unknowndata *unknown; +} upb_msg_internal; /* Maps upb_fieldtype_t -> memory size. */ extern char _upb_fieldtype_to_size[12]; +UPB_INLINE size_t upb_msg_sizeof(const upb_msglayout *l) { + return l->size + sizeof(upb_msg_internal); +} + +UPB_INLINE upb_msg *_upb_msg_new_inl(const upb_msglayout *l, upb_arena *a) { + size_t size = upb_msg_sizeof(l); + void *mem = upb_arena_malloc(a, size); + upb_msg *msg; + if (UPB_UNLIKELY(!mem)) return NULL; + msg = UPB_PTR_AT(mem, sizeof(upb_msg_internal), upb_msg); + memset(mem, 0, size); + return msg; +} + /* Creates a new messages with the given layout on the given arena. */ upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a); +UPB_INLINE upb_msg_internal *upb_msg_getinternal(upb_msg *msg) { + ptrdiff_t size = sizeof(upb_msg_internal); + return (upb_msg_internal*)((char*)msg - size); +} + /* Clears the given message. */ void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l); @@ -1100,9 +1139,11 @@ typedef struct { uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ size_t len; /* Measured in elements. */ size_t size; /* Measured in elements. */ + uint64_t junk; } upb_array; UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) { + UPB_ASSERT((arr->data & 7) <= 4); return (void*)(arr->data & ~(uintptr_t)7); } @@ -1110,17 +1151,32 @@ UPB_INLINE void *_upb_array_ptr(upb_array *arr) { return (void*)_upb_array_constptr(arr); } -/* Creates a new array on the given arena. */ -upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type); +UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) { + UPB_ASSERT(elem_size_lg2 <= 4); + UPB_ASSERT(((uintptr_t)ptr & 7) == 0); + return (uintptr_t)ptr | (unsigned)elem_size_lg2; +} + +UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size, + int elem_size_lg2) { + const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_array), 8); + const size_t bytes = sizeof(upb_array) + (init_size << elem_size_lg2); + upb_array *arr = (upb_array*)upb_arena_malloc(a, bytes); + if (!arr) return NULL; + arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2); + arr->len = 0; + arr->size = init_size; + return arr; +} /* Resizes the capacity of the array to be at least min_size. */ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena); /* Fallback functions for when the accessors require a resize. */ void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, - upb_fieldtype_t type, upb_arena *arena); + int elem_size_lg2, upb_arena *arena); bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, - upb_fieldtype_t type, upb_arena *arena); + int elem_size_lg2, upb_arena *arena); UPB_INLINE bool _upb_array_reserve(upb_array *arr, size_t size, upb_arena *arena) { @@ -1159,29 +1215,28 @@ UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, } } -UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, - upb_fieldtype_t type, - upb_arena *arena) { - upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*); +UPB_INLINE void *_upb_array_resize_accessor2(void *msg, size_t ofs, size_t size, + int elem_size_lg2, + upb_arena *arena) { + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array *); upb_array *arr = *arr_ptr; if (!arr || arr->size < size) { - return _upb_array_resize_fallback(arr_ptr, size, type, 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_accessor(void *msg, size_t ofs, - size_t elem_size, - upb_fieldtype_t type, - const void *value, - upb_arena *arena) { - upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*); +UPB_INLINE bool _upb_array_append_accessor2(void *msg, size_t ofs, + int elem_size_lg2, + const void *value, + upb_arena *arena) { + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array *); + size_t elem_size = 1 << elem_size_lg2; upb_array *arr = *arr_ptr; - void* ptr; + void *ptr; if (!arr || arr->len == arr->size) { - return _upb_array_append_fallback(arr_ptr, value, type, arena); + return _upb_array_append_fallback(arr_ptr, value, elem_size_lg2, arena); } ptr = _upb_array_ptr(arr); memcpy(PTR_AT(ptr, arr->len * elem_size, char), value, elem_size); @@ -1189,6 +1244,42 @@ UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs, return true; } +/* Used by old generated code, remove once all code has been regenerated. */ +UPB_INLINE int _upb_sizelg2(upb_fieldtype_t type) { + switch (type) { + case UPB_TYPE_BOOL: + return 0; + case UPB_TYPE_FLOAT: + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_ENUM: + return 2; + case UPB_TYPE_MESSAGE: + return UPB_SIZE(2, 3); + case UPB_TYPE_DOUBLE: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + return 3; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + return UPB_SIZE(3, 4); + } + UPB_UNREACHABLE(); +} +UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, + upb_fieldtype_t type, + upb_arena *arena) { + return _upb_array_resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena); +} +UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs, + size_t elem_size, upb_fieldtype_t type, + const void *value, + upb_arena *arena) { + (void)elem_size; + return _upb_array_append_accessor2(msg, ofs, _upb_sizelg2(type), value, + arena); +} + /** upb_map *******************************************************************/ /* Right now we use strmaps for everything. We'll likely want to use @@ -1245,17 +1336,17 @@ UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { } } -UPB_INLINE upb_value _upb_map_tovalue(const void *val, size_t size, - upb_arena *a) { - upb_value ret = {0}; +UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval, + upb_arena *a) { if (size == UPB_MAPTYPE_STRING) { upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp)); + if (!strp) return false; *strp = *(upb_strview*)val; - memcpy(&ret, &strp, sizeof(strp)); + *msgval = upb_value_ptr(strp); } else { - memcpy(&ret, val, size); + memcpy(msgval, val, size); } - return ret; + return true; } UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { @@ -1297,7 +1388,8 @@ UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size, void *val, size_t val_size, upb_arena *arena) { upb_strview strkey = _upb_map_tokey(key, key_size); - upb_value tabval = _upb_map_tovalue(val, val_size, arena); + upb_value tabval = {0}; + if (!_upb_map_tovalue(val, val_size, &tabval, arena)) return false; upb_alloc *a = upb_arena_alloc(arena); /* TODO(haberman): add overwrite operation to minimize number of lookups. */ @@ -1382,7 +1474,7 @@ UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, size_t size) /* This is like _upb_map_tovalue() except the entry already exists so we can * reuse the allocated upb_strview for string fields. */ if (size == UPB_MAPTYPE_STRING) { - upb_strview *strp = (upb_strview*)ent->val.val; + upb_strview *strp = (upb_strview*)(uintptr_t)ent->val.val; memcpy(strp, val, sizeof(*strp)); } else { memcpy(&ent->val.val, val, size); @@ -1410,6 +1502,34 @@ bool upb_decode(const char *buf, size_t size, upb_msg *msg, #endif #endif /* UPB_DECODE_H_ */ + +#ifndef UPB_INT_H_ +#define UPB_INT_H_ + + +struct mem_block; +typedef struct mem_block mem_block; + +struct upb_arena { + _upb_arena_head head; + uint32_t *cleanups; + + /* Allocator to allocate arena blocks. We are responsible for freeing these + * when we are destroyed. */ + upb_alloc *block_alloc; + uint32_t last_size; + + /* When multiple arenas are fused together, each arena points to a parent + * arena (root points to itself). The root tracks how many live arenas + * reference it. */ + uint32_t refcount; /* Only used when a->parent == a */ + struct upb_arena *parent; + + /* Linked list of blocks to free/cleanup. */ + mem_block *freelist, *freelist_tail; +}; + +#endif /* UPB_INT_H_ */ /* ** upb_encode: parsing into a upb_msg using a upb_msglayout. */ @@ -1602,12 +1722,12 @@ UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorS return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1660,22 +1780,22 @@ UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(g return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); } UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(3, 4), arena); } UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor(msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + 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_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1683,12 +1803,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorP return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1696,12 +1816,12 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescript return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len); } UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(48, 96), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1709,12 +1829,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptor return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len); } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(52, 104), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1748,20 +1868,20 @@ UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependenc return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len); } UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_TYPE_INT32, 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_accessor(msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + 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_accessor(msg, UPB_SIZE(60, 120), len, UPB_TYPE_INT32, 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_accessor(msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + 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) { @@ -1811,12 +1931,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1824,12 +1944,12 @@ UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mut return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1837,12 +1957,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1850,12 +1970,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_Desc return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); } UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1863,12 +1983,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1889,12 +2009,12 @@ UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProt return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); } UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1902,12 +2022,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_Descr return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); } UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -1915,10 +2035,10 @@ UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(go return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); } UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(3, 4), arena); } UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor(msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + return _upb_array_append_accessor2(msg, UPB_SIZE(44, 88), UPB_SIZE(3, 4), &val, arena); } @@ -2014,12 +2134,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeO return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2039,59 +2159,59 @@ UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_pro } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview); } +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(24, 24), 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, 1); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); } -UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), 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, 4); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t); } +UPB_INLINE 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(68, 104), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), 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_sethas(msg, 6); - *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 7); - *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 3); - *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 8); - *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 9); - *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { _upb_sethas(msg, 11); - *UPB_PTR_AT(msg, UPB_SIZE(76, 120), google_protobuf_FieldOptions*) = value; + *UPB_PTR_AT(msg, UPB_SIZE(64, 104), google_protobuf_FieldOptions*) = value; } UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg); @@ -2104,15 +2224,15 @@ UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorP } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 4); - *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 10); - *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) { _upb_sethas(msg, 5); - *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value; } /* google.protobuf.OneofDescriptorProto */ @@ -2184,12 +2304,12 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescri return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2210,12 +2330,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protob return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2223,10 +2343,10 @@ UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_nam return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(3, 4), arena); } UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), UPB_SIZE(3, 4), &val, arena); } @@ -2330,12 +2450,12 @@ UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescri return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2429,138 +2549,138 @@ UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_Fil } UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); } -UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); } -UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), 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, 13); } -UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); } -UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(17, 17), 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, 4); } -UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool); } +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); } -UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(19, 19), 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, 6); } -UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); } +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); } -UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(21, 21), 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, 8); } -UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool); } +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); } -UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool); } +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); } -UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); } -UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); } -UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); } -UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); } -UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); } -UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), 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(92, 160), upb_strview); } +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(100, 176), upb_strview); } -UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(108, 192)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(108, 192), len); } +UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 184)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(100, 184), len); } UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 11); - *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 12); - *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 13); - *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 3); - *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 4); - *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 5); - *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 6); - *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 7); - *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 8); - *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 9); - *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 14); - *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 15); - *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 16); - *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 17); - *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 18); - *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 10); - *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 19); - *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 20); - *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview) = value; + *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions *msg, size_t *len) { - return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), 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_accessor(msg, UPB_SIZE(108, 192), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(100, 184), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2610,12 +2730,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(8, 8), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2635,54 +2755,54 @@ UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_Fi } UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); } -UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), 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, 4); } -UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); } UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); } -UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(26, 26), 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, 2); } -UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } +UPB_INLINE 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(27, 27), bool); } -UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 32)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 16)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); } UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 3); - *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 4); - *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 5); - *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 6); - *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool) = value; + *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(28, 32), len); + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 16), len, UPB_SIZE(2, 3), arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) { struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); - bool ok = _upb_array_append_accessor( - msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(16, 16), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2708,12 +2828,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mu return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2751,12 +2871,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mut return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2788,12 +2908,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOption return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2825,12 +2945,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2850,30 +2970,30 @@ UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_M } UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 2); } -UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); } +UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); } UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); } -UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } -UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); } -UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } +UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); } UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { _upb_sethas(msg, 2); - *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value; } UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) { _upb_sethas(msg, 1); - *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) { - return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), 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_accessor(msg, UPB_SIZE(20, 24), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(12, 16), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2911,12 +3031,12 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_Uninte return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len); } UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(56, 80), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -2994,12 +3114,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeI return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) { - return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -3030,20 +3150,20 @@ UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_ return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_INT32, 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_accessor(msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + 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_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_INT32, 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_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + 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) { @@ -3058,10 +3178,10 @@ UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_ return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); } UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena); } UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val, arena); } @@ -3086,12 +3206,12 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_Genera return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) { - return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, 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_accessor( - msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena); if (!ok) return NULL; return sub; } @@ -3122,10 +3242,10 @@ UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(go return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); } UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_TYPE_INT32, 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_accessor(msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + 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) { @@ -3262,9 +3382,10 @@ typedef upb_inttable_iter upb_oneof_iter; const char *upb_oneofdef_name(const upb_oneofdef *o); const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o); -int upb_oneofdef_numfields(const upb_oneofdef *o); uint32_t upb_oneofdef_index(const upb_oneofdef *o); bool upb_oneofdef_issynthetic(const upb_oneofdef *o); +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. @@ -3278,11 +3399,8 @@ UPB_INLINE const upb_fielddef *upb_oneofdef_ntofz(const upb_oneofdef *o, } const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num); -/* upb_oneof_iter i; - * for(upb_oneof_begin(&i, e); !upb_oneof_done(&i); upb_oneof_next(&i)) { - * // ... - * } - */ +/* 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); @@ -3290,6 +3408,7 @@ 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 *****************************************************************/ @@ -3315,21 +3434,21 @@ typedef upb_strtable_iter upb_msg_oneof_iter; const char *upb_msgdef_fullname(const upb_msgdef *m); const upb_filedef *upb_msgdef_file(const upb_msgdef *m); const char *upb_msgdef_name(const upb_msgdef *m); -int upb_msgdef_numfields(const upb_msgdef *m); -int upb_msgdef_numoneofs(const upb_msgdef *m); -int upb_msgdef_numrealoneofs(const upb_msgdef *m); upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); bool upb_msgdef_mapentry(const upb_msgdef *m); upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); bool upb_msgdef_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); -const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i); UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m, const char *name) { @@ -3361,19 +3480,10 @@ UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name, const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, const char *name, size_t len); -/* Iteration over fields and oneofs. For example: - * - * upb_msg_field_iter i; - * for(upb_msg_field_begin(&i, m); - * !upb_msg_field_done(&i); - * upb_msg_field_next(&i)) { - * upb_fielddef *f = upb_msg_iter_field(&i); - * // ... - * } - * - * For C we don't have separate iterators for const and non-const. - * It is the caller's responsibility to cast the upb_fielddef* to - * const if the upb_msgdef* is const. */ +/* 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); @@ -3381,9 +3491,6 @@ upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter); void upb_msg_field_iter_setdone(upb_msg_field_iter *iter); bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, const upb_msg_field_iter * iter2); - -/* Similar to above, we also support iterating through the oneofs in a - * msgdef. */ void upb_msg_oneof_begin(upb_msg_oneof_iter * iter, const upb_msgdef *m); void upb_msg_oneof_next(upb_msg_oneof_iter * iter); bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter); @@ -3391,6 +3498,7 @@ 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 ****************************************************************/ @@ -3415,11 +3523,6 @@ UPB_INLINE bool upb_enumdef_ntoiz(const upb_enumdef *e, } const char *upb_enumdef_iton(const upb_enumdef *e, int32_t num); -/* upb_enum_iter i; - * for(upb_enum_begin(&i, e); !upb_enum_done(&i); upb_enum_next(&i)) { - * // ... - * } - */ void upb_enum_begin(upb_enum_iter *iter, const upb_enumdef *e); void upb_enum_next(upb_enum_iter *iter); bool upb_enum_done(upb_enum_iter *iter); @@ -3455,6 +3558,7 @@ int upb_symtab_filecount(const upb_symtab *s); const upb_filedef *upb_symtab_addfile( upb_symtab *s, const google_protobuf_FileDescriptorProto *file, upb_status *status); +size_t _upb_symtab_bytesloaded(const upb_symtab *s); /* For generated code only: loads a generated descriptor. */ typedef struct upb_def_init { @@ -3872,11 +3976,7 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, #undef UPB_UNUSED #undef UPB_ASSUME #undef UPB_ASSERT -#undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE -#undef UPB_INFINITY -#undef UPB_NAN -#undef UPB_MSVC_VSNPRINTF -#undef _upb_snprintf -#undef _upb_vsnprintf -#undef _upb_va_copy +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c index fa1cc114b1f4..761eeeb53257 100644 --- a/php/ext/google/protobuf/protobuf.c +++ b/php/ext/google/protobuf/protobuf.c @@ -35,7 +35,6 @@ #include "arena.h" #include "array.h" -#include "bundled_php.h" #include "convert.h" #include "def.h" #include "map.h" @@ -162,10 +161,6 @@ static PHP_RINIT_FUNCTION(protobuf) { upb_symtab *symtab = PROTOBUF_G(saved_symtab); DescriptorPool_CreateWithSymbolTable(&PROTOBUF_G(generated_pool), symtab); - // Set up autoloader for bundled sources. - zend_eval_string("spl_autoload_register('protobuf_internal_loadbundled');", - NULL, "autoload_register.php"); - zend_hash_init(&PROTOBUF_G(object_cache), 64, NULL, NULL, 0); zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0); zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0); @@ -193,34 +188,6 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) { return SUCCESS; } -// ----------------------------------------------------------------------------- -// Bundled PHP sources -// ----------------------------------------------------------------------------- - -// We bundle PHP sources for well-known types into the C extension. There is no -// need to implement these in C. - -static PHP_FUNCTION(protobuf_internal_loadbundled) { - char *name = NULL; - zend_long size; - BundledPhp_File *file; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &size) != SUCCESS) { - return; - } - - for (file = bundled_files; file->filename; file++) { - if (strcmp(file->filename, name) == 0) { - zend_eval_string((char*)file->contents, NULL, (char*)file->filename); - return; - } - } -} - -ZEND_BEGIN_ARG_INFO_EX(arginfo_load_bundled_source, 0, 0, 1) - ZEND_ARG_INFO(0, class_name) -ZEND_END_ARG_INFO() - // ----------------------------------------------------------------------------- // Object Cache. // ----------------------------------------------------------------------------- @@ -303,7 +270,6 @@ const upb_enumdef *NameMap_GetEnum(zend_class_entry *ce) { // ----------------------------------------------------------------------------- zend_function_entry protobuf_functions[] = { - PHP_FE(protobuf_internal_loadbundled, arginfo_load_bundled_source) ZEND_FE_END }; @@ -345,7 +311,7 @@ zend_module_entry protobuf_module_entry = { PHP_RINIT(protobuf), // request shutdown PHP_RSHUTDOWN(protobuf), // request shutdown NULL, // extension info - "3.13.0", // extension version + PHP_PROTOBUF_VERSION, // extension version PHP_MODULE_GLOBALS(protobuf), // globals descriptor PHP_GINIT(protobuf), // globals ctor PHP_GSHUTDOWN(protobuf), // globals dtor diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 195e2a797187..fe0b5a714772 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -69,7 +69,7 @@ const zval *get_generated_pool(); #define PROTO_STRLEN_P(obj) ZSTR_LEN(obj) #endif -#define PHP_PROTOBUF_VERSION "3.13.0.1" +#define PHP_PROTOBUF_VERSION "3.14.0" // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: diff --git a/php/ext/google/protobuf/wkt.inc b/php/ext/google/protobuf/wkt.inc new file mode 100644 index 000000000000..573ff30c1478 --- /dev/null +++ b/php/ext/google/protobuf/wkt.inc @@ -0,0 +1,3232 @@ +// This file is generated from the .proto files for the well-known +// types. Do not edit! +static void google_protobuf_any_proto_AddDescriptor(); +static void google_protobuf_api_proto_AddDescriptor(); +static void google_protobuf_duration_proto_AddDescriptor(); +static void google_protobuf_empty_proto_AddDescriptor(); +static void google_protobuf_field_mask_proto_AddDescriptor(); +static void google_protobuf_source_context_proto_AddDescriptor(); +static void google_protobuf_struct_proto_AddDescriptor(); +static void google_protobuf_type_proto_AddDescriptor(); +static void google_protobuf_timestamp_proto_AddDescriptor(); +static void google_protobuf_wrappers_proto_AddDescriptor(); +/* google/protobuf/any.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Any_ce; + +const char google_protobuf_any_proto_descriptor [212] = { +'\n', '\031', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'n', 'y', '.', 'p', 'r', 'o', +'t', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '&', '\n', '\003', 'A', 'n', +'y', '\022', '\020', '\n', '\010', 't', 'y', 'p', 'e', '_', 'u', 'r', 'l', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\r', '\n', '\005', 'v', 'a', +'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\014', 'B', 'v', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\010', 'A', 'n', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', ',', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', +'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'a', 'n', 'y', 'p', 'b', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', +'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', +'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_any_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/any.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/any.proto", google_protobuf_any_proto_descriptor, + sizeof(google_protobuf_any_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Any, initOnce) { + google_protobuf_any_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Any_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Any, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Any_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Any", + GPBMetadata_Google_Protobuf_Any_methods); + + GPBMetadata_Google_Protobuf_Any_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Any */ + +zend_class_entry* google_protobuf_Any_ce; + +static PHP_METHOD(google_protobuf_Any, __construct) { + google_protobuf_any_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Any, getTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Any, setTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Any, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Any, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Any_phpmethods[] = { + PHP_ME(google_protobuf_Any, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, getTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, setTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, setValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, is, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, pack, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, unpack, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Any_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Any", + google_protobuf_Any_phpmethods); + + google_protobuf_Any_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Any_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Any_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Any_ce, message_ce); +} + +/* google/protobuf/api.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Api_ce; + +const char google_protobuf_api_proto_descriptor [751] = { +'\n', '\031', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'p', 'i', '.', 'p', 'r', 'o', +'t', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\032', '$', 'g', 'o', 'o', 'g', +'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', +'t', '.', 'p', 'r', 'o', 't', 'o', '\032', '\032', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', +'t', 'y', 'p', 'e', '.', 'p', 'r', 'o', 't', 'o', '\"', '\201', '\002', '\n', '\003', 'A', 'p', 'i', '\022', '\014', '\n', '\004', 'n', 'a', 'm', +'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '(', '\n', '\007', 'm', 'e', 't', 'h', 'o', 'd', 's', '\030', '\002', ' ', '\003', '(', '\013', '2', +'\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', '\022', +'(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\017', '\n', '\007', 'v', 'e', 'r', 's', 'i', +'o', 'n', '\030', '\004', ' ', '\001', '(', '\t', '\022', '6', '\n', '\016', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', +'t', '\030', '\005', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', '&', '\n', '\006', 'm', 'i', 'x', 'i', 'n', 's', '\030', +'\006', ' ', '\003', '(', '\013', '2', '\026', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', +'i', 'x', 'i', 'n', '\022', '\'', '\n', '\006', 's', 'y', 'n', 't', 'a', 'x', '\030', '\007', ' ', '\001', '(', '\016', '2', '\027', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', 't', 'a', 'x', '\"', '\325', '\001', '\n', '\006', +'M', 'e', 't', 'h', 'o', 'd', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\030', '\n', '\020', 'r', +'e', 'q', 'u', 'e', 's', 't', '_', 't', 'y', 'p', 'e', '_', 'u', 'r', 'l', '\030', '\002', ' ', '\001', '(', '\t', '\022', '\031', '\n', '\021', +'r', 'e', 'q', 'u', 'e', 's', 't', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\003', ' ', '\001', '(', '\010', '\022', '\031', +'\n', '\021', 'r', 'e', 's', 'p', 'o', 'n', 's', 'e', '_', 't', 'y', 'p', 'e', '_', 'u', 'r', 'l', '\030', '\004', ' ', '\001', '(', '\t', +'\022', '\032', '\n', '\022', 'r', 'e', 's', 'p', 'o', 'n', 's', 'e', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\005', ' ', +'\001', '(', '\010', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\006', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\'', '\n', '\006', 's', +'y', 'n', 't', 'a', 'x', '\030', '\007', ' ', '\001', '(', '\016', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', +'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', 't', 'a', 'x', '\"', '#', '\n', '\005', 'M', 'i', 'x', 'i', 'n', '\022', '\014', '\n', '\004', 'n', +'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\014', '\n', '\004', 'r', 'o', 'o', 't', '\030', '\002', ' ', '\001', '(', '\t', 'B', 'v', +'\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\010', 'A', 'p', +'i', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', ',', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', +'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'a', +'p', 'i', 'p', 'b', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', +'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', +'3', +}; + +static void google_protobuf_api_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/api.proto")) return; + google_protobuf_source_context_proto_AddDescriptor(); + google_protobuf_type_proto_AddDescriptor(); + DescriptorPool_AddDescriptor("google/protobuf/api.proto", google_protobuf_api_proto_descriptor, + sizeof(google_protobuf_api_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Api, initOnce) { + google_protobuf_api_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Api_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Api, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Api_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Api", + GPBMetadata_Google_Protobuf_Api_methods); + + GPBMetadata_Google_Protobuf_Api_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Api */ + +zend_class_entry* google_protobuf_Api_ce; + +static PHP_METHOD(google_protobuf_Api, __construct) { + google_protobuf_api_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Api, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getMethods) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "methods"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setMethods) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "methods"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getVersion) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "version"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setVersion) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "version"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getMixins) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "mixins"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setMixins) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "mixins"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Api_phpmethods[] = { + PHP_ME(google_protobuf_Api, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getMethods, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setMethods, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getVersion, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setVersion, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getMixins, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setMixins, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Api_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Api", + google_protobuf_Api_phpmethods); + + google_protobuf_Api_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Api_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Api_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Api_ce, message_ce); +} + +/* google_protobuf_Method */ + +zend_class_entry* google_protobuf_Method_ce; + +static PHP_METHOD(google_protobuf_Method, __construct) { + google_protobuf_api_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Method, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getRequestTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setRequestTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getRequestStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_streaming"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setRequestStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_streaming"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getResponseTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setResponseTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getResponseStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_streaming"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setResponseStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_streaming"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Method_phpmethods[] = { + PHP_ME(google_protobuf_Method, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getRequestTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setRequestTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getRequestStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setRequestStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getResponseTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setResponseTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getResponseStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setResponseStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Method_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Method", + google_protobuf_Method_phpmethods); + + google_protobuf_Method_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Method_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Method_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Method_ce, message_ce); +} + +/* google_protobuf_Mixin */ + +zend_class_entry* google_protobuf_Mixin_ce; + +static PHP_METHOD(google_protobuf_Mixin, __construct) { + google_protobuf_api_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Mixin, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Mixin, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Mixin, getRoot) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "root"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Mixin, setRoot) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "root"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Mixin_phpmethods[] = { + PHP_ME(google_protobuf_Mixin, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, getRoot, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, setRoot, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Mixin_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Mixin", + google_protobuf_Mixin_phpmethods); + + google_protobuf_Mixin_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Mixin_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Mixin_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Mixin_ce, message_ce); +} + +/* google/protobuf/duration.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Duration_ce; + +const char google_protobuf_duration_proto_descriptor [235] = { +'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', +'n', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', +'*', '\n', '\010', 'D', 'u', 'r', 'a', 't', 'i', 'o', 'n', '\022', '\017', '\n', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\030', '\001', ' ', +'\001', '(', '\003', '\022', '\r', '\n', '\005', 'n', 'a', 'n', 'o', 's', '\030', '\002', ' ', '\001', '(', '\005', 'B', '\203', '\001', '\n', '\023', 'c', 'o', +'m', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\r', 'D', 'u', 'r', 'a', 't', 'i', +'o', 'n', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '1', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', +'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', +'d', 'u', 'r', 'a', 't', 'i', 'o', 'n', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', +'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', +'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_duration_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/duration.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/duration.proto", google_protobuf_duration_proto_descriptor, + sizeof(google_protobuf_duration_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Duration, initOnce) { + google_protobuf_duration_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Duration_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Duration, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Duration_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Duration", + GPBMetadata_Google_Protobuf_Duration_methods); + + GPBMetadata_Google_Protobuf_Duration_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Duration */ + +zend_class_entry* google_protobuf_Duration_ce; + +static PHP_METHOD(google_protobuf_Duration, __construct) { + google_protobuf_duration_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Duration, getSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Duration, setSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Duration, getNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Duration, setNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Duration_phpmethods[] = { + PHP_ME(google_protobuf_Duration, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, getSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, setSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, getNanos, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, setNanos, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Duration_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Duration", + google_protobuf_Duration_phpmethods); + + google_protobuf_Duration_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Duration_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Duration_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Duration_ce, message_ce); +} + +/* google/protobuf/empty.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_GPBEmpty_ce; + +const char google_protobuf_empty_proto_descriptor [190] = { +'\n', '\033', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'e', 'm', 'p', 't', 'y', '.', 'p', +'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '\007', '\n', '\005', +'E', 'm', 'p', 't', 'y', 'B', '}', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', 'B', '\n', 'E', 'm', 'p', 't', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', +'s', '/', 'k', 'n', 'o', 'w', 'n', '/', 'e', 'm', 'p', 't', 'y', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', +'\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', +'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_empty_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/empty.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/empty.proto", google_protobuf_empty_proto_descriptor, + sizeof(google_protobuf_empty_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_GPBEmpty, initOnce) { + google_protobuf_empty_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_GPBEmpty_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_GPBEmpty, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_GPBEmpty_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\GPBEmpty", + GPBMetadata_Google_Protobuf_GPBEmpty_methods); + + GPBMetadata_Google_Protobuf_GPBEmpty_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Empty */ + +zend_class_entry* google_protobuf_Empty_ce; + +static PHP_METHOD(google_protobuf_Empty, __construct) { + google_protobuf_empty_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static zend_function_entry google_protobuf_Empty_phpmethods[] = { + PHP_ME(google_protobuf_Empty, __construct, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Empty_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\GPBEmpty", + google_protobuf_Empty_phpmethods); + + google_protobuf_Empty_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Empty_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Empty_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Empty_ce, message_ce); +} + +/* google/protobuf/field_mask.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_FieldMask_ce; + +const char google_protobuf_field_mask_proto_descriptor [223] = { +'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'f', 'i', 'e', 'l', 'd', '_', 'm', +'a', 's', 'k', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', +'f', '\"', '\032', '\n', '\t', 'F', 'i', 'e', 'l', 'd', 'M', 'a', 's', 'k', '\022', '\r', '\n', '\005', 'p', 'a', 't', 'h', 's', '\030', '\001', +' ', '\003', '(', '\t', 'B', '\205', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', 'B', '\016', 'F', 'i', 'e', 'l', 'd', 'M', 'a', 's', 'k', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '2', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', +'t', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'f', 'i', 'e', 'l', 'd', 'm', 'a', 's', 'k', 'p', 'b', '\370', '\001', +'\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_field_mask_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/field_mask.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/field_mask.proto", google_protobuf_field_mask_proto_descriptor, + sizeof(google_protobuf_field_mask_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_FieldMask, initOnce) { + google_protobuf_field_mask_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_FieldMask_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_FieldMask, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_FieldMask_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\FieldMask", + GPBMetadata_Google_Protobuf_FieldMask_methods); + + GPBMetadata_Google_Protobuf_FieldMask_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_FieldMask */ + +zend_class_entry* google_protobuf_FieldMask_ce; + +static PHP_METHOD(google_protobuf_FieldMask, __construct) { + google_protobuf_field_mask_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_FieldMask, getPaths) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "paths"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_FieldMask, setPaths) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "paths"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_FieldMask_phpmethods[] = { + PHP_ME(google_protobuf_FieldMask, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FieldMask, getPaths, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FieldMask, setPaths, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_FieldMask_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\FieldMask", + google_protobuf_FieldMask_phpmethods); + + google_protobuf_FieldMask_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_FieldMask_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_FieldMask_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_FieldMask_ce, message_ce); +} + +/* google/protobuf/source_context.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_SourceContext_ce; + +const char google_protobuf_source_context_proto_descriptor [240] = { +'\n', '$', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 'o', 'u', 'r', 'c', 'e', '_', +'c', 'o', 'n', 't', 'e', 'x', 't', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '\"', '\"', '\n', '\r', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', '\021', '\n', +'\t', 'f', 'i', 'l', 'e', '_', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'B', '\212', '\001', '\n', '\023', 'c', 'o', 'm', '.', +'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\022', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', +'n', 't', 'e', 'x', 't', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '6', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', +'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', +'w', 'n', '/', 's', 'o', 'u', 'r', 'c', 'e', 'c', 'o', 'n', 't', 'e', 'x', 't', 'p', 'b', '\242', '\002', '\003', 'G', 'P', 'B', '\252', +'\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', +'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_source_context_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/source_context.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/source_context.proto", google_protobuf_source_context_proto_descriptor, + sizeof(google_protobuf_source_context_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_SourceContext, initOnce) { + google_protobuf_source_context_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_SourceContext_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_SourceContext, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_SourceContext_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\SourceContext", + GPBMetadata_Google_Protobuf_SourceContext_methods); + + GPBMetadata_Google_Protobuf_SourceContext_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_SourceContext */ + +zend_class_entry* google_protobuf_SourceContext_ce; + +static PHP_METHOD(google_protobuf_SourceContext, __construct) { + google_protobuf_source_context_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_SourceContext, getFileName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "file_name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_SourceContext, setFileName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "file_name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_SourceContext_phpmethods[] = { + PHP_ME(google_protobuf_SourceContext, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_SourceContext, getFileName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_SourceContext, setFileName, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_SourceContext_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\SourceContext", + google_protobuf_SourceContext_phpmethods); + + google_protobuf_SourceContext_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_SourceContext_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_SourceContext_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_SourceContext_ce, message_ce); +} + +/* google/protobuf/struct.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Struct_ce; + +const char google_protobuf_struct_proto_descriptor [638] = { +'\n', '\034', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 't', 'r', 'u', 'c', 't', '.', +'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '\204', '\001', +'\n', '\006', 'S', 't', 'r', 'u', 'c', 't', '\022', '3', '\n', '\006', 'f', 'i', 'e', 'l', 'd', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', +'#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 't', 'r', 'u', 'c', 't', '.', +'F', 'i', 'e', 'l', 'd', 's', 'E', 'n', 't', 'r', 'y', '\032', 'E', '\n', '\013', 'F', 'i', 'e', 'l', 'd', 's', 'E', 'n', 't', 'r', +'y', '\022', '\013', '\n', '\003', 'k', 'e', 'y', '\030', '\001', ' ', '\001', '(', '\t', '\022', '%', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', +' ', '\001', '(', '\013', '2', '\026', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'V', 'a', +'l', 'u', 'e', ':', '\002', '8', '\001', '\"', '\352', '\001', '\n', '\005', 'V', 'a', 'l', 'u', 'e', '\022', '0', '\n', '\n', 'n', 'u', 'l', 'l', +'_', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '\032', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '.', 'N', 'u', 'l', 'l', 'V', 'a', 'l', 'u', 'e', 'H', '\000', '\022', '\026', '\n', '\014', 'n', 'u', 'm', 'b', +'e', 'r', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\001', 'H', '\000', '\022', '\026', '\n', '\014', 's', 't', 'r', 'i', 'n', +'g', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'H', '\000', '\022', '\024', '\n', '\n', 'b', 'o', 'o', 'l', '_', 'v', +'a', 'l', 'u', 'e', '\030', '\004', ' ', '\001', '(', '\010', 'H', '\000', '\022', '/', '\n', '\014', 's', 't', 'r', 'u', 'c', 't', '_', 'v', 'a', +'l', 'u', 'e', '\030', '\005', ' ', '\001', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'S', 't', 'r', 'u', 'c', 't', 'H', '\000', '\022', '0', '\n', '\n', 'l', 'i', 's', 't', '_', 'v', 'a', 'l', 'u', 'e', +'\030', '\006', ' ', '\001', '(', '\013', '2', '\032', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'L', 'i', 's', 't', 'V', 'a', 'l', 'u', 'e', 'H', '\000', 'B', '\006', '\n', '\004', 'k', 'i', 'n', 'd', '\"', '3', '\n', '\t', 'L', 'i', +'s', 't', 'V', 'a', 'l', 'u', 'e', '\022', '&', '\n', '\006', 'v', 'a', 'l', 'u', 'e', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', '\026', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'V', 'a', 'l', 'u', 'e', '*', '\033', '\n', +'\t', 'N', 'u', 'l', 'l', 'V', 'a', 'l', 'u', 'e', '\022', '\016', '\n', '\n', 'N', 'U', 'L', 'L', '_', 'V', 'A', 'L', 'U', 'E', '\020', +'\000', 'B', '\177', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', +'\013', 'S', 't', 'r', 'u', 'c', 't', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '/', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', +'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', +'n', 'o', 'w', 'n', '/', 's', 't', 'r', 'u', 'c', 't', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', +'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', +'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_struct_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/struct.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/struct.proto", google_protobuf_struct_proto_descriptor, + sizeof(google_protobuf_struct_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Struct, initOnce) { + google_protobuf_struct_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Struct_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Struct, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Struct_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Struct", + GPBMetadata_Google_Protobuf_Struct_methods); + + GPBMetadata_Google_Protobuf_Struct_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Struct */ + +zend_class_entry* google_protobuf_Struct_ce; + +static PHP_METHOD(google_protobuf_Struct, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Struct, getFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct, setFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Struct_phpmethods[] = { + PHP_ME(google_protobuf_Struct, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct, getFields, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct, setFields, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Struct_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Struct", + google_protobuf_Struct_phpmethods); + + google_protobuf_Struct_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Struct_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Struct_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Struct_ce, message_ce); +} + +/* google_protobuf_Struct_FieldsEntry */ + +zend_class_entry* google_protobuf_Struct_FieldsEntry_ce; + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getKey) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "key"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setKey) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "key"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Struct_FieldsEntry_phpmethods[] = { + PHP_ME(google_protobuf_Struct_FieldsEntry, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, getKey, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, setKey, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Struct_FieldsEntry_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Struct\\FieldsEntry", + google_protobuf_Struct_FieldsEntry_phpmethods); + + google_protobuf_Struct_FieldsEntry_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Struct_FieldsEntry_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Struct_FieldsEntry_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Struct_FieldsEntry_ce, message_ce); +} + +/* google_protobuf_Value */ + +zend_class_entry* google_protobuf_Value_ce; + +static PHP_METHOD(google_protobuf_Value, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Value, getNullValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "null_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setNullValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "null_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getNumberValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setNumberValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getStringValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "string_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setStringValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "string_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getBoolValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "bool_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setBoolValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "bool_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getStructValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "struct_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setStructValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "struct_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getListValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "list_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setListValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "list_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getKind) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef, + "kind"); + const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof); + RETURN_STRING(field ? upb_fielddef_name(field) : ""); +} +static zend_function_entry google_protobuf_Value_phpmethods[] = { + PHP_ME(google_protobuf_Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getNullValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setNullValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getNumberValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setNumberValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getStringValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setStringValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getBoolValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setBoolValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getStructValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setStructValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getListValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setListValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getKind, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Value", + google_protobuf_Value_phpmethods); + + google_protobuf_Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Value_ce, message_ce); +} + +/* google_protobuf_ListValue */ + +zend_class_entry* google_protobuf_ListValue_ce; + +static PHP_METHOD(google_protobuf_ListValue, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_ListValue, getValues) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "values"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_ListValue, setValues) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "values"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_ListValue_phpmethods[] = { + PHP_ME(google_protobuf_ListValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_ListValue, getValues, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_ListValue, setValues, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_ListValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\ListValue", + google_protobuf_ListValue_phpmethods); + + google_protobuf_ListValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_ListValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_ListValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_ListValue_ce, message_ce); +} + +/* google_protobuf_NullValue */ + +zend_class_entry* google_protobuf_NullValue_ce; + +PHP_METHOD(google_protobuf_NullValue, name) { + google_protobuf_struct_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\NullValue has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_NullValue, value) { + google_protobuf_struct_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\NullValue has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_NullValue_phpmethods[] = { + PHP_ME(google_protobuf_NullValue, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_NullValue, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_NullValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\NullValue", + google_protobuf_NullValue_phpmethods); + + google_protobuf_NullValue_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_NullValue_ce, "NULL_VALUE", + strlen("NULL_VALUE"), 0); +} + +/* google/protobuf/type.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Type_ce; + +const char google_protobuf_type_proto_descriptor [1592] = { +'\n', '\032', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', '.', 'p', 'r', +'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\032', '\031', 'g', 'o', 'o', +'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'n', 'y', '.', 'p', 'r', 'o', 't', 'o', '\032', '$', 'g', +'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', +'t', 'e', 'x', 't', '.', 'p', 'r', 'o', 't', 'o', '\"', '\327', '\001', '\n', '\004', 'T', 'y', 'p', 'e', '\022', '\014', '\n', '\004', 'n', 'a', +'m', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '&', '\n', '\006', 'f', 'i', 'e', 'l', 'd', 's', '\030', '\002', ' ', '\003', '(', '\013', '2', +'\026', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', '\022', '\016', +'\n', '\006', 'o', 'n', 'e', 'o', 'f', 's', '\030', '\003', ' ', '\003', '(', '\t', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', +'\030', '\004', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'O', 'p', 't', 'i', 'o', 'n', '\022', '6', '\n', '\016', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '\030', +'\005', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', +'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', '\'', '\n', '\006', 's', 'y', 'n', 't', 'a', 'x', '\030', '\006', ' ', +'\001', '(', '\016', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', +'t', 'a', 'x', '\"', '\325', '\005', '\n', '\005', 'F', 'i', 'e', 'l', 'd', '\022', ')', '\n', '\004', 'k', 'i', 'n', 'd', '\030', '\001', ' ', '\001', +'(', '\016', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', +'d', '.', 'K', 'i', 'n', 'd', '\022', '7', '\n', '\013', 'c', 'a', 'r', 'd', 'i', 'n', 'a', 'l', 'i', 't', 'y', '\030', '\002', ' ', '\001', +'(', '\016', '2', '\"', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', +'d', '.', 'C', 'a', 'r', 'd', 'i', 'n', 'a', 'l', 'i', 't', 'y', '\022', '\016', '\n', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\030', '\003', +' ', '\001', '(', '\005', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\004', ' ', '\001', '(', '\t', '\022', '\020', '\n', '\010', 't', 'y', 'p', +'e', '_', 'u', 'r', 'l', '\030', '\006', ' ', '\001', '(', '\t', '\022', '\023', '\n', '\013', 'o', 'n', 'e', 'o', 'f', '_', 'i', 'n', 'd', 'e', +'x', '\030', '\007', ' ', '\001', '(', '\005', '\022', '\016', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\010', ' ', '\001', '(', '\010', '\022', '(', +'\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\t', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\021', '\n', '\t', 'j', 's', 'o', 'n', '_', 'n', +'a', 'm', 'e', '\030', '\n', ' ', '\001', '(', '\t', '\022', '\025', '\n', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', +'e', '\030', '\013', ' ', '\001', '(', '\t', '\"', '\310', '\002', '\n', '\004', 'K', 'i', 'n', 'd', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', +'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B', 'L', 'E', '\020', +'\001', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', +'_', 'I', 'N', 'T', '6', '4', '\020', '\003', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6', '4', '\020', '\004', +'\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', +'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\006', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '3', '2', +'\020', '\007', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', +'_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\t', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U', 'P', '\020', '\n', +'\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', +'E', '_', 'B', 'Y', 'T', 'E', 'S', '\020', '\014', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '3', '2', '\020', +'\r', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', +'S', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\017', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', +'6', '4', '\020', '\020', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022', '\017', '\n', '\013', +'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '6', '4', '\020', '\022', '\"', 't', '\n', '\013', 'C', 'a', 'r', 'd', 'i', 'n', 'a', 'l', +'i', 't', 'y', '\022', '\027', '\n', '\023', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', +'N', '\020', '\000', '\022', '\030', '\n', '\024', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'O', 'P', 'T', 'I', 'O', 'N', +'A', 'L', '\020', '\001', '\022', '\030', '\n', '\024', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'R', 'E', 'Q', 'U', 'I', +'R', 'E', 'D', '\020', '\002', '\022', '\030', '\n', '\024', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'R', 'E', 'P', 'E', +'A', 'T', 'E', 'D', '\020', '\003', '\"', '\316', '\001', '\n', '\004', 'E', 'n', 'u', 'm', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', +' ', '\001', '(', '\t', '\022', '-', '\n', '\t', 'e', 'n', 'u', 'm', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '\032', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', +'e', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '6', '\n', '\016', 's', 'o', 'u', +'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '\030', '\004', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', +'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', +'\'', '\n', '\006', 's', 'y', 'n', 't', 'a', 'x', '\030', '\005', ' ', '\001', '(', '\016', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', 't', 'a', 'x', '\"', 'S', '\n', '\t', 'E', 'n', 'u', 'm', 'V', 'a', +'l', 'u', 'e', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\016', '\n', '\006', 'n', 'u', 'm', 'b', +'e', 'r', '\030', '\002', ' ', '\001', '(', '\005', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\003', '(', '\013', +'2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', +'\"', ';', '\n', '\006', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', +'#', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\013', '2', '\024', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'A', 'n', 'y', '*', '.', '\n', '\006', 'S', 'y', 'n', 't', 'a', 'x', '\022', '\021', '\n', '\r', +'S', 'Y', 'N', 'T', 'A', 'X', '_', 'P', 'R', 'O', 'T', 'O', '2', '\020', '\000', '\022', '\021', '\n', '\r', 'S', 'Y', 'N', 'T', 'A', 'X', +'_', 'P', 'R', 'O', 'T', 'O', '3', '\020', '\001', 'B', '{', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\t', 'T', 'y', 'p', 'e', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '-', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', +'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 't', 'y', 'p', 'e', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', +'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', +'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_type_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/type.proto")) return; + google_protobuf_any_proto_AddDescriptor(); + google_protobuf_source_context_proto_AddDescriptor(); + DescriptorPool_AddDescriptor("google/protobuf/type.proto", google_protobuf_type_proto_descriptor, + sizeof(google_protobuf_type_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Type, initOnce) { + google_protobuf_type_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Type_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Type, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Type_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Type", + GPBMetadata_Google_Protobuf_Type_methods); + + GPBMetadata_Google_Protobuf_Type_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Type */ + +zend_class_entry* google_protobuf_Type_ce; + +static PHP_METHOD(google_protobuf_Type, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Type, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getOneofs) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneofs"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setOneofs) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneofs"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Type_phpmethods[] = { + PHP_ME(google_protobuf_Type, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getFields, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setFields, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getOneofs, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setOneofs, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Type_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Type", + google_protobuf_Type_phpmethods); + + google_protobuf_Type_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Type_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Type_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Type_ce, message_ce); +} + +/* google_protobuf_Field */ + +zend_class_entry* google_protobuf_Field_ce; + +static PHP_METHOD(google_protobuf_Field, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Field, getKind) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "kind"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setKind) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "kind"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getCardinality) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "cardinality"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setCardinality) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "cardinality"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getOneofIndex) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneof_index"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setOneofIndex) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneof_index"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getPacked) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "packed"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setPacked) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "packed"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getJsonName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "json_name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setJsonName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "json_name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getDefaultValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "default_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setDefaultValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "default_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Field_phpmethods[] = { + PHP_ME(google_protobuf_Field, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getKind, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setKind, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getCardinality, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setCardinality, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getOneofIndex, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setOneofIndex, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getPacked, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setPacked, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getJsonName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setJsonName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getDefaultValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setDefaultValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Field_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field", + google_protobuf_Field_phpmethods); + + google_protobuf_Field_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Field_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Field_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Field_ce, message_ce); +} + +/* google_protobuf_Field_Kind */ + +zend_class_entry* google_protobuf_Field_Kind_ce; + +PHP_METHOD(google_protobuf_Field_Kind, name) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Kind has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_Field_Kind, value) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Kind has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_Field_Kind_phpmethods[] = { + PHP_ME(google_protobuf_Field_Kind, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_Field_Kind, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_Field_Kind_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field\\Kind", + google_protobuf_Field_Kind_phpmethods); + + google_protobuf_Field_Kind_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UNKNOWN", + strlen("TYPE_UNKNOWN"), 0); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_DOUBLE", + strlen("TYPE_DOUBLE"), 1); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FLOAT", + strlen("TYPE_FLOAT"), 2); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_INT64", + strlen("TYPE_INT64"), 3); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UINT64", + strlen("TYPE_UINT64"), 4); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_INT32", + strlen("TYPE_INT32"), 5); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FIXED64", + strlen("TYPE_FIXED64"), 6); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FIXED32", + strlen("TYPE_FIXED32"), 7); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_BOOL", + strlen("TYPE_BOOL"), 8); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_STRING", + strlen("TYPE_STRING"), 9); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_GROUP", + strlen("TYPE_GROUP"), 10); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_MESSAGE", + strlen("TYPE_MESSAGE"), 11); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_BYTES", + strlen("TYPE_BYTES"), 12); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UINT32", + strlen("TYPE_UINT32"), 13); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_ENUM", + strlen("TYPE_ENUM"), 14); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SFIXED32", + strlen("TYPE_SFIXED32"), 15); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SFIXED64", + strlen("TYPE_SFIXED64"), 16); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SINT32", + strlen("TYPE_SINT32"), 17); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SINT64", + strlen("TYPE_SINT64"), 18); +} + +/* google_protobuf_Field_Cardinality */ + +zend_class_entry* google_protobuf_Field_Cardinality_ce; + +PHP_METHOD(google_protobuf_Field_Cardinality, name) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Cardinality has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_Field_Cardinality, value) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Cardinality has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_Field_Cardinality_phpmethods[] = { + PHP_ME(google_protobuf_Field_Cardinality, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_Field_Cardinality, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_Field_Cardinality_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field\\Cardinality", + google_protobuf_Field_Cardinality_phpmethods); + + google_protobuf_Field_Cardinality_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_UNKNOWN", + strlen("CARDINALITY_UNKNOWN"), 0); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_OPTIONAL", + strlen("CARDINALITY_OPTIONAL"), 1); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_REQUIRED", + strlen("CARDINALITY_REQUIRED"), 2); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_REPEATED", + strlen("CARDINALITY_REPEATED"), 3); +} + +/* google_protobuf_Enum */ + +zend_class_entry* google_protobuf_Enum_ce; + +static PHP_METHOD(google_protobuf_Enum, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Enum, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getEnumvalue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "enumvalue"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setEnumvalue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "enumvalue"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Enum_phpmethods[] = { + PHP_ME(google_protobuf_Enum, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getEnumvalue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setEnumvalue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Enum_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Enum", + google_protobuf_Enum_phpmethods); + + google_protobuf_Enum_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Enum_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Enum_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Enum_ce, message_ce); +} + +/* google_protobuf_EnumValue */ + +zend_class_entry* google_protobuf_EnumValue_ce; + +static PHP_METHOD(google_protobuf_EnumValue, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_EnumValue, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, getNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, setNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_EnumValue_phpmethods[] = { + PHP_ME(google_protobuf_EnumValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, getNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, setNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, setOptions, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_EnumValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\EnumValue", + google_protobuf_EnumValue_phpmethods); + + google_protobuf_EnumValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_EnumValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_EnumValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_EnumValue_ce, message_ce); +} + +/* google_protobuf_Option */ + +zend_class_entry* google_protobuf_Option_ce; + +static PHP_METHOD(google_protobuf_Option, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Option, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Option, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Option, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Option, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Option_phpmethods[] = { + PHP_ME(google_protobuf_Option, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Option_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Option", + google_protobuf_Option_phpmethods); + + google_protobuf_Option_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Option_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Option_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Option_ce, message_ce); +} + +/* google_protobuf_Syntax */ + +zend_class_entry* google_protobuf_Syntax_ce; + +PHP_METHOD(google_protobuf_Syntax, name) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Syntax has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_Syntax, value) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Syntax has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_Syntax_phpmethods[] = { + PHP_ME(google_protobuf_Syntax, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_Syntax, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_Syntax_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Syntax", + google_protobuf_Syntax_phpmethods); + + google_protobuf_Syntax_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_Syntax_ce, "SYNTAX_PROTO2", + strlen("SYNTAX_PROTO2"), 0); + zend_declare_class_constant_long(google_protobuf_Syntax_ce, "SYNTAX_PROTO3", + strlen("SYNTAX_PROTO3"), 1); +} + +/* google/protobuf/timestamp.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Timestamp_ce; + +const char google_protobuf_timestamp_proto_descriptor [239] = { +'\n', '\037', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'i', 'm', 'e', 's', 't', 'a', +'m', 'p', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'\"', '+', '\n', '\t', 'T', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', '\022', '\017', '\n', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\030', +'\001', ' ', '\001', '(', '\003', '\022', '\r', '\n', '\005', 'n', 'a', 'n', 'o', 's', '\030', '\002', ' ', '\001', '(', '\005', 'B', '\205', '\001', '\n', '\023', +'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\016', 'T', 'i', 'm', 'e', +'s', 't', 'a', 'm', 'p', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '2', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', +'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', +'w', 'n', '/', 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', +'\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', +'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_timestamp_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/timestamp.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/timestamp.proto", google_protobuf_timestamp_proto_descriptor, + sizeof(google_protobuf_timestamp_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Timestamp, initOnce) { + google_protobuf_timestamp_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Timestamp_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Timestamp, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Timestamp_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Timestamp", + GPBMetadata_Google_Protobuf_Timestamp_methods); + + GPBMetadata_Google_Protobuf_Timestamp_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Timestamp */ + +zend_class_entry* google_protobuf_Timestamp_ce; + +static PHP_METHOD(google_protobuf_Timestamp, __construct) { + google_protobuf_timestamp_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Timestamp, getSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Timestamp, setSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Timestamp, getNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Timestamp, setNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Timestamp_phpmethods[] = { + PHP_ME(google_protobuf_Timestamp, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, getSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, setSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, getNanos, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, setNanos, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, fromDateTime, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, toDateTime, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Timestamp_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Timestamp", + google_protobuf_Timestamp_phpmethods); + + google_protobuf_Timestamp_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Timestamp_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Timestamp_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Timestamp_ce, message_ce); +} + +/* google/protobuf/wrappers.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Wrappers_ce; + +const char google_protobuf_wrappers_proto_descriptor [455] = { +'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'w', 'r', 'a', 'p', 'p', 'e', 'r', +'s', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', +'\034', '\n', '\013', 'D', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', +' ', '\001', '(', '\001', '\"', '\033', '\n', '\n', 'F', 'l', 'o', 'a', 't', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', +'u', 'e', '\030', '\001', ' ', '\001', '(', '\002', '\"', '\033', '\n', '\n', 'I', 'n', 't', '6', '4', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', +'\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\003', '\"', '\034', '\n', '\013', 'U', 'I', 'n', 't', '6', '4', 'V', 'a', 'l', +'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\004', '\"', '\033', '\n', '\n', 'I', 'n', 't', '3', +'2', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\005', '\"', '\034', '\n', '\013', +'U', 'I', 'n', 't', '3', '2', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', +'\r', '\"', '\032', '\n', '\t', 'B', 'o', 'o', 'l', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', +' ', '\001', '(', '\010', '\"', '\034', '\n', '\013', 'S', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', +'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\"', '\033', '\n', '\n', 'B', 'y', 't', 'e', 's', 'V', 'a', 'l', 'u', 'e', '\022', '\r', +'\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\014', 'B', '\203', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\r', 'W', 'r', 'a', 'p', 'p', 'e', 'r', 's', 'P', 'r', 'o', +'t', 'o', 'P', '\001', 'Z', '1', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'w', 'r', 'a', 'p', 'p', +'e', 'r', 's', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', +'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', +'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_wrappers_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/wrappers.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/wrappers.proto", google_protobuf_wrappers_proto_descriptor, + sizeof(google_protobuf_wrappers_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Wrappers, initOnce) { + google_protobuf_wrappers_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Wrappers_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Wrappers, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Wrappers_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Wrappers", + GPBMetadata_Google_Protobuf_Wrappers_methods); + + GPBMetadata_Google_Protobuf_Wrappers_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_DoubleValue */ + +zend_class_entry* google_protobuf_DoubleValue_ce; + +static PHP_METHOD(google_protobuf_DoubleValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_DoubleValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_DoubleValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_DoubleValue_phpmethods[] = { + PHP_ME(google_protobuf_DoubleValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_DoubleValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_DoubleValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_DoubleValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\DoubleValue", + google_protobuf_DoubleValue_phpmethods); + + google_protobuf_DoubleValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_DoubleValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_DoubleValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_DoubleValue_ce, message_ce); +} + +/* google_protobuf_FloatValue */ + +zend_class_entry* google_protobuf_FloatValue_ce; + +static PHP_METHOD(google_protobuf_FloatValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_FloatValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_FloatValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_FloatValue_phpmethods[] = { + PHP_ME(google_protobuf_FloatValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FloatValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FloatValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_FloatValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\FloatValue", + google_protobuf_FloatValue_phpmethods); + + google_protobuf_FloatValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_FloatValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_FloatValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_FloatValue_ce, message_ce); +} + +/* google_protobuf_Int64Value */ + +zend_class_entry* google_protobuf_Int64Value_ce; + +static PHP_METHOD(google_protobuf_Int64Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Int64Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Int64Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Int64Value_phpmethods[] = { + PHP_ME(google_protobuf_Int64Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int64Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int64Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Int64Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Int64Value", + google_protobuf_Int64Value_phpmethods); + + google_protobuf_Int64Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Int64Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Int64Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Int64Value_ce, message_ce); +} + +/* google_protobuf_UInt64Value */ + +zend_class_entry* google_protobuf_UInt64Value_ce; + +static PHP_METHOD(google_protobuf_UInt64Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_UInt64Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_UInt64Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_UInt64Value_phpmethods[] = { + PHP_ME(google_protobuf_UInt64Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt64Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt64Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_UInt64Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\UInt64Value", + google_protobuf_UInt64Value_phpmethods); + + google_protobuf_UInt64Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_UInt64Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_UInt64Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_UInt64Value_ce, message_ce); +} + +/* google_protobuf_Int32Value */ + +zend_class_entry* google_protobuf_Int32Value_ce; + +static PHP_METHOD(google_protobuf_Int32Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Int32Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Int32Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Int32Value_phpmethods[] = { + PHP_ME(google_protobuf_Int32Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int32Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int32Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Int32Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Int32Value", + google_protobuf_Int32Value_phpmethods); + + google_protobuf_Int32Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Int32Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Int32Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Int32Value_ce, message_ce); +} + +/* google_protobuf_UInt32Value */ + +zend_class_entry* google_protobuf_UInt32Value_ce; + +static PHP_METHOD(google_protobuf_UInt32Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_UInt32Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_UInt32Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_UInt32Value_phpmethods[] = { + PHP_ME(google_protobuf_UInt32Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt32Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt32Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_UInt32Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\UInt32Value", + google_protobuf_UInt32Value_phpmethods); + + google_protobuf_UInt32Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_UInt32Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_UInt32Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_UInt32Value_ce, message_ce); +} + +/* google_protobuf_BoolValue */ + +zend_class_entry* google_protobuf_BoolValue_ce; + +static PHP_METHOD(google_protobuf_BoolValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_BoolValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_BoolValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_BoolValue_phpmethods[] = { + PHP_ME(google_protobuf_BoolValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BoolValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BoolValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_BoolValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\BoolValue", + google_protobuf_BoolValue_phpmethods); + + google_protobuf_BoolValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_BoolValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_BoolValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_BoolValue_ce, message_ce); +} + +/* google_protobuf_StringValue */ + +zend_class_entry* google_protobuf_StringValue_ce; + +static PHP_METHOD(google_protobuf_StringValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_StringValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_StringValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_StringValue_phpmethods[] = { + PHP_ME(google_protobuf_StringValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_StringValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_StringValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_StringValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\StringValue", + google_protobuf_StringValue_phpmethods); + + google_protobuf_StringValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_StringValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_StringValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_StringValue_ce, message_ce); +} + +/* google_protobuf_BytesValue */ + +zend_class_entry* google_protobuf_BytesValue_ce; + +static PHP_METHOD(google_protobuf_BytesValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_BytesValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_BytesValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_BytesValue_phpmethods[] = { + PHP_ME(google_protobuf_BytesValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BytesValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BytesValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_BytesValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\BytesValue", + google_protobuf_BytesValue_phpmethods); + + google_protobuf_BytesValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_BytesValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_BytesValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_BytesValue_ce, message_ce); +} + +static void WellKnownTypes_ModuleInit() { + GPBMetadata_Google_Protobuf_Any_ModuleInit(); + google_protobuf_Any_ModuleInit(); + GPBMetadata_Google_Protobuf_Api_ModuleInit(); + google_protobuf_Api_ModuleInit(); + google_protobuf_Method_ModuleInit(); + google_protobuf_Mixin_ModuleInit(); + GPBMetadata_Google_Protobuf_Duration_ModuleInit(); + google_protobuf_Duration_ModuleInit(); + GPBMetadata_Google_Protobuf_GPBEmpty_ModuleInit(); + google_protobuf_Empty_ModuleInit(); + GPBMetadata_Google_Protobuf_FieldMask_ModuleInit(); + google_protobuf_FieldMask_ModuleInit(); + GPBMetadata_Google_Protobuf_SourceContext_ModuleInit(); + google_protobuf_SourceContext_ModuleInit(); + GPBMetadata_Google_Protobuf_Struct_ModuleInit(); + google_protobuf_Struct_ModuleInit(); + google_protobuf_Struct_FieldsEntry_ModuleInit(); + google_protobuf_Value_ModuleInit(); + google_protobuf_ListValue_ModuleInit(); + google_protobuf_NullValue_ModuleInit(); + GPBMetadata_Google_Protobuf_Type_ModuleInit(); + google_protobuf_Type_ModuleInit(); + google_protobuf_Field_ModuleInit(); + google_protobuf_Field_Kind_ModuleInit(); + google_protobuf_Field_Cardinality_ModuleInit(); + google_protobuf_Enum_ModuleInit(); + google_protobuf_EnumValue_ModuleInit(); + google_protobuf_Option_ModuleInit(); + google_protobuf_Syntax_ModuleInit(); + GPBMetadata_Google_Protobuf_Timestamp_ModuleInit(); + google_protobuf_Timestamp_ModuleInit(); + GPBMetadata_Google_Protobuf_Wrappers_ModuleInit(); + google_protobuf_DoubleValue_ModuleInit(); + google_protobuf_FloatValue_ModuleInit(); + google_protobuf_Int64Value_ModuleInit(); + google_protobuf_UInt64Value_ModuleInit(); + google_protobuf_Int32Value_ModuleInit(); + google_protobuf_UInt32Value_ModuleInit(); + google_protobuf_BoolValue_ModuleInit(); + google_protobuf_StringValue_ModuleInit(); + google_protobuf_BytesValue_ModuleInit(); +} diff --git a/php/generate_descriptor_protos.sh b/php/generate_descriptor_protos.sh index f636cc0ebb48..9feaa96c8b51 100755 --- a/php/generate_descriptor_protos.sh +++ b/php/generate_descriptor_protos.sh @@ -3,6 +3,8 @@ # Run this script to regenerate descriptor protos after the protocol compiler # changes. +set -e + if test ! -e src/google/protobuf/stubs/common.h; then cat >&2 << __EOF__ Could not find source code. Make sure you are running this script from the @@ -13,4 +15,15 @@ fi pushd src ./protoc --php_out=internal:../php/src google/protobuf/descriptor.proto +./protoc --php_out=internal_generate_c_wkt:../php/src \ + google/protobuf/any.proto \ + google/protobuf/api.proto \ + google/protobuf/duration.proto \ + google/protobuf/empty.proto \ + google/protobuf/field_mask.proto \ + google/protobuf/source_context.proto \ + google/protobuf/struct.proto \ + google/protobuf/type.proto \ + google/protobuf/timestamp.proto \ + google/protobuf/wrappers.proto popd diff --git a/php/prepare_c_extension.sh b/php/prepare_c_extension.sh new file mode 100755 index 000000000000..84cd1aa3d155 --- /dev/null +++ b/php/prepare_c_extension.sh @@ -0,0 +1,6 @@ + +# wyhash has to live in the base third_party directory. +# We copy it into the ext/google/protobuf directory for the build +# (and for the release to PECL). +mkdir -p ../ext/google/protobuf/third_party/wyhash +cp ../../third_party/wyhash/* ../ext/google/protobuf/third_party/wyhash diff --git a/php/src/GPBMetadata/Google/Protobuf/Any.php b/php/src/GPBMetadata/Google/Protobuf/Any.php index 22cc25008fc8..fbce4bfdb10f 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Any.php +++ b/php/src/GPBMetadata/Google/Protobuf/Any.php @@ -14,15 +14,15 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0acd010a19676f6f676c652f70726f746f6275662f616e792e70726f746f" . - "120f676f6f676c652e70726f746f62756622260a03416e7912100a087479" . - "70655f75726c180120012809120d0a0576616c756518022001280c426f0a" . - "13636f6d2e676f6f676c652e70726f746f6275664208416e7950726f746f" . - "50015a256769746875622e636f6d2f676f6c616e672f70726f746f627566" . - "2f7074797065732f616e79a20203475042aa021e476f6f676c652e50726f" . - "746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/any.protogoogle.protobuf"& +Any +type_url (  +value ( Bv +com.google.protobufBAnyProtoPZ,google.golang.org/protobuf/types/known/anypbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Api.php b/php/src/GPBMetadata/Google/Protobuf/Api.php index b18e0d33ac03..75e0ec631805 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Api.php +++ b/php/src/GPBMetadata/Google/Protobuf/Api.php @@ -16,32 +16,31 @@ public static function initOnce() { } \GPBMetadata\Google\Protobuf\SourceContext::initOnce(); \GPBMetadata\Google\Protobuf\Type::initOnce(); - $pool->internalAddGeneratedFile(hex2bin( - "0ac8050a19676f6f676c652f70726f746f6275662f6170692e70726f746f" . - "120f676f6f676c652e70726f746f6275661a1a676f6f676c652f70726f74" . - "6f6275662f747970652e70726f746f2281020a03417069120c0a046e616d" . - "6518012001280912280a076d6574686f647318022003280b32172e676f6f" . - "676c652e70726f746f6275662e4d6574686f6412280a076f7074696f6e73" . - "18032003280b32172e676f6f676c652e70726f746f6275662e4f7074696f" . - "6e120f0a0776657273696f6e18042001280912360a0e736f757263655f63" . - "6f6e7465787418052001280b321e2e676f6f676c652e70726f746f627566" . - "2e536f75726365436f6e7465787412260a066d6978696e7318062003280b" . - "32162e676f6f676c652e70726f746f6275662e4d6978696e12270a067379" . - "6e74617818072001280e32172e676f6f676c652e70726f746f6275662e53" . - "796e74617822d5010a064d6574686f64120c0a046e616d65180120012809" . - "12180a10726571756573745f747970655f75726c18022001280912190a11" . - "726571756573745f73747265616d696e6718032001280812190a11726573" . - "706f6e73655f747970655f75726c180420012809121a0a12726573706f6e" . - "73655f73747265616d696e6718052001280812280a076f7074696f6e7318" . - "062003280b32172e676f6f676c652e70726f746f6275662e4f7074696f6e" . - "12270a0673796e74617818072001280e32172e676f6f676c652e70726f74" . - "6f6275662e53796e74617822230a054d6978696e120c0a046e616d651801" . - "20012809120c0a04726f6f7418022001280942750a13636f6d2e676f6f67" . - "6c652e70726f746f627566420841706950726f746f50015a2b676f6f676c" . - "652e676f6c616e672e6f72672f67656e70726f746f2f70726f746f627566" . - "2f6170693b617069a20203475042aa021e476f6f676c652e50726f746f62" . - "75662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/api.protogoogle.protobufgoogle/protobuf/type.proto" +Api +name ( ( +methods ( 2.google.protobuf.Method( +options ( 2.google.protobuf.Option +version ( 6 +source_context ( 2.google.protobuf.SourceContext& +mixins ( 2.google.protobuf.Mixin\' +syntax (2.google.protobuf.Syntax" +Method +name (  +request_type_url (  +request_streaming ( +response_type_url (  +response_streaming (( +options ( 2.google.protobuf.Option\' +syntax (2.google.protobuf.Syntax"# +Mixin +name (  +root ( Bv +com.google.protobufBApiProtoPZ,google.golang.org/protobuf/types/known/apipbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Duration.php b/php/src/GPBMetadata/Google/Protobuf/Duration.php index b1c85ad8894e..5d8023e4db9e 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Duration.php +++ b/php/src/GPBMetadata/Google/Protobuf/Duration.php @@ -14,16 +14,15 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ae3010a1e676f6f676c652f70726f746f6275662f6475726174696f6e2e" . - "70726f746f120f676f6f676c652e70726f746f627566222a0a0844757261" . - "74696f6e120f0a077365636f6e6473180120012803120d0a056e616e6f73" . - "180220012805427c0a13636f6d2e676f6f676c652e70726f746f62756642" . - "0d4475726174696f6e50726f746f50015a2a6769746875622e636f6d2f67" . - "6f6c616e672f70726f746f6275662f7074797065732f6475726174696f6e" . - "f80101a20203475042aa021e476f6f676c652e50726f746f6275662e5765" . - "6c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/duration.protogoogle.protobuf"* +Duration +seconds ( +nanos (B +com.google.protobufB DurationProtoPZ1google.golang.org/protobuf/types/known/durationpbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/FieldMask.php b/php/src/GPBMetadata/Google/Protobuf/FieldMask.php index 5812be1e2447..f31bcc001245 100644 --- a/php/src/GPBMetadata/Google/Protobuf/FieldMask.php +++ b/php/src/GPBMetadata/Google/Protobuf/FieldMask.php @@ -14,16 +14,14 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ae3010a20676f6f676c652f70726f746f6275662f6669656c645f6d6173" . - "6b2e70726f746f120f676f6f676c652e70726f746f627566221a0a094669" . - "656c644d61736b120d0a0570617468731801200328094289010a13636f6d" . - "2e676f6f676c652e70726f746f627566420e4669656c644d61736b50726f" . - "746f50015a39676f6f676c652e676f6c616e672e6f72672f67656e70726f" . - "746f2f70726f746f6275662f6669656c645f6d61736b3b6669656c645f6d" . - "61736ba20203475042aa021e476f6f676c652e50726f746f6275662e5765" . - "6c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + + google/protobuf/field_mask.protogoogle.protobuf" + FieldMask +paths ( B +com.google.protobufBFieldMaskProtoPZ2google.golang.org/protobuf/types/known/fieldmaskpbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php b/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php index 88f42a11a462..5e42536f270c 100644 --- a/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php +++ b/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php @@ -14,15 +14,14 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f" . - "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276" . - "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072" . - "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f" . - "6275662f7074797065732f656d707479f80101a20203475042aa021e476f" . - "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206" . - "70726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/empty.protogoogle.protobuf" +EmptyB} +com.google.protobufB +EmptyProtoPZ.google.golang.org/protobuf/types/known/emptypbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/SourceContext.php b/php/src/GPBMetadata/Google/Protobuf/SourceContext.php index 495c6de410ec..797732d9f326 100644 --- a/php/src/GPBMetadata/Google/Protobuf/SourceContext.php +++ b/php/src/GPBMetadata/Google/Protobuf/SourceContext.php @@ -14,17 +14,14 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0afb010a24676f6f676c652f70726f746f6275662f736f757263655f636f" . - "6e746578742e70726f746f120f676f6f676c652e70726f746f6275662222" . - "0a0d536f75726365436f6e7465787412110a0966696c655f6e616d651801" . - "200128094295010a13636f6d2e676f6f676c652e70726f746f6275664212" . - "536f75726365436f6e7465787450726f746f50015a41676f6f676c652e67" . - "6f6c616e672e6f72672f67656e70726f746f2f70726f746f6275662f736f" . - "757263655f636f6e746578743b736f757263655f636f6e74657874a20203" . - "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77" . - "6e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +$google/protobuf/source_context.protogoogle.protobuf"" + SourceContext + file_name ( B +com.google.protobufBSourceContextProtoPZ6google.golang.org/protobuf/types/known/sourcecontextpbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Struct.php b/php/src/GPBMetadata/Google/Protobuf/Struct.php index 8e6191dc7a26..888a81adee40 100644 Binary files a/php/src/GPBMetadata/Google/Protobuf/Struct.php and b/php/src/GPBMetadata/Google/Protobuf/Struct.php differ diff --git a/php/src/GPBMetadata/Google/Protobuf/Timestamp.php b/php/src/GPBMetadata/Google/Protobuf/Timestamp.php index 373665c977c0..09437271a91c 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Timestamp.php +++ b/php/src/GPBMetadata/Google/Protobuf/Timestamp.php @@ -14,16 +14,15 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ae7010a1f676f6f676c652f70726f746f6275662f74696d657374616d70" . - "2e70726f746f120f676f6f676c652e70726f746f627566222b0a0954696d" . - "657374616d70120f0a077365636f6e6473180120012803120d0a056e616e" . - "6f73180220012805427e0a13636f6d2e676f6f676c652e70726f746f6275" . - "66420e54696d657374616d7050726f746f50015a2b6769746875622e636f" . - "6d2f676f6c616e672f70726f746f6275662f7074797065732f74696d6573" . - "74616d70f80101a20203475042aa021e476f6f676c652e50726f746f6275" . - "662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/timestamp.protogoogle.protobuf"+ + Timestamp +seconds ( +nanos (B +com.google.protobufBTimestampProtoPZ2google.golang.org/protobuf/types/known/timestamppbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Type.php b/php/src/GPBMetadata/Google/Protobuf/Type.php index 8fbe8cbfe0d4..7d0bfbb533a2 100644 Binary files a/php/src/GPBMetadata/Google/Protobuf/Type.php and b/php/src/GPBMetadata/Google/Protobuf/Type.php differ diff --git a/php/src/GPBMetadata/Google/Protobuf/Wrappers.php b/php/src/GPBMetadata/Google/Protobuf/Wrappers.php index dd72ff48ce0e..e7ea1a3b9516 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Wrappers.php +++ b/php/src/GPBMetadata/Google/Protobuf/Wrappers.php @@ -14,23 +14,34 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0abf030a1e676f6f676c652f70726f746f6275662f77726170706572732e" . - "70726f746f120f676f6f676c652e70726f746f627566221c0a0b446f7562" . - "6c6556616c7565120d0a0576616c7565180120012801221b0a0a466c6f61" . - "7456616c7565120d0a0576616c7565180120012802221b0a0a496e743634" . - "56616c7565120d0a0576616c7565180120012803221c0a0b55496e743634" . - "56616c7565120d0a0576616c7565180120012804221b0a0a496e74333256" . - "616c7565120d0a0576616c7565180120012805221c0a0b55496e74333256" . - "616c7565120d0a0576616c756518012001280d221a0a09426f6f6c56616c" . - "7565120d0a0576616c7565180120012808221c0a0b537472696e6756616c" . - "7565120d0a0576616c7565180120012809221b0a0a427974657356616c75" . - "65120d0a0576616c756518012001280c427c0a13636f6d2e676f6f676c65" . - "2e70726f746f627566420d577261707065727350726f746f50015a2a6769" . - "746875622e636f6d2f676f6c616e672f70726f746f6275662f7074797065" . - "732f7772617070657273f80101a20203475042aa021e476f6f676c652e50" . - "726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/wrappers.protogoogle.protobuf" + DoubleValue +value (" + +FloatValue +value (" + +Int64Value +value (" + UInt64Value +value (" + +Int32Value +value (" + UInt32Value +value ( " + BoolValue +value (" + StringValue +value ( " + +BytesValue +value ( B +com.google.protobufB WrappersProtoPZ1google.golang.org/protobuf/types/known/wrapperspbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/Google/Protobuf/Any.php b/php/src/Google/Protobuf/Any.php index 2c7bc7545403..8fdc3c483d22 100644 --- a/php/src/Google/Protobuf/Any.php +++ b/php/src/Google/Protobuf/Any.php @@ -5,7 +5,6 @@ namespace Google\Protobuf; use Google\Protobuf\Internal\GPBType; -use Google\Protobuf\Internal\Message; use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\GPBUtil; @@ -39,10 +38,13 @@ * ... * Example 4: Pack and unpack a message in Go * foo := &pb.Foo{...} - * any, err := ptypes.MarshalAny(foo) + * any, err := anypb.New(foo) + * if err != nil { + * ... + * } * ... * foo := &pb.Foo{} - * if err := ptypes.UnmarshalAny(any, foo); err != nil { + * if err := any.UnmarshalTo(foo); err != nil { * ... * } * The pack methods provided by protobuf library will by default use @@ -76,11 +78,12 @@ * * Generated from protobuf message google.protobuf.Any */ -class Any extends \Google\Protobuf\Internal\Message +class Any extends \Google\Protobuf\Internal\AnyBase { /** * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -104,15 +107,13 @@ class Any extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string type_url = 1; */ - private $type_url = ''; + protected $type_url = ''; /** * Must be a valid serialized protocol buffer of the above specified type. * * Generated from protobuf field bytes value = 2; */ - private $value = ''; - - const TYPE_URL_PREFIX = 'type.googleapis.com/'; + protected $value = ''; /** * Constructor. @@ -122,7 +123,8 @@ class Any extends \Google\Protobuf\Internal\Message * * @type string $type_url * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -154,7 +156,8 @@ public function __construct($data = NULL) { /** * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -186,7 +189,8 @@ public function getTypeUrl() /** * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -246,78 +250,5 @@ public function setValue($var) return $this; } - /** - * This method will try to resolve the type_url in Any message to get the - * targeted message type. If failed, an error will be thrown. Otherwise, - * the method will create a message of the targeted type and fill it with - * the decoded value in Any. - * @return Message unpacked message - * @throws \Exception Type url needs to be type.googleapis.com/fully-qualified. - * @throws \Exception Class hasn't been added to descriptor pool. - * @throws \Exception cannot decode data in value field. - */ - public function unpack() - { - // Get fully qualified name from type url. - $url_prifix_len = strlen(GPBUtil::TYPE_URL_PREFIX); - if (substr($this->type_url, 0, $url_prifix_len) != - GPBUtil::TYPE_URL_PREFIX) { - throw new \Exception( - "Type url needs to be type.googleapis.com/fully-qulified"); - } - $fully_qualifed_name = - substr($this->type_url, $url_prifix_len); - - // Create message according to fully qualified name. - $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); - $desc = $pool->getDescriptorByProtoName($fully_qualifed_name); - if (is_null($desc)) { - throw new \Exception("Class ".$fully_qualifed_name - ." hasn't been added to descriptor pool"); - } - $klass = $desc->getClass(); - $msg = new $klass(); - - // Merge data into message. - $msg->mergeFromString($this->value); - return $msg; - } - - /** - * The type_url will be created according to the given message’s type and - * the value is encoded data from the given message.. - * @param message: A proto message. - */ - public function pack($msg) - { - if (!$msg instanceof Message) { - trigger_error("Given parameter is not a message instance.", - E_USER_ERROR); - return; - } - - // Set value using serialized message. - $this->value = $msg->serializeToString(); - - // Set type url. - $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); - $desc = $pool->getDescriptorByClassName(get_class($msg)); - $fully_qualifed_name = $desc->getFullName(); - $this->type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name; - } - - /** - * This method returns whether the type_url in any_message is corresponded - * to the given class. - * @param klass: The fully qualified PHP class name of a proto message type. - */ - public function is($klass) - { - $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); - $desc = $pool->getDescriptorByClassName($klass); - $fully_qualifed_name = $desc->getFullName(); - $type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name; - return $this->type_url === $type_url; - } } diff --git a/php/src/Google/Protobuf/Api.php b/php/src/Google/Protobuf/Api.php index db37ffb0194e..773397565c08 100644 --- a/php/src/Google/Protobuf/Api.php +++ b/php/src/Google/Protobuf/Api.php @@ -28,7 +28,7 @@ class Api extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * The methods of this interface, in unspecified order. * @@ -62,14 +62,14 @@ class Api extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string version = 4; */ - private $version = ''; + protected $version = ''; /** * Source context for the protocol buffer service represented by this * message. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; */ - private $source_context = null; + protected $source_context = null; /** * Included interfaces. See [Mixin][]. * @@ -81,7 +81,7 @@ class Api extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Syntax syntax = 7; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. @@ -275,7 +275,17 @@ public function setVersion($var) */ public function getSourceContext() { - return $this->source_context; + return isset($this->source_context) ? $this->source_context : null; + } + + public function hasSourceContext() + { + return isset($this->source_context); + } + + public function clearSourceContext() + { + unset($this->source_context); } /** diff --git a/php/src/Google/Protobuf/BoolValue.php b/php/src/Google/Protobuf/BoolValue.php index 13872eb1e464..ecdbf4dcc265 100644 --- a/php/src/Google/Protobuf/BoolValue.php +++ b/php/src/Google/Protobuf/BoolValue.php @@ -21,7 +21,7 @@ class BoolValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field bool value = 1; */ - private $value = false; + protected $value = false; /** * Constructor. diff --git a/php/src/Google/Protobuf/BytesValue.php b/php/src/Google/Protobuf/BytesValue.php index f1b381718564..1582e14acd90 100644 --- a/php/src/Google/Protobuf/BytesValue.php +++ b/php/src/Google/Protobuf/BytesValue.php @@ -21,7 +21,7 @@ class BytesValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field bytes value = 1; */ - private $value = ''; + protected $value = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/DoubleValue.php b/php/src/Google/Protobuf/DoubleValue.php index 236d91822354..b72399f460d6 100644 --- a/php/src/Google/Protobuf/DoubleValue.php +++ b/php/src/Google/Protobuf/DoubleValue.php @@ -21,7 +21,7 @@ class DoubleValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field double value = 1; */ - private $value = 0.0; + protected $value = 0.0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Duration.php b/php/src/Google/Protobuf/Duration.php index 414a1868b748..531cd50b5791 100644 --- a/php/src/Google/Protobuf/Duration.php +++ b/php/src/Google/Protobuf/Duration.php @@ -25,7 +25,7 @@ * if (duration.seconds < 0 && duration.nanos > 0) { * duration.seconds += 1; * duration.nanos -= 1000000000; - * } else if (durations.seconds > 0 && duration.nanos < 0) { + * } else if (duration.seconds > 0 && duration.nanos < 0) { * duration.seconds -= 1; * duration.nanos += 1000000000; * } @@ -66,7 +66,7 @@ class Duration extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int64 seconds = 1; */ - private $seconds = 0; + protected $seconds = 0; /** * Signed fractions of a second at nanosecond resolution of the span * of time. Durations less than one second are represented with a 0 @@ -77,7 +77,7 @@ class Duration extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int32 nanos = 2; */ - private $nanos = 0; + protected $nanos = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Enum.php b/php/src/Google/Protobuf/Enum.php index 243c40d2899d..ed5afc447fec 100644 --- a/php/src/Google/Protobuf/Enum.php +++ b/php/src/Google/Protobuf/Enum.php @@ -20,7 +20,7 @@ class Enum extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * Enum value definitions. * @@ -38,13 +38,13 @@ class Enum extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.SourceContext source_context = 4; */ - private $source_context = null; + protected $source_context = null; /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 5; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. @@ -155,7 +155,17 @@ public function setOptions($var) */ public function getSourceContext() { - return $this->source_context; + return isset($this->source_context) ? $this->source_context : null; + } + + public function hasSourceContext() + { + return isset($this->source_context); + } + + public function clearSourceContext() + { + unset($this->source_context); } /** diff --git a/php/src/Google/Protobuf/EnumValue.php b/php/src/Google/Protobuf/EnumValue.php index 1dc3c7a6eee0..905f4ad14b29 100644 --- a/php/src/Google/Protobuf/EnumValue.php +++ b/php/src/Google/Protobuf/EnumValue.php @@ -20,13 +20,13 @@ class EnumValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * Enum value number. * * Generated from protobuf field int32 number = 2; */ - private $number = 0; + protected $number = 0; /** * Protocol buffer options. * diff --git a/php/src/Google/Protobuf/Field.php b/php/src/Google/Protobuf/Field.php index 8da43e34da4f..76a505ea567d 100644 --- a/php/src/Google/Protobuf/Field.php +++ b/php/src/Google/Protobuf/Field.php @@ -20,45 +20,45 @@ class Field extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Field.Kind kind = 1; */ - private $kind = 0; + protected $kind = 0; /** * The field cardinality. * * Generated from protobuf field .google.protobuf.Field.Cardinality cardinality = 2; */ - private $cardinality = 0; + protected $cardinality = 0; /** * The field number. * * Generated from protobuf field int32 number = 3; */ - private $number = 0; + protected $number = 0; /** * The field name. * * Generated from protobuf field string name = 4; */ - private $name = ''; + protected $name = ''; /** * The field type URL, without the scheme, for message or enumeration * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. * * Generated from protobuf field string type_url = 6; */ - private $type_url = ''; + protected $type_url = ''; /** * The index of the field type in `Type.oneofs`, for message or enumeration * types. The first type has index 1; zero means the type is not in the list. * * Generated from protobuf field int32 oneof_index = 7; */ - private $oneof_index = 0; + protected $oneof_index = 0; /** * Whether to use alternative packed wire representation. * * Generated from protobuf field bool packed = 8; */ - private $packed = false; + protected $packed = false; /** * The protocol buffer options. * @@ -70,13 +70,13 @@ class Field extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string json_name = 10; */ - private $json_name = ''; + protected $json_name = ''; /** * The string value of the default value of this field. Proto2 syntax only. * * Generated from protobuf field string default_value = 11; */ - private $default_value = ''; + protected $default_value = ''; /** * Constructor. @@ -133,7 +133,7 @@ public function getKind() */ public function setKind($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Field_Kind::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Field\Kind::class); $this->kind = $var; return $this; @@ -159,7 +159,7 @@ public function getCardinality() */ public function setCardinality($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Field_Cardinality::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Field\Cardinality::class); $this->cardinality = $var; return $this; diff --git a/php/src/Google/Protobuf/Field/Cardinality.php b/php/src/Google/Protobuf/Field/Cardinality.php index 479dc0bfc2db..a42219957696 100644 --- a/php/src/Google/Protobuf/Field/Cardinality.php +++ b/php/src/Google/Protobuf/Field/Cardinality.php @@ -54,6 +54,7 @@ public static function name($value) return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/Field/Kind.php b/php/src/Google/Protobuf/Field/Kind.php index f30bd2f59bdf..2d8dd77c1cb4 100644 --- a/php/src/Google/Protobuf/Field/Kind.php +++ b/php/src/Google/Protobuf/Field/Kind.php @@ -159,6 +159,7 @@ public static function name($value) return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/FieldMask.php b/php/src/Google/Protobuf/FieldMask.php index 8fb38cbfb22c..0b9659d38f5c 100644 --- a/php/src/Google/Protobuf/FieldMask.php +++ b/php/src/Google/Protobuf/FieldMask.php @@ -62,45 +62,39 @@ * and leave the others untouched. If a resource is passed in to * describe the updated values, the API ignores the values of all * fields not covered by the mask. - * If a repeated field is specified for an update operation, the existing - * repeated values in the target resource will be overwritten by the new values. - * Note that a repeated field is only allowed in the last position of a `paths` - * string. + * If a repeated field is specified for an update operation, new values will + * be appended to the existing repeated field in the target resource. Note that + * a repeated field is only allowed in the last position of a `paths` string. * If a sub-message is specified in the last position of the field mask for an - * update operation, then the existing sub-message in the target resource is - * overwritten. Given the target message: + * update operation, then new value will be merged into the existing sub-message + * in the target resource. + * For example, given the target message: * f { * b { - * d : 1 - * x : 2 + * d: 1 + * x: 2 * } - * c : 1 + * c: [1] * } * And an update message: * f { * b { - * d : 10 + * d: 10 * } + * c: [2] * } * then if the field mask is: - * paths: "f.b" + * paths: ["f.b", "f.c"] * then the result will be: * f { * b { - * d : 10 - * } - * c : 1 - * } - * However, if the update mask was: - * paths: "f.b.d" - * then the result would be: - * f { - * b { - * d : 10 - * x : 2 + * d: 10 + * x: 2 * } - * c : 1 + * c: [1, 2] * } + * An implementation may provide options to override this default behavior for + * repeated and message fields. * In order to reset a field's value to the default, the field must * be in the mask and set to the default value in the provided resource. * Hence, in order to reset all fields of a resource, provide a default @@ -165,7 +159,7 @@ * ## Field Mask Verification * The implementation of any API method which has a FieldMask type field in the * request should verify the included field paths, and return an - * `INVALID_ARGUMENT` error if any path is duplicated or unmappable. + * `INVALID_ARGUMENT` error if any path is unmappable. * * Generated from protobuf message google.protobuf.FieldMask */ diff --git a/php/src/Google/Protobuf/FloatValue.php b/php/src/Google/Protobuf/FloatValue.php index 47ba52e6af3a..4285358d5e8c 100644 --- a/php/src/Google/Protobuf/FloatValue.php +++ b/php/src/Google/Protobuf/FloatValue.php @@ -21,7 +21,7 @@ class FloatValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field float value = 1; */ - private $value = 0.0; + protected $value = 0.0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Int32Value.php b/php/src/Google/Protobuf/Int32Value.php index d7fd528d21bf..cfd73cdc90f5 100644 --- a/php/src/Google/Protobuf/Int32Value.php +++ b/php/src/Google/Protobuf/Int32Value.php @@ -21,7 +21,7 @@ class Int32Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int32 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Int64Value.php b/php/src/Google/Protobuf/Int64Value.php index ca663055839c..143474fcd7cf 100644 --- a/php/src/Google/Protobuf/Int64Value.php +++ b/php/src/Google/Protobuf/Int64Value.php @@ -21,7 +21,7 @@ class Int64Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int64 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Internal/AnyBase.php b/php/src/Google/Protobuf/Internal/AnyBase.php new file mode 100644 index 000000000000..cba922d47547 --- /dev/null +++ b/php/src/Google/Protobuf/Internal/AnyBase.php @@ -0,0 +1,86 @@ +type_url, 0, $url_prifix_len) != + GPBUtil::TYPE_URL_PREFIX) { + throw new \Exception( + "Type url needs to be type.googleapis.com/fully-qulified"); + } + $fully_qualifed_name = + substr($this->type_url, $url_prifix_len); + + // Create message according to fully qualified name. + $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByProtoName($fully_qualifed_name); + if (is_null($desc)) { + throw new \Exception("Class ".$fully_qualifed_name + ." hasn't been added to descriptor pool"); + } + $klass = $desc->getClass(); + $msg = new $klass(); + + // Merge data into message. + $msg->mergeFromString($this->value); + return $msg; + } + + /** + * The type_url will be created according to the given message’s type and + * the value is encoded data from the given message.. + * @param message: A proto message. + */ + public function pack($msg) + { + if (!$msg instanceof Message) { + trigger_error("Given parameter is not a message instance.", + E_USER_ERROR); + return; + } + + // Set value using serialized message. + $this->value = $msg->serializeToString(); + + // Set type url. + $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByClassName(get_class($msg)); + $fully_qualifed_name = $desc->getFullName(); + $this->type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name; + } + + /** + * This method returns whether the type_url in any_message is corresponded + * to the given class. + * @param klass: The fully qualified PHP class name of a proto message type. + */ + public function is($klass) + { + $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByClassName($klass); + $fully_qualifed_name = $desc->getFullName(); + $type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name; + return $this->type_url === $type_url; + } +} diff --git a/php/src/Google/Protobuf/Internal/TimestampBase.php b/php/src/Google/Protobuf/Internal/TimestampBase.php new file mode 100644 index 000000000000..653d1e99d71c --- /dev/null +++ b/php/src/Google/Protobuf/Internal/TimestampBase.php @@ -0,0 +1,32 @@ +seconds = $datetime->getTimestamp(); + $this->nanos = 1000 * $datetime->format('u'); + } + + /** + * Converts Timestamp to PHP DateTime. + * + * @return \DateTime $datetime + */ + public function toDateTime() + { + $time = sprintf('%s.%06d', $this->seconds, $this->nanos / 1000); + return \DateTime::createFromFormat('U.u', $time); + } +} diff --git a/php/src/Google/Protobuf/Method.php b/php/src/Google/Protobuf/Method.php index 8e803506885c..2755baa0e8b0 100644 --- a/php/src/Google/Protobuf/Method.php +++ b/php/src/Google/Protobuf/Method.php @@ -20,31 +20,31 @@ class Method extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * A URL of the input message type. * * Generated from protobuf field string request_type_url = 2; */ - private $request_type_url = ''; + protected $request_type_url = ''; /** * If true, the request is streamed. * * Generated from protobuf field bool request_streaming = 3; */ - private $request_streaming = false; + protected $request_streaming = false; /** * The URL of the output message type. * * Generated from protobuf field string response_type_url = 4; */ - private $response_type_url = ''; + protected $response_type_url = ''; /** * If true, the response is streamed. * * Generated from protobuf field bool response_streaming = 5; */ - private $response_streaming = false; + protected $response_streaming = false; /** * Any metadata attached to the method. * @@ -56,7 +56,7 @@ class Method extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Syntax syntax = 7; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Mixin.php b/php/src/Google/Protobuf/Mixin.php index cf6277eb7064..4f7bf844ccfe 100644 --- a/php/src/Google/Protobuf/Mixin.php +++ b/php/src/Google/Protobuf/Mixin.php @@ -81,14 +81,14 @@ class Mixin extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * If non-empty specifies a path under which inherited HTTP paths * are rooted. * * Generated from protobuf field string root = 2; */ - private $root = ''; + protected $root = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/Option.php b/php/src/Google/Protobuf/Option.php index 22ecfc5f5c6c..9b2cc6c22c32 100644 --- a/php/src/Google/Protobuf/Option.php +++ b/php/src/Google/Protobuf/Option.php @@ -24,7 +24,7 @@ class Option extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * The option's value packed in an Any message. If the value is a primitive, * the corresponding wrapper type defined in google/protobuf/wrappers.proto @@ -33,7 +33,7 @@ class Option extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Any value = 2; */ - private $value = null; + protected $value = null; /** * Constructor. @@ -101,7 +101,17 @@ public function setName($var) */ public function getValue() { - return $this->value; + return isset($this->value) ? $this->value : null; + } + + public function hasValue() + { + return isset($this->value); + } + + public function clearValue() + { + unset($this->value); } /** diff --git a/php/src/Google/Protobuf/SourceContext.php b/php/src/Google/Protobuf/SourceContext.php index cbc50c684260..8b3ea11220cd 100644 --- a/php/src/Google/Protobuf/SourceContext.php +++ b/php/src/Google/Protobuf/SourceContext.php @@ -22,7 +22,7 @@ class SourceContext extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string file_name = 1; */ - private $file_name = ''; + protected $file_name = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/StringValue.php b/php/src/Google/Protobuf/StringValue.php index 8fb354f3881e..ad98316b2247 100644 --- a/php/src/Google/Protobuf/StringValue.php +++ b/php/src/Google/Protobuf/StringValue.php @@ -21,7 +21,7 @@ class StringValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string value = 1; */ - private $value = ''; + protected $value = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/Syntax.php b/php/src/Google/Protobuf/Syntax.php index 9812669dacac..10952bfd42ce 100644 --- a/php/src/Google/Protobuf/Syntax.php +++ b/php/src/Google/Protobuf/Syntax.php @@ -40,6 +40,7 @@ public static function name($value) return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/Timestamp.php b/php/src/Google/Protobuf/Timestamp.php index 6d26f6c5cfdf..a12f48520bf2 100644 --- a/php/src/Google/Protobuf/Timestamp.php +++ b/php/src/Google/Protobuf/Timestamp.php @@ -9,17 +9,17 @@ use Google\Protobuf\Internal\GPBUtil; /** - * A Timestamp represents a point in time independent of any time zone - * or calendar, represented as seconds and fractions of seconds at - * nanosecond resolution in UTC Epoch time. It is encoded using the - * Proleptic Gregorian Calendar which extends the Gregorian calendar - * backwards to year one. It is encoded assuming all minutes are 60 - * seconds long, i.e. leap seconds are "smeared" so that no leap second - * table is needed for interpretation. Range is from - * 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. - * By restricting to that range, we ensure that we can convert to - * and from RFC 3339 date strings. - * See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). + * A Timestamp represents a point in time independent of any time zone or local + * calendar, encoded as a count of seconds and fractions of seconds at + * nanosecond resolution. The count is relative to an epoch at UTC midnight on + * January 1, 1970, in the proleptic Gregorian calendar which extends the + * Gregorian calendar backwards to year one. + * All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + * second table is needed for interpretation, using a [24-hour linear + * smear](https://developers.google.com/time/smear). + * The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By + * restricting to that range, we ensure that we can convert to and from [RFC + * 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. * # Examples * Example 1: Compute Timestamp from POSIX `time()`. * Timestamp timestamp; @@ -44,7 +44,12 @@ * long millis = System.currentTimeMillis(); * Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) * .setNanos((int) ((millis % 1000) * 1000000)).build(); - * Example 5: Compute Timestamp from current time in Python. + * Example 5: Compute Timestamp from Java `Instant.now()`. + * Instant now = Instant.now(); + * Timestamp timestamp = + * Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + * .setNanos(now.getNano()).build(); + * Example 6: Compute Timestamp from current time in Python. * timestamp = Timestamp() * timestamp.GetCurrentTime() * # JSON Mapping @@ -61,17 +66,19 @@ * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past * 01:30 UTC on January 15, 2017. * In JavaScript, one can convert a Date object to this format using the - * standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] + * standard + * [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) * method. In Python, a standard `datetime.datetime` object can be converted - * to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) - * with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one - * can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( - * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- + * to this format using + * [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with + * the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use + * the Joda Time's [`ISODateTimeFormat.dateTime()`]( + * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D * ) to obtain a formatter capable of generating timestamps in this format. * * Generated from protobuf message google.protobuf.Timestamp */ -class Timestamp extends \Google\Protobuf\Internal\Message +class Timestamp extends \Google\Protobuf\Internal\TimestampBase { /** * Represents seconds of UTC time since Unix epoch @@ -80,7 +87,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int64 seconds = 1; */ - private $seconds = 0; + protected $seconds = 0; /** * Non-negative fractions of a second at nanosecond resolution. Negative * second values with fractions must still have non-negative nanos values @@ -89,7 +96,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int32 nanos = 2; */ - private $nanos = 0; + protected $nanos = 0; /** * Constructor. @@ -175,26 +182,5 @@ public function setNanos($var) return $this; } - /* - * Converts PHP DateTime to Timestamp. - * - * @param \DateTime $datetime - */ - public function fromDateTime(\DateTime $datetime) - { - $this->seconds = $datetime->getTimestamp(); - $this->nanos = 1000 * $datetime->format('u'); - } - - /** - * Converts Timestamp to PHP DateTime. - * - * @return \DateTime $datetime - */ - public function toDateTime() - { - $time = sprintf('%s.%06d', $this->seconds, $this->nanos / 1000); - return \DateTime::createFromFormat('U.u', $time); - } } diff --git a/php/src/Google/Protobuf/Type.php b/php/src/Google/Protobuf/Type.php index 1b47811050a4..f60686665cd3 100644 --- a/php/src/Google/Protobuf/Type.php +++ b/php/src/Google/Protobuf/Type.php @@ -20,7 +20,7 @@ class Type extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * The list of fields. * @@ -44,13 +44,13 @@ class Type extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; */ - private $source_context = null; + protected $source_context = null; /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 6; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. @@ -189,7 +189,17 @@ public function setOptions($var) */ public function getSourceContext() { - return $this->source_context; + return isset($this->source_context) ? $this->source_context : null; + } + + public function hasSourceContext() + { + return isset($this->source_context); + } + + public function clearSourceContext() + { + unset($this->source_context); } /** diff --git a/php/src/Google/Protobuf/UInt32Value.php b/php/src/Google/Protobuf/UInt32Value.php index f5a522d2e8ef..ae5fc5b42c8d 100644 --- a/php/src/Google/Protobuf/UInt32Value.php +++ b/php/src/Google/Protobuf/UInt32Value.php @@ -21,7 +21,7 @@ class UInt32Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field uint32 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/UInt64Value.php b/php/src/Google/Protobuf/UInt64Value.php index 89e69cd89206..aa9686726b93 100644 --- a/php/src/Google/Protobuf/UInt64Value.php +++ b/php/src/Google/Protobuf/UInt64Value.php @@ -21,7 +21,7 @@ class UInt64Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field uint64 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php index 90c1069ed3c6..037bd1be9c5c 100644 --- a/php/tests/GeneratedClassTest.php +++ b/php/tests/GeneratedClassTest.php @@ -1671,6 +1671,23 @@ public function testDeepEquality() # TODO: what about unknown fields? } + ######################################################### + # Test hasOneof methods exists and working + ######################################################### + + public function testHasOneof() { + $m = new TestMessage(); + $this->assertFalse($m->hasOneofInt32()); + $m->setOneofInt32(42); + $this->assertTrue($m->hasOneofInt32()); + $m->setOneofString("bar"); + $this->assertFalse($m->hasOneofInt32()); + $this->assertTrue($m->hasOneofString()); + $m->clear(); + $this->assertFalse($m->hasOneofInt32()); + $this->assertFalse($m->hasOneofString()); + } + ######################################################### # Test no segfault when error happens ######################################################### diff --git a/php/tests/compile_extension.sh b/php/tests/compile_extension.sh index d6dcabcbbb8d..85c73c6eb5dd 100755 --- a/php/tests/compile_extension.sh +++ b/php/tests/compile_extension.sh @@ -4,10 +4,10 @@ set -ex cd $(dirname $0) +../prepare_c_extension.sh pushd ../ext/google/protobuf phpize --clean rm -f configure.in configure.ac -php make-preload.php phpize if [ "$1" = "--release" ]; then ./configure --with-php-config=$(which php-config) diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml index 27315e83f45b..97fd11e700b3 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -8,7 +8,7 @@ com.google.protobuf protoc - 3.13.0 + 3.14.0 pom Protobuf Compiler diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index 4e0d0e3906a3..512d64105a91 100644 --- a/python/google/protobuf/__init__.py +++ b/python/google/protobuf/__init__.py @@ -31,9 +31,3 @@ # Copyright 2007 Google Inc. All Rights Reserved. __version__ = '3.13.0' - -if __name__ != '__main__': - try: - __import__('pkg_resources').declare_namespace(__name__) - except ImportError: - __path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py index c35b00d9fbdf..92793490bbc3 100644 --- a/python/google/protobuf/internal/containers.py +++ b/python/google/protobuf/internal/containers.py @@ -231,6 +231,9 @@ def sort(self, *args, **kwargs): kwargs['cmp'] = kwargs.pop('sort_function') self._values.sort(*args, **kwargs) + def reverse(self): + self._values.reverse() + collections_abc.MutableSequence.register(BaseContainer) diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index e052776d6397..2b9ed1cb5a44 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -1311,6 +1311,38 @@ def testRepeatedScalarsRemove(self): # Remove a non-existent element. self.assertRaises(ValueError, proto.repeated_int32.remove, 123) + def testRepeatedScalarsReverse_Empty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_int32) + self.assertEqual(0, len(proto.repeated_int32)) + + self.assertIsNone(proto.repeated_int32.reverse()) + + self.assertFalse(proto.repeated_int32) + self.assertEqual(0, len(proto.repeated_int32)) + + def testRepeatedScalarsReverse_NonEmpty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_int32) + self.assertEqual(0, len(proto.repeated_int32)) + + proto.repeated_int32.append(1) + proto.repeated_int32.append(2) + proto.repeated_int32.append(3) + proto.repeated_int32.append(4) + + self.assertEqual(4, len(proto.repeated_int32)) + + self.assertIsNone(proto.repeated_int32.reverse()) + + self.assertEqual(4, len(proto.repeated_int32)) + self.assertEqual(4, proto.repeated_int32[0]) + self.assertEqual(3, proto.repeated_int32[1]) + self.assertEqual(2, proto.repeated_int32[2]) + self.assertEqual(1, proto.repeated_int32[3]) + def testRepeatedComposites(self): proto = unittest_pb2.TestAllTypes() self.assertFalse(proto.repeated_nested_message) @@ -1423,6 +1455,35 @@ def testRepeatedCompositeRemove(self): self.assertEqual(1, len(proto.repeated_nested_message)) self.assertEqual(m1, proto.repeated_nested_message[0]) + def testRepeatedCompositeReverse_Empty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_nested_message) + self.assertEqual(0, len(proto.repeated_nested_message)) + + self.assertIsNone(proto.repeated_nested_message.reverse()) + + self.assertFalse(proto.repeated_nested_message) + self.assertEqual(0, len(proto.repeated_nested_message)) + + def testRepeatedCompositeReverse_NonEmpty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_nested_message) + self.assertEqual(0, len(proto.repeated_nested_message)) + + m0 = proto.repeated_nested_message.add() + m0.bb = len(proto.repeated_nested_message) + m1 = proto.repeated_nested_message.add() + m1.bb = len(proto.repeated_nested_message) + m2 = proto.repeated_nested_message.add() + m2.bb = len(proto.repeated_nested_message) + self.assertListsEqual([m0, m1, m2], proto.repeated_nested_message) + + self.assertIsNone(proto.repeated_nested_message.reverse()) + + self.assertListsEqual([m2, m1, m0], proto.repeated_nested_message) + def testHandWrittenReflection(self): # Hand written extensions are only supported by the pure-Python # implementation of the API. @@ -3061,10 +3122,10 @@ def testFieldDataDescriptor(self): unittest_pb2.ForeignMessage.c.__get__(msg) except TypeError: pass # The cpp implementation cannot mix fields from other messages. - # This test exercises a specific check that avoids a crash. + # This test exercises a specific check that avoids a crash. else: pass # The python implementation allows fields from other messages. - # This is useless, but works. + # This is useless, but works. def testInitKwargs(self): proto = unittest_pb2.TestAllTypes( diff --git a/python/google/protobuf/pyext/__init__.py b/python/google/protobuf/pyext/__init__.py index 558561412299..e69de29bb2d1 100644 --- a/python/google/protobuf/pyext/__init__.py +++ b/python/google/protobuf/pyext/__init__.py @@ -1,4 +0,0 @@ -try: - __import__('pkg_resources').declare_namespace(__name__) -except ImportError: - __path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc index 4188b5f4a1b8..d934f756bab5 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.cc +++ b/python/google/protobuf/pyext/repeated_composite_container.cc @@ -77,8 +77,7 @@ static Py_ssize_t Length(PyObject* pself) { PyObject* Add(RepeatedCompositeContainer* self, PyObject* args, PyObject* kwargs) { - if (cmessage::AssureWritable(self->parent) == -1) - return NULL; + if (cmessage::AssureWritable(self->parent) == -1) return nullptr; Message* message = self->parent->message; Message* sub_message = @@ -93,7 +92,7 @@ PyObject* Add(RepeatedCompositeContainer* self, PyObject* args, message->GetReflection()->RemoveLast( message, self->parent_field_descriptor); Py_DECREF(cmsg); - return NULL; + return nullptr; } return cmsg->AsPyObject(); @@ -172,28 +171,28 @@ static PyObject* Insert(PyObject* pself, PyObject* args) { PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) { cmessage::AssureWritable(self->parent); ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); - return NULL; + return nullptr; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { if (!PyObject_TypeCheck(next.get(), CMessage_Type)) { PyErr_SetString(PyExc_TypeError, "Not a cmessage"); - return NULL; + return nullptr; } - ScopedPyObjectPtr new_message(Add(self, NULL, NULL)); - if (new_message == NULL) { - return NULL; + ScopedPyObjectPtr new_message(Add(self, nullptr, nullptr)); + if (new_message == nullptr) { + return nullptr; } CMessage* new_cmessage = reinterpret_cast(new_message.get()); if (ScopedPyObjectPtr(cmessage::MergeFrom(new_cmessage, next.get())) == - NULL) { - return NULL; + nullptr) { + return nullptr; } } if (PyErr_Occurred()) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -220,7 +219,7 @@ static PyObject* GetItem(RepeatedCompositeContainer* self, Py_ssize_t index, } if (index < 0 || index >= length) { PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); - return NULL; + return nullptr; } Message* message = self->parent->message; Message* sub_message = message->GetReflection()->MutableRepeatedMessage( @@ -240,7 +239,7 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* item) { if (PyIndex_Check(item)) { Py_ssize_t index; index = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (index == -1 && PyErr_Occurred()) return NULL; + if (index == -1 && PyErr_Occurred()) return nullptr; if (index < 0) index += length; return GetItem(self, index, length); } else if (PySlice_Check(item)) { @@ -254,14 +253,14 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* item) { if (PySlice_GetIndicesEx(reinterpret_cast(item), length, &from, &to, &step, &slicelength) == -1) { #endif - return NULL; + return nullptr; } if (slicelength <= 0) { return PyList_New(0); } else { result = PyList_New(slicelength); - if (!result) return NULL; + if (!result) return nullptr; for (cur = from, i = 0; i < slicelength; cur += step, i++) { PyList_SET_ITEM(result, i, GetItem(self, cur, length)); @@ -272,7 +271,7 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* item) { } else { PyErr_Format(PyExc_TypeError, "indices must be integers, not %.200s", item->ob_type->tp_name); - return NULL; + return nullptr; } } @@ -283,7 +282,7 @@ static PyObject* SubscriptMethod(PyObject* self, PyObject* slice) { int AssignSubscript(RepeatedCompositeContainer* self, PyObject* slice, PyObject* value) { - if (value != NULL) { + if (value != nullptr) { PyErr_SetString(PyExc_TypeError, "does not support assignment"); return -1; } @@ -305,23 +304,23 @@ static PyObject* Remove(PyObject* pself, PyObject* value) { for (Py_ssize_t i = 0; i < len; i++) { ScopedPyObjectPtr item(GetItem(self, i, len)); - if (item == NULL) { - return NULL; + if (item == nullptr) { + return nullptr; } int result = PyObject_RichCompareBool(item.get(), value, Py_EQ); if (result < 0) { - return NULL; + return nullptr; } if (result) { ScopedPyObjectPtr py_index(PyLong_FromSsize_t(i)); - if (AssignSubscript(self, py_index.get(), NULL) < 0) { - return NULL; + if (AssignSubscript(self, py_index.get(), nullptr) < 0) { + return nullptr; } Py_RETURN_NONE; } } PyErr_SetString(PyExc_ValueError, "Item to delete not in list"); - return NULL; + return nullptr; } static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { @@ -332,23 +331,23 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { PyErr_SetString(PyExc_TypeError, "Can only compare repeated composite fields " "against other repeated composite fields."); - return NULL; + return nullptr; } if (opid == Py_EQ || opid == Py_NE) { // TODO(anuraag): Don't make new lists just for this... - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript(self, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } ScopedPyObjectPtr other_list( Subscript(reinterpret_cast(other), full_slice.get())); - if (other_list == NULL) { - return NULL; + if (other_list == nullptr) { + return nullptr; } return PyObject_RichCompare(list.get(), other_list.get(), opid); } else { @@ -358,14 +357,14 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { } static PyObject* ToStr(PyObject* pself) { - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript( reinterpret_cast(pself), full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } return PyObject_Repr(list.get()); } @@ -400,13 +399,12 @@ static int SortPythonMessages(RepeatedCompositeContainer* self, PyObject* kwds) { ScopedPyObjectPtr child_list( PySequence_List(reinterpret_cast(self))); - if (child_list == NULL) { + if (child_list == nullptr) { return -1; } ScopedPyObjectPtr m(PyObject_GetAttrString(child_list.get(), "sort")); - if (m == NULL) - return -1; - if (ScopedPyObjectPtr(PyObject_Call(m.get(), args, kwds)) == NULL) + if (m == nullptr) return -1; + if (ScopedPyObjectPtr(PyObject_Call(m.get(), args, kwds)) == nullptr) return -1; ReorderAttached(self, child_list.get()); return 0; @@ -418,9 +416,9 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { // Support the old sort_function argument for backwards // compatibility. - if (kwds != NULL) { + if (kwds != nullptr) { PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function"); - if (sort_func != NULL) { + if (sort_func != nullptr) { // Must set before deleting as sort_func is a borrowed reference // and kwds might be the only thing keeping it alive. PyDict_SetItemString(kwds, "cmp", sort_func); @@ -429,7 +427,35 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { } if (SortPythonMessages(self, args, kwds) < 0) { - return NULL; + return nullptr; + } + Py_RETURN_NONE; +} + +// --------------------------------------------------------------------- +// reverse() + +// Returns 0 if successful; returns -1 and sets an exception if +// unsuccessful. +static int ReversePythonMessages(RepeatedCompositeContainer* self) { + ScopedPyObjectPtr child_list( + PySequence_List(reinterpret_cast(self))); + if (child_list == nullptr) { + return -1; + } + if (ScopedPyObjectPtr( + PyObject_CallMethod(child_list.get(), "reverse", nullptr)) == nullptr) + return -1; + ReorderAttached(self, child_list.get()); + return 0; +} + +static PyObject* Reverse(PyObject* pself) { + RepeatedCompositeContainer* self = + reinterpret_cast(pself); + + if (ReversePythonMessages(self) < 0) { + return nullptr; } Py_RETURN_NONE; } @@ -448,17 +474,17 @@ static PyObject* Pop(PyObject* pself, PyObject* args) { Py_ssize_t index = -1; if (!PyArg_ParseTuple(args, "|n", &index)) { - return NULL; + return nullptr; } Py_ssize_t length = Length(pself); if (index < 0) index += length; PyObject* item = GetItem(self, index, length); - if (item == NULL) { - return NULL; + if (item == nullptr) { + return nullptr; } ScopedPyObjectPtr py_index(PyLong_FromSsize_t(index)); - if (AssignSubscript(self, py_index.get(), NULL) < 0) { - return NULL; + if (AssignSubscript(self, py_index.get(), nullptr) < 0) { + return nullptr; } return item; } @@ -473,14 +499,14 @@ RepeatedCompositeContainer *NewContainer( const FieldDescriptor* parent_field_descriptor, CMessageClass* child_message_class) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } RepeatedCompositeContainer* self = reinterpret_cast( PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -500,10 +526,10 @@ static void Dealloc(PyObject* pself) { } static PySequenceMethods SqMethods = { - Length, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - Item /* sq_item */ + Length, /* sq_length */ + nullptr, /* sq_concat */ + nullptr, /* sq_repeat */ + Item /* sq_item */ }; static PyMappingMethods MpMethods = { @@ -513,66 +539,65 @@ static PyMappingMethods MpMethods = { }; static PyMethodDef Methods[] = { - { "__deepcopy__", DeepCopy, METH_VARARGS, - "Makes a deep copy of the class." }, - { "add", (PyCFunction)AddMethod, METH_VARARGS | METH_KEYWORDS, - "Adds an object to the repeated container." }, - { "append", AppendMethod, METH_O, - "Appends a message to the end of the repeated container."}, - { "insert", Insert, METH_VARARGS, - "Inserts a message before the specified index." }, - { "extend", ExtendMethod, METH_O, - "Adds objects to the repeated container." }, - { "pop", Pop, METH_VARARGS, - "Removes an object from the repeated container and returns it." }, - { "remove", Remove, METH_O, - "Removes an object from the repeated container." }, - { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS, - "Sorts the repeated container." }, - { "MergeFrom", MergeFromMethod, METH_O, - "Adds objects to the repeated container." }, - { NULL, NULL } -}; + {"__deepcopy__", DeepCopy, METH_VARARGS, "Makes a deep copy of the class."}, + {"add", reinterpret_cast(AddMethod), + METH_VARARGS | METH_KEYWORDS, "Adds an object to the repeated container."}, + {"append", AppendMethod, METH_O, + "Appends a message to the end of the repeated container."}, + {"insert", Insert, METH_VARARGS, + "Inserts a message before the specified index."}, + {"extend", ExtendMethod, METH_O, "Adds objects to the repeated container."}, + {"pop", Pop, METH_VARARGS, + "Removes an object from the repeated container and returns it."}, + {"remove", Remove, METH_O, + "Removes an object from the repeated container."}, + {"sort", reinterpret_cast(Sort), METH_VARARGS | METH_KEYWORDS, + "Sorts the repeated container."}, + {"reverse", reinterpret_cast(Reverse), METH_NOARGS, + "Reverses elements order of the repeated container."}, + {"MergeFrom", MergeFromMethod, METH_O, + "Adds objects to the repeated container."}, + {nullptr, nullptr}}; } // namespace repeated_composite_container PyTypeObject RepeatedCompositeContainer_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".RepeatedCompositeContainer", // tp_name - sizeof(RepeatedCompositeContainer), // tp_basicsize - 0, // tp_itemsize - repeated_composite_container::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - repeated_composite_container::ToStr, // tp_repr - 0, // tp_as_number - &repeated_composite_container::SqMethods, // tp_as_sequence - &repeated_composite_container::MpMethods, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Repeated scalar container", // tp_doc - 0, // tp_traverse - 0, // tp_clear - repeated_composite_container::RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - repeated_composite_container::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".RepeatedCompositeContainer", // tp_name + sizeof(RepeatedCompositeContainer), // tp_basicsize + 0, // tp_itemsize + repeated_composite_container::Dealloc, // tp_dealloc + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + repeated_composite_container::ToStr, // tp_repr + nullptr, // tp_as_number + &repeated_composite_container::SqMethods, // tp_as_sequence + &repeated_composite_container::MpMethods, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Repeated scalar container", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + repeated_composite_container::RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + repeated_composite_container::Methods, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; } // namespace python diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc index 712182b3747e..8c937b7ccf69 100644 --- a/python/google/protobuf/pyext/repeated_scalar_container.cc +++ b/python/google/protobuf/pyext/repeated_scalar_container.cc @@ -46,13 +46,13 @@ #include #if PY_MAJOR_VERSION >= 3 - #define PyInt_FromLong PyLong_FromLong - #if PY_VERSION_HEX < 0x03030000 - #error "Python 3.0 - 3.2 are not supported." - #else - #define PyString_AsString(ob) \ - (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob)) - #endif +#define PyInt_FromLong PyLong_FromLong +#if PY_VERSION_HEX < 0x03030000 +#error "Python 3.0 - 3.2 are not supported." +#else +#define PyString_AsString(ob) \ + (PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob)) +#endif #endif namespace google { @@ -61,13 +61,13 @@ namespace python { namespace repeated_scalar_container { -static int InternalAssignRepeatedField( - RepeatedScalarContainer* self, PyObject* list) { +static int InternalAssignRepeatedField(RepeatedScalarContainer* self, + PyObject* list) { Message* message = self->parent->message; message->GetReflection()->ClearField(message, self->parent_field_descriptor); for (Py_ssize_t i = 0; i < PyList_GET_SIZE(list); ++i) { PyObject* value = PyList_GET_ITEM(list, i); - if (ScopedPyObjectPtr(Append(self, value)) == NULL) { + if (ScopedPyObjectPtr(Append(self, value)) == nullptr) { return -1; } } @@ -96,13 +96,12 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { index = field_size + index; } if (index < 0 || index >= field_size) { - PyErr_Format(PyExc_IndexError, - "list assignment index (%d) out of range", + PyErr_Format(PyExc_IndexError, "list assignment index (%d) out of range", static_cast(index)); return -1; } - if (arg == NULL) { + if (arg == nullptr) { ScopedPyObjectPtr py_index(PyLong_FromLong(index)); return cmessage::DeleteRepeatedField(self->parent, field_descriptor, py_index.get()); @@ -150,8 +149,8 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { break; } case FieldDescriptor::CPPTYPE_STRING: { - if (!CheckAndSetString( - arg, message, field_descriptor, reflection, false, index)) { + if (!CheckAndSetString(arg, message, field_descriptor, reflection, false, + index)) { return -1; } break; @@ -165,12 +164,12 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { const EnumDescriptor* enum_descriptor = field_descriptor->enum_type(); const EnumValueDescriptor* enum_value = enum_descriptor->FindValueByNumber(value); - if (enum_value != NULL) { + if (enum_value != nullptr) { reflection->SetRepeatedEnum(message, field_descriptor, index, enum_value); } else { ScopedPyObjectPtr s(PyObject_Str(arg)); - if (s != NULL) { + if (s != nullptr) { PyErr_Format(PyExc_ValueError, "Unknown enum value: %s", PyString_AsString(s.get())); } @@ -180,9 +179,9 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { break; } default: - PyErr_Format( - PyExc_SystemError, "Adding value to a field of unknown type %d", - field_descriptor->cpp_type()); + PyErr_Format(PyExc_SystemError, + "Adding value to a field of unknown type %d", + field_descriptor->cpp_type()); return -1; } return 0; @@ -201,60 +200,58 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { index = field_size + index; } if (index < 0 || index >= field_size) { - PyErr_Format(PyExc_IndexError, - "list index (%zd) out of range", - index); - return NULL; + PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); + return nullptr; } - PyObject* result = NULL; + PyObject* result = nullptr; switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { - int32 value = reflection->GetRepeatedInt32( - *message, field_descriptor, index); + int32 value = + reflection->GetRepeatedInt32(*message, field_descriptor, index); result = PyInt_FromLong(value); break; } case FieldDescriptor::CPPTYPE_INT64: { - int64 value = reflection->GetRepeatedInt64( - *message, field_descriptor, index); + int64 value = + reflection->GetRepeatedInt64(*message, field_descriptor, index); result = PyLong_FromLongLong(value); break; } case FieldDescriptor::CPPTYPE_UINT32: { - uint32 value = reflection->GetRepeatedUInt32( - *message, field_descriptor, index); + uint32 value = + reflection->GetRepeatedUInt32(*message, field_descriptor, index); result = PyLong_FromLongLong(value); break; } case FieldDescriptor::CPPTYPE_UINT64: { - uint64 value = reflection->GetRepeatedUInt64( - *message, field_descriptor, index); + uint64 value = + reflection->GetRepeatedUInt64(*message, field_descriptor, index); result = PyLong_FromUnsignedLongLong(value); break; } case FieldDescriptor::CPPTYPE_FLOAT: { - float value = reflection->GetRepeatedFloat( - *message, field_descriptor, index); + float value = + reflection->GetRepeatedFloat(*message, field_descriptor, index); result = PyFloat_FromDouble(value); break; } case FieldDescriptor::CPPTYPE_DOUBLE: { - double value = reflection->GetRepeatedDouble( - *message, field_descriptor, index); + double value = + reflection->GetRepeatedDouble(*message, field_descriptor, index); result = PyFloat_FromDouble(value); break; } case FieldDescriptor::CPPTYPE_BOOL: { - bool value = reflection->GetRepeatedBool( - *message, field_descriptor, index); + bool value = + reflection->GetRepeatedBool(*message, field_descriptor, index); result = PyBool_FromLong(value ? 1 : 0); break; } case FieldDescriptor::CPPTYPE_ENUM: { const EnumValueDescriptor* enum_value = - message->GetReflection()->GetRepeatedEnum( - *message, field_descriptor, index); + message->GetReflection()->GetRepeatedEnum(*message, field_descriptor, + index); result = PyInt_FromLong(enum_value->number()); break; } @@ -266,10 +263,9 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { break; } default: - PyErr_Format( - PyExc_SystemError, - "Getting value from a repeated field of unknown type %d", - field_descriptor->cpp_type()); + PyErr_Format(PyExc_SystemError, + "Getting value from a repeated field of unknown type %d", + field_descriptor->cpp_type()); } return result; @@ -287,23 +283,23 @@ static PyObject* Subscript(PyObject* pself, PyObject* slice) { from = to = PyInt_AsLong(slice); } else // NOLINT #endif - if (PyLong_Check(slice)) { + if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); } else if (PySlice_Check(slice)) { length = Len(pself); #if PY_MAJOR_VERSION >= 3 - if (PySlice_GetIndicesEx(slice, - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) == + -1) { #else - if (PySlice_GetIndicesEx(reinterpret_cast(slice), - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(reinterpret_cast(slice), length, + &from, &to, &step, &slicelength) == -1) { #endif - return NULL; + return nullptr; } return_list = true; } else { PyErr_SetString(PyExc_TypeError, "list indices must be integers"); - return NULL; + return nullptr; } if (!return_list) { @@ -311,8 +307,8 @@ static PyObject* Subscript(PyObject* pself, PyObject* slice) { } PyObject* list = PyList_New(0); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } if (from <= to) { if (step < 0) { @@ -348,73 +344,73 @@ PyObject* Append(RepeatedScalarContainer* self, PyObject* item) { const Reflection* reflection = message->GetReflection(); switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { - GOOGLE_CHECK_GET_INT32(item, value, NULL); + GOOGLE_CHECK_GET_INT32(item, value, nullptr); reflection->AddInt32(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_INT64: { - GOOGLE_CHECK_GET_INT64(item, value, NULL); + GOOGLE_CHECK_GET_INT64(item, value, nullptr); reflection->AddInt64(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_UINT32: { - GOOGLE_CHECK_GET_UINT32(item, value, NULL); + GOOGLE_CHECK_GET_UINT32(item, value, nullptr); reflection->AddUInt32(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_UINT64: { - GOOGLE_CHECK_GET_UINT64(item, value, NULL); + GOOGLE_CHECK_GET_UINT64(item, value, nullptr); reflection->AddUInt64(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_FLOAT: { - GOOGLE_CHECK_GET_FLOAT(item, value, NULL); + GOOGLE_CHECK_GET_FLOAT(item, value, nullptr); reflection->AddFloat(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_DOUBLE: { - GOOGLE_CHECK_GET_DOUBLE(item, value, NULL); + GOOGLE_CHECK_GET_DOUBLE(item, value, nullptr); reflection->AddDouble(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_BOOL: { - GOOGLE_CHECK_GET_BOOL(item, value, NULL); + GOOGLE_CHECK_GET_BOOL(item, value, nullptr); reflection->AddBool(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_STRING: { - if (!CheckAndSetString( - item, message, field_descriptor, reflection, true, -1)) { - return NULL; + if (!CheckAndSetString(item, message, field_descriptor, reflection, true, + -1)) { + return nullptr; } break; } case FieldDescriptor::CPPTYPE_ENUM: { - GOOGLE_CHECK_GET_INT32(item, value, NULL); + GOOGLE_CHECK_GET_INT32(item, value, nullptr); if (reflection->SupportsUnknownEnumValues()) { reflection->AddEnumValue(message, field_descriptor, value); } else { const EnumDescriptor* enum_descriptor = field_descriptor->enum_type(); const EnumValueDescriptor* enum_value = enum_descriptor->FindValueByNumber(value); - if (enum_value != NULL) { + if (enum_value != nullptr) { reflection->AddEnum(message, field_descriptor, enum_value); } else { ScopedPyObjectPtr s(PyObject_Str(item)); - if (s != NULL) { + if (s != nullptr) { PyErr_Format(PyExc_ValueError, "Unknown enum value: %s", PyString_AsString(s.get())); } - return NULL; + return nullptr; } } break; } default: - PyErr_Format( - PyExc_SystemError, "Adding value to a field of unknown type %d", - field_descriptor->cpp_type()); - return NULL; + PyErr_Format(PyExc_SystemError, + "Adding value to a field of unknown type %d", + field_descriptor->cpp_type()); + return nullptr; } Py_RETURN_NONE; @@ -437,25 +433,24 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) { cmessage::AssureWritable(self->parent); Message* message = self->parent->message; - const FieldDescriptor* field_descriptor = - self->parent_field_descriptor; + const FieldDescriptor* field_descriptor = self->parent_field_descriptor; #if PY_MAJOR_VERSION < 3 if (PyInt_Check(slice)) { from = to = PyInt_AsLong(slice); } else // NOLINT #endif - if (PyLong_Check(slice)) { + if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); } else if (PySlice_Check(slice)) { const Reflection* reflection = message->GetReflection(); length = reflection->FieldSize(*message, field_descriptor); #if PY_MAJOR_VERSION >= 3 - if (PySlice_GetIndicesEx(slice, - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) == + -1) { #else - if (PySlice_GetIndicesEx(reinterpret_cast(slice), - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(reinterpret_cast(slice), length, + &from, &to, &step, &slicelength) == -1) { #endif return -1; } @@ -465,7 +460,7 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) { return -1; } - if (value == NULL) { + if (value == nullptr) { return cmessage::DeleteRepeatedField(self->parent, field_descriptor, slice); } @@ -473,12 +468,12 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) { return AssignItem(pself, from, value); } - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { return -1; } ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get())); - if (new_list == NULL) { + if (new_list == nullptr) { return -1; } if (PySequence_SetSlice(new_list.get(), from, to, value) < 0) { @@ -495,23 +490,23 @@ PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) { if (value == Py_None) { Py_RETURN_NONE; } - if ((Py_TYPE(value)->tp_as_sequence == NULL) && PyObject_Not(value)) { + if ((Py_TYPE(value)->tp_as_sequence == nullptr) && PyObject_Not(value)) { Py_RETURN_NONE; } ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); - return NULL; + return nullptr; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { - if (ScopedPyObjectPtr(Append(self, next.get())) == NULL) { - return NULL; + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { + if (ScopedPyObjectPtr(Append(self, next.get())) == nullptr) { + return nullptr; } } if (PyErr_Occurred()) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -523,16 +518,16 @@ static PyObject* Insert(PyObject* pself, PyObject* args) { Py_ssize_t index; PyObject* value; if (!PyArg_ParseTuple(args, "lO", &index, &value)) { - return NULL; + return nullptr; } - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get())); if (PyList_Insert(new_list.get(), index, value) < 0) { - return NULL; + return nullptr; } int ret = InternalAssignRepeatedField(self, new_list.get()); if (ret < 0) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -548,10 +543,10 @@ static PyObject* Remove(PyObject* pself, PyObject* value) { } if (match_index == -1) { PyErr_SetString(PyExc_ValueError, "remove(x): x not in container"); - return NULL; + return nullptr; } - if (AssignItem(pself, match_index, NULL) < 0) { - return NULL; + if (AssignItem(pself, match_index, nullptr) < 0) { + return nullptr; } Py_RETURN_NONE; } @@ -570,9 +565,9 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { // also a repeated scalar container, into Python lists so we can delegate // to the list's compare method. - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr other_list_deleter; @@ -582,54 +577,72 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { } ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } return PyObject_RichCompare(list.get(), other, opid); } PyObject* Reduce(PyObject* unused_self, PyObject* unused_other) { - PyErr_Format( - PickleError_class, - "can't pickle repeated message fields, convert to list first"); - return NULL; + PyErr_Format(PickleError_class, + "can't pickle repeated message fields, convert to list first"); + return nullptr; } static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { // Support the old sort_function argument for backwards // compatibility. - if (kwds != NULL) { + if (kwds != nullptr) { PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function"); - if (sort_func != NULL) { + if (sort_func != nullptr) { // Must set before deleting as sort_func is a borrowed reference // and kwds might be the only thing keeping it alive. - if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1) - return NULL; - if (PyDict_DelItemString(kwds, "sort_function") == -1) - return NULL; + if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1) return nullptr; + if (PyDict_DelItemString(kwds, "sort_function") == -1) return nullptr; } } - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } ScopedPyObjectPtr m(PyObject_GetAttrString(list.get(), "sort")); - if (m == NULL) { - return NULL; + if (m == nullptr) { + return nullptr; } ScopedPyObjectPtr res(PyObject_Call(m.get(), args, kwds)); - if (res == NULL) { - return NULL; + if (res == nullptr) { + return nullptr; + } + int ret = InternalAssignRepeatedField( + reinterpret_cast(pself), list.get()); + if (ret < 0) { + return nullptr; + } + Py_RETURN_NONE; +} + +static PyObject* Reverse(PyObject* pself) { + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; + } + ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); + if (list == nullptr) { + return nullptr; + } + ScopedPyObjectPtr res(PyObject_CallMethod(list.get(), "reverse", nullptr)); + if (res == nullptr) { + return nullptr; } int ret = InternalAssignRepeatedField( reinterpret_cast(pself), list.get()); if (ret < 0) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -637,27 +650,27 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { static PyObject* Pop(PyObject* pself, PyObject* args) { Py_ssize_t index = -1; if (!PyArg_ParseTuple(args, "|n", &index)) { - return NULL; + return nullptr; } PyObject* item = Item(pself, index); - if (item == NULL) { + if (item == nullptr) { PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); - return NULL; + return nullptr; } - if (AssignItem(pself, index, NULL) < 0) { - return NULL; + if (AssignItem(pself, index, nullptr) < 0) { + return nullptr; } return item; } static PyObject* ToStr(PyObject* pself) { - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } return PyObject_Repr(list.get()); } @@ -670,13 +683,13 @@ static PyObject* MergeFrom(PyObject* pself, PyObject* arg) { RepeatedScalarContainer* NewContainer( CMessage* parent, const FieldDescriptor* parent_field_descriptor) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } RepeatedScalarContainer* self = reinterpret_cast( PyType_GenericAlloc(&RepeatedScalarContainer_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -696,81 +709,81 @@ static void Dealloc(PyObject* pself) { } static PySequenceMethods SqMethods = { - Len, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - Item, /* sq_item */ - 0, /* sq_slice */ - AssignItem /* sq_ass_item */ + Len, /* sq_length */ + nullptr, /* sq_concat */ + nullptr, /* sq_repeat */ + Item, /* sq_item */ + nullptr, /* sq_slice */ + AssignItem /* sq_ass_item */ }; static PyMappingMethods MpMethods = { - Len, /* mp_length */ - Subscript, /* mp_subscript */ - AssSubscript, /* mp_ass_subscript */ + Len, /* mp_length */ + Subscript, /* mp_subscript */ + AssSubscript, /* mp_ass_subscript */ }; static PyMethodDef Methods[] = { - { "__deepcopy__", DeepCopy, METH_VARARGS, - "Makes a deep copy of the class." }, - { "__reduce__", Reduce, METH_NOARGS, - "Outputs picklable representation of the repeated field." }, - { "append", AppendMethod, METH_O, - "Appends an object to the repeated container." }, - { "extend", ExtendMethod, METH_O, - "Appends objects to the repeated container." }, - { "insert", Insert, METH_VARARGS, - "Inserts an object at the specified position in the container." }, - { "pop", Pop, METH_VARARGS, - "Removes an object from the repeated container and returns it." }, - { "remove", Remove, METH_O, - "Removes an object from the repeated container." }, - { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS, - "Sorts the repeated container."}, - { "MergeFrom", (PyCFunction)MergeFrom, METH_O, - "Merges a repeated container into the current container." }, - { NULL, NULL } -}; + {"__deepcopy__", DeepCopy, METH_VARARGS, "Makes a deep copy of the class."}, + {"__reduce__", Reduce, METH_NOARGS, + "Outputs picklable representation of the repeated field."}, + {"append", AppendMethod, METH_O, + "Appends an object to the repeated container."}, + {"extend", ExtendMethod, METH_O, + "Appends objects to the repeated container."}, + {"insert", Insert, METH_VARARGS, + "Inserts an object at the specified position in the container."}, + {"pop", Pop, METH_VARARGS, + "Removes an object from the repeated container and returns it."}, + {"remove", Remove, METH_O, + "Removes an object from the repeated container."}, + {"sort", reinterpret_cast(Sort), METH_VARARGS | METH_KEYWORDS, + "Sorts the repeated container."}, + {"reverse", reinterpret_cast(Reverse), METH_NOARGS, + "Reverses elements order of the repeated container."}, + {"MergeFrom", static_cast(MergeFrom), METH_O, + "Merges a repeated container into the current container."}, + {nullptr, nullptr}}; } // namespace repeated_scalar_container PyTypeObject RepeatedScalarContainer_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".RepeatedScalarContainer", // tp_name - sizeof(RepeatedScalarContainer), // tp_basicsize - 0, // tp_itemsize - repeated_scalar_container::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - repeated_scalar_container::ToStr, // tp_repr - 0, // tp_as_number - &repeated_scalar_container::SqMethods, // tp_as_sequence - &repeated_scalar_container::MpMethods, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Repeated scalar container", // tp_doc - 0, // tp_traverse - 0, // tp_clear - repeated_scalar_container::RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - repeated_scalar_container::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".RepeatedScalarContainer", // tp_name + sizeof(RepeatedScalarContainer), // tp_basicsize + 0, // tp_itemsize + repeated_scalar_container::Dealloc, // tp_dealloc + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + repeated_scalar_container::ToStr, // tp_repr + nullptr, // tp_as_number + &repeated_scalar_container::SqMethods, // tp_as_sequence + &repeated_scalar_container::MpMethods, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Repeated scalar container", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + repeated_scalar_container::RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + repeated_scalar_container::Methods, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; } // namespace python diff --git a/python/protobuf_distutils/protobuf_distutils/__init__.py b/python/protobuf_distutils/protobuf_distutils/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py b/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py new file mode 100644 index 000000000000..515ded2334e3 --- /dev/null +++ b/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py @@ -0,0 +1,147 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Implements the generate_py_protobufs command.""" + +__author__ = 'dlj@google.com (David L. Jones)' + +import glob +import sys +import os +import distutils.spawn as spawn +from distutils.cmd import Command +from distutils.errors import DistutilsOptionError, DistutilsExecError + +class generate_py_protobufs(Command): + """Generates Python sources for .proto files.""" + + description = 'Generate Python sources for .proto files' + user_options = [ + ('extra-proto-paths=', None, + 'Additional paths to resolve imports in .proto files.'), + + ('protoc=', None, + 'Path to a specific `protoc` command to use.'), + ] + boolean_options = ['recurse'] + + def initialize_options(self): + """Sets the defaults for the command options.""" + self.source_dir = None + self.proto_root_path = None + self.extra_proto_paths = [] + self.output_dir = '.' + self.proto_files = None + self.recurse = True + self.protoc = None + + def finalize_options(self): + """Sets the final values for the command options. + + Defaults were set in `initialize_options`, but could have been changed + by command-line options or by other commands. + """ + self.ensure_dirname('source_dir') + self.ensure_string_list('extra_proto_paths') + + if self.output_dir is None: + self.output_dir = '.' + self.ensure_dirname('output_dir') + + # SUBTLE: if 'source_dir' is a subdirectory of any entry in + # 'extra_proto_paths', then in general, the shortest --proto_path prefix + # (and the longest relative .proto filenames) must be used for + # correctness. For example, consider: + # + # source_dir = 'a/b/c' + # extra_proto_paths = ['a/b', 'x/y'] + # + # In this case, we must ensure that a/b/c/d/foo.proto resolves + # canonically as c/d/foo.proto, not just d/foo.proto. Otherwise, this + # import: + # + # import "c/d/foo.proto"; + # + # would result in different FileDescriptor.name keys from "d/foo.proto". + # That will cause all the definitions in the file to be flagged as + # duplicates, with an error similar to: + # + # c/d/foo.proto: "packagename.MessageName" is already defined in file "d/foo.proto" + # + # For paths in self.proto_files, we transform them to be relative to + # self.proto_root_path, which may be different from self.source_dir. + # + # Although the order of --proto_paths is significant, shadowed filenames + # are errors: if 'a/b/c.proto' resolves to different files under two + # different --proto_path arguments, then the path is rejected as an + # error. (Implementation note: this is enforced in protoc's + # DiskSourceTree class.) + + if self.proto_root_path is None: + self.proto_root_path = os.path.normpath(self.source_dir) + for root_candidate in self.extra_proto_paths: + root_candidate = os.path.normpath(root_candidate) + if self.proto_root_path.startswith(root_candidate): + self.proto_root_path = root_candidate + if self.proto_root_path != self.source_dir: + self.announce('using computed proto_root_path: ' + self.proto_root_path, level=2) + + if not self.source_dir.startswith(self.proto_root_path): + raise DistutilsOptionError('source_dir ' + self.source_dir + + ' is not under proto_root_path ' + self.proto_root_path) + + if self.proto_files is None: + files = glob.glob(os.path.join(self.source_dir, '*.proto')) + if self.recurse: + files.extend(glob.glob(os.path.join(self.source_dir, '**', '*.proto'))) + self.proto_files = [f.partition(self.proto_root_path + os.path.sep)[-1] for f in files] + if not self.proto_files: + raise DistutilsOptionError('no .proto files were found under ' + self.source_dir) + + self.ensure_string_list('proto_files') + + if self.protoc is None: + self.protoc = os.getenv('PROTOC') + if self.protoc is None: + self.protoc = spawn.find_executable('protoc') + + def run(self): + # All proto file paths were adjusted in finalize_options to be relative + # to self.proto_root_path. + proto_paths = ['--proto_path=' + self.proto_root_path] + proto_paths.extend(['--proto_path=' + x for x in self.extra_proto_paths]) + + # Run protoc. It was already resolved, so don't try to resolve + # through PATH. + spawn.spawn( + [self.protoc, + '--python_out=' + self.output_dir, + ] + proto_paths + self.proto_files, + search_path=0) diff --git a/python/protobuf_distutils/setup.py b/python/protobuf_distutils/setup.py new file mode 100644 index 000000000000..96259a91e0cc --- /dev/null +++ b/python/protobuf_distutils/setup.py @@ -0,0 +1,77 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Setuptools/distutils extension for generating Python protobuf code.""" + +__author__ = 'dlj@google.com (David L. Jones)' + +from os import path +from setuptools import setup, find_packages + +# Use README.md as the source for long_description. +this_directory = path.abspath(path.dirname(__file__)) +with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: + _readme = f.read() + +setup( + name='protobuf_distutils', + version='1.0', + packages=find_packages(), + maintainer='protobuf@googlegroups.com', + maintainer_email='protobuf@googlegroups.com', + license='3-Clause BSD License', + classifiers=[ + "Framework :: Setuptools Plugin", + "Operating System :: OS Independent", + # These Python versions should match the protobuf package: + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Topic :: Software Development :: Code Generators", + ], + description=('This is a distutils extension to generate Python code for ' + '.proto files using an installed protoc binary.'), + long_description=_readme, + long_description_content_type='text/markdown', + url='https://github.com/protocolbuffers/protobuf/', + entry_points={ + 'distutils.commands': [ + ('generate_py_protobufs = ' + 'protobuf_distutils.generate_py_protobufs:generate_py_protobufs'), + ], + }, +) diff --git a/python/release.sh b/python/release.sh index 6db87f0bb20e..fc88b08e3eee 100755 --- a/python/release.sh +++ b/python/release.sh @@ -80,11 +80,11 @@ fi cd python # Run tests locally. -python setup.py build -python setup.py test +python3 setup.py build +python3 setup.py test # Deploy source package to testing PyPI -python setup.py sdist +python3 setup.py sdist twine upload --skip-existing -r testpypi -u protobuf-wheel-test dist/* # Test locally with different python versions. @@ -92,7 +92,7 @@ run_install_test ${TESTING_VERSION} python2.7 https://test.pypi.org/simple run_install_test ${TESTING_VERSION} python3 https://test.pypi.org/simple # Deploy egg/wheel packages to testing PyPI and test again. -python setup.py clean build bdist_wheel +python3 setup.py clean build bdist_wheel twine upload --skip-existing -r testpypi -u protobuf-wheel-test dist/* run_install_test ${TESTING_VERSION} python2.7 https://test.pypi.org/simple @@ -109,14 +109,14 @@ if [ $TESTING_ONLY -eq 0 ]; then echo "Publishing to PyPI..." # Be sure to run build before sdist, because otherwise sdist will not include # well-known types. - python setup.py clean build sdist + python3 setup.py clean build sdist twine upload --skip-existing -u protobuf-packages dist/* # Be sure to run clean before bdist_xxx, because otherwise bdist_xxx will # include files you may not want in the package. E.g., if you have built # and tested with --cpp_implemenation, bdist_xxx will include the _message.so # file even when you no longer pass the --cpp_implemenation flag. See: # https://github.com/protocolbuffers/protobuf/issues/3042 - python setup.py clean build bdist_wheel + python3 setup.py clean build bdist_wheel twine upload --skip-existing -u protobuf-packages dist/* else # Set the version number back (i.e., remove dev suffix). diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index 21528fe4c31e..1a18da3e952c 100644 --- a/ruby/google-protobuf.gemspec +++ b/ruby/google-protobuf.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "google-protobuf" - s.version = "3.13.0" + s.version = "3.14.0" git_tag = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag s.licenses = ["BSD-3-Clause"] s.summary = "Protocol Buffers" diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc index d22d64d2e347..029ba0d9299d 100644 --- a/src/google/protobuf/any.cc +++ b/src/google/protobuf/any.cc @@ -41,17 +41,17 @@ namespace google { namespace protobuf { namespace internal { -void AnyMetadata::PackFrom(const Message& message) { - PackFrom(message, kTypeGoogleApisComPrefix); +bool AnyMetadata::PackFrom(const Message& message) { + return PackFrom(message, kTypeGoogleApisComPrefix); } -void AnyMetadata::PackFrom(const Message& message, +bool AnyMetadata::PackFrom(const Message& message, StringPiece type_url_prefix) { type_url_->Set( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(), GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), nullptr); - message.SerializeToString( + return message.SerializeToString( value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr)); } @@ -80,3 +80,5 @@ bool GetAnyFieldDescriptors(const Message& message, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h index e8f2cacf16c6..684fbf158431 100644 --- a/src/google/protobuf/any.h +++ b/src/google/protobuf/any.h @@ -65,12 +65,14 @@ class PROTOBUF_EXPORT AnyMetadata { // Packs a message using the default type URL prefix: "type.googleapis.com". // The resulted type URL will be "type.googleapis.com/". + // Returns false if serializing the message failed. template - void PackFrom(const T& message) { - InternalPackFrom(message, kTypeGoogleApisComPrefix, T::FullMessageName()); + bool PackFrom(const T& message) { + return InternalPackFrom(message, kTypeGoogleApisComPrefix, + T::FullMessageName()); } - void PackFrom(const Message& message); + bool PackFrom(const Message& message); // Packs a message using the given type URL prefix. The type URL will be // constructed by concatenating the message type's full name to the prefix @@ -78,12 +80,13 @@ class PROTOBUF_EXPORT AnyMetadata { // For example, both PackFrom(message, "type.googleapis.com") and // PackFrom(message, "type.googleapis.com/") yield the same result type // URL: "type.googleapis.com/". + // Returns false if serializing the message failed. template - void PackFrom(const T& message, StringPiece type_url_prefix) { - InternalPackFrom(message, type_url_prefix, T::FullMessageName()); + bool PackFrom(const T& message, StringPiece type_url_prefix) { + return InternalPackFrom(message, type_url_prefix, T::FullMessageName()); } - void PackFrom(const Message& message, StringPiece type_url_prefix); + bool PackFrom(const Message& message, StringPiece type_url_prefix); // Unpacks the payload into the given message. Returns false if the message's // type doesn't match the type specified in the type URL (i.e., the full @@ -105,7 +108,7 @@ class PROTOBUF_EXPORT AnyMetadata { } private: - void InternalPackFrom(const MessageLite& message, + bool InternalPackFrom(const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name); bool InternalUnpackTo(StringPiece type_name, diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 79acf7b735ec..c421045fba98 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class AnyDefaultTypeInternal { public: @@ -76,7 +78,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fany_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -169,7 +171,6 @@ void Any::Clear() { const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 7c732564a674..ddf418bd5357 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -110,12 +110,12 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL : // implements Any ----------------------------------------------- - void PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) { - _any_metadata_.PackFrom(message); + bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) { + return _any_metadata_.PackFrom(message); } - void PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message, + bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message, ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { - _any_metadata_.PackFrom(message, type_url_prefix); + return _any_metadata_.PackFrom(message, type_url_prefix); } bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const { return _any_metadata_.UnpackTo(message); @@ -125,13 +125,13 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL : const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field); template ::value>::type> - void PackFrom(const T& message) { - _any_metadata_.PackFrom(message); + bool PackFrom(const T& message) { + return _any_metadata_.PackFrom(message); } template ::value>::type> - void PackFrom(const T& message, + bool PackFrom(const T& message, ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { - _any_metadata_.PackFrom(message, type_url_prefix);} + return _any_metadata_.PackFrom(message, type_url_prefix);} template ::value>::type> bool UnpackTo(T* message) const { return _any_metadata_.UnpackTo(message); diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index ffb26921359c..55b55ee18abb 100644 --- a/src/google/protobuf/any_lite.cc +++ b/src/google/protobuf/any_lite.cc @@ -53,12 +53,12 @@ const char kAnyFullTypeName[] = "google.protobuf.Any"; const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/"; const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/"; -void AnyMetadata::InternalPackFrom(const MessageLite& message, +bool AnyMetadata::InternalPackFrom(const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name) { type_url_->Set(&::google::protobuf::internal::GetEmptyString(), GetTypeUrl(type_name, type_url_prefix), nullptr); - message.SerializeToString( + return message.SerializeToString( value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr)); } diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc index 8aeab7602b81..1d136aa5575a 100644 --- a/src/google/protobuf/any_test.cc +++ b/src/google/protobuf/any_test.cc @@ -49,7 +49,7 @@ TEST(AnyTest, TestPackAndUnpack) { protobuf_unittest::TestAny submessage; submessage.set_int32_value(12345); protobuf_unittest::TestAny message; - message.mutable_any_value()->PackFrom(submessage); + ASSERT_TRUE(message.mutable_any_value()->PackFrom(submessage)); std::string data = message.SerializeAsString(); @@ -60,6 +60,13 @@ TEST(AnyTest, TestPackAndUnpack) { EXPECT_EQ(12345, submessage.int32_value()); } +TEST(AnyTest, TestPackFromSerializationExceedsSizeLimit) { + protobuf_unittest::TestAny submessage; + submessage.mutable_text()->resize(INT_MAX, 'a'); + protobuf_unittest::TestAny message; + EXPECT_FALSE(message.mutable_any_value()->PackFrom(submessage)); +} + TEST(AnyTest, TestUnpackWithTypeMismatch) { protobuf_unittest::TestAny payload; payload.set_int32_value(13); @@ -173,3 +180,5 @@ TEST(AnyTest, MoveAssignment) { } // namespace } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/any_test.proto b/src/google/protobuf/any_test.proto index 0c5b30ba3e4a..256035b4467d 100644 --- a/src/google/protobuf/any_test.proto +++ b/src/google/protobuf/any_test.proto @@ -34,8 +34,11 @@ package protobuf_unittest; import "google/protobuf/any.proto"; +option java_outer_classname = "TestAnyProto"; + message TestAny { int32 int32_value = 1; google.protobuf.Any any_value = 2; repeated google.protobuf.Any repeated_any_value = 3; + string text = 4; } diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 17c8e3309dc6..7ee673a527a7 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Method_google_2fprotobuf_2fapi_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Mixin_google_2fprotobuf_2fapi_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto; @@ -164,7 +166,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -225,8 +227,9 @@ void Api::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Api_google_2fprotobuf_2fapi_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&source_context_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&source_context_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&source_context_)) + sizeof(syntax_)); } @@ -279,7 +282,6 @@ void Api::Clear() { const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -638,8 +640,9 @@ void Method::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&request_streaming_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&request_streaming_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&request_streaming_)) + sizeof(syntax_)); } @@ -689,7 +692,6 @@ void Method::Clear() { const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1065,7 +1067,6 @@ void Mixin::Clear() { const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 414e0234f75c..d4779a2c6c80 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -32,10 +32,14 @@ #include #include +#include +#include #include +#include -#include +#include +#include #ifdef ADDRESS_SANITIZER #include #endif // ADDRESS_SANITIZER @@ -47,370 +51,388 @@ static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit. namespace google { namespace protobuf { +namespace internal { -PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)( - size_t) = &::operator new; +static SerialArena::Memory AllocateMemory(const AllocationPolicy* policy_ptr, + size_t last_size, size_t min_bytes) { + AllocationPolicy policy; // default policy + if (policy_ptr) policy = *policy_ptr; + size_t size; + if (last_size != 0) { + // Double the current block size, up to a limit. + auto max_size = policy.max_block_size; + size = std::min(2 * last_size, max_size); + } else { + size = policy.start_block_size; + } + // Verify that min_bytes + kBlockHeaderSize won't overflow. + GOOGLE_CHECK_LE(min_bytes, + std::numeric_limits::max() - SerialArena::kBlockHeaderSize); + size = std::max(size, SerialArena::kBlockHeaderSize + min_bytes); -namespace internal { + void* mem; + if (policy.block_alloc == nullptr) { + mem = ::operator new(size); + } else { + mem = policy.block_alloc(size); + } + return {mem, size}; +} + +class GetDeallocator { + public: + GetDeallocator(const AllocationPolicy* policy, size_t* space_allocated) + : dealloc_(policy ? policy->block_dealloc : nullptr), + space_allocated_(space_allocated) {} + + void operator()(SerialArena::Memory mem) const { +#ifdef ADDRESS_SANITIZER + // This memory was provided by the underlying allocator as unpoisoned, + // so return it in an unpoisoned state. + ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size); +#endif // ADDRESS_SANITIZER + if (dealloc_) { + dealloc_(mem.ptr, mem.size); + } else { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(mem.ptr, mem.size); +#else + ::operator delete(mem.ptr); +#endif + } + *space_allocated_ += mem.size; + } + + private: + void (*dealloc_)(void*, size_t); + size_t* space_allocated_; +}; + +SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size) { + owner_ = owner; + head_ = b; + ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize); + limit_ = b->Pointer(b->size & static_cast(-8)); +} + +SerialArena* SerialArena::New(Memory mem, void* owner) { + GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size); + + auto b = new (mem.ptr) Block{nullptr, mem.size}; + return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner); +} + +template +SerialArena::Memory SerialArena::Free(Deallocator deallocator) { + Block* b = head_; + Memory mem = {b, b->size}; + while (b->next) { + b = b->next; // We must first advance before deleting this block + deallocator(mem); + mem = {b, b->size}; + } + return mem; +} + +PROTOBUF_NOINLINE +std::pair +SerialArena::AllocateAlignedWithCleanupFallback( + size_t n, const AllocationPolicy* policy) { + AllocateNewBlock(n + kCleanupSize, policy); + return AllocateAlignedWithCleanup(n, policy); +} + +PROTOBUF_NOINLINE +void* SerialArena::AllocateAlignedFallback(size_t n, + const AllocationPolicy* policy) { + AllocateNewBlock(n, policy); + return AllocateAligned(n, policy); +} + +void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { + // Sync limit to block + head_->start = reinterpret_cast(limit_); + + // Record how much used in this block. + space_used_ += ptr_ - head_->Pointer(kBlockHeaderSize); + + auto mem = AllocateMemory(policy, head_->size, n); + // We don't want to emit an expensive RMW instruction that requires + // exclusive access to a cacheline. Hence we write it in terms of a + // regular add. + auto relaxed = std::memory_order_relaxed; + space_allocated_.store(space_allocated_.load(relaxed) + mem.size, relaxed); + head_ = new (mem.ptr) Block{head_, mem.size}; + ptr_ = head_->Pointer(kBlockHeaderSize); + limit_ = head_->Pointer(head_->size); + +#ifdef ADDRESS_SANITIZER + ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_); +#endif // ADDRESS_SANITIZER +} + +uint64 SerialArena::SpaceUsed() const { + uint64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize); + space_used += space_used_; + // Remove the overhead of the SerialArena itself. + space_used -= ThreadSafeArena::kSerialArenaSize; + return space_used; +} +void SerialArena::CleanupList() { + Block* b = head_; + b->start = reinterpret_cast(limit_); + do { + auto* limit = reinterpret_cast( + b->Pointer(b->size & static_cast(-8))); + auto it = b->start; + auto num = limit - it; + if (num > 0) { + for (; it < limit; it++) { + it->cleanup(it->elem); + } + } + b = b->next; + } while (b); +} -ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_; + +ThreadSafeArena::CacheAlignedLifecycleIdGenerator + ThreadSafeArena::lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) -ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { +ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() { static internal::ThreadLocalStorage* thread_cache_ = new internal::ThreadLocalStorage(); return *thread_cache_->Get(); } #elif defined(PROTOBUF_USE_DLLS) -ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { +ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() { static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = { 0, static_cast(-1), nullptr}; return thread_cache_; } #else -PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = { - 0, static_cast(-1), nullptr}; +PROTOBUF_THREAD_LOCAL ThreadSafeArena::ThreadCache + ThreadSafeArena::thread_cache_ = {0, static_cast(-1), + nullptr}; #endif -void ArenaFree(void* object, size_t size) { -#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) - ::operator delete(object, size); -#else - (void)size; - ::operator delete(object); -#endif -} - -ArenaImpl::ArenaImpl(const ArenaOptions& options) { - ArenaMetricsCollector* collector = nullptr; - bool record_allocs = false; - if (options.make_metrics_collector != nullptr) { - collector = (*options.make_metrics_collector)(); - record_allocs = (collector && collector->RecordAllocs()); - } +void ThreadSafeArena::InitializeFrom(void* mem, size_t size) { + GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0u); + Init(false); - // Get memory where we can store non-default options if needed. - // Use supplied initial_block if it is large enough. - size_t min_block_size = kOptionsSize + kBlockHeaderSize + kSerialArenaSize; - char* mem = options.initial_block; - size_t mem_size = options.initial_block_size; - GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0); - if (mem == nullptr || mem_size < min_block_size) { - // Supplied initial block is not big enough. - mem_size = std::max(min_block_size, options.start_block_size); - mem = reinterpret_cast((*options.block_alloc)(mem_size)); + // Ignore initial block if it is too small. + if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) { + alloc_policy_ |= kUserOwnedInitialBlock; + SetInitialBlock(mem, size); } +} - // Create the special block. - const bool special = true; - const bool user_owned = (mem == options.initial_block); - auto block = - new (mem) SerialArena::Block(mem_size, nullptr, special, user_owned); - - // Options occupy the beginning of the initial block. - options_ = new (block->Pointer(block->pos())) Options; -#ifdef ADDRESS_SANITIZER - ASAN_UNPOISON_MEMORY_REGION(options_, kOptionsSize); -#endif // ADDRESS_SANITIZER - options_->start_block_size = options.start_block_size; - options_->max_block_size = options.max_block_size; - options_->block_alloc = options.block_alloc; - options_->block_dealloc = options.block_dealloc; - options_->metrics_collector = collector; - block->set_pos(block->pos() + kOptionsSize); +void ThreadSafeArena::InitializeWithPolicy(void* mem, size_t size, + bool record_allocs, + AllocationPolicy policy) { + GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0u); Init(record_allocs); - SetInitialBlock(block); + + // Ignore initial block if it is too small. We include an optional + // AllocationPolicy in this check, so that this can be allocated on the + // first block. + constexpr size_t kAPSize = internal::AlignUpTo8(sizeof(AllocationPolicy)); + constexpr size_t kMinimumSize = kBlockHeaderSize + kSerialArenaSize + kAPSize; + if (mem != nullptr && size >= kMinimumSize) { + alloc_policy_ = kUserOwnedInitialBlock; + } else { + alloc_policy_ = 0; + auto tmp = AllocateMemory(&policy, 0, kMinimumSize); + mem = tmp.ptr; + size = tmp.size; + } + SetInitialBlock(mem, size); + + auto sa = threads_.load(std::memory_order_relaxed); + // We ensured enough space so this cannot fail. + void* p; + if (!sa || !sa->MaybeAllocateAligned(kAPSize, &p)) { + GOOGLE_LOG(FATAL) << "MaybeAllocateAligned cannot fail here."; + return; + } + new (p) AllocationPolicy{policy}; + alloc_policy_ |= reinterpret_cast(p); } -void ArenaImpl::Init(bool record_allocs) { +void ThreadSafeArena::Init(bool record_allocs) { ThreadCache& tc = thread_cache(); auto id = tc.next_lifecycle_id; - constexpr uint64 kInc = ThreadCache::kPerThreadIds * 2; + // We increment lifecycle_id's by multiples of two so we can use bit 0 as + // a tag. + constexpr uint64 kDelta = 2; + constexpr uint64 kInc = ThreadCache::kPerThreadIds * kDelta; if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) { - if (sizeof(lifecycle_id_generator_.id) == 4) { - // 2^32 is dangerous low to guarantee uniqueness. If we start dolling out - // unique id's in ranges of kInc it's unacceptably low. In this case - // we increment by 1. The additional range of kPerThreadIds that are used - // per thread effectively pushes the overflow time from weeks to years - // of continuous running. - id = lifecycle_id_generator_.id.fetch_add(1, std::memory_order_relaxed) * - kInc; - } else { - id = - lifecycle_id_generator_.id.fetch_add(kInc, std::memory_order_relaxed); - } + constexpr auto relaxed = std::memory_order_relaxed; + // On platforms that don't support uint64 atomics we can certainly not + // afford to increment by large intervals and expect uniqueness due to + // wrapping, hence we only add by 1. + id = lifecycle_id_generator_.id.fetch_add(1, relaxed) * kInc; } - tc.next_lifecycle_id = id + 2; - // We store "record_allocs" in the low bit of lifecycle_id_. - lifecycle_id_ = id | (record_allocs ? 1 : 0); + tc.next_lifecycle_id = id + kDelta; + tag_and_id_ = id | (record_allocs ? kRecordAllocs : 0); hint_.store(nullptr, std::memory_order_relaxed); threads_.store(nullptr, std::memory_order_relaxed); - space_allocated_.store(0, std::memory_order_relaxed); } -void ArenaImpl::SetInitialBlock(SerialArena::Block* block) { - // Calling thread owns the first block. This allows the single-threaded case - // to allocate on the first block without having to perform atomic operations. - SerialArena* serial = SerialArena::New(block, &thread_cache(), this); +void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) { + SerialArena* serial = SerialArena::New({mem, size}, &thread_cache()); serial->set_next(NULL); threads_.store(serial, std::memory_order_relaxed); - space_allocated_.store(block->size(), std::memory_order_relaxed); CacheSerialArena(serial); } -ArenaImpl::~ArenaImpl() { +ThreadSafeArena::~ThreadSafeArena() { // Have to do this in a first pass, because some of the destructors might // refer to memory in other blocks. CleanupList(); - ArenaMetricsCollector* collector = nullptr; - auto deallocator = &ArenaFree; - if (options_) { - collector = options_->metrics_collector; - deallocator = options_->block_dealloc; - } + size_t space_allocated = 0; + auto mem = Free(&space_allocated); - PerBlock([deallocator](SerialArena::Block* b) { -#ifdef ADDRESS_SANITIZER - // This memory was provided by the underlying allocator as unpoisoned, so - // return it in an unpoisoned state. - ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); -#endif // ADDRESS_SANITIZER - if (!b->user_owned()) { - (*deallocator)(b, b->size()); - } - }); + // Policy is about to get deleted. + auto p = AllocPolicy(); + ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr; - if (collector) { - collector->OnDestroy(SpaceAllocated()); + if (alloc_policy_ & kUserOwnedInitialBlock) { + space_allocated += mem.size; + } else { + GetDeallocator(AllocPolicy(), &space_allocated)(mem); } + + if (collector) collector->OnDestroy(space_allocated); } -uint64 ArenaImpl::Reset() { - if (options_ && options_->metrics_collector) { - options_->metrics_collector->OnReset(SpaceAllocated()); - } +SerialArena::Memory ThreadSafeArena::Free(size_t* space_allocated) { + SerialArena::Memory mem = {nullptr, 0}; + auto deallocator = GetDeallocator(AllocPolicy(), space_allocated); + PerSerialArena([deallocator, &mem](SerialArena* a) { + if (mem.ptr) deallocator(mem); + mem = a->Free(deallocator); + }); + return mem; +} +uint64 ThreadSafeArena::Reset() { // Have to do this in a first pass, because some of the destructors might // refer to memory in other blocks. CleanupList(); // Discard all blocks except the special block (if present). - uint64 space_allocated = 0; - SerialArena::Block* special_block = nullptr; - auto deallocator = (options_ ? options_->block_dealloc : &ArenaFree); - PerBlock( - [&space_allocated, &special_block, deallocator](SerialArena::Block* b) { - space_allocated += b->size(); -#ifdef ADDRESS_SANITIZER - // This memory was provided by the underlying allocator as unpoisoned, - // so return it in an unpoisoned state. - ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); -#endif // ADDRESS_SANITIZER - if (!b->special()) { - (*deallocator)(b, b->size()); - } else { - // Prepare special block for reuse. - // Note: if options_ is present, it occupies the beginning of the - // block and therefore pos is advanced past it. - GOOGLE_DCHECK(special_block == nullptr); - special_block = b; - } - }); - - Init(record_allocs()); - if (special_block != nullptr) { - // next() should still be nullptr since we are using a stack discipline, but - // clear it anyway to reduce fragility. - GOOGLE_DCHECK_EQ(special_block->next(), nullptr); - special_block->clear_next(); - special_block->set_pos(kBlockHeaderSize + (options_ ? kOptionsSize : 0)); - SetInitialBlock(special_block); - } - return space_allocated; -} + size_t space_allocated = 0; + auto mem = Free(&space_allocated); -std::pair ArenaImpl::NewBuffer(size_t last_size, - size_t min_bytes) { - size_t size; - if (last_size != -1) { - // Double the current block size, up to a limit. - auto max_size = options_ ? options_->max_block_size : kDefaultMaxBlockSize; - size = std::min(2 * last_size, max_size); + if (AllocPolicy()) { + auto saved_policy = *AllocPolicy(); + if (alloc_policy_ & kUserOwnedInitialBlock) { + space_allocated += mem.size; + } else { + GetDeallocator(AllocPolicy(), &space_allocated)(mem); + mem.ptr = nullptr; + mem.size = 0; + } + ArenaMetricsCollector* collector = saved_policy.metrics_collector; + if (collector) collector->OnReset(space_allocated); + InitializeWithPolicy(mem.ptr, mem.size, ShouldRecordAlloc(), saved_policy); } else { - size = options_ ? options_->start_block_size : kDefaultStartBlockSize; + // Nullptr policy + if (alloc_policy_ & kUserOwnedInitialBlock) { + space_allocated += mem.size; + InitializeFrom(mem.ptr, mem.size); + } else { + GetDeallocator(AllocPolicy(), &space_allocated)(mem); + Init(false); + } } - // Verify that min_bytes + kBlockHeaderSize won't overflow. - GOOGLE_CHECK_LE(min_bytes, std::numeric_limits::max() - kBlockHeaderSize); - size = std::max(size, kBlockHeaderSize + min_bytes); - void* mem = options_ ? (*options_->block_alloc)(size) : ::operator new(size); - space_allocated_.fetch_add(size, std::memory_order_relaxed); - return {mem, size}; -} - -SerialArena::Block* SerialArena::NewBlock(SerialArena::Block* last_block, - size_t min_bytes, ArenaImpl* arena) { - void* mem; - size_t size; - std::tie(mem, size) = - arena->NewBuffer(last_block ? last_block->size() : -1, min_bytes); - Block* b = new (mem) Block(size, last_block, false, false); - return b; -} - -PROTOBUF_NOINLINE -void SerialArena::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { - size_t size = cleanup_ ? cleanup_->size * 2 : kMinCleanupListElements; - size = std::min(size, kMaxCleanupListElements); - size_t bytes = internal::AlignUpTo8(CleanupChunk::SizeOf(size)); - CleanupChunk* list = reinterpret_cast(AllocateAligned(bytes)); - list->next = cleanup_; - list->size = size; - - cleanup_ = list; - cleanup_ptr_ = &list->nodes[0]; - cleanup_limit_ = &list->nodes[size]; - - AddCleanup(elem, cleanup); + return space_allocated; } -void* ArenaImpl::AllocateAlignedAndAddCleanup(size_t n, - void (*cleanup)(void*)) { +std::pair +ThreadSafeArena::AllocateAlignedWithCleanup(size_t n, + const std::type_info* type) { SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - return arena->AllocateAlignedAndAddCleanup(n, cleanup); + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(tag_and_id_, &arena))) { + return arena->AllocateAlignedWithCleanup(n, AllocPolicy()); } else { - return AllocateAlignedAndAddCleanupFallback(n, cleanup); + return AllocateAlignedWithCleanupFallback(n, type); } } -void ArenaImpl::AddCleanup(void* elem, void (*cleanup)(void*)) { +void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) { SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - arena->AddCleanup(elem, cleanup); + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(LifeCycleId(), &arena))) { + arena->AddCleanup(elem, cleanup, AllocPolicy()); } else { return AddCleanupFallback(elem, cleanup); } } PROTOBUF_NOINLINE -void* ArenaImpl::AllocateAlignedFallback(size_t n) { - return GetSerialArenaFallback(&thread_cache())->AllocateAligned(n); +void* ThreadSafeArena::AllocateAlignedFallback(size_t n, + const std::type_info* type) { + if (ShouldRecordAlloc()) { + RecordAlloc(type, n); + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(LifeCycleId(), &arena))) { + return arena->AllocateAligned(n, AllocPolicy()); + } + } + return GetSerialArenaFallback(&thread_cache()) + ->AllocateAligned(n, AllocPolicy()); } PROTOBUF_NOINLINE -void* ArenaImpl::AllocateAlignedAndAddCleanupFallback(size_t n, - void (*cleanup)(void*)) { - return GetSerialArenaFallback( - &thread_cache())->AllocateAlignedAndAddCleanup(n, cleanup); +std::pair +ThreadSafeArena::AllocateAlignedWithCleanupFallback( + size_t n, const std::type_info* type) { + if (ShouldRecordAlloc()) { + RecordAlloc(type, n); + SerialArena* arena; + if (GetSerialArenaFast(LifeCycleId(), &arena)) { + return arena->AllocateAlignedWithCleanup(n, AllocPolicy()); + } + } + return GetSerialArenaFallback(&thread_cache()) + ->AllocateAlignedWithCleanup(n, AllocPolicy()); } PROTOBUF_NOINLINE -void ArenaImpl::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { - GetSerialArenaFallback(&thread_cache())->AddCleanup(elem, cleanup); +void ThreadSafeArena::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { + GetSerialArenaFallback(&thread_cache()) + ->AddCleanup(elem, cleanup, AllocPolicy()); } -PROTOBUF_NOINLINE -void* SerialArena::AllocateAlignedFallback(size_t n) { - // Sync back to current's pos. - head_->set_pos(head_->size() - (limit_ - ptr_)); - - head_ = NewBlock(head_, n, arena_); - ptr_ = head_->Pointer(head_->pos()); - limit_ = head_->Pointer(head_->size()); - -#ifdef ADDRESS_SANITIZER - ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_); -#endif // ADDRESS_SANITIZER - - return AllocateAligned(n); -} - -uint64 ArenaImpl::SpaceAllocated() const { - return space_allocated_.load(std::memory_order_relaxed); -} - -uint64 ArenaImpl::SpaceUsed() const { +uint64 ThreadSafeArena::SpaceAllocated() const { SerialArena* serial = threads_.load(std::memory_order_acquire); - uint64 space_used = 0; + uint64 res = 0; for (; serial; serial = serial->next()) { - space_used += serial->SpaceUsed(); - } - // Remove the overhead of Options structure, if any. - if (options_) { - space_used -= kOptionsSize; + res += serial->SpaceAllocated(); } - return space_used; + return res; } -uint64 SerialArena::SpaceUsed() const { - // Get current block's size from ptr_ (since we can't trust head_->pos(). - uint64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize); - // Get subsequent block size from b->pos(). - for (Block* b = head_->next(); b; b = b->next()) { - space_used += (b->pos() - kBlockHeaderSize); - } - // Remove the overhead of the SerialArena itself. - space_used -= ArenaImpl::kSerialArenaSize; - return space_used; -} - -void ArenaImpl::CleanupList() { - // By omitting an Acquire barrier we ensure that any user code that doesn't - // properly synchronize Reset() or the destructor will throw a TSAN warning. - SerialArena* serial = threads_.load(std::memory_order_relaxed); - +uint64 ThreadSafeArena::SpaceUsed() const { + SerialArena* serial = threads_.load(std::memory_order_acquire); + uint64 space_used = 0; for (; serial; serial = serial->next()) { - serial->CleanupList(); - } -} - -void SerialArena::CleanupList() { - if (cleanup_ != NULL) { - CleanupListFallback(); + space_used += serial->SpaceUsed(); } + return space_used - (AllocPolicy() ? sizeof(AllocationPolicy) : 0); } -void SerialArena::CleanupListFallback() { - // The first chunk might be only partially full, so calculate its size - // from cleanup_ptr_. Subsequent chunks are always full, so use list->size. - size_t n = cleanup_ptr_ - &cleanup_->nodes[0]; - CleanupChunk* list = cleanup_; - while (true) { - CleanupNode* node = &list->nodes[0]; - // Cleanup newest elements first (allocated last). - for (size_t i = n; i > 0; i--) { - node[i - 1].cleanup(node[i - 1].elem); - } - list = list->next; - if (list == nullptr) { - break; - } - // All but the first chunk are always full. - n = list->size; - } -} - -SerialArena* SerialArena::New(Block* b, void* owner, ArenaImpl* arena) { - auto pos = b->pos(); - GOOGLE_DCHECK_LE(pos + ArenaImpl::kSerialArenaSize, b->size()); - SerialArena* serial = reinterpret_cast(b->Pointer(pos)); - b->set_pos(pos + ArenaImpl::kSerialArenaSize); - serial->arena_ = arena; - serial->owner_ = owner; - serial->head_ = b; - serial->ptr_ = b->Pointer(b->pos()); - serial->limit_ = b->Pointer(b->size()); - serial->cleanup_ = NULL; - serial->cleanup_ptr_ = NULL; - serial->cleanup_limit_ = NULL; - return serial; +void ThreadSafeArena::CleanupList() { + PerSerialArena([](SerialArena* a) { a->CleanupList(); }); } PROTOBUF_NOINLINE -SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { +SerialArena* ThreadSafeArena::GetSerialArenaFallback(void* me) { // Look for this SerialArena in our linked list. SerialArena* serial = threads_.load(std::memory_order_acquire); for (; serial; serial = serial->next()) { @@ -422,8 +444,8 @@ SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { if (!serial) { // This thread doesn't have any SerialArena, which also means it doesn't // have any blocks yet. So we'll allocate its first block now. - SerialArena::Block* b = SerialArena::NewBlock(NULL, kSerialArenaSize, this); - serial = SerialArena::New(b, me, this); + serial = SerialArena::New( + AllocateMemory(AllocPolicy(), 0, kSerialArenaSize), me); SerialArena* head = threads_.load(std::memory_order_relaxed); do { @@ -436,14 +458,25 @@ SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { return serial; } -ArenaMetricsCollector::~ArenaMetricsCollector() {} - } // namespace internal PROTOBUF_FUNC_ALIGN(32) void* Arena::AllocateAlignedNoHook(size_t n) { - return impl_.AllocateAligned(n); + return impl_.AllocateAligned(n, nullptr); +} + +PROTOBUF_FUNC_ALIGN(32) +void* Arena::AllocateAlignedWithHook(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) { + return impl_.AllocateAlignedWithCleanup(n, type); } } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index f28bebfd3437..c2404429532c 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -93,11 +93,28 @@ class EpsCopyInputStream; // defined in parse_context.h template class GenericTypeHandler; // defined in repeated_field.h +PROTOBUF_ALWAYS_INLINE +inline void* AlignTo(void* ptr, size_t align) { + return reinterpret_cast( + (reinterpret_cast(ptr) + align - 1) & (~align + 1)); +} + // Templated cleanup methods. template void arena_destruct_object(void* object) { reinterpret_cast(object)->~T(); } + +template +struct ObjectDestructor { + constexpr static void (*destructor)(void*) = &arena_destruct_object; +}; + +template +struct ObjectDestructor { + constexpr static void (*destructor)(void*) = nullptr; +}; + template void arena_delete_object(void* object) { delete reinterpret_cast(object); @@ -138,34 +155,38 @@ struct ArenaOptions { void (*block_dealloc)(void*, size_t); ArenaOptions() - : start_block_size(kDefaultStartBlockSize), - max_block_size(kDefaultMaxBlockSize), + : start_block_size(internal::AllocationPolicy::kDefaultStartBlockSize), + max_block_size(internal::AllocationPolicy::kDefaultMaxBlockSize), initial_block(NULL), initial_block_size(0), - block_alloc(kDefaultBlockAlloc), - block_dealloc(&internal::ArenaFree), + block_alloc(nullptr), + block_dealloc(nullptr), make_metrics_collector(nullptr) {} - PROTOBUF_EXPORT static void* (*const kDefaultBlockAlloc)(size_t); - private: // If make_metrics_collector is not nullptr, it will be called at Arena init // time. It may return a pointer to a collector instance that will be notified // of interesting events related to the arena. internal::ArenaMetricsCollector* (*make_metrics_collector)(); - // Constants define default starting block size and max block size for - // arena allocator behavior -- see descriptions above. - static const size_t kDefaultStartBlockSize = - internal::ArenaImpl::kDefaultStartBlockSize; - static const size_t kDefaultMaxBlockSize = - internal::ArenaImpl::kDefaultMaxBlockSize; + internal::ArenaMetricsCollector* MetricsCollector() const { + return make_metrics_collector ? (*make_metrics_collector)() : nullptr; + } + + internal::AllocationPolicy AllocationPolicy() const { + internal::AllocationPolicy res; + res.start_block_size = start_block_size; + res.max_block_size = max_block_size; + res.block_alloc = block_alloc; + res.block_dealloc = block_dealloc; + res.metrics_collector = MetricsCollector(); + return res; + } friend void arena_metrics::EnableArenaMetrics(ArenaOptions*); friend class Arena; friend class ArenaOptionsTestFriend; - friend class internal::ArenaImpl; }; // Support for non-RTTI environments. (The metrics hooks API uses type @@ -236,7 +257,9 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // Arena constructor taking custom options. See ArenaOptions above for // descriptions of the options available. - explicit Arena(const ArenaOptions& options) : impl_(options) {} + explicit Arena(const ArenaOptions& options) + : impl_(options.initial_block, options.initial_block_size, + options.AllocationPolicy()) {} // Block overhead. Use this as a guide for how much to over-allocate the // initial block if you want an allocation of size N to fit inside it. @@ -244,8 +267,9 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // WARNING: if you allocate multiple objects, it is difficult to guarantee // that a series of allocations will fit in the initial block, especially if // Arena changes its alignment guarantees in the future! - static const size_t kBlockOverhead = internal::ArenaImpl::kBlockHeaderSize + - internal::ArenaImpl::kSerialArenaSize; + static const size_t kBlockOverhead = + internal::ThreadSafeArena::kBlockHeaderSize + + internal::ThreadSafeArena::kSerialArenaSize; inline ~Arena() {} @@ -290,8 +314,16 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // is obtained from the arena). template PROTOBUF_ALWAYS_INLINE static T* Create(Arena* arena, Args&&... args) { - return CreateNoMessage(arena, is_arena_constructable(), - std::forward(args)...); + if (arena == NULL) { + return new T(std::forward(args)...); + } else { + auto destructor = + internal::ObjectDestructor::value, + T>::destructor; + return new (arena->AllocateInternal(sizeof(T), alignof(T), destructor, + RTTI_TYPE_ID(T))) + T(std::forward(args)...); + } } // Create an array of object type T on the arena *without* invoking the @@ -316,9 +348,12 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { } } + // The following are routines are for monitoring. They will aproximate the + // total sum allocated and used memory, but the exact value is an + // implementation deal. For instance allocated space depends on growth + // policies. Do not use these in unit tests. // Returns the total space allocated by the arena, which is the sum of the - // sizes of the underlying blocks. This method is relatively fast; a counter - // is kept as blocks are allocated. + // sizes of the underlying blocks. uint64 SpaceAllocated() const { return impl_.SpaceAllocated(); } // Returns the total space used by the arena. Similar to SpaceAllocated but // does not include free space and block overhead. The total space returned @@ -336,8 +371,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // Adds |object| to a list of heap-allocated objects to be freed with |delete| // when the arena is destroyed or reset. template - PROTOBUF_NOINLINE void Own(T* object) { - OwnInternal(object, std::is_convertible()); + PROTOBUF_ALWAYS_INLINE void Own(T* object) { + OwnInternal(object, std::is_convertible()); } // Adds |object| to a list of objects whose destructors will be manually @@ -346,7 +381,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // normally only used for objects that are placement-newed into // arena-allocated memory. template - PROTOBUF_NOINLINE void OwnDestructor(T* object) { + PROTOBUF_ALWAYS_INLINE void OwnDestructor(T* object) { if (object != NULL) { impl_.AddCleanup(object, &internal::arena_destruct_object); } @@ -356,8 +391,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // will be manually called when the arena is destroyed or reset. This differs // from OwnDestructor() in that any member function may be specified, not only // the class destructor. - PROTOBUF_NOINLINE void OwnCustomDestructor(void* object, - void (*destruct)(void*)) { + PROTOBUF_ALWAYS_INLINE void OwnCustomDestructor(void* object, + void (*destruct)(void*)) { impl_.AddCleanup(object, destruct); } @@ -436,6 +471,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { }; private: + internal::ThreadSafeArena impl_; + template struct has_get_arena : InternalHelper::has_get_arena {}; @@ -467,41 +504,26 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { } } - template - PROTOBUF_ALWAYS_INLINE static T* CreateInternal(Arena* arena, - Args&&... args) { - if (arena == NULL) { - return new T(std::forward(args)...); - } else { - return arena->DoCreate(std::is_trivially_destructible::value, - std::forward(args)...); - } - } - - inline void AllocHook(const std::type_info* allocated_type, size_t n) const { - impl_.RecordAlloc(allocated_type, n); - } - // Allocate and also optionally call collector with the allocated type info // when allocation recording is enabled. - template - PROTOBUF_ALWAYS_INLINE void* AllocateInternal(bool skip_explicit_ownership) { - const size_t n = internal::AlignUpTo8(sizeof(T)); + PROTOBUF_ALWAYS_INLINE void* AllocateInternal(size_t size, size_t align, + void (*destructor)(void*), + const std::type_info* type) { // Monitor allocation if needed. - impl_.RecordAlloc(RTTI_TYPE_ID(T), n); - if (skip_explicit_ownership) { - return AllocateAlignedTo(sizeof(T)); + if (destructor == nullptr) { + return AllocateAlignedWithHook(size, align, type); } else { - if (alignof(T) <= 8) { - return impl_.AllocateAlignedAndAddCleanup( - n, &internal::arena_destruct_object); + if (align <= 8) { + auto res = AllocateAlignedWithCleanup(internal::AlignUpTo8(size), type); + res.second->elem = res.first; + res.second->cleanup = destructor; + return res.first; } else { - auto ptr = - reinterpret_cast(impl_.AllocateAlignedAndAddCleanup( - sizeof(T) + alignof(T) - 8, - &internal::arena_destruct_object)); - return reinterpret_cast((ptr + alignof(T) - 8) & - (~alignof(T) + 1)); + auto res = AllocateAlignedWithCleanup(size + align - 8, type); + auto ptr = internal::AlignTo(res.first, align); + res.second->elem = ptr; + res.second->cleanup = destructor; + return ptr; } } } @@ -522,7 +544,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { PROTOBUF_ALWAYS_INLINE static T* DoCreateMaybeMessage(Arena* arena, std::false_type, Args&&... args) { - return CreateInternal(arena, std::forward(args)...); + return Create(arena, std::forward(args)...); } template @@ -532,25 +554,6 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { std::forward(args)...); } - template - PROTOBUF_ALWAYS_INLINE static T* CreateNoMessage(Arena* arena, std::true_type, - Args&&... args) { - // User is constructing with Create() despite the fact that T supports arena - // construction. In this case we have to delegate to CreateInternal(), and - // we can't use any CreateMaybeMessage() specialization that may be defined. - return CreateInternal(arena, std::forward(args)...); - } - - template - PROTOBUF_ALWAYS_INLINE static T* CreateNoMessage(Arena* arena, - std::false_type, - Args&&... args) { - // User is constructing with Create() and the type does not support arena - // construction. In this case we can delegate to CreateMaybeMessage() and - // use any specialization that may be available for that. - return CreateMaybeMessage(arena, std::forward(args)...); - } - // Just allocate the required size for the given type assuming the // type has a trivial constructor. template @@ -559,22 +562,19 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { << "Requested size is too large to fit into size_t."; // We count on compiler to realize that if sizeof(T) is a multiple of // 8 AlignUpTo can be elided. - const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements); - // Monitor allocation if needed. - impl_.RecordAlloc(RTTI_TYPE_ID(T), n); - return static_cast(AllocateAlignedTo(n)); + const size_t n = sizeof(T) * num_elements; + return static_cast( + AllocateAlignedWithHook(n, alignof(T), RTTI_TYPE_ID(T))); } - template - PROTOBUF_ALWAYS_INLINE T* DoCreate(bool skip_explicit_ownership, - Args&&... args) { - return new (AllocateInternal(skip_explicit_ownership)) - T(std::forward(args)...); - } template PROTOBUF_ALWAYS_INLINE T* DoCreateMessage(Args&&... args) { return InternalHelper::Construct( - AllocateInternal(InternalHelper::is_destructor_skippable::value), + AllocateInternal(sizeof(T), alignof(T), + internal::ObjectDestructor< + InternalHelper::is_destructor_skippable::value, + T>::destructor, + RTTI_TYPE_ID(T)), this, std::forward(args)...); } @@ -619,7 +619,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { template PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::true_type) { if (object != NULL) { - impl_.AddCleanup(object, &internal::arena_delete_object); + impl_.AddCleanup(object, &internal::arena_delete_object); } } template @@ -654,24 +654,38 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { } // For friends of arena. - void* AllocateAligned(size_t n) { - return AllocateAlignedNoHook(internal::AlignUpTo8(n)); + void* AllocateAligned(size_t n, size_t align = 8) { + if (align <= 8) { + return AllocateAlignedNoHook(internal::AlignUpTo8(n)); + } else { + // We are wasting space by over allocating align - 8 bytes. Compared + // to a dedicated function that takes current alignment in consideration. + // Such a scheme would only waste (align - 8)/2 bytes on average, but + // requires a dedicated function in the outline arena allocation + // functions. Possibly re-evaluate tradeoffs later. + return internal::AlignTo(AllocateAlignedNoHook(n + align - 8), align); + } } - template - void* AllocateAlignedTo(size_t n) { - static_assert(Align > 0, "Alignment must be greater than 0"); - static_assert((Align & (Align - 1)) == 0, "Alignment must be power of two"); - if (Align <= 8) return AllocateAligned(n); - // TODO(b/151247138): if the pointer would have been aligned already, - // this is wasting space. We should pass the alignment down. - uintptr_t ptr = reinterpret_cast(AllocateAligned(n + Align - 8)); - ptr = (ptr + Align - 1) & (~Align + 1); - return reinterpret_cast(ptr); + + void* AllocateAlignedWithHook(size_t n, size_t align, + const std::type_info* type) { + if (align <= 8) { + return AllocateAlignedWithHook(internal::AlignUpTo8(n), type); + } else { + // We are wasting space by over allocating align - 8 bytes. Compared + // to a dedicated function that takes current alignment in consideration. + // Such a schemee would only waste (align - 8)/2 bytes on average, but + // requires a dedicated function in the outline arena allocation + // functions. Possibly re-evaluate tradeoffs later. + return internal::AlignTo(AllocateAlignedWithHook(n + align - 8, type), + align); + } } void* AllocateAlignedNoHook(size_t n); - - internal::ArenaImpl impl_; + void* AllocateAlignedWithHook(size_t n, const std::type_info* type); + std::pair + AllocateAlignedWithCleanup(size_t n, const std::type_info* type); template friend class internal::GenericTypeHandler; diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index 137726862160..0583987f07f6 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -48,24 +49,19 @@ namespace google { namespace protobuf { - -struct ArenaOptions; - namespace internal { -inline size_t AlignUpTo8(size_t n) { +inline constexpr size_t AlignUpTo8(size_t n) { // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.) return (n + 7) & static_cast(-8); } using LifecycleIdAtomic = uint64_t; -void PROTOBUF_EXPORT ArenaFree(void* object, size_t size); - // MetricsCollector collects stats for a particular arena. class PROTOBUF_EXPORT ArenaMetricsCollector { public: - virtual ~ArenaMetricsCollector(); + ArenaMetricsCollector(bool record_allocs) : record_allocs_(record_allocs) {} // Invoked when the arena is about to be destroyed. This method will // typically finalize any metric collection and delete the collector. @@ -76,10 +72,6 @@ class PROTOBUF_EXPORT ArenaMetricsCollector { // space_allocated is the space used by the arena just before the reset. virtual void OnReset(uint64 space_allocated) = 0; - // Does OnAlloc() need to be called? If false, metric collection overhead - // will be reduced since we will not do extra work per allocation. - virtual bool RecordAllocs() = 0; - // OnAlloc is called when an allocation happens. // type_info is promised to be static - its lifetime extends to // match program's lifetime (It is given by typeid operator). @@ -88,78 +80,79 @@ class PROTOBUF_EXPORT ArenaMetricsCollector { // allocations for managing the arena) virtual void OnAlloc(const std::type_info* allocated_type, uint64 alloc_size) = 0; -}; - -class ArenaImpl; - -// A thread-unsafe Arena that can only be used within its owning thread. -class PROTOBUF_EXPORT SerialArena { - public: - // Blocks are variable length malloc-ed objects. The following structure - // describes the common header for all blocks. - class PROTOBUF_EXPORT Block { - public: - Block(size_t size, Block* next, bool special, bool user_owned) - : next_and_bits_(reinterpret_cast(next) | (special ? 1 : 0) | - (user_owned ? 2 : 0)), - pos_(kBlockHeaderSize), - size_(size) { - GOOGLE_DCHECK_EQ(reinterpret_cast(next) & 3, 0u); - } - - char* Pointer(size_t n) { - GOOGLE_DCHECK(n <= size_); - return reinterpret_cast(this) + n; - } - // One of the blocks may be special. This is either a user-supplied - // initial block, or a block we created at startup to hold Options info. - // A special block is not deleted by Reset. - bool special() const { return (next_and_bits_ & 1) != 0; } - - // Whether or not this current block is owned by the user. - // Only special blocks can be user_owned. - bool user_owned() const { return (next_and_bits_ & 2) != 0; } + // Does OnAlloc() need to be called? If false, metric collection overhead + // will be reduced since we will not do extra work per allocation. + bool RecordAllocs() { return record_allocs_; } - Block* next() const { - const uintptr_t bottom_bits = 3; - return reinterpret_cast(next_and_bits_ & ~bottom_bits); - } + protected: + // This class is destructed by the call to OnDestroy(). + ~ArenaMetricsCollector() = default; + const bool record_allocs_; +}; - void clear_next() { - next_and_bits_ &= 3; // Set next to nullptr, preserve bottom bits. - } +struct AllocationPolicy { + static constexpr size_t kDefaultStartBlockSize = 256; + static constexpr size_t kDefaultMaxBlockSize = 8192; - size_t pos() const { return pos_; } - size_t size() const { return size_; } - void set_pos(size_t pos) { pos_ = pos; } + size_t start_block_size = kDefaultStartBlockSize; + size_t max_block_size = kDefaultMaxBlockSize; + void* (*block_alloc)(size_t) = nullptr; + void (*block_dealloc)(void*, size_t) = nullptr; + ArenaMetricsCollector* metrics_collector = nullptr; - private: - // Holds pointer to next block for this thread + special/user_owned bits. - uintptr_t next_and_bits_; + bool IsDefault() const { + return start_block_size == kDefaultMaxBlockSize && + max_block_size == kDefaultMaxBlockSize && block_alloc == nullptr && + block_dealloc == nullptr && metrics_collector == nullptr; + } +}; - size_t pos_; - size_t size_; - // data follows +// A simple arena allocator. Calls to allocate functions must be properly +// serialized by the caller, hence this class cannot be used as a general +// purpose allocator in a multi-threaded program. It serves as a building block +// for ThreadSafeArena, which provides a thread-safe arena allocator. +// +// This class manages +// 1) Arena bump allocation + owning memory blocks. +// 2) Maintaining a cleanup list. +// It delagetes the actual memory allocation back to ThreadSafeArena, which +// contains the information on block growth policy and backing memory allocation +// used. +class PROTOBUF_EXPORT SerialArena { + public: + struct Memory { + void* ptr; + size_t size; }; - // The allocate/free methods here are a little strange, since SerialArena is - // allocated inside a Block which it also manages. This is to avoid doing - // an extra allocation for the SerialArena itself. + // Node contains the ptr of the object to be cleaned up and the associated + // cleanup function ptr. + struct CleanupNode { + void* elem; // Pointer to the object to be cleaned up. + void (*cleanup)(void*); // Function pointer to the destructor or deleter. + }; - // Creates a new SerialArena inside Block* and returns it. - static SerialArena* New(Block* b, void* owner, ArenaImpl* arena); + // Creates a new SerialArena inside mem using the remaining memory as for + // future allocations. + static SerialArena* New(SerialArena::Memory mem, void* owner); + // Free SerialArena returning the memory passed in to New + template + Memory Free(Deallocator deallocator); void CleanupList(); + uint64 SpaceAllocated() const { + return space_allocated_.load(std::memory_order_relaxed); + } uint64 SpaceUsed() const; bool HasSpace(size_t n) { return n <= static_cast(limit_ - ptr_); } - void* AllocateAligned(size_t n) { + void* AllocateAligned(size_t n, const AllocationPolicy* policy) { GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. GOOGLE_DCHECK_GE(limit_, ptr_); if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { - return AllocateAlignedFallback(n); + return AllocateAlignedFallback(n, policy); } void* ret = ptr_; ptr_ += n; @@ -183,51 +176,52 @@ class PROTOBUF_EXPORT SerialArena { return true; } - void AddCleanup(void* elem, void (*cleanup)(void*)) { - if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) { - AddCleanupFallback(elem, cleanup); - return; + std::pair AllocateAlignedWithCleanup( + size_t n, const AllocationPolicy* policy) { + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n + kCleanupSize))) { + return AllocateAlignedWithCleanupFallback(n, policy); } - cleanup_ptr_->elem = elem; - cleanup_ptr_->cleanup = cleanup; - cleanup_ptr_++; + void* ret = ptr_; + ptr_ += n; + limit_ -= kCleanupSize; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); + ASAN_UNPOISON_MEMORY_REGION(limit_, kCleanupSize); +#endif // ADDRESS_SANITIZER + return CreatePair(ret, reinterpret_cast(limit_)); } - void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)) { - void* ret = AllocateAligned(n); - AddCleanup(ret, cleanup); - return ret; + void AddCleanup(void* elem, void (*cleanup)(void*), + const AllocationPolicy* policy) { + auto res = AllocateAlignedWithCleanup(0, policy); + res.second->elem = elem; + res.second->cleanup = cleanup; } - Block* head() const { return head_; } void* owner() const { return owner_; } SerialArena* next() const { return next_; } void set_next(SerialArena* next) { next_ = next; } - static Block* NewBlock(Block* last_block, size_t min_bytes, ArenaImpl* arena); private: - // Node contains the ptr of the object to be cleaned up and the associated - // cleanup function ptr. - struct CleanupNode { - void* elem; // Pointer to the object to be cleaned up. - void (*cleanup)(void*); // Function pointer to the destructor or deleter. - }; - - // Cleanup uses a chunked linked list, to reduce pointer chasing. - struct CleanupChunk { - static size_t SizeOf(size_t i) { - return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1)); + // Blocks are variable length malloc-ed objects. The following structure + // describes the common header for all blocks. + struct Block { + char* Pointer(size_t n) { + GOOGLE_DCHECK(n <= size); + return reinterpret_cast(this) + n; } - size_t size; // Total elements in the list. - CleanupChunk* next; // Next node in the list. - CleanupNode nodes[1]; // True length is |size|. + + Block* next; + size_t size; + CleanupNode* start; + // data follows }; - ArenaImpl* arena_; // Containing arena. void* owner_; // &ThreadCache of this thread; Block* head_; // Head of linked list of blocks. - CleanupChunk* cleanup_; // Head of cleanup list. SerialArena* next_; // Next SerialArena in this linked list. + size_t space_used_ = 0; // Necessary for metrics. + std::atomic space_allocated_; // Next pointer to allocate from. Always 8-byte aligned. Points inside // head_ (and head_->pos will always be non-canonical). We keep these @@ -235,17 +229,20 @@ class PROTOBUF_EXPORT SerialArena { char* ptr_; char* limit_; - // Next CleanupList members to append to. These point inside cleanup_. - CleanupNode* cleanup_ptr_; - CleanupNode* cleanup_limit_; + // contructor private as to only New should be used. + inline SerialArena(Block* b, void* owner); + void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy); + std::pair AllocateAlignedWithCleanupFallback( + size_t n, const AllocationPolicy* policy); + void AllocateNewBlock(size_t n, const AllocationPolicy* policy); - void* AllocateAlignedFallback(size_t n); - void AddCleanupFallback(void* elem, void (*cleanup)(void*)); - void CleanupListFallback(); + std::pair CreatePair(void* ptr, CleanupNode* node) { + return {ptr, node}; + } public: - static constexpr size_t kBlockHeaderSize = - (sizeof(Block) + 7) & static_cast(-8); + static constexpr size_t kBlockHeaderSize = AlignUpTo8(sizeof(Block)); + static constexpr size_t kCleanupSize = AlignUpTo8(sizeof(CleanupNode)); }; // This class provides the core Arena memory allocation library. Different @@ -254,42 +251,43 @@ class PROTOBUF_EXPORT SerialArena { // in turn would be templates, which will/cannot happen. However separating // the memory allocation part from the cruft of the API users expect we can // use #ifdef the select the best implementation based on hardware / OS. -class PROTOBUF_EXPORT ArenaImpl { +class PROTOBUF_EXPORT ThreadSafeArena { public: - static const size_t kDefaultStartBlockSize = 256; - static const size_t kDefaultMaxBlockSize = 8192; - - ArenaImpl() { Init(false); } + ThreadSafeArena() { Init(false); } - ArenaImpl(char* mem, size_t size) { - GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0u); - Init(false); + ThreadSafeArena(char* mem, size_t size) { InitializeFrom(mem, size); } - // Ignore initial block if it is too small. - if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) { - SetInitialBlock(new (mem) SerialArena::Block(size, nullptr, true, true)); + explicit ThreadSafeArena(void* mem, size_t size, + const AllocationPolicy& policy) { + if (policy.IsDefault()) { + // Legacy code doesn't use the API above, but provides the initial block + // through ArenaOptions. I suspect most do not touch the allocation + // policy parameters. + InitializeFrom(mem, size); + } else { + auto collector = policy.metrics_collector; + bool record_allocs = collector && collector->RecordAllocs(); + InitializeWithPolicy(mem, size, record_allocs, policy); } } - explicit ArenaImpl(const ArenaOptions& options); - // Destructor deletes all owned heap allocated objects, and destructs objects // that have non-trivial destructors, except for proto2 message objects whose // destructors can be skipped. Also, frees all blocks except the initial block // if it was passed in. - ~ArenaImpl(); + ~ThreadSafeArena(); uint64 Reset(); uint64 SpaceAllocated() const; uint64 SpaceUsed() const; - void* AllocateAligned(size_t n) { + void* AllocateAligned(size_t n, const std::type_info* type) { SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - return arena->AllocateAligned(n); + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(tag_and_id_, &arena))) { + return arena->AllocateAligned(n, AllocPolicy()); } else { - return AllocateAlignedFallback(n); + return AllocateAlignedFallback(n, type); } } @@ -300,90 +298,74 @@ class PROTOBUF_EXPORT ArenaImpl { // code for the happy path. PROTOBUF_ALWAYS_INLINE bool MaybeAllocateAligned(size_t n, void** out) { SerialArena* a; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFromThreadCache(&a))) { + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFromThreadCache(tag_and_id_, &a))) { return a->MaybeAllocateAligned(n, out); } return false; } - void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)); + std::pair AllocateAlignedWithCleanup( + size_t n, const std::type_info* type); // Add object pointer and cleanup function pointer to the list. void AddCleanup(void* elem, void (*cleanup)(void*)); - inline void RecordAlloc(const std::type_info* allocated_type, - size_t n) const { - if (PROTOBUF_PREDICT_FALSE(record_allocs())) { - options_->metrics_collector->OnAlloc(allocated_type, n); - } - } + private: + // Unique for each arena. Changes on Reset(). + uint64 tag_and_id_; + // The LSB of tag_and_id_ indicates if allocs in this arena are recorded. + enum { kRecordAllocs = 1 }; - std::pair NewBuffer(size_t last_size, size_t min_bytes); + intptr_t alloc_policy_ = 0; // Tagged pointer to AllocPolicy. + // The LSB of alloc_policy_ indicates if the user owns the initial block. + enum { kUserOwnedInitialBlock = 1 }; - private: // Pointer to a linked list of SerialArena. std::atomic threads_; - std::atomic hint_; // Fast thread-local block access - std::atomic space_allocated_; // Total size of all allocated blocks. - - // Unique for each arena. Changes on Reset(). - // Least-significant-bit is 1 iff allocations should be recorded. - uint64 lifecycle_id_; - - struct Options { - size_t start_block_size; - size_t max_block_size; - void* (*block_alloc)(size_t); - void (*block_dealloc)(void*, size_t); - ArenaMetricsCollector* metrics_collector; - }; + std::atomic hint_; // Fast thread-local block access - Options* options_ = nullptr; - - void* AllocateAlignedFallback(size_t n); - void* AllocateAlignedAndAddCleanupFallback(size_t n, void (*cleanup)(void*)); + const AllocationPolicy* AllocPolicy() const { + return reinterpret_cast(alloc_policy_ & -8); + } + void InitializeFrom(void* mem, size_t size); + void InitializeWithPolicy(void* mem, size_t size, bool record_allocs, + AllocationPolicy policy); + void* AllocateAlignedFallback(size_t n, const std::type_info* type); + std::pair + AllocateAlignedWithCleanupFallback(size_t n, const std::type_info* type); void AddCleanupFallback(void* elem, void (*cleanup)(void*)); void Init(bool record_allocs); - void SetInitialBlock( - SerialArena::Block* block); // Can be called right after Init() + void SetInitialBlock(void* mem, size_t size); - // Return true iff allocations should be recorded in a metrics collector. - inline bool record_allocs() const { return lifecycle_id_ & 1; } + // Delete or Destruct all objects owned by the arena. + void CleanupList(); - // Invoke fn(b) for every Block* b. - template - void PerBlock(Functor fn) { - // By omitting an Acquire barrier we ensure that any user code that doesn't - // properly synchronize Reset() or the destructor will throw a TSAN warning. - SerialArena* serial = threads_.load(std::memory_order_relaxed); - while (serial) { - // fn() may delete blocks and arenas, so fetch next pointers before fn(); - SerialArena* cur = serial; - serial = serial->next(); - for (auto* block = cur->head(); block != nullptr;) { - auto* b = block; - block = b->next(); - fn(b); - } - } + inline bool ShouldRecordAlloc() const { return tag_and_id_ & kRecordAllocs; } + + inline uint64 LifeCycleId() const { + return tag_and_id_ & (-kRecordAllocs - 1); } - // Delete or Destruct all objects owned by the arena. - void CleanupList(); + inline void RecordAlloc(const std::type_info* allocated_type, + size_t n) const { + AllocPolicy()->metrics_collector->OnAlloc(allocated_type, n); + } inline void CacheSerialArena(SerialArena* serial) { thread_cache().last_serial_arena = serial; - thread_cache().last_lifecycle_id_seen = lifecycle_id_; + thread_cache().last_lifecycle_id_seen = LifeCycleId(); // TODO(haberman): evaluate whether we would gain efficiency by getting rid - // of hint_. It's the only write we do to ArenaImpl in the allocation path, - // which will dirty the cache line. + // of hint_. It's the only write we do to ThreadSafeArena in the allocation + // path, which will dirty the cache line. hint_.store(serial, std::memory_order_release); } - PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) { - if (GetSerialArenaFromThreadCache(arena)) return true; + PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(uint64 lifecycle_id, + SerialArena** arena) { + if (GetSerialArenaFromThreadCache(lifecycle_id, arena)) return true; + if (lifecycle_id & kRecordAllocs) return false; // Check whether we own the last accessed SerialArena on this arena. This // fast path optimizes the case where a single thread uses multiple arenas. @@ -397,12 +379,12 @@ class PROTOBUF_EXPORT ArenaImpl { } PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFromThreadCache( - SerialArena** arena) { + uint64 lifecycle_id, SerialArena** arena) { // If this thread already owns a block in this arena then try to use that. // This fast path optimizes the case where multiple threads allocate from // the same arena. ThreadCache* tc = &thread_cache(); - if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == lifecycle_id_)) { + if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == lifecycle_id)) { *arena = tc->last_serial_arena; return true; } @@ -410,6 +392,20 @@ class PROTOBUF_EXPORT ArenaImpl { } SerialArena* GetSerialArenaFallback(void* me); + template + void PerSerialArena(Functor fn) { + // By omitting an Acquire barrier we ensure that any user code that doesn't + // properly synchronize Reset() or the destructor will throw a TSAN warning. + SerialArena* serial = threads_.load(std::memory_order_relaxed); + + for (; serial; serial = serial->next()) fn(serial); + } + + // Releases all memory except the first block which it returns. The first + // block might be owned by the user and thus need some extra checks before + // deleting. + SerialArena::Memory Free(size_t* space_allocated); + #ifdef _MSC_VER #pragma warning(disable : 4324) #endif @@ -462,11 +458,11 @@ class PROTOBUF_EXPORT ArenaImpl { static ThreadCache& thread_cache() { return thread_cache_; } #endif - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl); + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadSafeArena); // All protos have pointers back to the arena hence Arena must have // pointer stability. - ArenaImpl(ArenaImpl&&) = delete; - ArenaImpl& operator=(ArenaImpl&&) = delete; + ThreadSafeArena(ThreadSafeArena&&) = delete; + ThreadSafeArena& operator=(ThreadSafeArena&&) = delete; public: // kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8 @@ -474,8 +470,6 @@ class PROTOBUF_EXPORT ArenaImpl { static constexpr size_t kBlockHeaderSize = SerialArena::kBlockHeaderSize; static constexpr size_t kSerialArenaSize = (sizeof(SerialArena) + 7) & static_cast(-8); - static constexpr size_t kOptionsSize = - (sizeof(Options) + 7) & static_cast(-8); static_assert(kBlockHeaderSize % 8 == 0, "kBlockHeaderSize must be a multiple of 8."); static_assert(kSerialArenaSize % 8 == 0, diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 829c6a070391..7e9016429f64 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -1331,7 +1331,7 @@ void ClearHookCounts() { } // namespace // A helper utility class that handles arena callbacks. -class ArenaOptionsTestFriend : public internal::ArenaMetricsCollector { +class ArenaOptionsTestFriend final : public internal::ArenaMetricsCollector { public: static internal::ArenaMetricsCollector* NewWithAllocs() { return new ArenaOptionsTestFriend(true); @@ -1352,7 +1352,7 @@ class ArenaOptionsTestFriend : public internal::ArenaMetricsCollector { } explicit ArenaOptionsTestFriend(bool record_allocs) - : record_allocs_(record_allocs) { + : ArenaMetricsCollector(record_allocs) { ++hooks_num_init; } void OnDestroy(uint64 space_allocated) override { @@ -1360,14 +1360,10 @@ class ArenaOptionsTestFriend : public internal::ArenaMetricsCollector { delete this; } void OnReset(uint64 space_allocated) override { ++hooks_num_reset; } - bool RecordAllocs() override { return record_allocs_; } void OnAlloc(const std::type_info* allocated_type, uint64 alloc_size) override { ++hooks_num_allocations; } - - private: - bool record_allocs_; }; // Test the hooks are correctly called. @@ -1408,3 +1404,5 @@ TEST(ArenaTest, ArenaHooksWhenAllocationsNotNeeded) { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc index b5f48c53a1e6..452d2bfec846 100644 --- a/src/google/protobuf/arenastring.cc +++ b/src/google/protobuf/arenastring.cc @@ -252,3 +252,5 @@ void ArenaStringPtr::ClearToDefault(const LazyString& default_value, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc index 321b45140f3f..8d7b520ac031 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -173,3 +173,5 @@ TEST(ArenaStringPtrTest, ArenaStringPtrOnArenaNoSSO) { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index 4d78bb1176c9..4544f3e71057 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -123,6 +123,15 @@ void ParseGeneratorParameter( } } +// Strips ".proto" or ".protodevel" from the end of a filename. +std::string StripProto(const std::string& filename) { + if (HasSuffixString(filename, ".protodevel")) { + return StripSuffixString(filename, ".protodevel"); + } else { + return StripSuffixString(filename, ".proto"); + } +} + } // namespace compiler } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 323f48e4a92b..c8d9e49b5aa5 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -193,6 +193,9 @@ typedef GeneratorContext OutputDirectory; PROTOC_EXPORT void ParseGeneratorParameter( const std::string&, std::vector >*); +// Strips ".proto" or ".protodevel" from the end of a filename. +PROTOC_EXPORT std::string StripProto(const std::string& filename); + } // namespace compiler } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 1cbc4b71c1b7..242cb7de4396 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -58,8 +58,10 @@ #include -#ifdef __APPLE__ +#if defined(__APPLE__) #include +#elif defined(__FreeBSD__) +#include #endif #include @@ -202,6 +204,13 @@ bool GetProtocAbsolutePath(std::string* path) { realpath(dirtybuffer, buffer); len = strlen(buffer); } +#elif defined(__FreeBSD__) + char buffer[PATH_MAX]; + size_t len = PATH_MAX; + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; + if (sysctl(mib, 4, &buffer, &len, NULL, 0) != 0) { + len = 0; + } #else char buffer[PATH_MAX]; int len = readlink("/proc/self/exe", buffer, PATH_MAX); @@ -2009,130 +2018,76 @@ CommandLineInterface::InterpretArgument(const std::string& name, void CommandLineInterface::PrintHelpText() { // Sorry for indentation here; line wrapping would be uglier. - std::cout - << - "Usage: " << executable_name_ - << " [OPTION] PROTO_FILES\n" - "Parse PROTO_FILES and generate output based on the options given:\n" - " -IPATH, --proto_path=PATH Specify the directory in which to " - "search for\n" - " imports. May be specified multiple " - "times;\n" - " directories will be searched in order. " - " If not\n" - " given, the current working directory " - "is used.\n" - " If not found in any of the these " - "directories,\n" - " the --descriptor_set_in descriptors " - "will be\n" - " checked for required proto file.\n" - " --version Show version info and exit.\n" - " -h, --help Show this text and exit.\n" - " --encode=MESSAGE_TYPE Read a text-format message of the " - "given type\n" - " from standard input and write it in " - "binary\n" - " to standard output. The message type " - "must\n" - " be defined in PROTO_FILES or their " - "imports.\n" - " --deterministic_output When using --encode, ensure map fields " - "are\n" - " deterministically ordered. Note that" - "this order is not\n" - " canonical, and changes across builds" - "or releases of protoc.\n" - " --decode=MESSAGE_TYPE Read a binary message of the given " - "type from\n" - " standard input and write it in text " - "format\n" - " to standard output. The message type " - "must\n" - " be defined in PROTO_FILES or their " - "imports.\n" - " --decode_raw Read an arbitrary protocol message " - "from\n" - " standard input and write the raw " - "tag/value\n" - " pairs in text format to standard " - "output. No\n" - " PROTO_FILES should be given when using " - "this\n" - " flag.\n" - " --descriptor_set_in=FILES Specifies a delimited list of FILES\n" - " each containing a FileDescriptorSet " - "(a\n" - " protocol buffer defined in " - "descriptor.proto).\n" - " The FileDescriptor for each of the " - "PROTO_FILES\n" - " provided will be loaded from these\n" - " FileDescriptorSets. If a " - "FileDescriptor\n" - " appears multiple times, the first " - "occurrence\n" - " will be used.\n" - " -oFILE, Writes a FileDescriptorSet (a protocol " - "buffer,\n" - " --descriptor_set_out=FILE defined in descriptor.proto) " - "containing all of\n" - " the input files to FILE.\n" - " --include_imports When using --descriptor_set_out, also " - "include\n" - " all dependencies of the input files in " - "the\n" - " set, so that the set is " - "self-contained.\n" - " --include_source_info When using --descriptor_set_out, do " - "not strip\n" - " SourceCodeInfo from the " - "FileDescriptorProto.\n" - " This results in vastly larger " - "descriptors that\n" - " include information about the " - "original\n" - " location of each decl in the source " - "file as\n" - " well as surrounding comments.\n" - " --dependency_out=FILE Write a dependency output file in the " - "format\n" - " expected by make. This writes the " - "transitive\n" - " set of input file paths to FILE\n" - " --error_format=FORMAT Set the format in which to print " - "errors.\n" - " FORMAT may be 'gcc' (the default) or " - "'msvs'\n" - " (Microsoft Visual Studio format).\n" - " --print_free_field_numbers Print the free field numbers of the " - "messages\n" - " defined in the given proto files. " - "Groups share\n" - " the same field number space with the " - "parent \n" - " message. Extension ranges are counted " - "as \n" - " occupied fields numbers.\n" - << std::endl; + std::cout << "Usage: " << executable_name_ << " [OPTION] PROTO_FILES"; + std::cout << R"( +Parse PROTO_FILES and generate output based on the options given: + -IPATH, --proto_path=PATH Specify the directory in which to search for + imports. May be specified multiple times; + directories will be searched in order. If not + given, the current working directory is used. + If not found in any of the these directories, + the --descriptor_set_in descriptors will be + checked for required proto file. + --version Show version info and exit. + -h, --help Show this text and exit. + --encode=MESSAGE_TYPE Read a text-format message of the given type + from standard input and write it in binary + to standard output. The message type must + be defined in PROTO_FILES or their imports. + --deterministic_output When using --encode, ensure map fields are + deterministically ordered. Note that this order + is not canonical, and changes across builds or + releases of protoc. + --decode=MESSAGE_TYPE Read a binary message of the given type from + standard input and write it in text format + to standard output. The message type must + be defined in PROTO_FILES or their imports. + --decode_raw Read an arbitrary protocol message from + standard input and write the raw tag/value + pairs in text format to standard output. No + PROTO_FILES should be given when using this + flag. + --descriptor_set_in=FILES Specifies a delimited list of FILES + each containing a FileDescriptorSet (a + protocol buffer defined in descriptor.proto). + The FileDescriptor for each of the PROTO_FILES + provided will be loaded from these + FileDescriptorSets. If a FileDescriptor + appears multiple times, the first occurrence + will be used. + -oFILE, Writes a FileDescriptorSet (a protocol buffer, + --descriptor_set_out=FILE defined in descriptor.proto) containing all of + the input files to FILE. + --include_imports When using --descriptor_set_out, also include + all dependencies of the input files in the + set, so that the set is self-contained. + --include_source_info When using --descriptor_set_out, do not strip + SourceCodeInfo from the FileDescriptorProto. + This results in vastly larger descriptors that + include information about the original + location of each decl in the source file as + well as surrounding comments. + --dependency_out=FILE Write a dependency output file in the format + expected by make. This writes the transitive + set of input file paths to FILE + --error_format=FORMAT Set the format in which to print errors. + FORMAT may be 'gcc' (the default) or 'msvs' + (Microsoft Visual Studio format). + --print_free_field_numbers Print the free field numbers of the messages + defined in the given proto files. Groups share + the same field number space with the parent + message. Extension ranges are counted as + occupied fields numbers.)"; if (!plugin_prefix_.empty()) { - std::cout - << " --plugin=EXECUTABLE Specifies a plugin executable to " - "use.\n" - " Normally, protoc searches the PATH " - "for\n" - " plugins, but you may specify " - "additional\n" - " executables not in the path using " - "this flag.\n" - " Additionally, EXECUTABLE may be of " - "the form\n" - " NAME=PATH, in which case the given " - "plugin name\n" - " is mapped to the given executable " - "even if\n" - " the executable's own name differs." - << std::endl; + std::cout << R"( + --plugin=EXECUTABLE Specifies a plugin executable to use. + Normally, protoc searches the PATH for + plugins, but you may specify additional + executables not in the path using this flag. + Additionally, EXECUTABLE may be of the form + NAME=PATH, in which case the given plugin name + is mapped to the given executable even if + the executable's own name differs.)"; } for (GeneratorMap::iterator iter = generators_by_flag_name_.begin(); @@ -2140,35 +2095,26 @@ void CommandLineInterface::PrintHelpText() { // FIXME(kenton): If the text is long enough it will wrap, which is ugly, // but fixing this nicely (e.g. splitting on spaces) is probably more // trouble than it's worth. - std::cout << " " << iter->first << "=OUT_DIR " + std::cout << std::endl + << " " << iter->first << "=OUT_DIR " << std::string(19 - iter->first.size(), ' ') // Spaces for alignment. - << iter->second.help_text << std::endl; - } - std::cout << " @ Read options and filenames from " - "file. If a\n" - " relative file path is specified, " - "the file\n" - " will be searched in the working " - "directory.\n" - " The --proto_path option will not " - "affect how\n" - " this argument file is searched. " - "Content of\n" - " the file will be expanded in the " - "position of\n" - " @ as in the argument " - "list. Note\n" - " that shell expansion is not " - "applied to the\n" - " content of the file (i.e., you " - "cannot use\n" - " quotes, wildcards, escapes, " - "commands, etc.).\n" - " Each line corresponds to a " - "single argument,\n" - " even if it contains spaces." - << std::endl; + << iter->second.help_text; + } + std::cout << R"( + @ Read options and filenames from file. If a + relative file path is specified, the file + will be searched in the working directory. + The --proto_path option will not affect how + this argument file is searched. Content of + the file will be expanded in the position of + @ as in the argument list. Note + that shell expansion is not applied to the + content of the file (i.e., you cannot use + quotes, wildcards, escapes, commands, etc.). + Each line corresponds to a single argument, + even if it contains spaces.)"; + std::cout << std::endl; } bool CommandLineInterface::EnforceProto3OptionalSupport( diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index 06da3f37c496..3792db81a80e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -99,8 +99,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, std::string scope = IsScoped() ? ClassName(descriptor_->extension_scope(), false) + "::" : ""; variables_["scope"] = scope; - std::string scoped_name = scope + ResolveKeyword(name); - variables_["scoped_name"] = scoped_name; + variables_["scoped_name"] = ExtensionName(descriptor_); variables_["number"] = StrCat(descriptor_->number()); } @@ -175,6 +174,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { } format( + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n" " $scoped_name$($constant_name$, $1$);\n", diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 875beec9f601..8ca7ba2f57e1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -429,6 +429,12 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { format("// @@protoc_insertion_point(includes)\n"); IncludeFile("net/proto2/public/port_def.inc", printer); + + // For MSVC builds, we use #pragma init_seg to move the initialization of our + // libraries to happen before the user code. + // This worksaround the fact that MSVC does not do constant initializers when + // required by the standard. + format("\nPROTOBUF_PRAGMA_INIT_SEG\n"); } void FileGenerator::GenerateSourceDefaultInstance(int idx, @@ -916,8 +922,9 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { if (file_->name() != "net/proto2/proto/descriptor.proto") { format( "// Force running AddDescriptors() at dynamic initialization time.\n" - "static bool $1$ = (static_cast(" - "::$proto_ns$::internal::AddDescriptors(&$desc_table$)), true);\n", + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " + "static ::$proto_ns$::internal::AddDescriptorsRunner " + "$1$(&$desc_table$);\n", UniqueName("dynamic_init_dummy", file_, options_)); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index f73ed6191def..010a215c5032 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -362,10 +362,16 @@ std::string QualifiedClassName(const EnumDescriptor* d) { return QualifiedClassName(d, Options()); } +std::string ExtensionName(const FieldDescriptor* d) { + if (const Descriptor* scope = d->extension_scope()) + return StrCat(ClassName(scope), "::", ResolveKeyword(d->name())); + return ResolveKeyword(d->name()); +} + std::string QualifiedExtensionName(const FieldDescriptor* d, const Options& options) { GOOGLE_DCHECK(d->is_extension()); - return QualifiedFileLevelSymbol(d->file(), FieldName(d), options); + return QualifiedFileLevelSymbol(d->file(), ExtensionName(d), options); } std::string QualifiedExtensionName(const FieldDescriptor* d) { @@ -1396,7 +1402,6 @@ class ParseLoopGenerator { format_.Set("has_bits", "_has_bits_"); } - format_("$p_ns$::Arena* arena = GetArena(); (void)arena;\n"); GenerateParseLoop(descriptor, ordered_fields); format_.Outdent(); format_("success:\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index a036bbc0b70f..1e455ffd28c4 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -134,6 +134,10 @@ inline std::string ClassName(const EnumDescriptor* descriptor, bool qualified) { : ClassName(descriptor); } +// Returns the extension name prefixed with the class name if nested but without +// the package name. +std::string ExtensionName(const FieldDescriptor* d); + std::string QualifiedExtensionName(const FieldDescriptor* d, const Options& options); std::string QualifiedExtensionName(const FieldDescriptor* d); diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 7c17e456d0c8..9bfb76e6346b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -308,12 +308,7 @@ bool ShouldMarkIsInitializedAsFinal(const Descriptor* descriptor, bool ShouldMarkNewAsFinal(const Descriptor* descriptor, const Options& options) { - static std::set exclusions{ - }; - - const std::string name = ClassName(descriptor, true); - return exclusions.find(name) == exclusions.end() || - options.opensource_runtime; + return true; } // Returns true to make the message serialize in order, decided by the following @@ -1054,6 +1049,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { " s->data(), static_cast(s->size()), " "::$proto_ns$::internal::" "WireFormatLite::PARSE, \"$1$\");\n" + "#else\n" + " (void) s;\n" "#endif\n" " return true;\n" " }\n", @@ -1081,6 +1078,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { " s->data(), static_cast(s->size()), " "::$proto_ns$::internal::" "WireFormatLite::PARSE, \"$1$\");\n" + "#else\n" + " (void) s;\n" "#endif\n" " return true;\n" " }\n", @@ -1228,13 +1227,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n"); if (HasDescriptorMethods(descriptor_->file(), options_)) { format( - "void PackFrom(const ::$proto_ns$::Message& message) {\n" - " _any_metadata_.PackFrom(message);\n" + "bool PackFrom(const ::$proto_ns$::Message& message) {\n" + " return _any_metadata_.PackFrom(message);\n" "}\n" - "void PackFrom(const ::$proto_ns$::Message& message,\n" + "bool PackFrom(const ::$proto_ns$::Message& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " _any_metadata_.PackFrom(message, type_url_prefix);\n" + " return _any_metadata_.PackFrom(message, type_url_prefix);\n" "}\n" "bool UnpackTo(::$proto_ns$::Message* message) const {\n" " return _any_metadata_.UnpackTo(message);\n" @@ -1246,16 +1245,16 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "template " "::value>::type>\n" - "void PackFrom(const T& message) {\n" - " _any_metadata_.PackFrom(message);\n" + "bool PackFrom(const T& message) {\n" + " return _any_metadata_.PackFrom(message);\n" "}\n" "template " "::value>::type>\n" - "void PackFrom(const T& message,\n" + "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " _any_metadata_.PackFrom(message, type_url_prefix);" + " return _any_metadata_.PackFrom(message, type_url_prefix);" "}\n" "template " @@ -1266,14 +1265,14 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { } else { format( "template \n" - "void PackFrom(const T& message) {\n" - " _any_metadata_.PackFrom(message);\n" + "bool PackFrom(const T& message) {\n" + " return _any_metadata_.PackFrom(message);\n" "}\n" "template \n" - "void PackFrom(const T& message,\n" + "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " _any_metadata_.PackFrom(message, type_url_prefix);\n" + " return _any_metadata_.PackFrom(message, type_url_prefix);\n" "}\n" "template \n" "bool UnpackTo(T* message) const {\n" @@ -2459,8 +2458,10 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; } else { pod_template = - "::memset(&$first$_, 0, static_cast(\n" - " reinterpret_cast(&$last$_) -\n" + "::memset(reinterpret_cast(this) + static_cast(\n" + " reinterpret_cast(&$first$_) - " + "reinterpret_cast(this)),\n" + " 0, static_cast(reinterpret_cast(&$last$_) -\n" " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; } @@ -3598,29 +3599,17 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( "_weak_field_map_);\n"); } - format( - "static const int kStart = GetInvariantPerBuild($1$UL) % $2$;\n" - "bool first_pass = true;\n" - "for (int i = kStart; i != kStart || first_pass; i = ((i + $3$) % $2$)) " - "{\n", - 0, - num_fields, kLargePrime); + format("for (int i = $1$; i >= 0; i-- ) {\n", num_fields - 1); format.Indent(); format("switch(i) {\n"); format.Indent(); - bool first_pass_set = false; int index = 0; for (const auto* f : ordered_fields) { format("case $1$: {\n", index++); format.Indent(); - if (!first_pass_set) { - first_pass_set = true; - format("first_pass = false;\n"); - } - GenerateSerializeOneField(printer, f, -1); format("break;\n"); @@ -3632,11 +3621,6 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( format("case $1$: {\n", index++); format.Indent(); - if (!first_pass_set) { - first_pass_set = true; - format("first_pass = false;\n"); - } - GenerateSerializeOneExtensionRange(printer, r); format("break;\n"); diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index 6c4d894e69ad..3a685aa2ffd6 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -89,6 +89,17 @@ const std::unordered_set* kReservedNames = "transient", "try", "void", "volatile", "while", }); +// Names that should be avoided as field names in Kotlin. +// All Kotlin hard keywords are in this list. +const std::unordered_set* kKotlinForbiddenNames = + new std::unordered_set({ + "as", "as?", "break", "class", "continue", "do", "else", + "false", "for", "fun", "if", "in", "!in", "interface", + "is", "!is", "null", "object", "package", "return", "super", + "this", "throw", "true", "try", "typealias", "typeof", "val", + "var", "when", "while", + }); + bool IsForbidden(const std::string& field_name) { for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { if (field_name == kForbiddenWordList[i]) { @@ -215,6 +226,7 @@ std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) { return name; } + std::string UniqueFileScopeIdentifier(const Descriptor* descriptor) { return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); } diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index 046fe7e3430c..eda84631e811 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -51,6 +51,7 @@ namespace java { extern const char kThickSeparator[]; extern const char kThinSeparator[]; + // If annotation_file is non-empty, prints a javax.annotation.Generated // annotation to the given Printer. annotation_file will be referenced in the // annotation's comments field. delimiter should be the Printer's delimiter diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc index bc13dd8733c3..866bb0362d35 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -67,6 +67,7 @@ std::string ClassNameWithoutPackage(const Descriptor* descriptor, return StripPackageName(descriptor->full_name(), descriptor->file()); } + // Get the name of an enum's Java class without package name prefix. std::string ClassNameWithoutPackage(const EnumDescriptor* descriptor, bool immutable) { diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index 20c007245651..34aa6acd3487 100644 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -3163,6 +3163,15 @@ void Generator::GenerateClassDeserializeBinaryField( (field->type() == FieldDescriptor::TYPE_GROUP) ? (StrCat(field->number()) + ", ") : ""); + } else if (field->is_packable()) { + printer->Print( + " var values = /** @type {$fieldtype$} */ " + "(reader.isDelimited() " + "? reader.readPacked$reader$() : [reader.read$reader$()]);\n", + "fieldtype", + JSFieldTypeAnnotation(options, field, false, true, + /* singular_if_not_packed */ false, BYTES_U8), + "reader", JSBinaryReaderMethodType(field)); } else { printer->Print( " var value = /** @type {$fieldtype$} */ " @@ -3174,7 +3183,14 @@ void Generator::GenerateClassDeserializeBinaryField( JSBinaryReadWriteMethodName(field, /* is_writer = */ false)); } - if (field->is_repeated() && !field->is_packed()) { + if (field->is_packable()) { + printer->Print( + " for (var i = 0; i < values.length; i++) {\n" + " msg.add$name$(values[i]);\n" + " }\n", + "name", + JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); + } else if (field->is_repeated()) { printer->Print( " msg.add$name$(value);\n", "name", JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 26ef63f021e3..cce1695a844e 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -362,14 +363,6 @@ std::string EscapeTrigraphs(const std::string& to_escape) { return StringReplace(to_escape, "?", "\\?", true); } -std::string StripProto(const std::string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - void TrimWhitespace(StringPiece* input) { while (!input->empty() && ascii_isspace(*input->data())) { input->remove_prefix(1); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 1414152bca25..ce2d92cf3cf3 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -59,9 +59,6 @@ struct Options { // Escape C++ trigraphs by escaping question marks to "\?". std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& to_escape); -// Strips ".proto" or ".protodevel" from the end of a filename. -std::string PROTOC_EXPORT StripProto(const std::string& filename); - // Remove white space from either end of a StringPiece. void PROTOC_EXPORT TrimWhitespace(StringPiece* input); diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 6f100a054bf9..d5cdee31d555 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -78,37 +78,41 @@ namespace protobuf { namespace compiler { namespace php { +struct Options { + bool is_descriptor = false; + bool aggregate_metadata = false; + bool gen_c_wkt = false; + std::set aggregate_metadata_prefixes; +}; + +namespace { + // Forward decls. -std::string PhpName(const std::string& full_name, bool is_descriptor); -std::string DefaultForField(FieldDescriptor* field); +std::string PhpName(const std::string& full_name, const Options& options); std::string IntToString(int32 value); std::string FilenameToClassname(const std::string& filename); std::string GeneratedMetadataFileName(const FileDescriptor* file, - bool is_descriptor); -std::string LabelForField(FieldDescriptor* field); -std::string TypeName(FieldDescriptor* field); + const Options& options); std::string UnderscoresToCamelCase(const std::string& name, bool cap_first_letter); std::string BinaryToHex(const std::string& binary); void Indent(io::Printer* printer); void Outdent(io::Printer* printer); -void GenerateAddFilesToPool( - const FileDescriptor* file, - const std::set& aggregate_metadata_prefixes, - io::Printer* printer); +void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, + io::Printer* printer); void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, - int is_descriptor); + const Options& options); void GenerateMessageConstructorDocComment(io::Printer* printer, const Descriptor* message, - int is_descriptor); + const Options& options); void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, - int is_descriptor, int function_type); + const Options& options, int function_type); void GenerateWrapperFieldGetterDocComment(io::Printer* printer, const FieldDescriptor* field); void GenerateWrapperFieldSetterDocComment(io::Printer* printer, const FieldDescriptor* field); void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, - int is_descriptor); + const Options& options); void GenerateEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value); void GenerateServiceDocComment(io::Printer* printer, @@ -142,8 +146,8 @@ std::string ReservedNamePrefix(const std::string& classname, } template -std::string DescriptorFullName(const DescriptorType* desc, bool is_descriptor) { - if (is_descriptor) { +std::string DescriptorFullName(const DescriptorType* desc, bool is_internal) { + if (is_internal) { return StringReplace(desc->full_name(), "google.protobuf", "google.protobuf.internal", false); @@ -180,18 +184,6 @@ std::string GeneratedClassNameImpl(const ServiceDescriptor* desc) { return ClassNamePrefix(classname, desc) + classname; } -std::string GeneratedClassName(const Descriptor* desc) { - return GeneratedClassNameImpl(desc); -} - -std::string GeneratedClassName(const EnumDescriptor* desc) { - return GeneratedClassNameImpl(desc); -} - -std::string GeneratedClassName(const ServiceDescriptor* desc) { - return GeneratedClassNameImpl(desc); -} - template std::string LegacyGeneratedClassName(const DescriptorType* desc) { std::string classname = desc->name(); @@ -244,7 +236,8 @@ std::string ConstantNamePrefix(const std::string& classname) { } template -std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { +std::string RootPhpNamespace(const DescriptorType* desc, + const Options& options) { if (desc->file()->options().has_php_namespace()) { const std::string& php_namespace = desc->file()->options().php_namespace(); if (!php_namespace.empty()) { @@ -254,15 +247,15 @@ std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { } if (!desc->file()->package().empty()) { - return PhpName(desc->file()->package(), is_descriptor); + return PhpName(desc->file()->package(), options); } return ""; } template -std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { +std::string FullClassName(const DescriptorType* desc, const Options& options) { std::string classname = GeneratedClassNameImpl(desc); - std::string php_namespace = RootPhpNamespace(desc, is_descriptor); + std::string php_namespace = RootPhpNamespace(desc, options); if (!php_namespace.empty()) { return php_namespace + "\\" + classname; } @@ -270,17 +263,25 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { } template -std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) { +std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return FullClassName(desc, options); +} + +template +std::string LegacyFullClassName(const DescriptorType* desc, + const Options& options) { std::string classname = LegacyGeneratedClassName(desc); - std::string php_namespace = RootPhpNamespace(desc, is_descriptor); + std::string php_namespace = RootPhpNamespace(desc, options); if (!php_namespace.empty()) { return php_namespace + "\\" + classname; } return classname; } -std::string PhpName(const std::string& full_name, bool is_descriptor) { - if (is_descriptor) { +std::string PhpName(const std::string& full_name, const Options& options) { + if (options.is_descriptor) { return kDescriptorPackageName; } @@ -329,7 +330,7 @@ std::string DefaultForField(const FieldDescriptor* field) { } std::string GeneratedMetadataFileName(const FileDescriptor* file, - bool is_descriptor) { + const Options& options) { const std::string& proto_file = file->name(); int start_index = 0; int first_index = proto_file.find_first_of("/", start_index); @@ -339,7 +340,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, if (proto_file == kEmptyFile) { return kEmptyMetadataFile; } - if (is_descriptor) { + if (options.is_descriptor) { return kDescriptorMetadataFile; } @@ -386,10 +387,17 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, return result + ReservedNamePrefix(segment, file) + segment + ".php"; } +std::string GeneratedMetadataFileName(const FileDescriptor* file, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return GeneratedMetadataFileName(file, options); +} + template std::string GeneratedClassFileName(const DescriptorType* desc, - bool is_descriptor) { - std::string result = FullClassName(desc, is_descriptor); + const Options& options) { + std::string result = FullClassName(desc, options); for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -400,8 +408,8 @@ std::string GeneratedClassFileName(const DescriptorType* desc, template std::string LegacyGeneratedClassFileName(const DescriptorType* desc, - bool is_descriptor) { - std::string result = LegacyFullClassName(desc, is_descriptor); + const Options& options) { + std::string result = LegacyFullClassName(desc, options); for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { @@ -412,8 +420,8 @@ std::string LegacyGeneratedClassFileName(const DescriptorType* desc, } std::string GeneratedServiceFileName(const ServiceDescriptor* service, - bool is_descriptor) { - std::string result = FullClassName(service, is_descriptor) + "Interface"; + const Options& options) { + std::string result = FullClassName(service, options) + "Interface"; for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -437,31 +445,8 @@ std::string LabelForField(const FieldDescriptor* field) { } } -std::string TypeName(const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_INT32: return "int32"; - case FieldDescriptor::TYPE_INT64: return "int64"; - case FieldDescriptor::TYPE_UINT32: return "uint32"; - case FieldDescriptor::TYPE_UINT64: return "uint64"; - case FieldDescriptor::TYPE_SINT32: return "sint32"; - case FieldDescriptor::TYPE_SINT64: return "sint64"; - case FieldDescriptor::TYPE_FIXED32: return "fixed32"; - case FieldDescriptor::TYPE_FIXED64: return "fixed64"; - case FieldDescriptor::TYPE_SFIXED32: return "sfixed32"; - case FieldDescriptor::TYPE_SFIXED64: return "sfixed64"; - case FieldDescriptor::TYPE_DOUBLE: return "double"; - case FieldDescriptor::TYPE_FLOAT: return "float"; - case FieldDescriptor::TYPE_BOOL: return "bool"; - case FieldDescriptor::TYPE_ENUM: return "enum"; - case FieldDescriptor::TYPE_STRING: return "string"; - case FieldDescriptor::TYPE_BYTES: return "bytes"; - case FieldDescriptor::TYPE_MESSAGE: return "message"; - case FieldDescriptor::TYPE_GROUP: return "group"; - default: assert(false); return ""; - } -} - -std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) { +std::string PhpSetterTypeName(const FieldDescriptor* field, + const Options& options) { if (field->is_map()) { return "array|\\Google\\Protobuf\\Internal\\MapField"; } @@ -494,7 +479,7 @@ std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) type = "string"; break; case FieldDescriptor::TYPE_MESSAGE: - type = "\\" + FullClassName(field->message_type(), is_descriptor); + type = "\\" + FullClassName(field->message_type(), options); break; case FieldDescriptor::TYPE_GROUP: return "null"; @@ -511,7 +496,15 @@ std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) return type; } -std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor) { +std::string PhpSetterTypeName(const FieldDescriptor* field, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return PhpSetterTypeName(field, options); +} + +std::string PhpGetterTypeName(const FieldDescriptor* field, + const Options& options) { if (field->is_map()) { return "\\Google\\Protobuf\\Internal\\MapField"; } @@ -536,23 +529,40 @@ std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor) case FieldDescriptor::TYPE_STRING: case FieldDescriptor::TYPE_BYTES: return "string"; case FieldDescriptor::TYPE_MESSAGE: - return "\\" + FullClassName(field->message_type(), is_descriptor); + return "\\" + FullClassName(field->message_type(), options); case FieldDescriptor::TYPE_GROUP: return "null"; default: assert(false); return ""; } } -std::string EnumOrMessageSuffix( - const FieldDescriptor* field, bool is_descriptor) { +std::string PhpGetterTypeName(const FieldDescriptor* field, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return PhpGetterTypeName(field, options); +} + +std::string EnumOrMessageSuffix(const FieldDescriptor* field, + const Options& options) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - return ", '" + DescriptorFullName(field->message_type(), is_descriptor) + "'"; + return ", '" + + DescriptorFullName(field->message_type(), options.is_descriptor) + + "'"; } if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - return ", '" + DescriptorFullName(field->enum_type(), is_descriptor) + "'"; + return ", '" + + DescriptorFullName(field->enum_type(), options.is_descriptor) + "'"; } return ""; } +std::string EnumOrMessageSuffix(const FieldDescriptor* field, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return EnumOrMessageSuffix(field, options); +} + // Converts a name to camel-case. If cap_first_letter is true, capitalize the // first letter. std::string UnderscoresToCamelCase(const std::string& name, @@ -621,9 +631,9 @@ void Outdent(io::Printer* printer) { } void GenerateField(const FieldDescriptor* field, io::Printer* printer, - bool is_descriptor) { + const Options& options) { if (field->is_repeated()) { - GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty); + GenerateFieldDocComment(printer, field, options, kFieldProperty); printer->Print( "private $^name^;\n", "name", field->name()); @@ -633,7 +643,7 @@ void GenerateField(const FieldDescriptor* field, io::Printer* printer, } else { std::string initial_value = field->has_presence() ? "null" : DefaultForField(field); - GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty); + GenerateFieldDocComment(printer, field, options, kFieldProperty); printer->Print( "protected $^name^ = ^initial_value^;\n", "name", field->name(), @@ -649,12 +659,12 @@ void GenerateOneofField(const OneofDescriptor* oneof, io::Printer* printer) { "name", oneof->name()); } -void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, +void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, io::Printer* printer) { const OneofDescriptor* oneof = field->real_containing_oneof(); // Generate getter. - GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); + GenerateFieldDocComment(printer, field, options, kFieldGetter); if (oneof != NULL) { printer->Print( @@ -711,7 +721,7 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, } // Generate setter. - GenerateFieldDocComment(printer, field, is_descriptor, kFieldSetter); + GenerateFieldDocComment(printer, field, options, kFieldSetter); printer->Print( "public function set^camel_name^($var)\n" "{\n", @@ -734,12 +744,12 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(value->message_type(), is_descriptor) + "::class"); + FullClassName(value->message_type(), options) + "::class"); } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(value->enum_type(), is_descriptor) + "::class"); + FullClassName(value->enum_type(), options) + "::class"); } else { printer->Print(");\n"); } @@ -752,23 +762,23 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(field->message_type(), is_descriptor) + "::class"); + FullClassName(field->message_type(), options) + "::class"); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(field->enum_type(), is_descriptor) + "::class"); + FullClassName(field->enum_type(), options) + "::class"); } else { printer->Print(");\n"); } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { printer->Print( "GPBUtil::checkMessage($var, \\^class_name^::class);\n", - "class_name", FullClassName(field->message_type(), is_descriptor)); + "class_name", FullClassName(field->message_type(), options)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( "GPBUtil::checkEnum($var, \\^class_name^::class);\n", - "class_name", FullClassName(field->enum_type(), is_descriptor)); + "class_name", FullClassName(field->enum_type(), options)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { printer->Print( "GPBUtil::checkString($var, ^utf8^);\n", @@ -929,17 +939,15 @@ void GenerateMessageToPool(const std::string& name_prefix, } } -void GenerateAddFileToPool( - const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, - io::Printer* printer) { +void GenerateAddFileToPool(const FileDescriptor* file, const Options& options, + io::Printer* printer) { printer->Print( "public static $is_initialized = false;\n\n" "public static function initOnce() {\n"); Indent(printer); - if (aggregate_metadata) { - GenerateAddFilesToPool(file, aggregate_metadata_prefixes, printer); + if (options.aggregate_metadata) { + GenerateAddFilesToPool(file, options, printer); } else { printer->Print( "$pool = \\Google\\Protobuf\\Internal\\" @@ -948,7 +956,7 @@ void GenerateAddFileToPool( " return;\n" "}\n"); - if (is_descriptor) { + if (options.is_descriptor) { for (int i = 0; i < file->message_type_count(); i++) { GenerateMessageToPool("", file->message_type(i), printer); } @@ -968,7 +976,7 @@ void GenerateAddFileToPool( continue; } std::string dependency_filename = - GeneratedMetadataFileName(file->dependency(i), is_descriptor); + GeneratedMetadataFileName(file->dependency(i), options); printer->Print( "\\^name^::initOnce();\n", "name", FilenameToClassname(dependency_filename)); @@ -1002,16 +1010,28 @@ void GenerateAddFileToPool( std::string files_data; files.SerializeToString(&files_data); - printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n"); + printer->Print("$pool->internalAddGeneratedFile(\n"); Indent(printer); + printer->Print("'"); + + for (auto ch : files_data) { + switch (ch) { + case '\\': + printer->Print(R"(\\)"); + break; + case '\'': + printer->Print(R"(\')"); + break; + default: + printer->Print("^char^", "char", std::string(1, ch)); + break; + } + } - printer->Print( - "\"^data^\"\n", - "data", BinaryToHex(files_data)); - + printer->Print("'\n"); Outdent(printer); printer->Print( - "), true);\n\n"); + ", true);\n\n"); } printer->Print( "static::$is_initialized = true;\n"); @@ -1054,14 +1074,13 @@ static void AnalyzeDependencyForFile( } } -static bool NeedsUnwrapping( - const FileDescriptor* file, - const std::set& aggregate_metadata_prefixes) { +static bool NeedsUnwrapping(const FileDescriptor* file, + const Options& options) { bool has_aggregate_metadata_prefix = false; - if (aggregate_metadata_prefixes.empty()) { + if (options.aggregate_metadata_prefixes.empty()) { has_aggregate_metadata_prefix = true; } else { - for (const auto& prefix : aggregate_metadata_prefixes) { + for (const auto& prefix : options.aggregate_metadata_prefixes) { if (HasPrefixString(file->package(), prefix)) { has_aggregate_metadata_prefix = true; break; @@ -1072,10 +1091,8 @@ static bool NeedsUnwrapping( return has_aggregate_metadata_prefix; } -void GenerateAddFilesToPool( - const FileDescriptor* file, - const std::set& aggregate_metadata_prefixes, - io::Printer* printer) { +void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, + io::Printer* printer) { printer->Print( "$pool = \\Google\\Protobuf\\Internal\\" "DescriptorPool::getGeneratedPool();\n" @@ -1104,7 +1121,7 @@ void GenerateAddFilesToPool( } } - bool needs_aggregate = NeedsUnwrapping(file, aggregate_metadata_prefixes); + bool needs_aggregate = NeedsUnwrapping(file, options); if (needs_aggregate) { auto file_proto = sorted_file_set.add_file(); @@ -1130,8 +1147,7 @@ void GenerateAddFilesToPool( it->clear_extension(); } } else { - std::string dependency_filename = - GeneratedMetadataFileName(file, false); + std::string dependency_filename = GeneratedMetadataFileName(file, false); printer->Print( "\\^name^::initOnce();\n", "name", FilenameToClassname(dependency_filename)); @@ -1141,23 +1157,35 @@ void GenerateAddFilesToPool( std::string files_data; sorted_file_set.SerializeToString(&files_data); - printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n"); + printer->Print("$pool->internalAddGeneratedFile(\n"); Indent(printer); + printer->Print("'"); - printer->Print( - "\"^data^\"\n", - "data", BinaryToHex(files_data)); + for (auto ch : files_data) { + switch (ch) { + case '\\': + printer->Print(R"(\\)"); + break; + case '\'': + printer->Print(R"(\')"); + break; + default: + printer->Print("^char^", "char", std::string(1, ch)); + break; + } + } + printer->Print("'\n"); Outdent(printer); printer->Print( - "), true);\n"); + ", true);\n"); printer->Print( "static::$is_initialized = true;\n"); } -void GenerateUseDeclaration(bool is_descriptor, io::Printer* printer) { - if (!is_descriptor) { +void GenerateUseDeclaration(const Options& options, io::Printer* printer) { + if (!options.is_descriptor) { printer->Print( "use Google\\Protobuf\\Internal\\GPBType;\n" "use Google\\Protobuf\\Internal\\RepeatedField;\n" @@ -1192,11 +1220,9 @@ std::string FilenameToClassname(const std::string& filename) { return result; } -void GenerateMetadataFile( - const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, - GeneratorContext* generator_context) { - std::string filename = GeneratedMetadataFileName(file, is_descriptor); +void GenerateMetadataFile(const FileDescriptor* file, const Options& options, + GeneratorContext* generator_context) { + std::string filename = GeneratedMetadataFileName(file, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1223,32 +1249,30 @@ void GenerateMetadataFile( } Indent(&printer); - GenerateAddFileToPool(file, is_descriptor, aggregate_metadata, - aggregate_metadata_prefixes, &printer); + GenerateAddFileToPool(file, options, &printer); Outdent(&printer); printer.Print("}\n\n"); } template -void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* desc, - bool is_descriptor, - GeneratorContext* generator_context) { - - std::string filename = LegacyGeneratedClassFileName(desc, is_descriptor); +void LegacyGenerateClassFile(const FileDescriptor* file, + const DescriptorType* desc, const Options& options, + GeneratorContext* generator_context) { + std::string filename = LegacyGeneratedClassFileName(desc, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); GenerateHead(file, &printer); - std::string php_namespace = RootPhpNamespace(desc, is_descriptor); + std::string php_namespace = RootPhpNamespace(desc, options); if (!php_namespace.empty()) { printer.Print( "namespace ^name^;\n\n", "name", php_namespace); } - std::string newname = FullClassName(desc, is_descriptor); + std::string newname = FullClassName(desc, options); printer.Print("if (false) {\n"); Indent(&printer); printer.Print("/**\n"); @@ -1264,13 +1288,14 @@ void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* d "new", GeneratedClassNameImpl(desc)); printer.Print("@trigger_error('^old^ is deprecated and will be removed in " "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n", - "old", LegacyFullClassName(desc, is_descriptor), + "old", LegacyFullClassName(desc, options), "fullname", newname); } void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, - bool is_descriptor, GeneratorContext* generator_context) { - std::string filename = GeneratedClassFileName(en, is_descriptor); + const Options& options, + GeneratorContext* generator_context) { + std::string filename = GeneratedClassFileName(en, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1290,7 +1315,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, printer.Print("use UnexpectedValueException;\n\n"); } - GenerateEnumDocComment(&printer, en, is_descriptor); + GenerateEnumDocComment(&printer, en, options); if (lastindex != std::string::npos) { fullname = fullname.substr(lastindex + 1); @@ -1367,14 +1392,13 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, printer.Print( "class_alias(^new^::class, \\^old^::class);\n\n", "new", fullname, - "old", LegacyFullClassName(en, is_descriptor)); - LegacyGenerateClassFile(file, en, is_descriptor, generator_context); + "old", LegacyFullClassName(en, options)); + LegacyGenerateClassFile(file, en, options, generator_context); } } void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, - bool is_descriptor, - bool aggregate_metadata, + const Options& options, GeneratorContext* generator_context) { // Don't generate MapEntry messages -- we use the PHP extension's native // support for map fields instead. @@ -1382,7 +1406,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, return; } - std::string filename = GeneratedClassFileName(message, is_descriptor); + std::string filename = GeneratedClassFileName(message, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1398,23 +1422,38 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, "name", fullname.substr(0, lastindex)); } - GenerateUseDeclaration(is_descriptor, &printer); + GenerateUseDeclaration(options, &printer); - GenerateMessageDocComment(&printer, message, is_descriptor); + GenerateMessageDocComment(&printer, message, options); if (lastindex != std::string::npos) { fullname = fullname.substr(lastindex + 1); } + std::string base; + + switch (message->well_known_type()) { + case Descriptor::WELLKNOWNTYPE_ANY: + base = "\\Google\\Protobuf\\Internal\\AnyBase"; + break; + case Descriptor::WELLKNOWNTYPE_TIMESTAMP: + base = "\\Google\\Protobuf\\Internal\\TimestampBase"; + break; + default: + base = "\\Google\\Protobuf\\Internal\\Message"; + break; + } + printer.Print( - "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n" + "class ^name^ extends ^base^\n" "{\n", + "base", base, "name", fullname); Indent(&printer); // Field and oneof definitions. for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); - GenerateField(field, &printer, is_descriptor); + GenerateField(field, &printer, options); } for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); @@ -1422,13 +1461,12 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, } printer.Print("\n"); - GenerateMessageConstructorDocComment(&printer, message, is_descriptor); + GenerateMessageConstructorDocComment(&printer, message, options); printer.Print( "public function __construct($data = NULL) {\n"); Indent(&printer); - std::string metadata_filename = - GeneratedMetadataFileName(file, is_descriptor); + std::string metadata_filename = GeneratedMetadataFileName(file, options); std::string metadata_fullname = FilenameToClassname(metadata_filename); printer.Print( "\\^fullname^::initOnce();\n", @@ -1443,7 +1481,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, // Field and oneof accessors. for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); - GenerateFieldAccessor(field, is_descriptor, &printer); + GenerateFieldAccessor(field, options, &printer); } for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); @@ -1469,26 +1507,24 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, printer.Print( "class_alias(^new^::class, \\^old^::class);\n\n", "new", fullname, - "old", LegacyFullClassName(message, is_descriptor)); - LegacyGenerateClassFile(file, message, is_descriptor, generator_context); + "old", LegacyFullClassName(message, options)); + LegacyGenerateClassFile(file, message, options, generator_context); } // Nested messages and enums. for (int i = 0; i < message->nested_type_count(); i++) { - GenerateMessageFile(file, message->nested_type(i), is_descriptor, - aggregate_metadata, + GenerateMessageFile(file, message->nested_type(i), options, generator_context); } for (int i = 0; i < message->enum_type_count(); i++) { - GenerateEnumFile(file, message->enum_type(i), is_descriptor, - generator_context); + GenerateEnumFile(file, message->enum_type(i), options, generator_context); } } -void GenerateServiceFile(const FileDescriptor* file, - const ServiceDescriptor* service, bool is_descriptor, - GeneratorContext* generator_context) { - std::string filename = GeneratedServiceFileName(service, is_descriptor); +void GenerateServiceFile( + const FileDescriptor* file, const ServiceDescriptor* service, + const Options& options, GeneratorContext* generator_context) { + std::string filename = GeneratedServiceFileName(service, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1532,26 +1568,20 @@ void GenerateServiceFile(const FileDescriptor* file, printer.Print("}\n\n"); } -void GenerateFile(const FileDescriptor* file, bool is_descriptor, - bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, +void GenerateFile(const FileDescriptor* file, const Options& options, GeneratorContext* generator_context) { - GenerateMetadataFile(file, is_descriptor, aggregate_metadata, - aggregate_metadata_prefixes, generator_context); + GenerateMetadataFile(file, options, generator_context); for (int i = 0; i < file->message_type_count(); i++) { - GenerateMessageFile(file, file->message_type(i), is_descriptor, - aggregate_metadata, + GenerateMessageFile(file, file->message_type(i), options, generator_context); } for (int i = 0; i < file->enum_type_count(); i++) { - GenerateEnumFile(file, file->enum_type(i), is_descriptor, - generator_context); + GenerateEnumFile(file, file->enum_type(i), options, generator_context); } if (file->options().php_generic_services()) { for (int i = 0; i < file->service_count(); i++) { - GenerateServiceFile(file, file->service(i), is_descriptor, - generator_context); + GenerateServiceFile(file, file->service(i), options, generator_context); } } } @@ -1655,20 +1685,20 @@ static std::string FirstLineOf(const std::string& value) { return result; } -void GenerateMessageDocComment(io::Printer* printer, - const Descriptor* message, int is_descriptor) { +void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, + const Options& options) { printer->Print("/**\n"); GenerateDocCommentBody(printer, message); printer->Print( " * Generated from protobuf message ^messagename^\n" " */\n", - "fullname", EscapePhpdoc(FullClassName(message, is_descriptor)), + "fullname", EscapePhpdoc(FullClassName(message, options)), "messagename", EscapePhpdoc(message->full_name())); } void GenerateMessageConstructorDocComment(io::Printer* printer, const Descriptor* message, - int is_descriptor) { + const Options& options) { // In theory we should have slightly different comments for setters, getters, // etc., but in practice everyone already knows the difference between these // so it's redundant information. @@ -1686,7 +1716,7 @@ void GenerateMessageConstructorDocComment(io::Printer* printer, for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); printer->Print(" * @type ^php_type^ $^var^\n", - "php_type", PhpSetterTypeName(field, is_descriptor), + "php_type", PhpSetterTypeName(field, options), "var", field->name()); SourceLocation location; if (field->GetSourceLocation(&location)) { @@ -1708,7 +1738,7 @@ void GenerateServiceDocComment(io::Printer* printer, } void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, - int is_descriptor, int function_type) { + const Options& options, int function_type) { // In theory we should have slightly different comments for setters, getters, // etc., but in practice everyone already knows the difference between these // so it's redundant information. @@ -1724,11 +1754,11 @@ void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, "def", EscapePhpdoc(FirstLineOf(field->DebugString()))); if (function_type == kFieldSetter) { printer->Print(" * @param ^php_type^ $var\n", - "php_type", PhpSetterTypeName(field, is_descriptor)); + "php_type", PhpSetterTypeName(field, options)); printer->Print(" * @return $this\n"); } else if (function_type == kFieldGetter) { printer->Print(" * @return ^php_type^\n", - "php_type", PhpGetterTypeName(field, is_descriptor)); + "php_type", PhpGetterTypeName(field, options)); } printer->Print(" */\n"); } @@ -1769,7 +1799,7 @@ void GenerateWrapperFieldSetterDocComment(io::Printer* printer, const FieldDescr } void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, - int is_descriptor) { + const Options& options) { printer->Print("/**\n"); GenerateDocCommentBody(printer, enum_); printer->Print( @@ -1789,7 +1819,7 @@ void GenerateEnumValueDocComment(io::Printer* printer, } void GenerateServiceMethodDocComment(io::Printer* printer, - const MethodDescriptor* method) { + const MethodDescriptor* method) { printer->Print("/**\n"); GenerateDocCommentBody(printer, method); printer->Print( @@ -1805,33 +1835,411 @@ void GenerateServiceMethodDocComment(io::Printer* printer, "return_type", EscapePhpdoc(FullClassName(method->output_type(), false))); } +std::string FilenameCName(const FileDescriptor* file) { + std::string c_name = file->name(); + c_name = StringReplace(c_name, ".", "_", true); + c_name = StringReplace(c_name, "/", "_", true); + return c_name; +} + +void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) { + std::string c_name = desc->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + std::string php_name = FullClassName(desc, Options()); + php_name = StringReplace(php_name, "\\", "\\\\", true); + printer->Print( + "/* $c_name$ */\n" + "\n" + "zend_class_entry* $c_name$_ce;\n" + "\n" + "PHP_METHOD($c_name$, name) {\n" + " $file_c_name$_AddDescriptor();\n" + " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" + " const char *name;\n" + " zend_long value;\n" + " if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"l\", &value) ==\n" + " FAILURE) {\n" + " return;\n" + " }\n" + " name = upb_enumdef_iton(e, value);\n" + " if (!name) {\n" + " zend_throw_exception_ex(NULL, 0,\n" + " \"$php_name$ has no name \"\n" + " \"defined for value \" ZEND_LONG_FMT \".\",\n" + " value);\n" + " return;\n" + " }\n" + " RETURN_STRING(name);\n" + "}\n" + "\n" + "PHP_METHOD($c_name$, value) {\n" + " $file_c_name$_AddDescriptor();\n" + " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" + " char *name = NULL;\n" + " size_t name_len;\n" + " int32_t num;\n" + " if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"s\", &name,\n" + " &name_len) == FAILURE) {\n" + " return;\n" + " }\n" + " if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n" + " zend_throw_exception_ex(NULL, 0,\n" + " \"$php_name$ has no value \"\n" + " \"defined for name %s.\",\n" + " name);\n" + " return;\n" + " }\n" + " RETURN_LONG(num);\n" + "}\n" + "\n" + "static zend_function_entry $c_name$_phpmethods[] = {\n" + " PHP_ME($c_name$, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n" + " PHP_ME($c_name$, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n" + " ZEND_FE_END\n" + "};\n" + "\n" + "static void $c_name$_ModuleInit() {\n" + " zend_class_entry tmp_ce;\n" + "\n" + " INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n" + " $c_name$_phpmethods);\n" + "\n" + " $c_name$_ce = zend_register_internal_class(&tmp_ce);\n", + "name", desc->full_name(), + "file_c_name", FilenameCName(desc->file()), + "c_name", c_name, + "php_name", php_name); + + for (int i = 0; i < desc->value_count(); i++) { + const EnumValueDescriptor* value = desc->value(i); + printer->Print( + " zend_declare_class_constant_long($c_name$_ce, \"$name$\",\n" + " strlen(\"$name$\"), $num$);\n", + "c_name", c_name, + "name", value->name(), + "num", std::to_string(value->number())); + } + + printer->Print( + "}\n" + "\n"); +} + +void GenerateCMessage(const Descriptor* message, io::Printer* printer) { + std::string c_name = message->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + std::string php_name = FullClassName(message, Options()); + php_name = StringReplace(php_name, "\\", "\\\\", true); + printer->Print( + "/* $c_name$ */\n" + "\n" + "zend_class_entry* $c_name$_ce;\n" + "\n" + "static PHP_METHOD($c_name$, __construct) {\n" + " $file_c_name$_AddDescriptor();\n" + " zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n" + "}\n" + "\n", + "file_c_name", FilenameCName(message->file()), + "c_name", c_name); + + for (int i = 0; i < message->field_count(); i++) { + auto field = message->field(i); + printer->Print( + "static PHP_METHOD($c_name$, get$camel_name$) {\n" + " Message* intern = (Message*)Z_OBJ_P(getThis());\n" + " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" + " \"$name$\");\n" + " zval ret;\n" + " Message_get(intern, f, &ret);\n" + " RETURN_ZVAL(&ret, 1, 0);\n" + "}\n" + "\n" + "static PHP_METHOD($c_name$, set$camel_name$) {\n" + " Message* intern = (Message*)Z_OBJ_P(getThis());\n" + " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" + " \"$name$\");\n" + " zval *val;\n" + " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"z\", &val)\n" + " == FAILURE) {\n" + " return;\n" + " }\n" + " Message_set(intern, f, val);\n" + " RETURN_ZVAL(getThis(), 1, 0);\n" + "}\n" + "\n", + "c_name", c_name, + "name", field->name(), + "camel_name", UnderscoresToCamelCase(field->name(), true)); + } + + for (int i = 0; i < message->real_oneof_decl_count(); i++) { + auto oneof = message->oneof_decl(i); + printer->Print( + "static PHP_METHOD($c_name$, get$camel_name$) {\n" + " Message* intern = (Message*)Z_OBJ_P(getThis());\n" + " const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n" + " \"$name$\");\n" + " const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n" + " RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n" + "}\n", + "c_name", c_name, + "name", oneof->name(), + "camel_name", UnderscoresToCamelCase(oneof->name(), true)); + } + + printer->Print( + "static zend_function_entry $c_name$_phpmethods[] = {\n" + " PHP_ME($c_name$, __construct, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name); + + for (int i = 0; i < message->field_count(); i++) { + auto field = message->field(i); + printer->Print( + " PHP_ME($c_name$, get$camel_name$, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, set$camel_name$, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name, + "camel_name", UnderscoresToCamelCase(field->name(), true)); + } + + for (int i = 0; i < message->real_oneof_decl_count(); i++) { + auto oneof = message->oneof_decl(i); + printer->Print( + " PHP_ME($c_name$, get$camel_name$, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name, + "camel_name", UnderscoresToCamelCase(oneof->name(), true)); + } + + // Extra hand-written functions added to the well-known types. + switch (message->well_known_type()) { + case Descriptor::WELLKNOWNTYPE_ANY: + printer->Print( + " PHP_ME($c_name$, is, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, pack, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, unpack, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name); + break; + case Descriptor::WELLKNOWNTYPE_TIMESTAMP: + printer->Print( + " PHP_ME($c_name$, fromDateTime, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, toDateTime, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name); + break; + default: + break; + } + + printer->Print( + " ZEND_FE_END\n" + "};\n" + "\n" + "static void $c_name$_ModuleInit() {\n" + " zend_class_entry tmp_ce;\n" + "\n" + " INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n" + " $c_name$_phpmethods);\n" + "\n" + " $c_name$_ce = zend_register_internal_class(&tmp_ce);\n" + " $c_name$_ce->ce_flags |= ZEND_ACC_FINAL;\n" + " $c_name$_ce->create_object = Message_create;\n" + " zend_do_inheritance($c_name$_ce, message_ce);\n" + "}\n" + "\n", + "c_name", c_name, + "php_name", php_name); + + for (int i = 0; i < message->nested_type_count(); i++) { + GenerateCMessage(message->nested_type(i), printer); + } + for (int i = 0; i < message->enum_type_count(); i++) { + GenerateCEnum(message->enum_type(i), printer); + } +} + +void GenerateEnumCInit(const EnumDescriptor* desc, io::Printer* printer) { + std::string c_name = desc->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + + printer->Print( + " $c_name$_ModuleInit();\n", + "c_name", c_name); +} + +void GenerateCInit(const Descriptor* message, io::Printer* printer) { + std::string c_name = message->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + + printer->Print( + " $c_name$_ModuleInit();\n", + "c_name", c_name); + + for (int i = 0; i < message->nested_type_count(); i++) { + GenerateCInit(message->nested_type(i), printer); + } + for (int i = 0; i < message->enum_type_count(); i++) { + GenerateEnumCInit(message->enum_type(i), printer); + } +} + +void GenerateCWellKnownTypes(const std::vector& files, + GeneratorContext* context) { + std::unique_ptr output( + context->Open("../ext/google/protobuf/wkt.inc")); + io::Printer printer(output.get(), '$'); + + printer.Print( + "// This file is generated from the .proto files for the well-known\n" + "// types. Do not edit!\n"); + + for (auto file : files) { + printer.Print( + "static void $c_name$_AddDescriptor();\n", + "c_name", FilenameCName(file)); + } + + for (auto file : files) { + std::string c_name = FilenameCName(file); + std::string metadata_filename = GeneratedMetadataFileName(file, Options()); + std::string metadata_classname = FilenameToClassname(metadata_filename); + std::string metadata_c_name = + StringReplace(metadata_classname, "\\", "_", true); + metadata_classname = StringReplace(metadata_classname, "\\", "\\\\", true); + FileDescriptorProto file_proto; + file->CopyTo(&file_proto); + std::string serialized; + file_proto.SerializeToString(&serialized); + printer.Print( + "/* $filename$ */\n" + "\n" + "zend_class_entry* $metadata_c_name$_ce;\n" + "\n" + "const char $c_name$_descriptor [$size$] = {\n", + "filename", file->name(), + "c_name", c_name, + "metadata_c_name", metadata_c_name, + "size", std::to_string(serialized.size())); + + for (size_t i = 0; i < serialized.size();) { + for (size_t j = 0; j < 25 && i < serialized.size(); ++i, ++j) { + printer.Print("'$ch$', ", "ch", CEscape(serialized.substr(i, 1))); + } + printer.Print("\n"); + } + + printer.Print( + "};\n" + "\n" + "static void $c_name$_AddDescriptor() {\n" + " if (DescriptorPool_HasFile(\"$filename$\")) return;\n", + "filename", file->name(), + "c_name", c_name, + "metadata_c_name", metadata_c_name); + + for (int i = 0; i < file->dependency_count(); i++) { + std::string dep_c_name = FilenameCName(file->dependency(i)); + printer.Print( + " $dep_c_name$_AddDescriptor();\n", + "dep_c_name", dep_c_name); + } + + printer.Print( + " DescriptorPool_AddDescriptor(\"$filename$\", $c_name$_descriptor,\n" + " sizeof($c_name$_descriptor));\n" + "}\n" + "\n" + "static PHP_METHOD($metadata_c_name$, initOnce) {\n" + " $c_name$_AddDescriptor();\n" + "}\n" + "\n" + "static zend_function_entry $metadata_c_name$_methods[] = {\n" + " PHP_ME($metadata_c_name$, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n" + " ZEND_FE_END\n" + "};\n" + "\n" + "static void $metadata_c_name$_ModuleInit() {\n" + " zend_class_entry tmp_ce;\n" + "\n" + " INIT_CLASS_ENTRY(tmp_ce, \"$metadata_classname$\",\n" + " $metadata_c_name$_methods);\n" + "\n" + " $metadata_c_name$_ce = zend_register_internal_class(&tmp_ce);\n" + "}\n" + "\n", + "filename", file->name(), + "c_name", c_name, + "metadata_c_name", metadata_c_name, + "metadata_classname", metadata_classname); + for (int i = 0; i < file->message_type_count(); i++) { + GenerateCMessage(file->message_type(i), &printer); + } + for (int i = 0; i < file->enum_type_count(); i++) { + GenerateCEnum(file->enum_type(i), &printer); + } + } + + printer.Print( + "static void WellKnownTypes_ModuleInit() {\n"); + + for (auto file : files) { + std::string metadata_filename = GeneratedMetadataFileName(file, Options()); + std::string metadata_classname = FilenameToClassname(metadata_filename); + std::string metadata_c_name = + StringReplace(metadata_classname, "\\", "_", true); + printer.Print( + " $metadata_c_name$_ModuleInit();\n", + "metadata_c_name", metadata_c_name); + for (int i = 0; i < file->message_type_count(); i++) { + GenerateCInit(file->message_type(i), &printer); + } + for (int i = 0; i < file->enum_type_count(); i++) { + GenerateEnumCInit(file->enum_type(i), &printer); + } + } + + printer.Print( + "}\n"); +} + +} // namespace + +std::string GeneratedClassName(const Descriptor* desc) { + return GeneratedClassNameImpl(desc); +} + +std::string GeneratedClassName(const EnumDescriptor* desc) { + return GeneratedClassNameImpl(desc); +} + +std::string GeneratedClassName(const ServiceDescriptor* desc) { + return GeneratedClassNameImpl(desc); +} + bool Generator::Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* generator_context, std::string* error) const { - return Generate(file, false, false, std::set(), - generator_context, error); + return Generate(file, Options(), generator_context, error); } -bool Generator::Generate( - const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, - GeneratorContext* generator_context, std::string* error) const { - if (is_descriptor && file->name() != kDescriptorFile) { +bool Generator::Generate(const FileDescriptor* file, const Options& options, + GeneratorContext* generator_context, + std::string* error) const { + if (options.is_descriptor && file->name() != kDescriptorFile) { *error = "Can only generate PHP code for google/protobuf/descriptor.proto.\n"; return false; } - if (!is_descriptor && file->syntax() != FileDescriptor::SYNTAX_PROTO3) { + if (!options.is_descriptor && file->syntax() != FileDescriptor::SYNTAX_PROTO3) { *error = "Can only generate PHP code for proto3 .proto files.\n" "Please add 'syntax = \"proto3\";' to the top of your .proto file.\n"; return false; } - GenerateFile(file, is_descriptor, aggregate_metadata, - aggregate_metadata_prefixes, generator_context); + GenerateFile(file, options, generator_context); return true; } @@ -1840,35 +2248,31 @@ bool Generator::GenerateAll(const std::vector& files, const std::string& parameter, GeneratorContext* generator_context, std::string* error) const { - bool is_descriptor = false; - bool aggregate_metadata = false; - std::set aggregate_metadata_prefixes; + Options options; for (const auto& option : Split(parameter, ",", true)) { const std::vector option_pair = Split(option, "=", true); if (HasPrefixString(option_pair[0], "aggregate_metadata")) { - std::string options_string = option_pair[1]; - const std::vector options = - Split(options_string, "#", false); - aggregate_metadata = true; - for (int i = 0; i < options.size(); i++) { - aggregate_metadata_prefixes.insert(options[i]); - GOOGLE_LOG(INFO) << options[i]; + options.aggregate_metadata = true; + for (const auto& prefix : Split(option_pair[1], "#", false)) { + options.aggregate_metadata_prefixes.insert(prefix); + GOOGLE_LOG(INFO) << prefix; } - } - if (option_pair[0] == "internal") { - is_descriptor = true; + } else if (option_pair[0] == "internal") { + options.is_descriptor = true; + } else if (option_pair[0] == "internal_generate_c_wkt") { + GenerateCWellKnownTypes(files, generator_context); + } else { + GOOGLE_LOG(FATAL) << "Unknown codegen option: " << option_pair[0]; } } for (auto file : files) { - if (!Generate( - file, is_descriptor, aggregate_metadata, - aggregate_metadata_prefixes, - generator_context, error)) { + if (!Generate(file, options, generator_context, error)) { return false; } } + return true; } diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index a3ca6092f996..17cb59c08b6a 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -43,6 +43,8 @@ namespace protobuf { namespace compiler { namespace php { +struct Options; + class PROTOC_EXPORT Generator : public CodeGenerator { public: virtual bool Generate( @@ -63,9 +65,7 @@ class PROTOC_EXPORT Generator : public CodeGenerator { private: bool Generate( const FileDescriptor* file, - bool is_descriptor, - bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, + const Options& options, GeneratorContext* generator_context, std::string* error) const; }; diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index a173a78b4928..58283cd742bd 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto; @@ -204,7 +206,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); PROTOBUF_NAMESPACE_OPEN namespace compiler { const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor() { @@ -272,8 +274,9 @@ Version::Version(const Version& from) void Version::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base); suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&major_, 0, static_cast( - reinterpret_cast(&patch_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&major_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&patch_) - reinterpret_cast(&major_)) + sizeof(patch_)); } @@ -325,7 +328,6 @@ void Version::Clear() { const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -662,7 +664,6 @@ void CodeGeneratorRequest::Clear() { const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1033,7 +1034,6 @@ void CodeGeneratorResponse_File::Clear() { const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1360,7 +1360,6 @@ void CodeGeneratorResponse::Clear() { const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 8998e1bd7832..7af37c57f309 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -855,15 +855,15 @@ void DescriptorPool::Tables::RollbackToLastCheckpoint() { GOOGLE_DCHECK(!checkpoints_.empty()); const CheckPoint& checkpoint = checkpoints_.back(); - for (int i = checkpoint.pending_symbols_before_checkpoint; + for (size_t i = checkpoint.pending_symbols_before_checkpoint; i < symbols_after_checkpoint_.size(); i++) { symbols_by_name_.erase(symbols_after_checkpoint_[i]); } - for (int i = checkpoint.pending_files_before_checkpoint; + for (size_t i = checkpoint.pending_files_before_checkpoint; i < files_after_checkpoint_.size(); i++) { files_by_name_.erase(files_after_checkpoint_[i]); } - for (int i = checkpoint.pending_extensions_before_checkpoint; + for (size_t i = checkpoint.pending_extensions_before_checkpoint; i < extensions_after_checkpoint_.size(); i++) { extensions_.erase(extensions_after_checkpoint_[i]); } @@ -4203,13 +4203,13 @@ void DescriptorBuilder::AllocateOptionsImpl( void DescriptorBuilder::AddRecursiveImportError( const FileDescriptorProto& proto, int from_here) { std::string error_message("File recursively imports itself: "); - for (int i = from_here; i < tables_->pending_files_.size(); i++) { + for (size_t i = from_here; i < tables_->pending_files_.size(); i++) { error_message.append(tables_->pending_files_[i]); error_message.append(" -> "); } error_message.append(proto.name()); - if (from_here < tables_->pending_files_.size() - 1) { + if (static_cast(from_here) < tables_->pending_files_.size() - 1) { AddError(tables_->pending_files_[from_here + 1], proto, DescriptorPool::ErrorCollector::IMPORT, error_message); } else { @@ -4282,7 +4282,7 @@ const FileDescriptor* DescriptorBuilder::BuildFile( // mid-file, but that's pretty ugly, and I'm pretty sure there are // some languages out there that do not allow recursive dependencies // at all. - for (int i = 0; i < tables_->pending_files_.size(); i++) { + for (size_t i = 0; i < tables_->pending_files_.size(); i++) { if (tables_->pending_files_[i] == proto.name()) { AddRecursiveImportError(proto, i); return nullptr; @@ -6702,10 +6702,10 @@ void DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo( if (matched) { // see if this location is in the range to remove bool loc_matches = true; - if (loc->path_size() < pathv.size()) { + if (loc->path_size() < static_cast(pathv.size())) { loc_matches = false; } else { - for (int j = 0; j < pathv.size(); j++) { + for (size_t j = 0; j < pathv.size(); j++) { if (loc->path(j) != pathv[j]) { loc_matches = false; break; @@ -7444,3 +7444,5 @@ void LazyDescriptor::OnceInternal() { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 5bfecf508966..0625b5022156 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -1491,7 +1491,8 @@ class PROTOBUF_EXPORT FileDescriptor { Syntax syntax() const; static const char* SyntaxName(Syntax syntax); - // Find a top-level message type by name. Returns nullptr if not found. + // Find a top-level message type by name (not full_name). Returns nullptr if + // not found. const Descriptor* FindMessageTypeByName(ConstStringParam name) const; // Find a top-level enum type by name. Returns nullptr if not found. const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const; diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 288ff0659a54..d9590f8b8e8b 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto; @@ -1174,7 +1176,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); PROTOBUF_NAMESPACE_OPEN const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descriptor() { ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); @@ -1406,7 +1408,6 @@ void FileDescriptorSet::Clear() { const char* FileDescriptorSet::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1636,8 +1637,9 @@ void FileDescriptorProto::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&source_code_info_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&source_code_info_) - reinterpret_cast(&options_)) + sizeof(source_code_info_)); } @@ -1711,7 +1713,6 @@ void FileDescriptorProto::Clear() { const char* FileDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -2250,8 +2251,9 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorP void DescriptorProto_ExtensionRange::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&options_)) + sizeof(end_)); } @@ -2304,7 +2306,6 @@ void DescriptorProto_ExtensionRange::Clear() { const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -2537,8 +2538,9 @@ DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorPro } void DescriptorProto_ReservedRange::SharedCtor() { - ::memset(&start_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&start_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&start_)) + sizeof(end_)); } @@ -2586,7 +2588,6 @@ void DescriptorProto_ReservedRange::Clear() { const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -2882,7 +2883,6 @@ void DescriptorProto::Clear() { const char* DescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -3372,7 +3372,6 @@ void ExtensionRangeOptions::Clear() { const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -3629,8 +3628,9 @@ void FieldDescriptorProto::SharedCtor() { type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&proto3_optional_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&proto3_optional_) - reinterpret_cast(&options_)) + sizeof(proto3_optional_)); label_ = 1; type_ = 1; @@ -3712,7 +3712,6 @@ void FieldDescriptorProto::Clear() { const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -4257,7 +4256,6 @@ void OneofDescriptorProto::Clear() { const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -4468,8 +4466,9 @@ EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(con } void EnumDescriptorProto_EnumReservedRange::SharedCtor() { - ::memset(&start_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&start_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&start_)) + sizeof(end_)); } @@ -4517,7 +4516,6 @@ void EnumDescriptorProto_EnumReservedRange::Clear() { const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -4798,7 +4796,6 @@ void EnumDescriptorProto::Clear() { const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -5122,8 +5119,9 @@ EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProt void EnumValueDescriptorProto::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&number_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&number_) - reinterpret_cast(&options_)) + sizeof(number_)); } @@ -5178,7 +5176,6 @@ void EnumValueDescriptorProto::Clear() { const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -5489,7 +5486,6 @@ void ServiceDescriptorProto::Clear() { const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -5771,8 +5767,9 @@ void MethodDescriptorProto::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&server_streaming_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&server_streaming_) - reinterpret_cast(&options_)) + sizeof(server_streaming_)); } @@ -5837,7 +5834,6 @@ void MethodDescriptorProto::Clear() { const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -6281,8 +6277,9 @@ void FileOptions::SharedCtor() { php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&java_multiple_files_, 0, static_cast( - reinterpret_cast(&deprecated_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&java_multiple_files_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&deprecated_) - reinterpret_cast(&java_multiple_files_)) + sizeof(deprecated_)); optimize_for_ = 1; cc_enable_arenas_ = true; @@ -6385,7 +6382,6 @@ void FileOptions::Clear() { const char* FileOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -7158,8 +7154,9 @@ MessageOptions::MessageOptions(const MessageOptions& from) void MessageOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&message_set_wire_format_, 0, static_cast( - reinterpret_cast(&map_entry_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&message_set_wire_format_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&map_entry_) - reinterpret_cast(&message_set_wire_format_)) + sizeof(map_entry_)); } @@ -7206,7 +7203,6 @@ void MessageOptions::Clear() { const char* MessageOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -7516,8 +7512,9 @@ FieldOptions::FieldOptions(const FieldOptions& from) void FieldOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&ctype_, 0, static_cast( - reinterpret_cast(&jstype_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&ctype_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&jstype_) - reinterpret_cast(&ctype_)) + sizeof(jstype_)); } @@ -7567,7 +7564,6 @@ void FieldOptions::Clear() { const char* FieldOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -7950,7 +7946,6 @@ void OneofOptions::Clear() { const char* OneofOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -8144,8 +8139,9 @@ EnumOptions::EnumOptions(const EnumOptions& from) void EnumOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&allow_alias_, 0, static_cast( - reinterpret_cast(&deprecated_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&allow_alias_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&deprecated_) - reinterpret_cast(&allow_alias_)) + sizeof(deprecated_)); } @@ -8192,7 +8188,6 @@ void EnumOptions::Clear() { const char* EnumOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -8485,7 +8480,6 @@ void EnumValueOptions::Clear() { const char* EnumValueOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -8745,7 +8739,6 @@ void ServiceOptions::Clear() { const char* ServiceOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -8966,8 +8959,9 @@ MethodOptions::MethodOptions(const MethodOptions& from) void MethodOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&deprecated_, 0, static_cast( - reinterpret_cast(&idempotency_level_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&deprecated_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&idempotency_level_) - reinterpret_cast(&deprecated_)) + sizeof(idempotency_level_)); } @@ -9017,7 +9011,6 @@ void MethodOptions::Clear() { const char* MethodOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -9327,7 +9320,6 @@ void UninterpretedOption_NamePart::Clear() { const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -9582,8 +9574,9 @@ void UninterpretedOption::SharedCtor() { identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&positive_int_value_, 0, static_cast( - reinterpret_cast(&double_value_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&positive_int_value_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&double_value_) - reinterpret_cast(&positive_int_value_)) + sizeof(double_value_)); } @@ -9646,7 +9639,6 @@ void UninterpretedOption::Clear() { const char* UninterpretedOption::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -10062,7 +10054,6 @@ void SourceCodeInfo_Location::Clear() { const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -10415,7 +10406,6 @@ void SourceCodeInfo::Clear() { const char* SourceCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -10597,8 +10587,9 @@ GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeIn void GeneratedCodeInfo_Annotation::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto.base); source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&begin_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&begin_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&begin_)) + sizeof(end_)); } @@ -10651,7 +10642,6 @@ void GeneratedCodeInfo_Annotation::Clear() { const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -10955,7 +10945,6 @@ void GeneratedCodeInfo::Clear() { const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index 92f27320330a..5f53cd138185 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -625,7 +625,7 @@ bool EncodedDescriptorDatabase::DescriptorIndex::AddFile(const FileProto& file, Value value) { // We push `value` into the array first. This is important because the AddXXX // functions below will expect it to be there. - all_values_.push_back({value.first, value.second}); + all_values_.push_back({value.first, value.second, {}}); if (!ValidateSymbolName(file.package())) { GOOGLE_LOG(ERROR) << "Invalid package name: " << file.package(); @@ -962,14 +962,14 @@ bool MergedDescriptorDatabase::FindFileByName(const std::string& filename, bool MergedDescriptorDatabase::FindFileContainingSymbol( const std::string& symbol_name, FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { + for (size_t i = 0; i < sources_.size(); i++) { if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) { // The symbol was found in source i. However, if one of the previous // sources defines a file with the same name (which presumably doesn't // contain the symbol, since it wasn't found in that source), then we // must hide it from the caller. FileDescriptorProto temp; - for (int j = 0; j < i; j++) { + for (size_t j = 0; j < i; j++) { if (sources_[j]->FindFileByName(output->name(), &temp)) { // Found conflicting file in a previous source. return false; @@ -984,7 +984,7 @@ bool MergedDescriptorDatabase::FindFileContainingSymbol( bool MergedDescriptorDatabase::FindFileContainingExtension( const std::string& containing_type, int field_number, FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { + for (size_t i = 0; i < sources_.size(); i++) { if (sources_[i]->FindFileContainingExtension(containing_type, field_number, output)) { // The symbol was found in source i. However, if one of the previous @@ -992,7 +992,7 @@ bool MergedDescriptorDatabase::FindFileContainingExtension( // contain the symbol, since it wasn't found in that source), then we // must hide it from the caller. FileDescriptorProto temp; - for (int j = 0; j < i; j++) { + for (size_t j = 0; j < i; j++) { if (sources_[j]->FindFileByName(output->name(), &temp)) { // Found conflicting file in a previous source. return false; diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 331a0c5b6fab..2521d92c0ae3 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -1851,12 +1851,17 @@ class ExtensionDescriptorTest : public testing::Test { // extensions 10 to 19; // extensions 30 to 39; // } - // extends Foo with optional int32 foo_int32 = 10; - // extends Foo with repeated TestEnum foo_enum = 19; + // extend Foo { + // optional int32 foo_int32 = 10; + // } + // extend Foo { + // repeated TestEnum foo_enum = 19; + // } // message Bar { - // extends Foo with optional Qux foo_message = 30; - // // (using Qux as the group type) - // extends Foo with repeated group foo_group = 39; + // extend Foo { + // optional Qux foo_message = 30; + // repeated Qux foo_group = 39; // (but internally set to TYPE_GROUP) + // } // } FileDescriptorProto foo_file; @@ -8110,3 +8115,5 @@ TEST_F(LazilyBuildDependenciesTest, Dependency) { } // namespace descriptor_unittest } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index 2284cdc5f0fd..87f54dff38b7 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class DurationDefaultTypeInternal { public: @@ -76,7 +78,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fduration_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto(&descriptor_table_google_2fprotobuf_2fduration_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -101,8 +103,9 @@ Duration::Duration(const Duration& from) } void Duration::SharedCtor() { - ::memset(&seconds_, 0, static_cast( - reinterpret_cast(&nanos_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&seconds_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); } @@ -145,7 +148,6 @@ void Duration::Clear() { const char* Duration::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index e57d27f51a05..3a484941d68e 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -509,7 +509,7 @@ DynamicMessage::~DynamicMessage() { void* field_ptr = OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * field->containing_oneof()->index()); - if (*(reinterpret_cast(field_ptr)) == field->number()) { + if (*(reinterpret_cast(field_ptr)) == field->number()) { field_ptr = OffsetToPointer( type_info_->offsets[descriptor->field_count() + field->containing_oneof()->index()]); diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index f30f2c97d29d..2c6346d7e6bc 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class EmptyDefaultTypeInternal { public: @@ -73,7 +75,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fempty_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto(&descriptor_table_google_2fprotobuf_2fempty_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -133,7 +135,6 @@ void Empty::Clear() { const char* Empty::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index bfa1c42a88ad..08848c8e8313 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -180,7 +180,6 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, Register(containing_type, number, info); } - // =================================================================== // Constructors and basic methods. @@ -2141,3 +2140,5 @@ size_t ExtensionSet::MessageSetByteSize() const { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index b3a6e3a07b5e..a74d2a96a6df 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -1328,7 +1328,9 @@ RepeatedMessageTypeTraits::GetDefaultRepeatedField() { // ExtensionIdentifier // This is the type of actual extension objects. E.g. if you have: -// extends Foo with optional int32 bar = 1234; +// extend Foo { +// optional int32 bar = 1234; +// } // then "bar" will be defined in C++ as: // ExtensionIdentifier, 5, false> bar(1234); // diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 86e710c6f7d7..76ac0766f6d4 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -534,3 +534,5 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index 2c299c15cafc..6a6fc25b3cd5 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -1335,3 +1335,5 @@ TEST(ExtensionSetTest, ConstInit) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index 4389093b6b1a..a3822eaca707 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class FieldMaskDefaultTypeInternal { public: @@ -75,7 +77,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -139,7 +141,6 @@ void FieldMask::Clear() { const char* FieldMask::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/generated_enum_util.cc b/src/google/protobuf/generated_enum_util.cc index d0c25a96d963..df7583e99984 100644 --- a/src/google/protobuf/generated_enum_util.cc +++ b/src/google/protobuf/generated_enum_util.cc @@ -83,7 +83,7 @@ int LookUpEnumName(const EnumEntry* enums, const int* sorted_indices, bool InitializeEnumStrings( const EnumEntry* enums, const int* sorted_indices, size_t size, internal::ExplicitlyConstructed* enum_strings) { - for (int i = 0; i < size; ++i) { + for (size_t i = 0; i < size; ++i) { enum_strings[i].Construct(enums[sorted_indices[i]].name); internal::OnShutdownDestroyString(enum_strings[i].get_mutable()); } diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index e8b19c862b6d..b81f58339736 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -836,7 +836,7 @@ void Reflection::ClearField(Message* message, } case FieldDescriptor::CPPTYPE_MESSAGE: - if (schema_.HasBitIndex(field) == -1) { + if (schema_.HasBitIndex(field) == static_cast(-1)) { // Proto3 does not have has-bits and we need to set a message field // to nullptr in order to indicate its un-presence. if (GetArena(message) == nullptr) { @@ -1046,7 +1046,8 @@ void Reflection::ListFieldsMayFailOnStripped( schema_.HasHasbits() ? GetHasBits(message) : nullptr; const uint32* const has_bits_indices = schema_.has_bit_indices_; output->reserve(descriptor_->field_count()); - for (int i = 0; i <= last_non_weak_field_index_; i++) { + const int last_non_weak_field_index = last_non_weak_field_index_; + for (int i = 0; i <= last_non_weak_field_index; i++) { const FieldDescriptor* field = descriptor_->field(i); if (!should_fail && schema_.IsFieldStripped(field)) { continue; @@ -1061,10 +1062,11 @@ void Reflection::ListFieldsMayFailOnStripped( const uint32* const oneof_case_array = GetConstPointerAtOffset( &message, schema_.oneof_case_offset_); // Equivalent to: HasOneofField(message, field) - if (oneof_case_array[containing_oneof->index()] == field->number()) { + if (static_cast(oneof_case_array[containing_oneof->index()]) == + field->number()) { output->push_back(field); } - } else if (has_bits && has_bits_indices[i] != -1) { + } else if (has_bits && has_bits_indices[i] != static_cast(-1)) { CheckInvalidAccess(schema_, field); // Equivalent to: HasBit(message, field) if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) { @@ -2005,7 +2007,7 @@ InternalMetadata* Reflection::MutableInternalMetadata(Message* message) const { bool Reflection::HasBit(const Message& message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); - if (schema_.HasBitIndex(field) != -1) { + if (schema_.HasBitIndex(field) != static_cast(-1)) { return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field)); } @@ -2064,7 +2066,7 @@ bool Reflection::HasBit(const Message& message, void Reflection::SetBit(Message* message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); const uint32 index = schema_.HasBitIndex(field); - if (index == -1) return; + if (index == static_cast(-1)) return; MutableHasBits(message)[index / 32] |= (static_cast(1) << (index % 32)); } @@ -2073,7 +2075,7 @@ void Reflection::ClearBit(Message* message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); const uint32 index = schema_.HasBitIndex(field); - if (index == -1) return; + if (index == static_cast(-1)) return; MutableHasBits(message)[index / 32] &= ~(static_cast(1) << (index % 32)); } @@ -2107,7 +2109,8 @@ bool Reflection::HasOneof(const Message& message, bool Reflection::HasOneofField(const Message& message, const FieldDescriptor* field) const { - return (GetOneofCase(message, field->containing_oneof()) == field->number()); + return (GetOneofCase(message, field->containing_oneof()) == + static_cast(field->number())); } void Reflection::SetOneofCase(Message* message, @@ -2416,6 +2419,8 @@ struct MetadataOwner { std::vector > metadata_arrays_; }; +void AddDescriptors(const DescriptorTable* table); + void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) { // Ensure the file descriptor is added to the pool. { @@ -2493,6 +2498,16 @@ void AddDescriptorsImpl(const DescriptorTable* table) { MessageFactory::InternalRegisterGeneratedFile(table); } +void AddDescriptors(const DescriptorTable* table) { + // AddDescriptors is not thread safe. Callers need to ensure calls are + // properly serialized. This function is only called pre-main by global + // descriptors and we can assume single threaded access or it's called + // by AssignDescriptorImpl which uses a mutex to sequence calls. + if (table->is_initialized) return; + table->is_initialized = true; + AddDescriptorsImpl(table); +} + } // namespace // Separate function because it needs to be a friend of @@ -2513,14 +2528,8 @@ void AssignDescriptors(const DescriptorTable* table, bool eager) { call_once(*table->once, AssignDescriptorsImpl, table, eager); } -void AddDescriptors(const DescriptorTable* table) { - // AddDescriptors is not thread safe. Callers need to ensure calls are - // properly serialized. This function is only called pre-main by global - // descriptors and we can assume single threaded access or it's called - // by AssignDescriptorImpl which uses a mutex to sequence calls. - if (table->is_initialized) return; - table->is_initialized = true; - AddDescriptorsImpl(table); +AddDescriptorsRunner::AddDescriptorsRunner(const DescriptorTable* table) { + AddDescriptors(table); } void RegisterFileLevelMetadata(const DescriptorTable* table) { @@ -2544,3 +2553,5 @@ void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 12abb4f97f70..2ffa7d2c724e 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -291,18 +291,15 @@ enum { void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table, bool eager = false); -// AddDescriptors() is a file-level procedure which adds the encoded -// FileDescriptorProto for this .proto file to the global DescriptorPool for -// generated files (DescriptorPool::generated_pool()). It ordinarily runs at -// static initialization time, but is not used at all in LITE_RUNTIME mode. -// AddDescriptors() is *not* thread-safe. -void PROTOBUF_EXPORT AddDescriptors(const DescriptorTable* table); - // These cannot be in lite so we put them in the reflection. PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag, uint32 has_offset, io::CodedOutputStream* output); +struct PROTOBUF_EXPORT AddDescriptorsRunner { + explicit AddDescriptorsRunner(const DescriptorTable* table); +}; + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h index 3c65acdfe870..6813d18bdf42 100644 --- a/src/google/protobuf/generated_message_table_driven_lite.h +++ b/src/google/protobuf/generated_message_table_driven_lite.h @@ -172,7 +172,7 @@ template inline void ResetOneofField(const ParseTable& table, int field_number, Arena* arena, MessageLite* msg, uint32* oneof_case, int64 offset, const void* default_ptr) { - if (*oneof_case == field_number) { + if (static_cast(*oneof_case) == field_number) { // The oneof is already set to the right type, so there is no need to clear // it. return; diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index f1f6f88332c7..8f86f6087456 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -52,10 +52,14 @@ #include #include #include -#include #include #include +// Must be included last +#include + +PROTOBUF_PRAGMA_INIT_SEG + namespace google { namespace protobuf { @@ -68,8 +72,9 @@ void DestroyString(const void* s) { static_cast(s)->~basic_string(); } -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EmptyString - fixed_address_empty_string; // NOLINT +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY EmptyString + fixed_address_empty_string; // NOLINT PROTOBUF_CONSTINIT std::atomic init_protobuf_defaults_state{false}; @@ -90,6 +95,11 @@ void InitProtobufDefaultsSlow() { static bool is_inited = InitProtobufDefaultsImpl(); (void)is_inited; } +// Force the initialization of the empty string. +// Normally, registration would do it, but we don't have any guarantee that +// there is any object with reflection. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static std::true_type init_empty_string = + (InitProtobufDefaultsSlow(), std::true_type{}); size_t StringSpaceUsedExcludingSelfLong(const std::string& str) { const void* start = &str; @@ -802,3 +812,5 @@ void InitSCCImpl(SCCInfoBase* scc) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/implicit_weak_message.cc b/src/google/protobuf/implicit_weak_message.cc index 539061693c79..528cf95d4108 100644 --- a/src/google/protobuf/implicit_weak_message.cc +++ b/src/google/protobuf/implicit_weak_message.cc @@ -63,3 +63,5 @@ const ImplicitWeakMessage* ImplicitWeakMessage::default_instance() { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index 59d86f98333e..2b20e0a5ce6e 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -312,7 +312,7 @@ bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) { uint8 bytes[sizeof(*value)]; const uint8* ptr; - if (BufferSize() >= sizeof(*value)) { + if (BufferSize() >= static_cast(sizeof(*value))) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -329,7 +329,7 @@ bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { uint8 bytes[sizeof(*value)]; const uint8* ptr; - if (BufferSize() >= sizeof(*value)) { + if (BufferSize() >= static_cast(sizeof(*value))) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -351,7 +351,7 @@ template const uint8* DecodeVarint64KnownSize(const uint8* buffer, uint64* value) { GOOGLE_DCHECK_GT(N, 0); uint64 result = static_cast(buffer[N - 1]) << (7 * (N - 1)); - for (int i = 0, offset = 0; i < N - 1; i++, offset += 7) { + for (size_t i = 0, offset = 0; i < N - 1; i++, offset += 7) { result += static_cast(buffer[i] - 0x80) << offset; } *value = result; @@ -954,3 +954,5 @@ uint8* CodedOutputStream::WriteStringWithSizeToArray(const std::string& str, } // namespace io } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc index 266b902eeebc..d2f8959c7b7a 100644 --- a/src/google/protobuf/io/coded_stream_unittest.cc +++ b/src/google/protobuf/io/coded_stream_unittest.cc @@ -1344,3 +1344,5 @@ TEST_F(CodedStreamTest, InputOver2G) { } // namespace io } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc index 86e212677e94..ad6bb5f1c422 100644 --- a/src/google/protobuf/io/gzip_stream.cc +++ b/src/google/protobuf/io/gzip_stream.cc @@ -298,7 +298,7 @@ bool GzipOutputStream::Next(void** data, int* size) { return true; } void GzipOutputStream::BackUp(int count) { - GOOGLE_CHECK_GE(zcontext_.avail_in, count); + GOOGLE_CHECK_GE(zcontext_.avail_in, static_cast(count)); zcontext_.avail_in -= count; } int64_t GzipOutputStream::ByteCount() const { diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc index 95b03f474b23..230960c908ad 100644 --- a/src/google/protobuf/io/printer.cc +++ b/src/google/protobuf/io/printer.cc @@ -296,7 +296,7 @@ void Printer::FormatInternal(const std::vector& args, } push_back(c); } - if (arg_index != args.size()) { + if (arg_index != static_cast(args.size())) { GOOGLE_LOG(FATAL) << " Unused arguments. " << save; } if (!annotations.empty()) { @@ -324,7 +324,7 @@ const char* Printer::WriteVariable( GOOGLE_CHECK(std::isdigit(start[1])); GOOGLE_CHECK_EQ(end - start, 2); int idx = start[1] - '1'; - if (idx < 0 || idx >= args.size()) { + if (idx < 0 || static_cast(idx) >= args.size()) { GOOGLE_LOG(FATAL) << "Annotation ${" << idx + 1 << "$ is out of bounds."; } if (idx > *arg_index) { @@ -358,10 +358,10 @@ const char* Printer::WriteVariable( start_var, static_cast(end_var - start_var)}; std::string sub; if (std::isdigit(var_name[0])) { - GOOGLE_CHECK_EQ(var_name.size(), 1); // No need for multi-digits + GOOGLE_CHECK_EQ(var_name.size(), 1U); // No need for multi-digits int idx = var_name[0] - '1'; // Start counting at 1 GOOGLE_CHECK_GE(idx, 0); - if (idx >= args.size()) { + if (static_cast(idx) >= args.size()) { GOOGLE_LOG(FATAL) << "Argument $" << idx + 1 << "$ is out of bounds."; } if (idx > *arg_index) { diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index 6853b1ac3ada..129b4889e53d 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc @@ -888,7 +888,8 @@ bool Tokenizer::ParseInteger(const std::string& text, uint64 max_value, // token, but Tokenizer still think it's integer. return false; } - if (digit > max_value || result > (max_value - digit) / base) { + if (static_cast(digit) > max_value || + result > (max_value - digit) / base) { // Overflow. return false; } @@ -918,7 +919,8 @@ double Tokenizer::ParseFloat(const std::string& text) { ++end; } - GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-') + GOOGLE_LOG_IF(DFATAL, + static_cast(end - start) != text.size() || *start == '-') << " Tokenizer::ParseFloat() passed text that could not have been" " tokenized as a float: " << CEscape(text); @@ -1114,8 +1116,8 @@ void Tokenizer::ParseStringAppend(const std::string& text, template static bool AllInClass(const std::string& s) { - for (int i = 0; i < s.size(); ++i) { - if (!CharacterClass::InClass(s[i])) return false; + for (const char character : s) { + if (!CharacterClass::InClass(character)) return false; } return true; } diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index 54c5db945e4e..0eeeb0e760ab 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -168,7 +168,7 @@ bool StringOutputStream::Next(void** data, int* size) { void StringOutputStream::BackUp(int count) { GOOGLE_CHECK_GE(count, 0); GOOGLE_CHECK(target_ != NULL); - GOOGLE_CHECK_LE(count, target_->size()); + GOOGLE_CHECK_LE(static_cast(count), target_->size()); target_->resize(target_->size() - count); } diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 17090f0063b1..7efee12526a9 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -838,6 +838,7 @@ class Map { // non-determinism to the map ordering. bool ShouldInsertAfterHead(void* node) { #ifdef NDEBUG + (void)node; return false; #else // Doing modulo with a prime mixes the bits more. diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index 7dffa568c23e..542a1f8335b3 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -601,3 +601,5 @@ size_t DynamicMapField::SpaceUsedExcludingSelfNoLock() const { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 9fbd06ade976..e05d3ee04da2 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -72,8 +72,8 @@ class MapIterator; // map key. class PROTOBUF_EXPORT MapKey { public: - MapKey() : type_(0) {} - MapKey(const MapKey& other) : type_(0) { CopyFrom(other); } + MapKey() : type_() {} + MapKey(const MapKey& other) : type_() { CopyFrom(other); } MapKey& operator=(const MapKey& other) { CopyFrom(other); @@ -87,12 +87,12 @@ class PROTOBUF_EXPORT MapKey { } FieldDescriptor::CppType type() const { - if (type_ == 0) { + if (type_ == FieldDescriptor::CppType()) { GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" << "MapKey::type MapKey is not initialized. " << "Call set methods to initialize MapKey."; } - return (FieldDescriptor::CppType)type_; + return type_; } void SetInt64Value(int64 value) { @@ -261,7 +261,8 @@ class PROTOBUF_EXPORT MapKey { } // type_ is 0 or a valid FieldDescriptor::CppType. - int type_; + // Use "CppType()" to indicate zero. + FieldDescriptor::CppType type_; }; } // namespace protobuf @@ -329,7 +330,7 @@ class PROTOBUF_EXPORT MapFieldBase { // It uses a linker initialized mutex, so it is not compatible with regular // runtime instances. // Except in MSVC, where we can't have a constinit mutex. - explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized) + explicit constexpr MapFieldBase(ConstantInitialized) : arena_(nullptr), repeated_field_(nullptr), mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED), @@ -678,7 +679,7 @@ class PROTOBUF_EXPORT DynamicMapField // the map value. class PROTOBUF_EXPORT MapValueConstRef { public: - MapValueConstRef() : data_(nullptr), type_(0) {} + MapValueConstRef() : data_(nullptr), type_() {} int64 GetInt64Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, @@ -735,15 +736,16 @@ class PROTOBUF_EXPORT MapValueConstRef { // own this value. void* data_; // type_ is 0 or a valid FieldDescriptor::CppType. - int type_; + // Use "CppType()" to indicate zero. + FieldDescriptor::CppType type_; FieldDescriptor::CppType type() const { - if (type_ == 0 || data_ == nullptr) { + if (type_ == FieldDescriptor::CppType() || data_ == nullptr) { GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" << "MapValueConstRef::type MapValueConstRef is not initialized."; } - return static_cast(type_); + return type_; } private: diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index f6274c0da32a..dd70e989d0e1 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -501,3 +501,5 @@ TEST(MapFieldTest, ConstInit) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 9c53b510f487..8fb0b908f5a9 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -3770,3 +3770,5 @@ TEST(MoveTest, MoveAssignmentWorks) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 6e1e25ea5092..259fde8010ab 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -363,3 +363,5 @@ PROTOBUF_NOINLINE } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 4e7ac9d06200..e20b16239304 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -1045,7 +1045,7 @@ class PROTOBUF_EXPORT Reflection final { const OneofDescriptor* oneof_descriptor) const; inline uint32* MutableOneofCase( Message* message, const OneofDescriptor* oneof_descriptor) const; - inline bool HasExtensionSet(const Message& message) const { + inline bool HasExtensionSet(const Message& /* message */) const { return schema_.HasExtensionSet(); } const internal::ExtensionSet& GetExtensionSet(const Message& message) const; @@ -1252,7 +1252,8 @@ const T* DynamicCastToGenerated(const Message* from) { #if PROTOBUF_RTTI return dynamic_cast(from); #else - bool ok = T::default_instance().GetReflection() == from->GetReflection(); + bool ok = from != nullptr && + T::default_instance().GetReflection() == from->GetReflection(); return ok ? down_cast(from) : nullptr; #endif } diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 0e85991476a8..0cae40fbaeb8 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -389,7 +389,7 @@ bool MessageLite::SerializePartialToCodedStream( } int final_byte_count = output->ByteCount(); - if (final_byte_count - original_byte_count != size) { + if (final_byte_count - original_byte_count != static_cast(size)) { ByteSizeConsistencyError(size, ByteSizeLong(), final_byte_count - original_byte_count, *this); } @@ -488,7 +488,7 @@ bool MessageLite::SerializePartialToArray(void* data, int size) const { << " exceeded maximum protobuf size of 2GB: " << byte_size; return false; } - if (size < byte_size) return false; + if (size < static_cast(byte_size)) return false; uint8* start = reinterpret_cast(data); SerializeToArrayImpl(*this, start, byte_size); return true; @@ -581,3 +581,5 @@ void ShutdownProtobufLibrary() { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index a76c16e5a492..87e9d2b4ccfa 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -151,7 +151,6 @@ class ExplicitlyConstructed { } union_; }; -PROTOBUF_DISABLE_MSVC_UNION_WARNING // We need a publicly accessible `value` object to allow constexpr // support in C++11. // A constexpr accessor does not work portably. @@ -163,7 +162,6 @@ union EmptyString { std::false_type dummy; std::string value; }; -PROTOBUF_ENABLE_MSVC_UNION_WARNING // Default empty string object. Don't use this directly. Instead, call // GetEmptyString() to get the reference. diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index 1b0aa333a4e5..4608714d1ef0 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -235,6 +235,10 @@ TEST(MESSAGE_TEST_NAME, DynamicCastToGenerated) { test_all_types_pointer_const)); EXPECT_EQ(nullptr, DynamicCastToGenerated( test_all_types_pointer_const)); + + Message* test_all_types_pointer_nullptr = nullptr; + EXPECT_EQ(nullptr, DynamicCastToGenerated( + test_all_types_pointer_nullptr)); } #ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet. diff --git a/src/google/protobuf/parse_context.cc b/src/google/protobuf/parse_context.cc index 22cdcbba5b1a..8143af8d8bcf 100644 --- a/src/google/protobuf/parse_context.cc +++ b/src/google/protobuf/parse_context.cc @@ -591,3 +591,5 @@ const char* UnknownFieldParse(uint32 tag, std::string* unknown, const char* ptr, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h index 555fd4ebc43b..aa2cfc1eb862 100644 --- a/src/google/protobuf/port.h +++ b/src/google/protobuf/port.h @@ -39,5 +39,9 @@ #include +// Protobuf intends to move into the pb:: namespace. +namespace protobuf_future_namespace_placeholder {} +namespace pb = ::protobuf_future_namespace_placeholder; + #endif // GOOGLE_PROTOBUF_PORT_H__ diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 8b39d698962a..14473d201192 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -139,21 +139,21 @@ #ifdef PROTOBUF_FINAL #error PROTOBUF_FINAL was previously defined #endif -#ifdef PROTOBUF_DISABLE_MSVC_UNION_WARNING -#error PROTOBUF_DISABLE_MSVC_UNION_WARNING was previously defined -#endif #ifdef PROTOBUF_ENABLE_MSVC_UNION_WARNING #error PROTOBUF_ENABLE_MSVC_UNION_WARNING was previously defined #endif #ifdef PROTOBUF_CONSTINIT #error PROTOBUF_CONSTINIT was previously defined #endif -#ifdef PROTOBUF_MAYBE_CONSTEXPR -#error PROTOBUF_MAYBE_CONSTEXPR was previously defined -#endif #ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY #error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined #endif +#ifdef PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#error PROTOBUF_ATTRIBUTE_INIT_PRIORITY was previously defined +#endif +#ifdef PROTOBUF_PRAGMA_INIT_SEG +#error PROTOBUF_PRAGMA_INIT_SEG was previously defined +#endif #define PROTOBUF_NAMESPACE "google::protobuf" @@ -464,10 +464,6 @@ // name. #pragma push_macro("DEBUG") #undef DEBUG -#pragma push_macro("TRUE") -#undef TRUE -#pragma push_macro("FALSE") -#undef FALSE #endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) #if defined(__clang__) @@ -560,28 +556,6 @@ #define PROTOBUF_CONSTINIT #endif -// Some constructors can't be constexpr under MSVC, but given that MSVC will not -// do constant initialization of globals anyway we can omit `constexpr` from -// them. These constructors are marked with PROTOBUF_MAYBE_CONSTEXPR -#if defined(_MSC_VER) -#define PROTOBUF_MAYBE_CONSTEXPR -#else -#define PROTOBUF_MAYBE_CONSTEXPR constexpr -#endif - -#if _MSC_VER -#define PROTOBUF_DISABLE_MSVC_UNION_WARNING \ - __pragma(warning(push)) \ - __pragma(warning(disable : 4582)) \ - __pragma(warning(disable : 4583)) - -#define PROTOBUF_ENABLE_MSVC_UNION_WARNING \ - __pragma(warning(pop)) -#else -#define PROTOBUF_DISABLE_MSVC_UNION_WARNING -#define PROTOBUF_ENABLE_MSVC_UNION_WARNING -#endif - #if defined(__cpp_constinit) #define PROTOBUF_CONSTINIT constinit #elif defined(__has_cpp_attribute) @@ -604,3 +578,34 @@ #if !defined(PROTOBUF_ATTRIBUTE_NO_DESTROY) #define PROTOBUF_ATTRIBUTE_NO_DESTROY #endif + +#if defined(__GNUC__) +// Protobuf extensions and reflection require registration of the protos linked +// in the binary. Not until everything is registered does the runtime have a +// complete view on all protos. When code is using reflection or extensions +// in between registration calls this can lead to surprising behavior. By +// having the registration run first we mitigate this scenario. +// Highest priority is 101. We use 102 to allow code that really wants to +// higher priority to still beat us. +#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY __attribute__((init_priority((102)))) +#else +#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#endif + +#if _MSC_VER +#define PROTOBUF_PRAGMA_INIT_SEG __pragma(init_seg(lib)) +#else +#define PROTOBUF_PRAGMA_INIT_SEG +#endif + +// Silence some MSVC warnings in all our code. +#if _MSC_VER +#pragma warning(push) +// For non-trivial unions +#pragma warning(disable : 4582) +#pragma warning(disable : 4583) +// For init_seg(lib) +#pragma warning(disable : 4073) +// To silence the fact that we will pop this push from another file +#pragma warning(disable : 5031) +#endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index d1414285e4fc..17cf8378a9b5 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -75,8 +75,9 @@ #undef PROTOBUF_DISABLE_MSVC_UNION_WARNING #undef PROTOBUF_ENABLE_MSVC_UNION_WARNING #undef PROTOBUF_CONSTINIT -#undef PROTOBUF_MAYBE_CONSTEXPR #undef PROTOBUF_ATTRIBUTE_NO_DESTROY +#undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#undef PROTOBUF_PRAGMA_INIT_SEG // Restore macro that may have been #undef'd in port_def.inc. #ifdef _MSC_VER @@ -105,8 +106,6 @@ #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) #pragma pop_macro("DEBUG") -#pragma pop_macro("TRUE") -#pragma pop_macro("FALSE") #endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) #if defined(__clang__) @@ -114,3 +113,8 @@ #elif defined(__GNUC__) #pragma GCC diagnostic pop #endif + +// Pop the warning(push) from port_def.inc +#if _MSC_VER +#pragma warning(pop) +#endif diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index 29fc5dbaaf45..9a622f4ac8a6 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -436,3 +436,5 @@ void GenericSwap(Message* m1, Message* m2) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc index 6450679122d9..f5e83ffaba91 100644 --- a/src/google/protobuf/repeated_field.cc +++ b/src/google/protobuf/repeated_field.cc @@ -58,8 +58,10 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { Arena* arena = GetArena(); new_size = std::max(internal::kRepeatedFieldLowerClampLimit, std::max(total_size_ * 2, new_size)); - GOOGLE_CHECK_LE(new_size, (std::numeric_limits::max() - kRepHeaderSize) / - sizeof(old_rep->elements[0])) + GOOGLE_CHECK_LE( + static_cast(new_size), + static_cast((std::numeric_limits::max() - kRepHeaderSize) / + sizeof(old_rep->elements[0]))) << "Requested size is too large to fit into size_t."; size_t bytes = kRepHeaderSize + sizeof(old_rep->elements[0]) * new_size; if (arena == NULL) { @@ -134,3 +136,5 @@ template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedPtrField; } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 26d58473312c..b9ea50dc8217 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -1206,6 +1206,12 @@ RepeatedField::RepeatedField(Iter begin, const Iter& end) template RepeatedField::~RepeatedField() { +#ifndef NDEBUG + // Try to trigger segfault / asan failure in non-opt builds. If arena_ + // lifetime has ended before the destructor. + auto arena = GetArena(); + if (arena) (void)arena->SpaceAllocated(); +#endif if (total_size_ > 0) { InternalDeallocate(rep(), total_size_); } diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 4072f47b6cf1..a396b619f249 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -2090,3 +2090,5 @@ TEST_F(RepeatedFieldInsertionIteratorsTest, MoveProtos) { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index a9e0f843d319..fbd180477f97 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class SourceContextDefaultTypeInternal { public: @@ -75,7 +77,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -144,7 +146,6 @@ void SourceContext::Clear() { const char* SourceContext::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index a6d9095303bf..396654cc1849 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto; PROTOBUF_NAMESPACE_OPEN class Struct_FieldsEntry_DoNotUseDefaultTypeInternal { @@ -145,7 +147,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto(&descriptor_table_google_2fprotobuf_2fstruct_2eproto); PROTOBUF_NAMESPACE_OPEN const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullValue_descriptor() { ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto); @@ -239,7 +241,6 @@ void Struct::Clear() { const char* Struct::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -586,7 +587,6 @@ void Value::Clear() { const char* Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -921,7 +921,6 @@ void ListValue::Clear() { const char* ListValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index bc150f56a90d..f2859e94bbee 100644 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -327,3 +327,5 @@ const char* FatalException::what() const throw() { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc index 2119e65505e5..7fc7dd8c5e19 100644 --- a/src/google/protobuf/stubs/int128.cc +++ b/src/google/protobuf/stubs/int128.cc @@ -190,3 +190,5 @@ std::ostream& operator<<(std::ostream& o, const uint128& b) { } // namespace protobuf } // namespace google + +#include // NOLINT diff --git a/src/google/protobuf/stubs/int128_unittest.cc b/src/google/protobuf/stubs/int128_unittest.cc index 9a8125d4887e..53dbd09ec0c4 100644 --- a/src/google/protobuf/stubs/int128_unittest.cc +++ b/src/google/protobuf/stubs/int128_unittest.cc @@ -515,3 +515,5 @@ TEST(Int128, OStream) { } } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h index b222ff746df6..53bb25d694ba 100644 --- a/src/google/protobuf/stubs/mutex.h +++ b/src/google/protobuf/stubs/mutex.h @@ -90,12 +90,33 @@ class PROTOBUF_EXPORT CriticalSectionLock { #endif +// In MSVC std::mutex does not have a constexpr constructor. +// This wrapper makes the constructor constexpr. +template +class CallOnceInitializedMutex { + public: + constexpr CallOnceInitializedMutex() : flag_{}, buf_{} {} + ~CallOnceInitializedMutex() { get().~T(); } + + void lock() { get().lock(); } + void unlock() { get().unlock(); } + + private: + T& get() { + std::call_once(flag_, [&] { ::new (static_cast(&buf_)) T(); }); + return reinterpret_cast(buf_); + } + + std::once_flag flag_; + alignas(T) char buf_[sizeof(T)]; +}; + // Mutex is a natural type to wrap. As both google and other organization have // specialized mutexes. gRPC also provides an injection mechanism for custom // mutexes. class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex { public: - WrappedMutex() = default; + constexpr WrappedMutex() = default; void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); } void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); } // Crash if this Mutex is not held exclusively by this thread. @@ -103,11 +124,13 @@ class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex { void AssertHeld() const {} private: -#ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP +#if defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP) + CallOnceInitializedMutex mu_; +#elif defined(_MSC_VER) + CallOnceInitializedMutex mu_; +#else std::mutex mu_; -#else // ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP - CriticalSectionLock mu_; -#endif // #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP +#endif }; using Mutex = WrappedMutex; diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 3c7ada385c05..db8b62f6b3a4 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -51,11 +51,11 @@ #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) #define PROTOBUF_LITTLE_ENDIAN 1 #endif - #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) - // If MSVC has "/RTCc" set, it will complain about truncating casts at - // runtime. This file contains some intentional truncating casts. - #pragma runtime_checks("c", off) - #endif +#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) +// If MSVC has "/RTCc" set, it will complain about truncating casts at +// runtime. This file contains some intentional truncating casts. +#pragma runtime_checks("c", off) +#endif #else #include // __BYTE_ORDER #if defined(__OpenBSD__) diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index f47d4e8d013a..1af250d3f52a 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include @@ -63,6 +62,9 @@ #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -161,7 +163,7 @@ TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation( const std::vector* locations = FindOrNull(locations_, field); - if (locations == nullptr || index >= locations->size()) { + if (locations == nullptr || index >= static_cast(locations->size())) { return TextFormat::ParseLocation(); } @@ -176,7 +178,7 @@ TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( } auto it = nested_.find(field); - if (it == nested_.end() || index >= it->second.size()) { + if (it == nested_.end() || index >= static_cast(it->second.size())) { return nullptr; } @@ -1321,7 +1323,7 @@ class TextFormat::Printer::TextGenerator if (failed_) return; } - while (size > buffer_size_) { + while (static_cast(size) > buffer_size_) { // Data exceeds space in the buffer. Copy what we can and request a // new buffer. if (buffer_size_ > 0) { @@ -2393,7 +2395,8 @@ void TextFormat::Printer::PrintFieldValue(const Message& message, const std::string* value_to_print = &value; std::string truncated_value; if (truncate_string_field_longer_than_ > 0 && - truncate_string_field_longer_than_ < value.size()) { + static_cast(truncate_string_field_longer_than_) < + value.size()) { truncated_value = value.substr(0, truncate_string_field_longer_than_) + "......"; value_to_print = &truncated_value; @@ -2576,3 +2579,5 @@ void TextFormat::Printer::PrintUnknownFields( } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index f7ced059209b..449a78c6dc2b 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -2160,3 +2160,5 @@ TEST(TextFormatUnknownFieldTest, TestUnknownExtension) { } // namespace text_format_unittest } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 65c8d5469aa7..24b8ee9a0bc2 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class TimestampDefaultTypeInternal { public: @@ -76,7 +78,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -101,8 +103,9 @@ Timestamp::Timestamp(const Timestamp& from) } void Timestamp::SharedCtor() { - ::memset(&seconds_, 0, static_cast( - reinterpret_cast(&nanos_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&seconds_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); } @@ -145,7 +148,6 @@ void Timestamp::Clear() { const char* Timestamp::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index a320ee6a4af1..5c94072592f5 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Any_google_2fprotobuf_2fany_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Field_google_2fprotobuf_2ftype_2eproto; @@ -250,7 +252,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto(&descriptor_table_google_2fprotobuf_2ftype_2eproto); PROTOBUF_NAMESPACE_OPEN const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Kind_descriptor() { ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto); @@ -396,8 +398,9 @@ Type::Type(const Type& from) void Type::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Type_google_2fprotobuf_2ftype_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&source_context_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&source_context_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&source_context_)) + sizeof(syntax_)); } @@ -448,7 +451,6 @@ void Type::Clear() { const char* Type::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -785,8 +787,9 @@ void Field::SharedCtor() { type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&kind_, 0, static_cast( - reinterpret_cast(&packed_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&kind_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&packed_) - reinterpret_cast(&kind_)) + sizeof(packed_)); } @@ -838,7 +841,6 @@ void Field::Clear() { const char* Field::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1266,8 +1268,9 @@ Enum::Enum(const Enum& from) void Enum::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Enum_google_2fprotobuf_2ftype_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&source_context_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&source_context_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&source_context_)) + sizeof(syntax_)); } @@ -1317,7 +1320,6 @@ void Enum::Clear() { const char* Enum::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1643,7 +1645,6 @@ void EnumValue::Clear() { const char* EnumValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1925,7 +1926,6 @@ void Option::Clear() { const char* Option::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index f40a577cb2d2..8ab4a1a19982 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc @@ -183,7 +183,7 @@ void UnknownFieldSet::DeleteSubrange(int start, int num) { (fields_)[i + start].Delete(); } // Slide down the remaining fields. - for (int i = start + num; i < fields_.size(); ++i) { + for (size_t i = start + num; i < fields_.size(); ++i) { (fields_)[i - num] = (fields_)[i]; } // Pop off the # of deleted fields. @@ -193,8 +193,8 @@ void UnknownFieldSet::DeleteSubrange(int start, int num) { } void UnknownFieldSet::DeleteByNumber(int number) { - int left = 0; // The number of fields left after deletion. - for (int i = 0; i < fields_.size(); ++i) { + size_t left = 0; // The number of fields left after deletion. + for (size_t i = 0; i < fields_.size(); ++i) { UnknownField* field = &(fields_)[i]; if (field->number() == number) { field->Delete(); @@ -324,3 +324,5 @@ const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/util/delimited_message_util.cc b/src/google/protobuf/util/delimited_message_util.cc index 425dc2cfdff8..80cab309be3d 100644 --- a/src/google/protobuf/util/delimited_message_util.cc +++ b/src/google/protobuf/util/delimited_message_util.cc @@ -74,12 +74,18 @@ bool ParseDelimitedFromCodedStream(MessageLite* message, return false; } + // Get the position after any size bytes have been read (and only the message + // itself remains). + int position_after_size = input->CurrentPosition(); + // Tell the stream not to read beyond that size. io::CodedInputStream::Limit limit = input->PushLimit(size); // Parse the message. if (!message->MergeFromCodedStream(input)) return false; if (!input->ConsumedEntireMessage()) return false; + if (input->CurrentPosition() - position_after_size != static_cast(size)) + return false; // Release the limit. input->PopLimit(limit); diff --git a/src/google/protobuf/util/delimited_message_util_test.cc b/src/google/protobuf/util/delimited_message_util_test.cc index 9ed67784ee1c..9483a646e738 100644 --- a/src/google/protobuf/util/delimited_message_util_test.cc +++ b/src/google/protobuf/util/delimited_message_util_test.cc @@ -82,6 +82,35 @@ TEST(DelimitedMessageUtilTest, DelimitedMessages) { } } +TEST(DelimitedMessageUtilTest, FailsAtEndOfStream) { + std::stringstream full_stream; + std::stringstream partial_stream; + + { + protobuf_unittest::ForeignMessage message; + message.set_c(42); + message.set_d(24); + EXPECT_TRUE(SerializeDelimitedToOstream(message, &full_stream)); + + std::string full_output = full_stream.str(); + ASSERT_GT(full_output.size(), size_t{2}); + ASSERT_EQ(full_output[0], 4); + + partial_stream << full_output[0] << full_output[1] << full_output[2]; + } + + { + bool clean_eof; + io::IstreamInputStream zstream(&partial_stream); + + protobuf_unittest::ForeignMessage message; + clean_eof = true; + EXPECT_FALSE(ParseDelimitedFromZeroCopyStream(&message, + &zstream, &clean_eof)); + EXPECT_FALSE(clean_eof); + } +} + } // namespace util } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 12cbf945ef10..68af4d17ba24 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -141,7 +141,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator int path_index) const { const FieldDescriptor* field = key_field_path[path_index]; std::vector current_parent_fields(parent_fields); - if (path_index == key_field_path.size() - 1) { + if (path_index == static_cast(key_field_path.size() - 1)) { if (field->is_repeated()) { if (!message_differencer_->CompareRepeatedField( message1, message2, field, ¤t_parent_fields)) { @@ -187,7 +187,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator void MatchIndicesPostProcessorForSmartList( std::vector* match_list1, std::vector* match_list2) { int last_matched_index = -1; - for (int i = 0; i < match_list1->size(); ++i) { + for (size_t i = 0; i < match_list1->size(); ++i) { if (match_list1->at(i) < 0) { continue; } @@ -395,7 +395,7 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey( GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) << "Field has to be message type. Field name is: " << field->full_name(); for (const auto& key_field_path : key_field_paths) { - for (int j = 0; j < key_field_path.size(); ++j) { + for (size_t j = 0; j < key_field_path.size(); ++j) { const FieldDescriptor* parent_field = j == 0 ? field : key_field_path[j - 1]; const FieldDescriptor* child_field = key_field_path[j]; @@ -669,8 +669,8 @@ bool MessageDifferencer::CompareRequestedFieldsUsingSettings( FieldDescriptorArray MessageDifferencer::CombineFields( const FieldDescriptorArray& fields1, Scope fields1_scope, const FieldDescriptorArray& fields2, Scope fields2_scope) { - int index1 = 0; - int index2 = 0; + size_t index1 = 0; + size_t index2 = 0; tmp_message_fields_.clear(); @@ -1417,8 +1417,8 @@ bool MessageDifferencer::CompareUnknownFields( // Now that we have two sorted lists, we can detect fields which appear only // in one list or the other by traversing them simultaneously. - int index1 = 0; - int index2 = 0; + size_t index1 = 0; + size_t index2 = 0; while (index1 < fields1.size() || index2 < fields2.size()) { enum { ADDITION, @@ -1523,12 +1523,14 @@ bool MessageDifferencer::CompareUnknownFields( if (IsUnknownFieldIgnored(message1, message2, specific_field, *parent_field)) { - if (reporter_ != NULL) { + if (report_ignores_ && reporter_ != NULL) { parent_field->push_back(specific_field); reporter_->ReportUnknownFieldIgnored(message1, message2, *parent_field); parent_field->pop_back(); } - return true; + if (change_type != ADDITION) ++index1; + if (change_type != DELETION) ++index2; + continue; } if (change_type == ADDITION || change_type == DELETION || @@ -1881,7 +1883,7 @@ MessageDifferencer::StreamReporter::~StreamReporter() { void MessageDifferencer::StreamReporter::PrintPath( const std::vector& field_path, bool left_side) { - for (int i = 0; i < field_path.size(); ++i) { + for (size_t i = 0; i < field_path.size(); ++i) { if (i > 0) { printer_->Print("."); } diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index 2f5908ee1fe4..a3f0fd5dc6e9 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -1645,7 +1645,7 @@ size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: \ if (field->is_repeated()) { \ - for (int j = 0; j < count; j++) { \ + for (size_t j = 0; j < count; j++) { \ data_size += WireFormatLite::TYPE_METHOD##Size( \ message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ j)); \ @@ -1685,7 +1685,7 @@ size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, case FieldDescriptor::TYPE_ENUM: { if (field->is_repeated()) { - for (int j = 0; j < count; j++) { + for (size_t j = 0; j < count; j++) { data_size += WireFormatLite::EnumSize( message_reflection->GetRepeatedEnum(message, field, j)->number()); } @@ -1700,7 +1700,7 @@ size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, // instead of copying. case FieldDescriptor::TYPE_STRING: case FieldDescriptor::TYPE_BYTES: { - for (int j = 0; j < count; j++) { + for (size_t j = 0; j < count; j++) { std::string scratch; const std::string& value = field->is_repeated() @@ -1748,3 +1748,5 @@ size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index dc256082850f..d07f903584d8 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc @@ -479,7 +479,7 @@ void WireFormatLite::WriteString(int field_number, const std::string& value, io::CodedOutputStream* output) { // String is for UTF-8 text only WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteString(value); } @@ -488,14 +488,14 @@ void WireFormatLite::WriteStringMaybeAliased(int field_number, io::CodedOutputStream* output) { // String is for UTF-8 text only WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteRawMaybeAliased(value.data(), value.size()); } void WireFormatLite::WriteBytes(int field_number, const std::string& value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteString(value); } @@ -503,7 +503,7 @@ void WireFormatLite::WriteBytesMaybeAliased(int field_number, const std::string& value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteRawMaybeAliased(value.data(), value.size()); } @@ -776,3 +776,5 @@ size_t WireFormatLite::SInt64Size(const RepeatedField& value) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index e3463e35126c..e75fc316f875 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -1526,3 +1526,5 @@ TEST(RepeatedVarint, Enum) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index ef86a350ea9c..8274cec9f404 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class DoubleValueDefaultTypeInternal { public: @@ -289,7 +291,7 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fwrappers_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fwrappers_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fwrappers_2eproto(&descriptor_table_google_2fprotobuf_2fwrappers_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -352,7 +354,6 @@ void DoubleValue::Clear() { const char* DoubleValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -545,7 +546,6 @@ void FloatValue::Clear() { const char* FloatValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -738,7 +738,6 @@ void Int64Value::Clear() { const char* Int64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -933,7 +932,6 @@ void UInt64Value::Clear() { const char* UInt64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1128,7 +1126,6 @@ void Int32Value::Clear() { const char* Int32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1323,7 +1320,6 @@ void UInt32Value::Clear() { const char* UInt32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1518,7 +1514,6 @@ void BoolValue::Clear() { const char* BoolValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1717,7 +1712,6 @@ void StringValue::Clear() { const char* StringValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1924,7 +1918,6 @@ void BytesValue::Clear() { const char* BytesValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); diff --git a/tests.sh b/tests.sh index 5113e4a73163..6d63aad30d0d 100755 --- a/tests.sh +++ b/tests.sh @@ -478,16 +478,10 @@ build_php7.0() { } build_php7.0_c() { - IS_64BIT=$1 use_php 7.0 php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -503,16 +497,10 @@ build_php7.0_mixed() { } build_php7.0_zts_c() { - IS_64BIT=$1 use_php_zts 7.0 php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -575,16 +563,10 @@ build_php7.1() { } build_php7.1_c() { - IS_64BIT=$1 use_php 7.1 php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -600,16 +582,10 @@ build_php7.1_mixed() { } build_php7.1_zts_c() { - IS_64BIT=$1 use_php_zts 7.1 php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -624,16 +600,10 @@ build_php7.4() { } build_php7.4_c() { - IS_64BIT=$1 use_php 7.4 php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -649,16 +619,10 @@ build_php7.4_mixed() { } build_php7.4_zts_c() { - IS_64BIT=$1 use_php_zts 7.4 php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -673,16 +637,10 @@ build_php8.0() { } build_php8.0_c() { - IS_64BIT=$1 use_php 8.0 php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } diff --git a/third_party/wyhash/LICENSE b/third_party/wyhash/LICENSE new file mode 100644 index 000000000000..471f09f4cfb5 --- /dev/null +++ b/third_party/wyhash/LICENSE @@ -0,0 +1,25 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + diff --git a/third_party/wyhash/wyhash.h b/third_party/wyhash/wyhash.h new file mode 100644 index 000000000000..5658f02df3ce --- /dev/null +++ b/third_party/wyhash/wyhash.h @@ -0,0 +1,145 @@ +/* Copyright 2020 王一 Wang Yi + This is free and unencumbered software released into the public domain. http://unlicense.org/ + See github.com/wangyi-fudan/wyhash/ LICENSE + */ +#ifndef wyhash_final_version +#define wyhash_final_version +//defines that change behavior +#ifndef WYHASH_CONDOM +#define WYHASH_CONDOM 1 //0: read 8 bytes before and after boundaries, dangerous but fastest. 1: normal valid behavior 2: extra protection against entropy loss (probability=2^-63), aka. "blind multiplication" +#endif +#define WYHASH_32BIT_MUM 0 //faster on 32 bit system +//includes +#include +#include +#if defined(_MSC_VER) && defined(_M_X64) + #include + #pragma intrinsic(_umul128) +#endif +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) + #define _likely_(x) __builtin_expect(x,1) + #define _unlikely_(x) __builtin_expect(x,0) +#else + #define _likely_(x) (x) + #define _unlikely_(x) (x) +#endif +//mum function +static inline uint64_t _wyrot(uint64_t x) { return (x>>32)|(x<<32); } +static inline void _wymum(uint64_t *A, uint64_t *B){ +#if(WYHASH_32BIT_MUM) + uint64_t hh=(*A>>32)*(*B>>32), hl=(*A>>32)*(unsigned)*B, lh=(unsigned)*A*(*B>>32), ll=(uint64_t)(unsigned)*A*(unsigned)*B; + #if(WYHASH_CONDOM>1) + *A^=_wyrot(hl)^hh; *B^=_wyrot(lh)^ll; + #else + *A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll; + #endif +#elif defined(__SIZEOF_INT128__) + __uint128_t r=*A; r*=*B; + #if(WYHASH_CONDOM>1) + *A^=(uint64_t)r; *B^=(uint64_t)(r>>64); + #else + *A=(uint64_t)r; *B=(uint64_t)(r>>64); + #endif +#elif defined(_MSC_VER) && defined(_M_X64) + #if(WYHASH_CONDOM>1) + uint64_t a, b; + a=_umul128(*A,*B,&b); + *A^=a; *B^=b; + #else + *A=_umul128(*A,*B,B); + #endif +#else + uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo; + uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t>32)+(rm1>>32)+c; + #if(WYHASH_CONDOM>1) + *A^=lo; *B^=hi; + #else + *A=lo; *B=hi; + #endif +#endif +} +static inline uint64_t _wymix(uint64_t A, uint64_t B){ _wymum(&A,&B); return A^B; } +//read functions +#ifndef WYHASH_LITTLE_ENDIAN + #if defined(_WIN32) || defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #define WYHASH_LITTLE_ENDIAN 1 + #elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + #define WYHASH_LITTLE_ENDIAN 0 + #endif +#endif +#if (WYHASH_LITTLE_ENDIAN) +static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return v;} +static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return v;} +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) +static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return __builtin_bswap64(v);} +static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return __builtin_bswap32(v);} +#elif defined(_MSC_VER) +static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return _byteswap_uint64(v);} +static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return _byteswap_ulong(v);} +#endif +static inline uint64_t _wyr3(const uint8_t *p, unsigned k) { return (((uint64_t)p[0])<<16)|(((uint64_t)p[k>>1])<<8)|p[k-1];} +//wyhash function +static inline uint64_t _wyfinish16(const uint8_t *p, uint64_t len, uint64_t seed, const uint64_t *secret, uint64_t i){ +#if(WYHASH_CONDOM>0) + uint64_t a, b; + if(_likely_(i<=8)){ + if(_likely_(i>=4)){ a=_wyr4(p); b=_wyr4(p+i-4); } + else if (_likely_(i)){ a=_wyr3(p,i); b=0; } + else a=b=0; + } + else{ a=_wyr8(p); b=_wyr8(p+i-8); } + return _wymix(secret[1]^len,_wymix(a^secret[1], b^seed)); +#else + #define oneshot_shift ((i<8)*((8-i)<<3)) + return _wymix(secret[1]^len,_wymix((_wyr8(p)<>oneshot_shift)^seed)); +#endif +} + +static inline uint64_t _wyfinish(const uint8_t *p, uint64_t len, uint64_t seed, const uint64_t *secret, uint64_t i){ + if(_likely_(i<=16)) return _wyfinish16(p,len,seed,secret,i); + return _wyfinish(p+16,len,_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed),secret,i-16); +} + +static inline uint64_t wyhash(const void *key, uint64_t len, uint64_t seed, const uint64_t *secret){ + const uint8_t *p=(const uint8_t *)key; + uint64_t i=len; seed^=*secret; + if(_unlikely_(i>64)){ + uint64_t see1=seed; + do{ + seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed)^_wymix(_wyr8(p+16)^secret[2],_wyr8(p+24)^seed); + see1=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see1)^_wymix(_wyr8(p+48)^secret[4],_wyr8(p+56)^see1); + p+=64; i-=64; + }while(i>64); + seed^=see1; + } + return _wyfinish(p,len,seed,secret,i); +} +//utility functions +const uint64_t _wyp[5] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull, 0x8ebc6af09c88c6e3ull, 0x589965cc75374cc3ull, 0x1d8e4e27c47d124full}; +static inline uint64_t wyhash64(uint64_t A, uint64_t B){ A^=_wyp[0]; B^=_wyp[1]; _wymum(&A,&B); return _wymix(A^_wyp[0],B^_wyp[1]);} +static inline uint64_t wyrand(uint64_t *seed){ *seed+=_wyp[0]; return _wymix(*seed,*seed^_wyp[1]);} +static inline double wy2u01(uint64_t r){ const double _wynorm=1.0/(1ull<<52); return (r>>12)*_wynorm;} +static inline double wy2gau(uint64_t r){ const double _wynorm=1.0/(1ull<<20); return ((r&0x1fffff)+((r>>21)&0x1fffff)+((r>>42)&0x1fffff))*_wynorm-3.0;} +static inline uint64_t wy2u0k(uint64_t r, uint64_t k){ _wymum(&r,&k); return k; } + +static inline void make_secret(uint64_t seed, uint64_t *secret){ + uint8_t c[] = {15, 23, 27, 29, 30, 39, 43, 45, 46, 51, 53, 54, 57, 58, 60, 71, 75, 77, 78, 83, 85, 86, 89, 90, 92, 99, 101, 102, 105, 106, 108, 113, 114, 116, 120, 135, 139, 141, 142, 147, 149, 150, 153, 154, 156, 163, 165, 166, 169, 170, 172, 177, 178, 180, 184, 195, 197, 198, 201, 202, 204, 209, 210, 212, 216, 225, 226, 228, 232, 240 }; + for(size_t i=0;i<5;i++){ + uint8_t ok; + do{ + ok=1; secret[i]=0; + for(size_t j=0;j<64;j+=8) secret[i]|=((uint64_t)c[wyrand(&seed)%sizeof(c)])<