Sync from Piper @464784061 PROTOBUF_SYNC_PIPER
diff --git a/BUILD.bazel b/BUILD.bazel index 1a305e7..a14476a 100644 --- a/BUILD.bazel +++ b/BUILD.bazel
@@ -266,7 +266,7 @@ alias( name = "well_known_types_py_pb2", actual = "//python:well_known_types_py_pb2", - visibility = ["@upb//:__subpackages__"], + visibility = ["//visibility:public"], ) alias(
diff --git a/CHANGES.txt b/CHANGES.txt index a8e7fd1..a7d74a7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt
@@ -6,14 +6,26 @@ * Add C++20 keywords guarded by PROTOBUF_FUTURE_CPP20_KEYWORDS * Fixed crash in ThreadLocalStorage for pre-C++17 compilers on 32-bit ARM. * Clarified that JSON API non-OK statuses are not a stable API. + * Added a default implementation of MessageDifferencer::Reporter methods. + * proto2::MapPair is now an alias to std::pair. + * Hide C++ RepeatedField::UnsafeArenaSwap Kotlin * Kotlin generated code comments now use kdoc format instead of javadoc. * Escape keywords in package names in proto generated code + * Add Kotlin enum int value getters and setters Java * Performance improvement for repeated use of FieldMaskUtil#merge by caching constructed FieldMaskTrees. + * Optimized Java proto serialization gencode for protos having many extension ranges with few fields in between. + + Python + * Changes ordering of printed fields in .pyi files from lexicographic to the same ordering found in the proto descriptor. + + Compiler + * Print full path name of source .proto file on error + 2022-07-25 version 21.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby)
diff --git a/CMakeLists.txt b/CMakeLists.txt index 04cb330..2ed5ca1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -57,9 +57,11 @@ 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_PROTOBUF_BINARIES "Build protobuf libraries and protoc compiler" ON) option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON) option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF) option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF) +option(protobuf_TEST_XML_OUTDIR "Output directory for XML logs from tests." "") if (BUILD_SHARED_LIBS) set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON) else (BUILD_SHARED_LIBS) @@ -81,6 +83,9 @@ if (protobuf_BUILD_PROTOC_BINARIES OR protobuf_BUILD_TESTS) set(protobuf_BUILD_LIBPROTOC ON) endif () +if (NOT protobuf_BUILD_PROTOBUF_BINARIES) + set(protobuf_INSTALL OFF) +endif() # Path to main configure script set(protobuf_CONFIGURE_SCRIPT "${protobuf_SOURCE_DIR}/configure.ac") @@ -242,12 +247,12 @@ if (MSVC) if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # Build with multiple processes - add_definitions(/MP) + add_compile_options(/MP) endif() # Set source file and execution character sets to UTF-8 - add_definitions(/utf-8) + add_compile_options(/utf-8) # MSVC warning suppressions - add_definitions( + add_compile_options( /wd4065 # switch statement contains 'default' but no 'case' labels /wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data /wd4251 # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' @@ -262,23 +267,16 @@ /wd4996 # The compiler encountered a deprecated declaration. ) # Allow big object - add_definitions(/bigobj) + add_compile_options(/bigobj) string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR}) string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR}) string(REPLACE "." "," protobuf_RC_FILEVERSION "${protobuf_VERSION}") - configure_file(${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in extract_includes.bat) # Suppress linker warnings about files with no symbols defined. - set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") + string(APPEND CMAKE_STATIC_LINKER_FLAGS " /ignore:4221") - if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - # Configure Resource Compiler - enable_language(RC) - # use English language (0x409) in resource compiler - set(rc_flags "/l0x409") - # fix rc.exe invocations because of usage of add_definitions() - set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> ${rc_flags} <DEFINES> /fo<OBJECT> <SOURCE>") - endif() + # use English language (0x409) in resource compiler + string(APPEND CMAKE_RC_FLAGS " -l0x409") # Generate the version.rc file used elsewhere. configure_file(${protobuf_SOURCE_DIR}/cmake/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) @@ -304,28 +302,49 @@ add_definitions(-DUNICODE -D_UNICODE) endif (protobuf_UNICODE) -include(${protobuf_SOURCE_DIR}/cmake/libprotobuf-lite.cmake) -include(${protobuf_SOURCE_DIR}/cmake/libprotobuf.cmake) -if (protobuf_BUILD_LIBPROTOC) - include(${protobuf_SOURCE_DIR}/cmake/libprotoc.cmake) -endif (protobuf_BUILD_LIBPROTOC) -if (protobuf_BUILD_PROTOC_BINARIES) - include(${protobuf_SOURCE_DIR}/cmake/protoc.cmake) - if (NOT DEFINED protobuf_PROTOC_EXE) - set(protobuf_PROTOC_EXE protoc) - endif (NOT DEFINED protobuf_PROTOC_EXE) -endif (protobuf_BUILD_PROTOC_BINARIES) +if (protobuf_BUILD_PROTOBUF_BINARIES) + include(${protobuf_SOURCE_DIR}/cmake/libprotobuf-lite.cmake) + if (NOT DEFINED protobuf_LIB_PROTOBUF_LITE) + set(protobuf_LIB_PROTOBUF_LITE libprotobuf-lite) + endif () + include(${protobuf_SOURCE_DIR}/cmake/libprotobuf.cmake) + if (NOT DEFINED protobuf_LIB_PROTOBUF) + set(protobuf_LIB_PROTOBUF libprotobuf) + endif () + if (protobuf_BUILD_LIBPROTOC) + include(${protobuf_SOURCE_DIR}/cmake/libprotoc.cmake) + if (NOT DEFINED protobuf_LIB_PROTOC) + set(protobuf_LIB_PROTOC libprotoc) + endif () + endif () + if (protobuf_BUILD_PROTOC_BINARIES) + include(${protobuf_SOURCE_DIR}/cmake/protoc.cmake) + if (NOT DEFINED protobuf_PROTOC_EXE) + set(protobuf_PROTOC_EXE protoc) + endif () + endif () +else () + find_package(protobuf) + if (protobuf_FOUND) + set(protobuf_PROTOC_EXE protobuf::protoc) + set(protobuf_LIB_PROTOC protobuf::libprotoc) + set(protobuf_LIB_PROTOBUF protobuf::libprotobuf) + set(protobuf_LIB_PROTOBUF_LITE protobuf::libprotobuf-lite) + message(STATUS "CMake installation of Protobuf found.") + endif () +endif () -# Ensure we have a protoc executable if we need one +# Ensure we have a protoc executable and protobuf libraries if we need one if (protobuf_BUILD_TESTS OR protobuf_BUILD_CONFORMANCE OR protobuf_BUILD_EXAMPLES) if (NOT DEFINED protobuf_PROTOC_EXE) - find_program(protobuf_PROTOC_EXE protoc) - if (NOT protobuf_PROTOC_EXE) - message(FATAL "Build requires 'protoc' but binary not found and not building protoc.") - endif () + find_program(protobuf_PROTOC_EXE protoc REQUIRED) + message(STATUS "Found system ${protobuf_PROTOC_EXE}.") endif () if(protobuf_VERBOSE) message(STATUS "Using protoc : ${protobuf_PROTOC_EXE}") + message(STATUS "Using libprotobuf : ${protobuf_LIB_PROTOBUF}") + message(STATUS "Using libprotobuf-lite : ${protobuf_LIB_PROTOBUF_LITE}") + message(STATUS "Using libprotoc : ${protobuf_LIB_PROTOC}") endif(protobuf_VERBOSE) endif ()
diff --git a/Makefile.am b/Makefile.am index d35bcaf..acc72c2 100644 --- a/Makefile.am +++ b/Makefile.am
@@ -131,11 +131,13 @@ csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs \ csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj \ csharp/src/Google.Protobuf.Test/IssuesTest.cs \ + csharp/src/Google.Protobuf.Test/JsonFormatterSettingsTest.cs \ csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs \ csharp/src/Google.Protobuf.Test/JsonParserTest.cs \ csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs \ csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs \ csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs \ + csharp/src/Google.Protobuf.Test/ParsingPrimitivesTest.cs \ csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs \ csharp/src/Google.Protobuf.Test/ReadOnlySequenceFactory.cs \ csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs \ @@ -174,6 +176,7 @@ csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs \ csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs \ csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs \ + csharp/src/Google.Protobuf.Test/WritingPrimitivesTest.cs \ csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs \ csharp/src/Google.Protobuf.Test/testprotos.pb \ csharp/src/Google.Protobuf.sln \ @@ -958,6 +961,8 @@ php/tests/EncodeDecodeTest.php \ php/tests/force_c_ext.php \ php/tests/gdb_test.sh \ + php/tests/generated_previous/GPBMetadata/ProtoPrevious/TestPreviouslyUnreservedMessage.php \ + php/tests/generated_previous/Previous/readonly.php \ php/tests/GeneratedClassTest.php \ php/tests/GeneratedPhpdocTest.php \ php/tests/GeneratedServiceTest.php \ @@ -967,6 +972,7 @@ php/tests/multirequest.php \ php/tests/multirequest.sh \ php/tests/PhpImplementationTest.php \ + php/tests/PreviouslyGeneratedClassTest.php \ php/tests/proto/empty/echo.proto \ php/tests/proto/test.proto \ php/tests/proto/test_descriptors.proto \ @@ -985,6 +991,7 @@ php/tests/proto/test_service.proto \ php/tests/proto/test_service_namespace.proto \ php/tests/proto/test_wrapper_type_setters.proto \ + php/tests/proto_previous/test_previously_unreserved_message.proto \ php/tests/test_base.php \ php/tests/test_util.php \ php/tests/valgrind.supp \ @@ -1214,7 +1221,6 @@ cmake/README.md \ cmake/conformance.cmake \ cmake/examples.cmake \ - cmake/extract_includes.bat.in \ cmake/install.cmake \ cmake/libprotobuf-lite.cmake \ cmake/libprotobuf.cmake \
diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec index c8a516b..858a861 100644 --- a/Protobuf-C++.podspec +++ b/Protobuf-C++.podspec
@@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Protobuf-C++' - s.version = '3.21.2' + s.version = '3.21.4' s.summary = 'Protocol Buffers v3 runtime library for C++.' s.homepage = 'https://github.com/google/protobuf' s.license = 'BSD-3-Clause'
diff --git a/cmake/README.md b/cmake/README.md index ce3e680..4a4259e 100644 --- a/cmake/README.md +++ b/cmake/README.md
@@ -1,15 +1,19 @@ -This directory contains *CMake* files that can be used to build protobuf -with *MSVC* on *Windows*. You can build the project from *Command Prompt* -and using an *Visual Studio* IDE. +This directory contains *CMake* files that can be used to build protobuf. -You need to have [CMake](http://www.cmake.org), [Visual Studio](https://www.visualstudio.com) -and optionally [Git](http://git-scm.com) installed on your computer before proceeding. +You need to have [CMake](http://www.cmake.org) and +[Git](http://git-scm.com) installed on your computer before proceeding. -Most of the instructions will be given to the *Сommand Prompt*, but the same -actions can be performed using appropriate GUI tools. +Most of the instructions will be given using CMake's command-line interface, but +the same actions can be performed using appropriate GUI tools. -Environment Setup -================= +# Windows Builds + +On Windows, you can build the project from *Command Prompt* and using an +*Visual Studio* IDE. You will also need to have +[Visual Studio](https://www.visualstudio.com) installed on your computer before +proceeding. + +## Environment Setup Open the appropriate *Command Prompt* from the *Start* menu. @@ -42,8 +46,7 @@ Good. Now you are ready to continue. -Getting Sources -=============== +## Getting Sources You can get the latest stable source packages from the release page: @@ -76,8 +79,7 @@ Good. Now you are ready for *CMake* configuration. -CMake Configuration -=================== +## CMake Configuration *CMake* supports a lot of different [generators](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html) @@ -137,8 +139,7 @@ It will generate *Visual Studio* solution file *protobuf.sln* in current directory. -Unit Tests ----------- +### Unit Tests Unit tests are being built along with the rest of protobuf. The unit tests require Google Mock (now a part of Google Test). @@ -178,8 +179,7 @@ -Dprotobuf_BUILD_TESTS=OFF ^ C:\Path\to\src\protobuf -Compiling -========= +## Compiling The standard way to compile a *CMake* project is `cmake --build <directory>`. @@ -206,8 +206,7 @@ And wait for the compilation to finish. -Testing -======= +## Testing To run unit-tests, first you must compile protobuf as described above. Then run: @@ -259,8 +258,7 @@ If all tests are passed, safely continue. -Installing -========== +## Installing To install protobuf to the *install* folder you've specified in the configuration step, you need to build the `install` target: @@ -292,8 +290,7 @@ debug build of libprotobufd.lib with "d" postfix. Similarly, release builds should link against release libprotobuf.lib library. -DLLs vs. static linking -======================= +## DLLs vs. static linking Static linking is now the default for the Protocol Buffer libraries. Due to issues with Win32's use of a separate heap for each DLL, as well as binary @@ -318,8 +315,7 @@ public interface, and that you statically link protocol buffers into your library. -ZLib support -============ +## ZLib support If you want to include GzipInputStream and GzipOutputStream (google/protobuf/io/gzip_stream.h) in libprotobuf, you will need to do a few @@ -369,8 +365,7 @@ Build and testing protobuf as usual. -Notes on Compiler Warnings -========================== +## Notes on Compiler Warnings The following warnings have been disabled while building the protobuf libraries and compiler. You may have to disable some of them in your own project as @@ -397,3 +392,23 @@ nevertheless. So, we disable it. Unfortunately, this warning will also be produced when compiling code which merely uses protocol buffers, meaning you may have to disable it in your code too. + +# Linux Builds + +Building with CMake works very similarly on Linux. Instead of Visual Studio, +you will need to have gcc or clang installed to handle the C++ builds. CMake +will generate Makefiles by default, but can also be configured to use Ninja. To +build Protobuf, you will need to run (from the source directory): + + cmake . + cmake --build . --parallel 10 + +Protobuf can be tested and installed with CMake: + + ctest --verbose + sudo cmake --install . + +or directly with the generated Makefiles: + + make VERBOSE=1 test + sudo make install
diff --git a/cmake/conformance.cmake b/cmake/conformance.cmake index d6c435a..338b275 100644 --- a/cmake/conformance.cmake +++ b/cmake/conformance.cmake
@@ -24,6 +24,9 @@ ${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc ${protobuf_SOURCE_DIR}/conformance/conformance_test.cc ${protobuf_SOURCE_DIR}/conformance/conformance_test_runner.cc + ${protobuf_SOURCE_DIR}/conformance/conformance_test_main.cc + ${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.cc + ${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.h ${protobuf_SOURCE_DIR}/conformance/third_party/jsoncpp/json.h ${protobuf_SOURCE_DIR}/conformance/third_party/jsoncpp/jsoncpp.cpp ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc @@ -45,5 +48,13 @@ conformance_cpp PUBLIC ${protobuf_SOURCE_DIR}/conformance) -target_link_libraries(conformance_test_runner libprotobuf) -target_link_libraries(conformance_cpp libprotobuf) +target_link_libraries(conformance_test_runner ${protobuf_LIB_PROTOBUF}) +target_link_libraries(conformance_cpp ${protobuf_LIB_PROTOBUF}) + +add_test(NAME conformance_cpp_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/conformance_test_runner + --failure_list ${protobuf_SOURCE_DIR}/conformance/failure_list_cpp.txt + --text_format_failure_list ${protobuf_SOURCE_DIR}/conformance/text_format_failure_list_cpp.txt + --output_dir ${protobuf_TEST_XML_OUTDIR} + ${CMAKE_CURRENT_BINARY_DIR}/conformance_cpp + DEPENDS conformance_test_runner conformance_cpp)
diff --git a/cmake/examples.cmake b/cmake/examples.cmake index 3b83d2b..07cfad2 100644 --- a/cmake/examples.cmake +++ b/cmake/examples.cmake
@@ -30,7 +30,7 @@ # Add examples as an external project. # sub_directory cannot be used because the find_package(protobuf) call would cause failures with redefined targets. add_examples_build(examples "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}") -add_dependencies(examples libprotobuf protoc) +add_dependencies(examples ${protobuf_LIB_PROTOBUF} ${protobuf_PROTOC_EXE}) option(protobuf_BUILD_EXAMPLES_MULTITEST "Build Examples in multiple configurations. Useful for testing." OFF) mark_as_advanced(protobuf_BUILD_EXAMPLES_MULTITEST) @@ -42,7 +42,7 @@ "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}" "-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE" ) - add_dependencies(examples-legacy libprotobuf protoc) + add_dependencies(examples-legacy ${protobuf_LIB_PROTOBUF} ${protobuf_PROTOC_EXE}) #Build using the installed library. add_examples_build(examples-installed
diff --git a/cmake/install.cmake b/cmake/install.cmake index 2da8170..cf24e30 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake
@@ -43,25 +43,23 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") -file(STRINGS ${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in _extract_strings - REGEX "^copy") -foreach(_extract_string ${_extract_strings}) - string(REGEX REPLACE "^.* .+ include\\\\(.+)$" "\\1" - _header ${_extract_string}) - string(REPLACE "\\" "/" _header ${_header}) +include(${protobuf_SOURCE_DIR}/src/file_lists.cmake) +set(protobuf_HEADERS + ${libprotobuf_hdrs} + ${libprotoc_hdrs} + ${wkt_protos_files} + ${descriptor_proto_proto_srcs} + ${plugin_proto_proto_srcs} +) +foreach(_header ${protobuf_HEADERS}) + string(REPLACE "${protobuf_SOURCE_DIR}/src" "" _header ${_header}) get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/src/${_header}" ABSOLUTE) get_filename_component(_extract_name ${_header} NAME) get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" DIRECTORY) - if(EXISTS "${_extract_from}") - install(FILES "${_extract_from}" - DESTINATION "${_extract_to}" - COMPONENT protobuf-headers - RENAME "${_extract_name}") - else() - message(AUTHOR_WARNING "The file \"${_extract_from}\" is listed in " - "\"${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in\" " - "but there not exists. The file will not be installed.") - endif() + install(FILES "${_extract_from}" + DESTINATION "${_extract_to}" + COMPONENT protobuf-headers + RENAME "${_extract_name}") endforeach() # Internal function for parsing auto tools scripts
diff --git a/cmake/tests.cmake b/cmake/tests.cmake index be1d429..6a1d1c0 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake
@@ -1,6 +1,7 @@ option(protobuf_USE_EXTERNAL_GTEST "Use external Google Test (i.e. not the one in third_party/googletest)" OFF) -option(protobuf_TEST_XML_OUTDIR "Output directory for XML logs from tests." "") +option(protobuf_REMOVE_INSTALLED_HEADERS + "Remove local headers so that installed ones are used instead" OFF) option(protobuf_ABSOLUTE_TEST_PLUGIN_PATH "Using absolute test_plugin path in tests" ON) @@ -77,10 +78,9 @@ add_library(protobuf-lite-test-common STATIC ${lite_test_util_srcs} ${lite_test_proto_files}) -target_link_libraries(protobuf-lite-test-common libprotobuf-lite GTest::gmock) +target_link_libraries(protobuf-lite-test-common ${protobuf_LIB_PROTOBUF_LITE} GTest::gmock) set(common_test_files - ${lite_test_util_srcs} ${test_util_hdrs} ${test_util_srcs} ${mock_code_generator_srcs} @@ -89,7 +89,7 @@ add_library(protobuf-test-common STATIC ${common_test_files} ${tests_proto_files}) -target_link_libraries(protobuf-test-common libprotobuf GTest::gmock) +target_link_libraries(protobuf-test-common ${protobuf_LIB_PROTOBUF} GTest::gmock) set(tests_files ${protobuf_test_files} @@ -130,7 +130,7 @@ /wd4146 # unary minus operator applied to unsigned type, result still unsigned ) endif() -target_link_libraries(tests protobuf-lite-test-common protobuf-test-common libprotoc libprotobuf GTest::gmock_main) +target_link_libraries(tests protobuf-lite-test-common protobuf-test-common ${protobuf_LIB_PROTOC} ${protobuf_LIB_PROTOBUF} GTest::gmock_main) set(test_plugin_files ${test_plugin_files} @@ -139,19 +139,50 @@ ) add_executable(test_plugin ${test_plugin_files}) -target_link_libraries(test_plugin libprotoc libprotobuf GTest::gmock) +target_link_libraries(test_plugin ${protobuf_LIB_PROTOC} ${protobuf_LIB_PROTOBUF} GTest::gmock) add_executable(lite-test ${protobuf_lite_test_files}) -target_link_libraries(lite-test protobuf-lite-test-common libprotobuf-lite GTest::gmock_main) +target_link_libraries(lite-test protobuf-lite-test-common ${protobuf_LIB_PROTOBUF_LITE} GTest::gmock_main) add_test(NAME lite-test COMMAND lite-test ${protobuf_GTEST_ARGS}) add_custom_target(check COMMAND tests - DEPENDS tests test_plugin + DEPENDS tests lite-test test_plugin WORKING_DIRECTORY ${protobuf_SOURCE_DIR}) add_test(NAME check - COMMAND tests ${protobuf_GTEST_ARGS} - WORKING_DIRECTORY "${protobuf_SOURCE_DIR}") + COMMAND tests ${protobuf_GTEST_ARGS}) + +# For test purposes, remove headers that should already be installed. This +# prevents accidental conflicts and also version skew (since local headers take +# precedence over installed headers). +add_custom_target(save-installed-headers) +add_custom_target(remove-installed-headers) +add_custom_target(restore-installed-headers) + +# Explicitly skip the bootstrapping headers as it's directly used in tests +set(_installed_hdrs ${libprotobuf_hdrs} ${libprotoc_hdrs}) +list(REMOVE_ITEM _installed_hdrs + "${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.h" + "${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h") + +foreach(_hdr ${_installed_hdrs}) + string(REPLACE "${protobuf_SOURCE_DIR}/src" "" _file ${_hdr}) + set(_tmp_file "${CMAKE_BINARY_DIR}/tmp-install-test/${_file}") + add_custom_command(TARGET remove-installed-headers PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E remove -f "${_hdr}") + add_custom_command(TARGET save-installed-headers PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E + copy "${_hdr}" "${_tmp_file}" || true) + add_custom_command(TARGET restore-installed-headers PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E + copy "${_tmp_file}" "${_hdr}") +endforeach() + +add_dependencies(remove-installed-headers save-installed-headers) +if(protobuf_REMOVE_INSTALLED_HEADERS) + add_dependencies(protobuf-lite-test-common remove-installed-headers) + add_dependencies(protobuf-test-common remove-installed-headers) +endif()
diff --git a/configure.ac b/configure.ac index c55a6a2..64ddb3d 100644 --- a/configure.ac +++ b/configure.ac
@@ -17,7 +17,7 @@ # In the SVN trunk, the version should always be the next anticipated release # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # the size of one file name in the dist tarfile over the 99-char limit.) -AC_INIT([Protocol Buffers],[3.21.2],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[3.21.4],[protobuf@googlegroups.com],[protobuf]) AM_MAINTAINER_MODE([enable])
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs index 57e59a9..d3284a4 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs
@@ -580,23 +580,23 @@ if (other == null) { return; } - mapInt32Int32_.Add(other.mapInt32Int32_); - mapInt64Int64_.Add(other.mapInt64Int64_); - mapUint32Uint32_.Add(other.mapUint32Uint32_); - mapUint64Uint64_.Add(other.mapUint64Uint64_); - mapSint32Sint32_.Add(other.mapSint32Sint32_); - mapSint64Sint64_.Add(other.mapSint64Sint64_); - mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_); - mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_); - mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_); - mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_); - mapInt32Float_.Add(other.mapInt32Float_); - mapInt32Double_.Add(other.mapInt32Double_); - mapBoolBool_.Add(other.mapBoolBool_); - mapStringString_.Add(other.mapStringString_); - mapInt32Bytes_.Add(other.mapInt32Bytes_); - mapInt32Enum_.Add(other.mapInt32Enum_); - mapInt32ForeignMessage_.Add(other.mapInt32ForeignMessage_); + mapInt32Int32_.MergeFrom(other.mapInt32Int32_); + mapInt64Int64_.MergeFrom(other.mapInt64Int64_); + mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_); + mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_); + mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_); + mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_); + mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_); + mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_); + mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_); + mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_); + mapInt32Float_.MergeFrom(other.mapInt32Float_); + mapInt32Double_.MergeFrom(other.mapInt32Double_); + mapBoolBool_.MergeFrom(other.mapBoolBool_); + mapStringString_.MergeFrom(other.mapStringString_); + mapInt32Bytes_.MergeFrom(other.mapInt32Bytes_); + mapInt32Enum_.MergeFrom(other.mapInt32Enum_); + mapInt32ForeignMessage_.MergeFrom(other.mapInt32ForeignMessage_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1100,7 +1100,7 @@ if (other == null) { return; } - mapInt32Message_.Add(other.mapInt32Message_); + mapInt32Message_.MergeFrom(other.mapInt32Message_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1298,8 +1298,8 @@ if (other == null) { return; } - map1_.Add(other.map1_); - map2_.Add(other.map2_); + map1_.MergeFrom(other.map1_); + map2_.MergeFrom(other.map2_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1723,21 +1723,21 @@ if (other == null) { return; } - mapInt32Int32_.Add(other.mapInt32Int32_); - mapInt64Int64_.Add(other.mapInt64Int64_); - mapUint32Uint32_.Add(other.mapUint32Uint32_); - mapUint64Uint64_.Add(other.mapUint64Uint64_); - mapSint32Sint32_.Add(other.mapSint32Sint32_); - mapSint64Sint64_.Add(other.mapSint64Sint64_); - mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_); - mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_); - mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_); - mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_); - mapInt32Float_.Add(other.mapInt32Float_); - mapInt32Double_.Add(other.mapInt32Double_); - mapBoolBool_.Add(other.mapBoolBool_); - mapInt32Enum_.Add(other.mapInt32Enum_); - mapInt32ForeignMessage_.Add(other.mapInt32ForeignMessage_); + mapInt32Int32_.MergeFrom(other.mapInt32Int32_); + mapInt64Int64_.MergeFrom(other.mapInt64Int64_); + mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_); + mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_); + mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_); + mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_); + mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_); + mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_); + mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_); + mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_); + mapInt32Float_.MergeFrom(other.mapInt32Float_); + mapInt32Double_.MergeFrom(other.mapInt32Double_); + mapBoolBool_.MergeFrom(other.mapBoolBool_); + mapInt32Enum_.MergeFrom(other.mapInt32Enum_); + mapInt32ForeignMessage_.MergeFrom(other.mapInt32ForeignMessage_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -2031,7 +2031,7 @@ if (other == null) { return; } - type_.Add(other.type_); + type_.MergeFrom(other.type_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -2224,7 +2224,7 @@ if (other == null) { return; } - entry_.Add(other.entry_); + entry_.MergeFrom(other.entry_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); }
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs index 08b1aaf..d573455 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
@@ -4344,25 +4344,25 @@ unpackedDouble_.Add(other.unpackedDouble_); unpackedBool_.Add(other.unpackedBool_); unpackedNestedEnum_.Add(other.unpackedNestedEnum_); - mapInt32Int32_.Add(other.mapInt32Int32_); - mapInt64Int64_.Add(other.mapInt64Int64_); - mapUint32Uint32_.Add(other.mapUint32Uint32_); - mapUint64Uint64_.Add(other.mapUint64Uint64_); - mapSint32Sint32_.Add(other.mapSint32Sint32_); - mapSint64Sint64_.Add(other.mapSint64Sint64_); - mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_); - mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_); - mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_); - mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_); - mapInt32Float_.Add(other.mapInt32Float_); - mapInt32Double_.Add(other.mapInt32Double_); - mapBoolBool_.Add(other.mapBoolBool_); - mapStringString_.Add(other.mapStringString_); - mapStringBytes_.Add(other.mapStringBytes_); - mapStringNestedMessage_.Add(other.mapStringNestedMessage_); - mapStringForeignMessage_.Add(other.mapStringForeignMessage_); - mapStringNestedEnum_.Add(other.mapStringNestedEnum_); - mapStringForeignEnum_.Add(other.mapStringForeignEnum_); + mapInt32Int32_.MergeFrom(other.mapInt32Int32_); + mapInt64Int64_.MergeFrom(other.mapInt64Int64_); + mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_); + mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_); + mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_); + mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_); + mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_); + mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_); + mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_); + mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_); + mapInt32Float_.MergeFrom(other.mapInt32Float_); + mapInt32Double_.MergeFrom(other.mapInt32Double_); + mapBoolBool_.MergeFrom(other.mapBoolBool_); + mapStringString_.MergeFrom(other.mapStringString_); + mapStringBytes_.MergeFrom(other.mapStringBytes_); + mapStringNestedMessage_.MergeFrom(other.mapStringNestedMessage_); + mapStringForeignMessage_.MergeFrom(other.mapStringForeignMessage_); + mapStringNestedEnum_.MergeFrom(other.mapStringNestedEnum_); + mapStringForeignEnum_.MergeFrom(other.mapStringForeignEnum_); if (other.HasData) { if (!HasData) { Data = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.Data();
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs index 520216f..74e2a57 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs
@@ -3753,25 +3753,25 @@ unpackedDouble_.Add(other.unpackedDouble_); unpackedBool_.Add(other.unpackedBool_); unpackedNestedEnum_.Add(other.unpackedNestedEnum_); - mapInt32Int32_.Add(other.mapInt32Int32_); - mapInt64Int64_.Add(other.mapInt64Int64_); - mapUint32Uint32_.Add(other.mapUint32Uint32_); - mapUint64Uint64_.Add(other.mapUint64Uint64_); - mapSint32Sint32_.Add(other.mapSint32Sint32_); - mapSint64Sint64_.Add(other.mapSint64Sint64_); - mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_); - mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_); - mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_); - mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_); - mapInt32Float_.Add(other.mapInt32Float_); - mapInt32Double_.Add(other.mapInt32Double_); - mapBoolBool_.Add(other.mapBoolBool_); - mapStringString_.Add(other.mapStringString_); - mapStringBytes_.Add(other.mapStringBytes_); - mapStringNestedMessage_.Add(other.mapStringNestedMessage_); - mapStringForeignMessage_.Add(other.mapStringForeignMessage_); - mapStringNestedEnum_.Add(other.mapStringNestedEnum_); - mapStringForeignEnum_.Add(other.mapStringForeignEnum_); + mapInt32Int32_.MergeFrom(other.mapInt32Int32_); + mapInt64Int64_.MergeFrom(other.mapInt64Int64_); + mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_); + mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_); + mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_); + mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_); + mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_); + mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_); + mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_); + mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_); + mapInt32Float_.MergeFrom(other.mapInt32Float_); + mapInt32Double_.MergeFrom(other.mapInt32Double_); + mapBoolBool_.MergeFrom(other.mapBoolBool_); + mapStringString_.MergeFrom(other.mapStringString_); + mapStringBytes_.MergeFrom(other.mapStringBytes_); + mapStringNestedMessage_.MergeFrom(other.mapStringNestedMessage_); + mapStringForeignMessage_.MergeFrom(other.mapStringForeignMessage_); + mapStringNestedEnum_.MergeFrom(other.mapStringNestedEnum_); + mapStringForeignEnum_.MergeFrom(other.mapStringForeignEnum_); if (other.optionalBoolWrapper_ != null) { if (optionalBoolWrapper_ == null || other.OptionalBoolWrapper != false) { OptionalBoolWrapper = other.OptionalBoolWrapper;
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs b/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs index c1f43ce..7f1aca1 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs
@@ -24112,7 +24112,7 @@ if (other == null) { return; } - foo_.Add(other.foo_); + foo_.MergeFrom(other.foo_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -30708,7 +30708,7 @@ } OptionalGroup.MergeFrom(other.OptionalGroup); } - stringStringMap_.Add(other.stringStringMap_); + stringStringMap_.MergeFrom(other.stringStringMap_); switch (other.OneofFieldCase) { case OneofFieldOneofCase.OneofUint32: OneofUint32 = other.OneofUint32;
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs index 3ec8d35..50b9046 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs
@@ -3258,24 +3258,24 @@ if (other == null) { return; } - anyField_.Add(other.anyField_); - apiField_.Add(other.apiField_); - durationField_.Add(other.durationField_); - emptyField_.Add(other.emptyField_); - fieldMaskField_.Add(other.fieldMaskField_); - sourceContextField_.Add(other.sourceContextField_); - structField_.Add(other.structField_); - timestampField_.Add(other.timestampField_); - typeField_.Add(other.typeField_); - doubleField_.Add(other.doubleField_); - floatField_.Add(other.floatField_); - int64Field_.Add(other.int64Field_); - uint64Field_.Add(other.uint64Field_); - int32Field_.Add(other.int32Field_); - uint32Field_.Add(other.uint32Field_); - boolField_.Add(other.boolField_); - stringField_.Add(other.stringField_); - bytesField_.Add(other.bytesField_); + anyField_.MergeFrom(other.anyField_); + apiField_.MergeFrom(other.apiField_); + durationField_.MergeFrom(other.durationField_); + emptyField_.MergeFrom(other.emptyField_); + fieldMaskField_.MergeFrom(other.fieldMaskField_); + sourceContextField_.MergeFrom(other.sourceContextField_); + structField_.MergeFrom(other.structField_); + timestampField_.MergeFrom(other.timestampField_); + typeField_.MergeFrom(other.typeField_); + doubleField_.MergeFrom(other.doubleField_); + floatField_.MergeFrom(other.floatField_); + int64Field_.MergeFrom(other.int64Field_); + uint64Field_.MergeFrom(other.uint64Field_); + int32Field_.MergeFrom(other.int32Field_); + uint32Field_.MergeFrom(other.uint32Field_); + boolField_.MergeFrom(other.boolField_); + stringField_.MergeFrom(other.stringField_); + bytesField_.MergeFrom(other.bytesField_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); }
diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs index 8387291..17c5249 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
@@ -36,6 +36,7 @@ using NUnit.Framework; using System.Linq; using Google.Protobuf.WellKnownTypes; +using Google.Protobuf.Collections; namespace Google.Protobuf { @@ -795,5 +796,44 @@ EqualityTester.AssertInequality(message1, message2); EqualityTester.AssertEquality(message1, message3); } + + [Test] + [TestCase(false)] + [TestCase(true)] + public void MapFieldMerging(bool direct) + { + var message1 = new TestMap + { + MapStringString = + { + { "x1", "y1" }, + { "common", "message1" } + } + }; + var message2 = new TestMap + { + MapStringString = + { + { "x2", "y2" }, + { "common", "message2" } + } + }; + if (direct) + { + message1.MergeFrom(message2); + } + else + { + message1.MergeFrom(message2.ToByteArray()); + } + + var expected = new MapField<string, string> + { + { "x1", "y1" }, + { "x2", "y2" }, + { "common", "message2" } + }; + Assert.AreEqual(expected, message1.MapStringString); + } } } \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs index f0124ee..09afb75 100644 --- a/csharp/src/Google.Protobuf/Collections/MapField.cs +++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -238,6 +238,21 @@ } /// <summary> + /// Adds the specified entries to the map, replacing any existing entries with the same keys. + /// The keys and values are not automatically cloned. + /// </summary> + /// <remarks>This method primarily exists to be called from MergeFrom methods in generated classes for messages.</remarks> + /// <param name="entries">The entries to add to the map.</param> + public void MergeFrom(IDictionary<TKey, TValue> entries) + { + ProtoPreconditions.CheckNotNull(entries, nameof(entries)); + foreach (var pair in entries) + { + this[pair.Key] = pair.Value; + } + } + + /// <summary> /// Returns an enumerator that iterates through the collection. /// </summary> /// <returns>
diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs index 66907d4..5710292 100644 --- a/csharp/src/Google.Protobuf/MessageParser.cs +++ b/csharp/src/Google.Protobuf/MessageParser.cs
@@ -171,6 +171,10 @@ /// <summary> /// Parses a message from the given JSON. /// </summary> + /// <remarks>This method always uses the default JSON parser; it is not affected by <see cref="WithDiscardUnknownFields(bool)"/>. + /// To ignore unknown fields when parsing JSON, create a <see cref="JsonParser"/> using a <see cref="JsonParser.Settings"/> + /// with <see cref="JsonParser.Settings.IgnoreUnknownFields"/> set to true and call <see cref="JsonParser.Parse{T}(string)"/> directly. + /// </remarks> /// <param name="json">The JSON to parse.</param> /// <returns>The parsed message.</returns> /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception> @@ -203,6 +207,9 @@ /// <summary> /// Creates a new message parser which optionally discards unknown fields when parsing. /// </summary> + /// <remarks>Note that this does not affect the behavior of <see cref="ParseJson(string)"/> + /// at all. To ignore unknown fields when parsing JSON, create a <see cref="JsonParser"/> using a <see cref="JsonParser.Settings"/> + /// with <see cref="JsonParser.Settings.IgnoreUnknownFields"/> set to true and call <see cref="JsonParser.Parse{T}(string)"/> directly.</remarks> /// <param name="discardUnknownFields">Whether or not to discard unknown fields when parsing.</param> /// <returns>A newly configured message parser.</returns> public MessageParser WithDiscardUnknownFields(bool discardUnknownFields) =>
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs index 8c1eec5..aa25686 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
@@ -212,7 +212,7 @@ if (other == null) { return; } - fields_.Add(other.fields_); + fields_.MergeFrom(other.fields_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); }
diff --git a/java/core/src/main/java/com/google/protobuf/BinaryWriter.java b/java/core/src/main/java/com/google/protobuf/BinaryWriter.java index cf394e3..66cf51d 100644 --- a/java/core/src/main/java/com/google/protobuf/BinaryWriter.java +++ b/java/core/src/main/java/com/google/protobuf/BinaryWriter.java
@@ -209,7 +209,7 @@ } } - private final void writeInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed) + private void writeInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE)); @@ -227,7 +227,7 @@ } } - private final void writeInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed) + private void writeInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE)); @@ -255,7 +255,7 @@ } } - private final void writeFixed32List_Internal(int fieldNumber, List<Integer> list, boolean packed) + private void writeFixed32List_Internal(int fieldNumber, List<Integer> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE)); @@ -273,7 +273,7 @@ } } - private final void writeFixed32List_Internal(int fieldNumber, IntArrayList list, boolean packed) + private void writeFixed32List_Internal(int fieldNumber, IntArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE)); @@ -307,7 +307,7 @@ } } - private final void writeUInt64List_Internal(int fieldNumber, List<Long> list, boolean packed) + private void writeUInt64List_Internal(int fieldNumber, List<Long> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE)); @@ -325,7 +325,7 @@ } } - private final void writeUInt64List_Internal(int fieldNumber, LongArrayList list, boolean packed) + private void writeUInt64List_Internal(int fieldNumber, LongArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE)); @@ -353,7 +353,7 @@ } } - private final void writeFixed64List_Internal(int fieldNumber, List<Long> list, boolean packed) + private void writeFixed64List_Internal(int fieldNumber, List<Long> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE)); @@ -371,7 +371,7 @@ } } - private final void writeFixed64List_Internal(int fieldNumber, LongArrayList list, boolean packed) + private void writeFixed64List_Internal(int fieldNumber, LongArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE)); @@ -399,7 +399,7 @@ } } - private final void writeFloatList_Internal(int fieldNumber, List<Float> list, boolean packed) + private void writeFloatList_Internal(int fieldNumber, List<Float> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE)); @@ -417,7 +417,7 @@ } } - private final void writeFloatList_Internal(int fieldNumber, FloatArrayList list, boolean packed) + private void writeFloatList_Internal(int fieldNumber, FloatArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE)); @@ -445,7 +445,7 @@ } } - private final void writeDoubleList_Internal(int fieldNumber, List<Double> list, boolean packed) + private void writeDoubleList_Internal(int fieldNumber, List<Double> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE)); @@ -463,7 +463,7 @@ } } - private final void writeDoubleList_Internal(int fieldNumber, DoubleArrayList list, boolean packed) + private void writeDoubleList_Internal(int fieldNumber, DoubleArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE)); @@ -497,7 +497,7 @@ } } - private final void writeBoolList_Internal(int fieldNumber, List<Boolean> list, boolean packed) + private void writeBoolList_Internal(int fieldNumber, List<Boolean> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + list.size()); @@ -515,7 +515,7 @@ } } - private final void writeBoolList_Internal(int fieldNumber, BooleanArrayList list, boolean packed) + private void writeBoolList_Internal(int fieldNumber, BooleanArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + list.size()); @@ -572,7 +572,7 @@ } } - private final void writeUInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed) + private void writeUInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE)); @@ -590,7 +590,7 @@ } } - private final void writeUInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed) + private void writeUInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE)); @@ -630,7 +630,7 @@ } } - private final void writeSInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed) + private void writeSInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE)); @@ -648,7 +648,7 @@ } } - private final void writeSInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed) + private void writeSInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE)); @@ -759,7 +759,7 @@ } } - private final void writeSInt64List_Internal(int fieldNumber, List<Long> list, boolean packed) + private void writeSInt64List_Internal(int fieldNumber, List<Long> list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE)); @@ -777,7 +777,7 @@ } } - private final void writeSInt64List_Internal(int fieldNumber, LongArrayList list, boolean packed) + private void writeSInt64List_Internal(int fieldNumber, LongArrayList list, boolean packed) throws IOException { if (packed) { requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE));
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java index e212ab5..0c16000 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -137,7 +137,7 @@ // any unnecessary intermediary allocations while reducing the generated code size. /** Lazily initializes unknown fields. */ - private final void ensureUnknownFieldsInitialized() { + private void ensureUnknownFieldsInitialized() { if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) { unknownFields = UnknownFieldSetLite.newInstance(); }
diff --git a/kokoro/linux/bazel_distcheck/build.sh b/kokoro/linux/bazel_distcheck/build.sh deleted file mode 100755 index a50b175..0000000 --- a/kokoro/linux/bazel_distcheck/build.sh +++ /dev/null
@@ -1,61 +0,0 @@ -#!/bin/bash -# -# Build file to set up and run tests using bazel-build dist archive -# -# Note that the builds use WORKSPACE to fetch external sources, not -# git submodules. - -set -eu - -use_bazel.sh 5.0.0 || true -bazel version - -# Change to repo root -cd $(dirname $0)/../../.. - -# Get kokoro scripts from repo root by default. -: ${SCRIPT_ROOT:=$(pwd)} -source ${SCRIPT_ROOT}/kokoro/common/pyenv.sh - -# Build distribution archive -echo "============================================================" -echo -e "[[ $(date) ]] Building distribution archive...\n" -${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh build //pkg:dist_all_tar -DIST_ARCHIVE=$(readlink $(bazel info bazel-bin)/pkg/dist_all_tar.tar.gz) -bazel shutdown - -# Extract the dist archive. -echo "============================================================" -echo -e "[[ $(date) ]] Extracting distribution archive...\n" - -# Construct temp directory for running the dist build. -# If you want to run locally and keep the build dir, create a directory -# and pass it in the DIST_WORK_ROOT env var. -if [[ -z ${DIST_WORK_ROOT:-} ]]; then - : ${DIST_WORK_ROOT:=$(mktemp -d)} - function dist_cleanup() { - (( $BASH_SUBSHELL == 0 )) && rm -rf ${DIST_WORK_ROOT} - } - trap dist_cleanup EXIT -fi - -DIST_WORKSPACE=${DIST_WORK_ROOT}/protobuf -mkdir -p ${DIST_WORKSPACE} -tar -C ${DIST_WORKSPACE} --strip-components=1 -axf bazel-bin/pkg/dist_all_tar.tar.gz - -echo "============================================================" -echo -e "[[ $(date) ]] Building extracted archive...\n" - -cd ${DIST_WORKSPACE} - -bazel_args=( - test - --keep_going - --test_output=errors - -- - //... - -//objectivec/... # only works on macOS - -//csharp/... # release builds require external dependencies - @com_google_protobuf_examples//... -) -${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh "${bazel_args[@]}"
diff --git a/kokoro/linux/bazel_distcheck/common.cfg b/kokoro/linux/bazel_distcheck/common.cfg deleted file mode 100644 index 6b18488..0000000 --- a/kokoro/linux/bazel_distcheck/common.cfg +++ /dev/null
@@ -1,9 +0,0 @@ -# Common config shared by presubmit and continuous. - -bazel_setting: { - project_id: "protobuf-build" - bes_backend_address: "buildeventservice.googleapis.com" - foundry_backend_address: "remotebuildexecution.googleapis.com" - upsalite_frontend_address: "https://source.cloud.google.com" - local_execution: true -}
diff --git a/kokoro/linux/bazel_distcheck/continuous.cfg b/kokoro/linux/bazel_distcheck/continuous.cfg deleted file mode 100644 index 4ea8b21..0000000 --- a/kokoro/linux/bazel_distcheck/continuous.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/bazel_distcheck/build.sh" -timeout_mins: 15
diff --git a/kokoro/linux/bazel_distcheck/presubmit.cfg b/kokoro/linux/bazel_distcheck/presubmit.cfg deleted file mode 100644 index 4ea8b21..0000000 --- a/kokoro/linux/bazel_distcheck/presubmit.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/bazel_distcheck/build.sh" -timeout_mins: 15
diff --git a/kokoro/linux/cmake/build.sh b/kokoro/linux/cmake/build.sh index 1b0ebfc..523253d 100755 --- a/kokoro/linux/cmake/build.sh +++ b/kokoro/linux/cmake/build.sh
@@ -1,6 +1,6 @@ #!/bin/bash # -# Build file to set up and run tests based on distribution archive +# Build file to set up and run tests using CMake set -eux
diff --git a/kokoro/linux/cmake_distcheck/build.sh b/kokoro/linux/cmake_distcheck/build.sh deleted file mode 100755 index 116e40b..0000000 --- a/kokoro/linux/cmake_distcheck/build.sh +++ /dev/null
@@ -1,60 +0,0 @@ -#!/bin/bash -# -# Build file to set up and run tests based on distribution archive - -set -eux - -# Change to repo root -cd $(dirname $0)/../../.. - -# -# Update git submodules -# -git submodule update --init --recursive - -# -# Build distribution archive -# -# TODO: this should use Bazel-built dist archives. -date ; ./autogen.sh -date ; ./configure -date ; make dist -date - -DIST_ARCHIVE=( $(ls protobuf-*.tar.gz) ) -if (( ${#DIST_ARCHIVE[@]} != 1 )); then - echo >&2 "Distribution archive not found. ${#DIST_ARCHIVE[@]} matches:" - echo >&2 "${DIST_ARCHIVE[@]}" - exit 1 -fi - -# -# Check for all expected files -# -kokoro/common/check_missing_dist_files.sh ${DIST_ARCHIVE} - -# -# Extract to a temporary directory -# -if [[ -z ${DIST_WORK_ROOT:-} ]]; then - # If you want to preserve the extracted sources, set the DIST_WORK_ROOT - # environment variable to an existing directory that should be used. - DIST_WORK_ROOT=$(mktemp -d) - function cleanup_work_root() { - echo "Cleaning up temporary directory ${DIST_WORK_ROOT}..." - rm -rf ${DIST_WORK_ROOT} - } - trap cleanup_work_root EXIT -fi - -tar -C ${DIST_WORK_ROOT} --strip-components=1 -axf ${DIST_ARCHIVE} - -# -# Run tests using extracted sources -# -SOURCE_DIR=${DIST_WORK_ROOT} \ -CMAKE_GENERATOR=Ninja \ -CTEST_PARALLEL_LEVEL=$(nproc) \ -kokoro/common/cmake.sh - -echo "PASS"
diff --git a/kokoro/linux/cmake_distcheck/continuous.cfg b/kokoro/linux/cmake_distcheck/continuous.cfg deleted file mode 100644 index 6ef4c89..0000000 --- a/kokoro/linux/cmake_distcheck/continuous.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/cmake_distcheck/build.sh" -timeout_mins: 1440
diff --git a/kokoro/linux/cmake_distcheck/presubmit.cfg b/kokoro/linux/cmake_distcheck/presubmit.cfg deleted file mode 100644 index 6ef4c89..0000000 --- a/kokoro/linux/cmake_distcheck/presubmit.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/cmake_distcheck/build.sh" -timeout_mins: 1440
diff --git a/kokoro/linux/cmake_install/build.sh b/kokoro/linux/cmake_install/build.sh index 6fdafa5..7fdf267 100755 --- a/kokoro/linux/cmake_install/build.sh +++ b/kokoro/linux/cmake_install/build.sh
@@ -1,6 +1,6 @@ #!/bin/bash # -# Build file to set up and run tests based on distribution archive +# Build file to build, install, and test using CMake. set -eux
diff --git a/kokoro/linux/cmake_ninja/build.sh b/kokoro/linux/cmake_ninja/build.sh index d3a281f..21cc01e 100755 --- a/kokoro/linux/cmake_ninja/build.sh +++ b/kokoro/linux/cmake_ninja/build.sh
@@ -1,6 +1,6 @@ #!/bin/bash # -# Build file to set up and run tests based on distribution archive +# Build file to set up and run tests using CMake with the Ninja generator. set -eux
diff --git a/kokoro/linux/cmake_shared/build.sh b/kokoro/linux/cmake_shared/build.sh new file mode 100755 index 0000000..87dde41 --- /dev/null +++ b/kokoro/linux/cmake_shared/build.sh
@@ -0,0 +1,7 @@ +#!/bin/bash +# +# Build file to set up and run tests via CMake using shared libraries + +set -eux + +# TODO(mkruskal) Implement this. \ No newline at end of file
diff --git a/kokoro/linux/cmake_shared/continuous.cfg b/kokoro/linux/cmake_shared/continuous.cfg new file mode 100644 index 0000000..f03bd39 --- /dev/null +++ b/kokoro/linux/cmake_shared/continuous.cfg
@@ -0,0 +1,11 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/linux/cmake/build.sh" +timeout_mins: 1440 + +action { + define_artifacts { + regex: "**/sponge_log.*" + } +}
diff --git a/kokoro/linux/cmake_shared/presubmit.cfg b/kokoro/linux/cmake_shared/presubmit.cfg new file mode 100644 index 0000000..f03bd39 --- /dev/null +++ b/kokoro/linux/cmake_shared/presubmit.cfg
@@ -0,0 +1,11 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/linux/cmake/build.sh" +timeout_mins: 1440 + +action { + define_artifacts { + regex: "**/sponge_log.*" + } +}
diff --git a/kokoro/linux/cpp_distcheck/build.sh b/kokoro/linux/cpp_distcheck/build.sh deleted file mode 100755 index a28843e..0000000 --- a/kokoro/linux/cpp_distcheck/build.sh +++ /dev/null
@@ -1,25 +0,0 @@ -#!/bin/bash -# -# Build file to set up and run tests - -set -ex # exit immediately on error - -# Change to repo root -cd $(dirname $0)/../../.. - -./tests.sh cpp_distcheck - -# Run tests under release docker image. -DOCKER_IMAGE_NAME=protobuf/protoc_$(sha1sum protoc-artifacts/Dockerfile | cut -f1 -d " ") -until docker pull $DOCKER_IMAGE_NAME; do sleep 10; done - -docker run -v $(pwd):/var/local/protobuf --rm $DOCKER_IMAGE_NAME \ - bash -l /var/local/protobuf/tests.sh cpp || FAILED="true" - -# This directory is owned by root. We need to delete it, because otherwise -# Kokoro will attempt to rsync it and fail with a permission error. -rm -rf src/core - -if [ "$FAILED" = "true" ]; then - exit 1 -fi
diff --git a/kokoro/linux/cpp_distcheck/continuous.cfg b/kokoro/linux/cpp_distcheck/continuous.cfg deleted file mode 100644 index 4289f6a..0000000 --- a/kokoro/linux/cpp_distcheck/continuous.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/cpp_distcheck/build.sh" -timeout_mins: 1440
diff --git a/kokoro/linux/cpp_distcheck/presubmit.cfg b/kokoro/linux/cpp_distcheck/presubmit.cfg deleted file mode 100644 index 4289f6a..0000000 --- a/kokoro/linux/cpp_distcheck/presubmit.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/cpp_distcheck/build.sh" -timeout_mins: 1440
diff --git a/kokoro/linux/dist_install/build.sh b/kokoro/linux/dist_install/build.sh deleted file mode 100755 index c456ee8..0000000 --- a/kokoro/linux/dist_install/build.sh +++ /dev/null
@@ -1,15 +0,0 @@ -#!/bin/bash -# -# Build file to set up and run tests - -set -ex # exit immediately on error - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/java_stretch -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="dist_install" -./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/dist_install/presubmit.cfg b/kokoro/linux/dist_install/presubmit.cfg deleted file mode 100644 index b1e0b20..0000000 --- a/kokoro/linux/dist_install/presubmit.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/dist_install/build.sh" -timeout_mins: 1440
diff --git a/kokoro/macos/cpp_distcheck/build.sh b/kokoro/macos/cpp_distcheck/build.sh deleted file mode 100755 index d729b63..0000000 --- a/kokoro/macos/cpp_distcheck/build.sh +++ /dev/null
@@ -1,11 +0,0 @@ -#!/bin/bash -# -# Build file to set up and run tests - -# Change to repo root -cd $(dirname $0)/../../.. - -# Prepare worker environment to run tests -source kokoro/macos/prepare_build_macos_rc - -./tests.sh cpp_distcheck
diff --git a/kokoro/macos/cpp_distcheck/continuous.cfg b/kokoro/macos/cpp_distcheck/continuous.cfg deleted file mode 100644 index 89441bc..0000000 --- a/kokoro/macos/cpp_distcheck/continuous.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/cpp_distcheck/build.sh" -timeout_mins: 1440
diff --git a/kokoro/macos/cpp_distcheck/presubmit.cfg b/kokoro/macos/cpp_distcheck/presubmit.cfg deleted file mode 100644 index 89441bc..0000000 --- a/kokoro/macos/cpp_distcheck/presubmit.cfg +++ /dev/null
@@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/cpp_distcheck/build.sh" -timeout_mins: 1440
diff --git a/kokoro/windows/bazel/build.bat b/kokoro/windows/bazel/build.bat new file mode 100644 index 0000000..52b83f4 --- /dev/null +++ b/kokoro/windows/bazel/build.bat
@@ -0,0 +1,4 @@ +@rem enter repo root +cd /d %~dp0\..\..\.. + +@rem TODO(mkruskal) Implement tests
diff --git a/kokoro/linux/dist_install/continuous.cfg b/kokoro/windows/bazel/continuous.cfg similarity index 64% rename from kokoro/linux/dist_install/continuous.cfg rename to kokoro/windows/bazel/continuous.cfg index b1e0b20..37e89e0 100644 --- a/kokoro/linux/dist_install/continuous.cfg +++ b/kokoro/windows/bazel/continuous.cfg
@@ -1,5 +1,5 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/dist_install/build.sh" +build_file: "protobuf/kokoro/windows/cmake/build.bat" timeout_mins: 1440
diff --git a/kokoro/linux/dist_install/continuous.cfg b/kokoro/windows/bazel/presubmit.cfg similarity index 64% copy from kokoro/linux/dist_install/continuous.cfg copy to kokoro/windows/bazel/presubmit.cfg index b1e0b20..37e89e0 100644 --- a/kokoro/linux/dist_install/continuous.cfg +++ b/kokoro/windows/bazel/presubmit.cfg
@@ -1,5 +1,5 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/dist_install/build.sh" +build_file: "protobuf/kokoro/windows/cmake/build.bat" timeout_mins: 1440
diff --git a/kokoro/windows/cmake_shared/build.bat b/kokoro/windows/cmake_shared/build.bat new file mode 100644 index 0000000..52b83f4 --- /dev/null +++ b/kokoro/windows/cmake_shared/build.bat
@@ -0,0 +1,4 @@ +@rem enter repo root +cd /d %~dp0\..\..\.. + +@rem TODO(mkruskal) Implement tests
diff --git a/kokoro/linux/dist_install/continuous.cfg b/kokoro/windows/cmake_shared/continuous.cfg similarity index 64% copy from kokoro/linux/dist_install/continuous.cfg copy to kokoro/windows/cmake_shared/continuous.cfg index b1e0b20..37e89e0 100644 --- a/kokoro/linux/dist_install/continuous.cfg +++ b/kokoro/windows/cmake_shared/continuous.cfg
@@ -1,5 +1,5 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/dist_install/build.sh" +build_file: "protobuf/kokoro/windows/cmake/build.bat" timeout_mins: 1440
diff --git a/kokoro/linux/dist_install/continuous.cfg b/kokoro/windows/cmake_shared/presubmit.cfg similarity index 64% copy from kokoro/linux/dist_install/continuous.cfg copy to kokoro/windows/cmake_shared/presubmit.cfg index b1e0b20..37e89e0 100644 --- a/kokoro/linux/dist_install/continuous.cfg +++ b/kokoro/windows/cmake_shared/presubmit.cfg
@@ -1,5 +1,5 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/dist_install/build.sh" +build_file: "protobuf/kokoro/windows/cmake/build.bat" timeout_mins: 1440
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index 2c3e06c..b01d870 100644 --- a/python/google/protobuf/__init__.py +++ b/python/google/protobuf/__init__.py
@@ -30,4 +30,4 @@ # Copyright 2007 Google Inc. All Rights Reserved. -__version__ = '4.21.2' +__version__ = '4.21.4'
diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py index 76c6802..0fe6a4f 100644 --- a/python/google/protobuf/message.py +++ b/python/google/protobuf/message.py
@@ -74,7 +74,8 @@ __slots__ = [] - #: The :class:`google.protobuf.descriptor.Descriptor` for this message type. + #: The :class:`google.protobuf.Descriptor` + # for this message type. DESCRIPTOR = None def __deepcopy__(self, memo=None):
diff --git a/src/Makefile.am b/src/Makefile.am index 4f4fc80..15f7aa4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am
@@ -18,7 +18,7 @@ PTHREAD_DEF = endif -PROTOBUF_VERSION = 32:2:0 +PROTOBUF_VERSION = 32:4:0 if GCC # Turn on all warnings except for sign comparison (we ignore sign comparison
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 2368446..0a9ee26 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index ac80560..4903294 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/arenaz_sampler.cc b/src/google/protobuf/arenaz_sampler.cc index ab524fb..53b524e 100644 --- a/src/google/protobuf/arenaz_sampler.cc +++ b/src/google/protobuf/arenaz_sampler.cc
@@ -56,13 +56,20 @@ PROTOBUF_CONSTINIT std::atomic<bool> g_arenaz_enabled{true}; PROTOBUF_CONSTINIT std::atomic<int32_t> g_arenaz_sample_parameter{1 << 10}; +PROTOBUF_CONSTINIT std::atomic<ThreadSafeArenazConfigListener> + g_arenaz_config_listener{nullptr}; PROTOBUF_THREAD_LOCAL absl::profiling_internal::ExponentialBiased g_exponential_biased_generator; +void TriggerThreadSafeArenazConfigListener() { + auto* listener = g_arenaz_config_listener.load(std::memory_order_acquire); + if (listener != nullptr) listener(); +} + } // namespace PROTOBUF_THREAD_LOCAL SamplingState global_sampling_state = { - .next_sample = int64_t{1} << 10, .sample_stride = int64_t{1} << 10}; + /*next_sample=*/0, /*sample_stride=*/0}; ThreadSafeArenaStats::ThreadSafeArenaStats() { PrepareForSampling(0); } ThreadSafeArenaStats::~ThreadSafeArenaStats() = default; @@ -118,11 +125,29 @@ return GlobalThreadSafeArenazSampler().Register(old_stride); } +void SetThreadSafeArenazConfigListener(ThreadSafeArenazConfigListener l) { + g_arenaz_config_listener.store(l, std::memory_order_release); +} + +bool IsThreadSafeArenazEnabled() { + return g_arenaz_enabled.load(std::memory_order_acquire); +} + void SetThreadSafeArenazEnabled(bool enabled) { + SetThreadSafeArenazEnabledInternal(enabled); + TriggerThreadSafeArenazConfigListener(); +} + +void SetThreadSafeArenazEnabledInternal(bool enabled) { g_arenaz_enabled.store(enabled, std::memory_order_release); } void SetThreadSafeArenazSampleParameter(int32_t rate) { + SetThreadSafeArenazSampleParameterInternal(rate); + TriggerThreadSafeArenazConfigListener(); +} + +void SetThreadSafeArenazSampleParameterInternal(int32_t rate) { if (rate > 0) { g_arenaz_sample_parameter.store(rate, std::memory_order_release); } else { @@ -136,6 +161,11 @@ } void SetThreadSafeArenazMaxSamples(int32_t max) { + SetThreadSafeArenazMaxSamplesInternal(max); + TriggerThreadSafeArenazConfigListener(); +} + +void SetThreadSafeArenazMaxSamplesInternal(int32_t max) { if (max > 0) { GlobalThreadSafeArenazSampler().SetMaxSamples(max); } else { @@ -144,6 +174,10 @@ } } +size_t ThreadSafeArenazMaxSamples() { + return GlobalThreadSafeArenazSampler().GetMaxSamples(); +} + void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) { if (next_sample >= 0) { global_sampling_state.next_sample = next_sample; @@ -160,10 +194,16 @@ return nullptr; } +void SetThreadSafeArenazConfigListener(ThreadSafeArenazConfigListener) {} void SetThreadSafeArenazEnabled(bool enabled) {} +void SetThreadSafeArenazEnabledInternal(bool enabled) {} +bool IsThreadSafeArenazEnabled() { return false; } void SetThreadSafeArenazSampleParameter(int32_t rate) {} +void SetThreadSafeArenazSampleParameterInternal(int32_t rate) {} int32_t ThreadSafeArenazSampleParameter() { return 0; } void SetThreadSafeArenazMaxSamples(int32_t max) {} +void SetThreadSafeArenazMaxSamplesInternal(int32_t max) {} +size_t ThreadSafeArenazMaxSamples() { return 0; } void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) {} #endif // defined(PROTOBUF_ARENAZ_SAMPLE)
diff --git a/src/google/protobuf/arenaz_sampler.h b/src/google/protobuf/arenaz_sampler.h index e9a4dec..43d1acb 100644 --- a/src/google/protobuf/arenaz_sampler.h +++ b/src/google/protobuf/arenaz_sampler.h
@@ -199,17 +199,29 @@ // Returns a global Sampler. ThreadSafeArenazSampler& GlobalThreadSafeArenazSampler(); +using ThreadSafeArenazConfigListener = void (*)(); +void SetThreadSafeArenazConfigListener(ThreadSafeArenazConfigListener l); + // Enables or disables sampling for thread safe arenas. void SetThreadSafeArenazEnabled(bool enabled); +void SetThreadSafeArenazEnabledInternal(bool enabled); + +// Returns true if sampling is on, false otherwise. +bool IsThreadSafeArenazEnabled(); // Sets the rate at which thread safe arena will be sampled. void SetThreadSafeArenazSampleParameter(int32_t rate); +void SetThreadSafeArenazSampleParameterInternal(int32_t rate); // Returns the rate at which thread safe arena will be sampled. int32_t ThreadSafeArenazSampleParameter(); // Sets a soft max for the number of samples that will be kept. void SetThreadSafeArenazMaxSamples(int32_t max); +void SetThreadSafeArenazMaxSamplesInternal(int32_t max); + +// Returns the max number of samples that will be kept. +size_t ThreadSafeArenazMaxSamples(); // Sets the current value for when arenas should be next sampled. void SetThreadSafeArenazGlobalNextSample(int64_t next_sample);
diff --git a/src/google/protobuf/arenaz_sampler_test.cc b/src/google/protobuf/arenaz_sampler_test.cc index 1b73938..774e70d 100644 --- a/src/google/protobuf/arenaz_sampler_test.cc +++ b/src/google/protobuf/arenaz_sampler_test.cc
@@ -375,6 +375,7 @@ SetThreadSafeArenazEnabled(true); // Setting 1 as the parameter value means one in every two arenas would be // sampled, on average. + int32_t oldparam = ThreadSafeArenazSampleParameter(); SetThreadSafeArenazSampleParameter(1); SetThreadSafeArenazGlobalNextSample(0); auto& sampler = GlobalThreadSafeArenazSampler(); @@ -402,6 +403,95 @@ } } EXPECT_GT(count, 0); + SetThreadSafeArenazSampleParameter(oldparam); +} + +class SampleFirstArenaThread : public Thread { + protected: + void Run() override { + google::protobuf::Arena arena; + google::protobuf::ArenaSafeUniquePtr< + protobuf_test_messages::proto2::TestAllTypesProto2> + message = google::protobuf::MakeArenaSafeUnique< + protobuf_test_messages::proto2::TestAllTypesProto2>(&arena); + GOOGLE_CHECK(message != nullptr); + arena_created_.Notify(); + samples_counted_.WaitForNotification(); + } + + public: + explicit SampleFirstArenaThread(const thread::Options& options) + : Thread(options, "SampleFirstArenaThread") {} + + absl::Notification arena_created_; + absl::Notification samples_counted_; +}; + +// Test that the first arena created on a thread may and may not be chosen for +// sampling. +TEST(ThreadSafeArenazSamplerTest, SampleFirstArena) { + SetThreadSafeArenazEnabled(true); + auto& sampler = GlobalThreadSafeArenazSampler(); + + enum class SampleResult { + kSampled, + kUnsampled, + kSpoiled, + }; + + auto count_samples = [&]() { + int count = 0; + sampler.Iterate([&](const ThreadSafeArenaStats& h) { ++count; }); + return count; + }; + + auto run_sample_experiment = [&]() { + int before = count_samples(); + thread::Options options; + options.set_joinable(true); + SampleFirstArenaThread t(options); + t.Start(); + t.arena_created_.WaitForNotification(); + int during = count_samples(); + t.samples_counted_.Notify(); + t.Join(); + int after = count_samples(); + + // If we didn't get back where we were, some other thread may have + // created an arena and produced an invalid experiment run. + if (before != after) return SampleResult::kSpoiled; + + switch (during - before) { + case 1: + return SampleResult::kSampled; + case 0: + return SampleResult::kUnsampled; + default: + return SampleResult::kSpoiled; + } + }; + + constexpr int kTrials = 10000; + bool sampled = false; + bool unsampled = false; + for (int i = 0; i < kTrials; ++i) { + switch (run_sample_experiment()) { + case SampleResult::kSampled: + sampled = true; + break; + case SampleResult::kUnsampled: + unsampled = true; + break; + default: + break; + } + + // This is the success criteria for the entire test. At some point + // we sampled the first arena and at some point we did not. + if (sampled && unsampled) return; + } + EXPECT_TRUE(sampled); + EXPECT_TRUE(unsampled); } #endif // defined(PROTOBUF_ARENAZ_SAMPLE)
diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 51a3e65..50b86f7 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc
@@ -2205,11 +2205,12 @@ " if (IsSplitMessageDefault()) {\n" " void* chunk = " "::PROTOBUF_NAMESPACE_ID::internal::CreateSplitMessageGeneric(" - "GetArenaForAllocation(), &$1$, sizeof(Impl_::Split));\n" + "GetArenaForAllocation(), &$1$, sizeof(Impl_::Split), this, &$2$);\n" " $split$ = reinterpret_cast<Impl_::Split*>(chunk);\n" " }\n" "}\n", - DefaultInstanceName(descriptor_, options_, /*split=*/true)); + DefaultInstanceName(descriptor_, options_, /*split=*/true), + DefaultInstanceName(descriptor_, options_, /*split=*/false)); } GenerateVerify(printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc index e21eff1..56b920d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
@@ -74,6 +74,22 @@ EXPECT_FALSE(IsDescriptorOptionMessage(DescriptorProto::descriptor())); } +TEST(CSharpIdentifiers, UnderscoresToCamelCase) { + EXPECT_EQ("FooBar", UnderscoresToCamelCase("Foo_Bar", true)); + EXPECT_EQ("fooBar", UnderscoresToCamelCase("FooBar", false)); + EXPECT_EQ("foo123", UnderscoresToCamelCase("foo_123", false)); + // remove leading underscores + EXPECT_EQ("Foo123", UnderscoresToCamelCase("_Foo_123", true)); + // this one has slight unexpected output as it capitalises the first + // letter after consuming the underscores, but this was the existing + // behaviour so I have not changed it + EXPECT_EQ("FooBar", UnderscoresToCamelCase("___fooBar", false)); + // leave a leading underscore for identifiers that would otherwise + // be invalid because they would start with a digit + EXPECT_EQ("_123Foo", UnderscoresToCamelCase("_123_foo", true)); + EXPECT_EQ("_123Foo", UnderscoresToCamelCase("___123_foo", true)); +} + } // namespace } // namespace csharp } // namespace compiler
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index aa84dc7..1b58b95 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
@@ -144,6 +144,7 @@ bool cap_next_letter, bool preserve_period) { std::string result; + // Note: I distrust ctype.h due to locales. for (int i = 0; i < input.size(); i++) { if ('a' <= input[i] && input[i] <= 'z') { @@ -177,6 +178,23 @@ if (input.size() > 0 && input[input.size() - 1] == '#') { result += '_'; } + + // https://github.com/protocolbuffers/protobuf/issues/8101 + // To avoid generating invalid identifiers - if the input string + // starts with _<digit> (or multiple underscores then digit) then + // we need to preserve the underscore as an identifier cannot start + // with a digit. + // This check is being done after the loop rather than before + // to handle the case where there are multiple underscores before the + // first digit. We let them all be consumed so we can see if we would + // start with a digit. + // Note: not preserving leading underscores for all otherwise valid identifiers + // so as to not break anything that relies on the existing behaviour + if (result.size() > 0 && ('0' <= result[0] && result[0] <= '9') + && input.size() > 0 && input[0] == '_') + { + result.insert(0, 1, '_'); + } return result; }
diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index a13b995..9efd3d5 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc
@@ -90,7 +90,7 @@ void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) { printer->Print( variables_, - "$name$_.Add(other.$name$_);\n"); + "$name$_.MergeFrom(other.$name$_);\n"); } void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index b73c9de..51152e6 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index f6f5da5..439db9f 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 87729c4..1e4a3e1 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index fdc398c..c5f528b 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index fd75b88..01ecfac 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 0353b74..70014b2 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc
@@ -2514,6 +2514,7 @@ } void Reflection::PrepareSplitMessageForWrite(Message* message) const { + GOOGLE_DCHECK_NE(message, schema_.default_instance_); void** split = MutableSplitField(message); const void* default_split = GetSplitField(schema_.default_instance_); if (*split == default_split) {
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index f9e0776..9614d01 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc
@@ -406,7 +406,7 @@ case '\n': { if (!allow_multiline_strings_) { - AddError("String literals cannot cross line boundaries."); + AddError("Multiline strings are not allowed. Did you miss a \"?."); return; } NextChar();
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc index 16ba940..6233d6a 100644 --- a/src/google/protobuf/io/tokenizer_unittest.cc +++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -1067,7 +1067,8 @@ {"'\\X' foo", true, "0:2: Invalid escape sequence in string literal.\n"}, {"'\\x' foo", true, "0:3: Expected hex digits for escape sequence.\n"}, {"'foo", false, "0:4: Unexpected end of string.\n"}, - {"'bar\nfoo", true, "0:4: String literals cannot cross line boundaries.\n"}, + {"'bar\nfoo", true, + "0:4: Multiline strings are not allowed. Did you miss a \"?.\n"}, {"'\\u01' foo", true, "0:5: Expected four hex digits for \\u escape sequence.\n"}, {"'\\u01' foo", true,
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 1279164..5052b1c 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc
@@ -215,7 +215,9 @@ namespace internal { void* CreateSplitMessageGeneric(Arena* arena, const void* default_split, - size_t size) { + size_t size, const void* message, + const void* default_message) { + GOOGLE_DCHECK_NE(message, default_message); void* split = (arena == nullptr) ? ::operator new(size) : arena->AllocateAligned(size); memcpy(split, default_split, size);
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index b61fafb..5a9111f 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h
@@ -412,7 +412,8 @@ namespace internal { // Creates and returns an allocation for a split message. void* CreateSplitMessageGeneric(Arena* arena, const void* default_split, - size_t size); + size_t size, const void* message, + const void* default_message); // Forward-declare interfaces used to implement RepeatedFieldRef. // These are protobuf internals that users shouldn't care about.
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 27a8b38..2674b26 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc
@@ -521,18 +521,14 @@ *to = from; } -// Non-inline implementations of InternalMetadata routines -#if defined(NDEBUG) || defined(_MSC_VER) -// for opt and MSVC builds, the destructor is defined in the header. -#else +// Non-inline implementations of InternalMetadata destructor // This is moved out of the header because the GOOGLE_DCHECK produces a lot of code. -InternalMetadata::~InternalMetadata() { +void InternalMetadata::CheckedDestruct() { if (HasMessageOwnedArenaTag()) { GOOGLE_DCHECK(!HasUnknownFieldsTag()); delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask); } } -#endif // Non-inline variants of std::string specializations for // various InternalMetadata routines.
diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h index af840e5..d015dc2 100644 --- a/src/google/protobuf/metadata_lite.h +++ b/src/google/protobuf/metadata_lite.h
@@ -77,15 +77,19 @@ GOOGLE_DCHECK(!is_message_owned || arena != nullptr); } -#if defined(NDEBUG) || defined(_MSC_VER) + // To keep the ABI identical between debug and non-debug builds, + // the destructor is always defined here even though it may delegate + // to a non-inline private method. + // (see https://github.com/protocolbuffers/protobuf/issues/9947) ~InternalMetadata() { +#if defined(NDEBUG) || defined(_MSC_VER) if (HasMessageOwnedArenaTag()) { delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask); } - } #else - ~InternalMetadata(); + CheckedDestruct(); #endif + } template <typename T> void Delete() { @@ -264,6 +268,9 @@ PROTOBUF_NOINLINE void DoSwap(T* other) { mutable_unknown_fields<T>()->Swap(other); } + + // Private helper with debug checks for ~InternalMetadata() + void CheckedDestruct(); }; // String Template specializations.
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 94d299d..7d067fd 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc
@@ -212,7 +212,7 @@ #ifdef PROTOBUF_VERSION #error PROTOBUF_VERSION was previously defined #endif -#define PROTOBUF_VERSION 3021002 +#define PROTOBUF_VERSION 3021004 #ifdef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC #error PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC was previously defined @@ -690,15 +690,16 @@ # define PROTOBUF_CONSTEXPR constexpr # endif #else -# if defined(__cpp_constinit) +# if defined(__cpp_constinit) && !defined(__CYGWIN__) # define PROTOBUF_CONSTINIT constinit # define PROTOBUF_CONSTEXPR constexpr // Some older Clang versions incorrectly raise an error about // constant-initializing weak default instance pointers. Versions 12.0 and // higher seem to work, except that XCode 12.5.1 shows the error even though it // uses Clang 12.0.5. -# elif __has_cpp_attribute(clang::require_constant_initialization) && \ - ((defined(__APPLE__) && PROTOBUF_CLANG_MIN(13, 0)) || \ +# elif !defined(__CYGWIN__) && \ + __has_cpp_attribute(clang::require_constant_initialization) && \ + ((defined(__APPLE__) && PROTOBUF_CLANG_MIN(13, 0)) || \ (!defined(__APPLE__) && PROTOBUF_CLANG_MIN(12, 0))) # define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] # define PROTOBUF_CONSTEXPR constexpr
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index fb2e29f..899cfb0 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 7a0805d..154ea45 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 9d90305..c4d2636 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h
@@ -82,7 +82,7 @@ // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 3021002 +#define GOOGLE_PROTOBUF_VERSION 3021004 // A suffix string for alpha, beta or rc releases. Empty for stable releases. #define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 3b5a469..771216e 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index bcf1a44..2555602 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index 7176f09..de78f9a 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto
@@ -346,6 +346,16 @@ optional bytes oneof_bytes_extension = 114; } +message TestMixedFieldsAndExtensions { + optional int32 a = 1; + repeated fixed32 b = 3; + extensions 2, 4; + extend TestMixedFieldsAndExtensions { + optional int32 c = 2; + repeated fixed32 d = 4; + } +} + message TestGroup { optional group OptionalGroup = 16 { optional int32 a = 17;
diff --git a/src/google/protobuf/util/json_format_proto3.proto b/src/google/protobuf/util/json_format_proto3.proto index f9c5199..4df5eb9 100644 --- a/src/google/protobuf/util/json_format_proto3.proto +++ b/src/google/protobuf/util/json_format_proto3.proto
@@ -189,6 +189,14 @@ int32 value = 1 [json_name = "@value"]; } +message TestEvilJson { + int32 regular_value = 1 [json_name = "regular_name"]; + int32 script = 2 [json_name = "</script>"]; + int32 quotes = 3 [json_name = "unbalanced\"quotes"]; + int32 script_and_quotes = 4 + [json_name = "\"<script>alert('hello!);</script>"]; +} + message TestExtensions { .protobuf_unittest.TestAllExtensions extensions = 1; }
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc index ca9fe73..99272d7 100644 --- a/src/google/protobuf/util/json_util_test.cc +++ b/src/google/protobuf/util/json_util_test.cc
@@ -64,6 +64,11 @@ // Must be included last. #include <google/protobuf/port_def.inc> +bool IsJson2() { + // Pay no attention to the person behind the curtain. + return false; +} + namespace google { namespace protobuf { namespace util { @@ -76,6 +81,7 @@ using ::proto3::TestWrapper; using ::proto_util_converter::testing::MapIn; using ::testing::ElementsAre; +using ::testing::Not; using ::testing::SizeIs; // TODO(b/234474291): Use the gtest versions once that's available in OSS. @@ -274,20 +280,37 @@ // The ESF parser actually gets this wrong, and serializes floats whose // default value is non-finite as 0. We make sure to reproduce this bug. - EXPECT_THAT( - ToJson(protobuf_unittest::TestExtremeDefaultValues(), options), - IsOkAndHolds( - R"({"escapedBytes":"XDAwMFwwMDFcMDA3XDAxMFwwMTRcblxyXHRcMDEzXFxcJ1wiXDM3Ng==")" - R"(,"largeUint32":4294967295,"largeUint64":"18446744073709551615",)" - R"("smallInt32":-2147483647,"smallInt64":"-9223372036854775807")" - R"(,"reallySmallInt32":-2147483648,"reallySmallInt64":"-9223372036854775808",)" - R"("utf8String":"ሴ","zeroFloat":0,"oneFloat":1,"smallFloat":1.5,)" - R"("negativeOneFloat":-1,"negativeFloat":-1.5,"largeFloat":2e+08,)" - R"("smallNegativeFloat":-8e-28,"infDouble":0,"negInfDouble":0)" - R"(,"nanDouble":0,"infFloat":0,"negInfFloat":0,"nanFloat":0)" - R"(,"cppTrigraph":"? ? ?? ?? ??? ??/ ??-","stringWithZero":"hel\u0000lo")" - R"(,"bytesWithZero":"d29yXDAwMGxk","stringPieceWithZero":"ab\u0000c")" - R"(,"cordWithZero":"12\u00003","replacementString":"${unknown}"})")); + if (IsJson2()) { + EXPECT_THAT( + ToJson(protobuf_unittest::TestExtremeDefaultValues(), options), + IsOkAndHolds( + R"({"escapedBytes":"XDAwMFwwMDFcMDA3XDAxMFwwMTRcblxyXHRcMDEzXFxcJ1wiXDM3Ng==")" + R"(,"largeUint32":4294967295,"largeUint64":"18446744073709551615",)" + R"("smallInt32":-2147483647,"smallInt64":"-9223372036854775807",)" + R"("utf8String":"ሴ","zeroFloat":0,"oneFloat":1,"smallFloat":1.5,)" + R"("negativeOneFloat":-1,"negativeFloat":-1.5,"largeFloat":2e+08,)" + R"("smallNegativeFloat":-8e-28,"infDouble":0,"negInfDouble":0,)" + R"("nanDouble":0,"infFloat":0,"negInfFloat":0,"nanFloat":0,)" + R"("cppTrigraph":"? ? ?? ?? ??? ??/ ??-","reallySmallInt32":-2147483648)" + R"(,"reallySmallInt64":"-9223372036854775808","stringWithZero":"hel\u0000lo")" + R"(,"bytesWithZero":"d29yXDAwMGxk","stringPieceWithZero":"ab\u0000c")" + R"(,"cordWithZero":"12\u00003","replacementString":"${unknown}"})")); + } else { + EXPECT_THAT( + ToJson(protobuf_unittest::TestExtremeDefaultValues(), options), + IsOkAndHolds( + R"({"escapedBytes":"XDAwMFwwMDFcMDA3XDAxMFwwMTRcblxyXHRcMDEzXFxcJ1wiXDM3Ng==")" + R"(,"largeUint32":4294967295,"largeUint64":"18446744073709551615",)" + R"("smallInt32":-2147483647,"smallInt64":"-9223372036854775807")" + R"(,"reallySmallInt32":-2147483648,"reallySmallInt64":"-9223372036854775808",)" + R"("utf8String":"ሴ","zeroFloat":0,"oneFloat":1,"smallFloat":1.5,)" + R"("negativeOneFloat":-1,"negativeFloat":-1.5,"largeFloat":2e+08,)" + R"("smallNegativeFloat":-8e-28,"infDouble":0,"negInfDouble":0)" + R"(,"nanDouble":0,"infFloat":0,"negInfFloat":0,"nanFloat":0)" + R"(,"cppTrigraph":"? ? ?? ?? ??? ??/ ??-","stringWithZero":"hel\u0000lo")" + R"(,"bytesWithZero":"d29yXDAwMGxk","stringPieceWithZero":"ab\u0000c")" + R"(,"cordWithZero":"12\u00003","replacementString":"${unknown}"})")); + } } TEST_P(JsonTest, TestPreserveProtoFieldNames) { @@ -762,6 +785,20 @@ } )json"), StatusIs(util::StatusCode::kInvalidArgument)); + + TestAny m2; + m2.mutable_value(); + EXPECT_THAT(ToJson(m2), IsOkAndHolds(R"({"value":{}})")); + m2.mutable_value()->set_value("garbage"); + // The ESF parser does not return InvalidArgument for this error. + EXPECT_THAT(ToJson(m2), Not(StatusIs(util::StatusCode::kOk))); + + m2.Clear(); + m2.mutable_value()->set_type_url("type.googleapis.com/proto3.TestMessage"); + EXPECT_THAT( + ToJson(m2), + IsOkAndHolds( + R"({"value":{"@type":"type.googleapis.com/proto3.TestMessage"}})")); } TEST_P(JsonTest, TestFlatList) { @@ -773,7 +810,7 @@ ASSERT_OK(m); EXPECT_THAT(m->repeated_int32_value(), ElementsAre(5, 6)); - // The above flatteing behavior is supressed for google::protobuf::ListValue. + // The above flatteing behavior is suppressed for google::protobuf::ListValue. auto m2 = ToProto<google::protobuf::Value>(R"json( { "repeatedInt32Value": [[[5]], [6]] @@ -952,6 +989,37 @@ EXPECT_EQ(m.enum_value(), proto3::BAR); } +// This functionality is not correctly implemented by the ESF parser, so +// the test is only turned on when testing json2. +TEST_P(JsonTest, Extensions) { + if (GetParam() == Codec::kResolver || !IsJson2()) { + GTEST_SKIP(); + } + + auto m = ToProto<protobuf_unittest::TestMixedFieldsAndExtensions>(R"json({ + "[protobuf_unittest.TestMixedFieldsAndExtensions.c]": 42, + "a": 5, + "b": [1, 2, 3], + "[protobuf_unittest.TestMixedFieldsAndExtensions.d]": [1, 1, 2, 3, 5, 8, 13] + })json"); + ASSERT_OK(m); + EXPECT_EQ(m->a(), 5); + EXPECT_THAT(m->b(), ElementsAre(1, 2, 3)); + EXPECT_EQ(m->GetExtension(protobuf_unittest::TestMixedFieldsAndExtensions::c), + 42); + EXPECT_THAT( + m->GetRepeatedExtension(protobuf_unittest::TestMixedFieldsAndExtensions::d), + ElementsAre(1, 1, 2, 3, 5, 8, 13)); + + EXPECT_THAT( + ToJson(*m), + IsOkAndHolds( + R"({"a":5,)" + R"("[protobuf_unittest.TestMixedFieldsAndExtensions.c]":42,)" + R"("b":[1,2,3],)" + R"("[protobuf_unittest.TestMixedFieldsAndExtensions.d]":[1,1,2,3,5,8,13]})")); +} + // Parsing does NOT work like MergeFrom: existing repeated field values are // clobbered, not appended to. TEST_P(JsonTest, TestOverwriteRepeated) { @@ -1158,6 +1226,34 @@ m.set_string_value("</script>"); EXPECT_THAT(ToJson(m), IsOkAndHolds(R"({"stringValue":"\u003c/script\u003e"})")); + + proto3::TestEvilJson m2; + JsonPrintOptions opts; + opts.always_print_primitive_fields = true; + EXPECT_THAT( + ToJson(m2, opts), + IsOkAndHolds( + R"({"regular_name":0,"\u003c/script\u003e":0,)" + R"("unbalanced\"quotes":0,)" + R"("\"\u003cscript\u003ealert('hello!);\u003c/script\u003e":0})")); +} + +TEST_P(JsonTest, FieldOrder) { + // $ protoscope -s <<< "3: 3 22: 2 1: 1 22: 2" + std::string out; + util::Status s = BinaryToJsonString( + resolver_.get(), "type.googleapis.com/proto3.TestMessage", + "\x18\x03\xb0\x01\x02\x08\x01\xb0\x01\x02", &out); + ASSERT_OK(s); + if (IsJson2()) { + EXPECT_EQ( + out, + R"({"boolValue":true,"int64Value":"3","repeatedInt32Value":[2,2]})"); + } else { + EXPECT_EQ( + out, + R"({"int64Value":"3","repeatedInt32Value":[2],"boolValue":true,"repeatedInt32Value":[2]})"); + } } } // namespace
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 72304a5..f629e5e 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h
@@ -13,7 +13,7 @@ #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3021002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021004 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc.
diff --git a/tests.sh b/tests.sh index ecd7e12..6508674 100755 --- a/tests.sh +++ b/tests.sh
@@ -45,44 +45,6 @@ PPROF_PATH=/usr/bin/google-pprof HEAPCHECK=strict ./protobuf-test } -build_cpp_distcheck() { - grep -q -- "-Og" src/Makefile.am && - echo "The -Og flag is incompatible with Clang versions older than 4.0." && - exit 1 - - # Initialize any submodules. - git submodule update --init --recursive - ./autogen.sh - ./configure - make dist - - # List all files that should be included in the distribution package. - git ls-files | grep "^\(java\|python\|objectivec\|csharp\|ruby\|php\|cmake\|examples\|src/google/protobuf/.*\.proto\)" |\ - grep -v ".gitignore" | grep -v "java/lite/proguard.pgcfg" |\ - grep -v "python/compatibility_tests" | grep -v "python/docs" | grep -v "python/.repo-metadata.json" |\ - grep -v "python/protobuf_distutils" | grep -v "csharp/compatibility_tests" > dist.lst - # Unzip the dist tar file. - DIST=`ls *.tar.gz` - tar -xf $DIST - cd ${DIST//.tar.gz} - # Check if every file exists in the dist tar file. - FILES_MISSING="" - for FILE in $(<../dist.lst); do - [ -f "$FILE" ] || { - echo "$FILE is not found!" - FILES_MISSING="$FILE $FILES_MISSING" - } - done - cd .. - if [ ! -z "$FILES_MISSING" ]; then - echo "Missing files in EXTRA_DIST: $FILES_MISSING" - exit 1 - fi - - # Do the regular dist-check for C++. - make distcheck -j$(nproc) -} - build_dist_install() { # Create a symlink pointing to python2 and put it at the beginning of $PATH. # This is necessary because the googletest build system involves a Python @@ -539,7 +501,6 @@ if [ "$#" -ne 1 ]; then echo " Usage: $0 { cpp | - cpp_distcheck | csharp | java_jdk7 | java_oracle7 |
diff --git a/third_party/benchmark b/third_party/benchmark index 0baacde..5b7683f 160000 --- a/third_party/benchmark +++ b/third_party/benchmark
@@ -1 +1 @@ -Subproject commit 0baacde3618ca617da95375e0af13ce1baadea47 +Subproject commit 5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8