From 0eb317c36d673bf417e95e567179b09a3d02519c Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Mon, 28 Sep 2020 11:55:27 -0700 Subject: [PATCH 01/15] Updated Changelog. --- CHANGES.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 511d84e88258..e02fa98c97a4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,10 +3,12 @@ Unreleased Changes Protocol Compiler * The proto compiler no longer requires a .proto filename when it is not generating code. + * Added flag `--deterministic_output` to `protoc --encode=...`. C++ * Arenas are now unconditionally enabled. cc_enable_arenas no longer has any effect. + * Removed inlined string support, which is incompatible with arenas. * Fix a memory corruption bug in reflection when mixing optional and non-optional fields. * Make SpaceUsed() calculation more thorough for map fields. @@ -20,9 +22,16 @@ Unreleased Changes * When running under ASAN, skip a test that makes huge allocations. * Fixed a crash that could happen when creating more than 256 extensions in a single message. + * Fix a crash in BuildFile when passing in invalid descriptor proto. + * Parser security fix when operating with CodedInputStream. + * Warn against the use of AllowUnknownExtension. Java * Bugfix in mergeFrom() when a oneof has multiple message fields. + * Fix RopeByteString.RopeInputStream.read() returning -1 when told to read + 0 bytes when not at EOF. + * Redefine remove(Object) on primitive repeated field Lists to avoid + autoboxing. Python * Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is From 2181e8cb3fdb9a903edf7157202e2b8f7278530f Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Mon, 28 Sep 2020 12:04:15 -0700 Subject: [PATCH 02/15] Fixed undeclared variable errors. --- src/google/protobuf/generated_message_reflection.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index dc990b561aeb..12abb4f97f70 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -200,17 +200,17 @@ struct ReflectionSchema { // Returns true if the field's accessor is called by any external code (aka, // non proto library code). - bool IsFieldUsed(const FieldDescriptor* /* field */) const { + bool IsFieldUsed(const FieldDescriptor* field) const { (void)field; return true; } - bool IsFieldStripped(const FieldDescriptor* /* field */) const { + bool IsFieldStripped(const FieldDescriptor* field) const { (void)field; return false; } - bool IsMessageStripped(const Descriptor* /* descriptor */) const { + bool IsMessageStripped(const Descriptor* descriptor) const { (void)descriptor; return false; } From a633ad452d81e5f207692c23eefba3960238bfcc Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Mon, 28 Sep 2020 12:19:39 -0700 Subject: [PATCH 03/15] Ran update_file_lists.sh to pick up arenastring.cc. --- BUILD | 1 + cmake/extract_includes.bat.in | 1 - cmake/libprotobuf.cmake | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/BUILD b/BUILD index afad437c1002..b4c9f5e01ab7 100644 --- a/BUILD +++ b/BUILD @@ -164,6 +164,7 @@ cc_library( # AUTOGEN(protobuf_lite_srcs) "src/google/protobuf/any_lite.cc", "src/google/protobuf/arena.cc", + "src/google/protobuf/arenastring.cc", "src/google/protobuf/extension_set.cc", "src/google/protobuf/generated_enum_util.cc", "src/google/protobuf/generated_message_table_driven_lite.cc", diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index f8fc0e9813e3..5c5799efa1e8 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -87,7 +87,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" i copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index d7d077067aa3..0c12596c238b 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -2,7 +2,6 @@ set(libprotobuf_files ${protobuf_source_dir}/src/google/protobuf/any.cc ${protobuf_source_dir}/src/google/protobuf/any.pb.cc ${protobuf_source_dir}/src/google/protobuf/api.pb.cc - ${protobuf_source_dir}/src/google/protobuf/arenastring.cc ${protobuf_source_dir}/src/google/protobuf/compiler/importer.cc ${protobuf_source_dir}/src/google/protobuf/compiler/parser.cc ${protobuf_source_dir}/src/google/protobuf/descriptor.cc From d90f3b8b171ed7887a28e1ebb9fce04b9941797b Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Mon, 28 Sep 2020 14:40:09 -0700 Subject: [PATCH 04/15] Fixed build failure in conformance tests. --- conformance/text_format_conformance_suite.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index 78462c4763ca..4c9dc7dbe051 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -259,8 +259,7 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { "optional_float: 18446744073709551616"); // String literals x {Strings, Bytes} - for (const auto& field_type : - std::vector{"String", "Bytes"}) { + for (const auto& field_type : std::vector{"String", "Bytes"}) { const std::string field_name = field_type == "String" ? "optional_string" : "optional_bytes"; RunValidTextFormatTest( From de371235c9f50eadad7a3562572b79a9422cd754 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 21 Oct 2020 10:04:14 -0700 Subject: [PATCH 05/15] Sync from Piper @338284531 PROTOBUF_SYNC_PIPER --- .github/mergeable.yml | 4 +- .github/workflows/codespell.yml | 2 +- BUILD | 28 +- WORKSPACE | 4 +- conformance/text_format_failure_list_java.txt | 8 - .../com/google/protobuf/CodedInputStream.java | 17 +- .../java/com/google/protobuf/Descriptors.java | 5 +- .../protobuf/ExtensionRegistryFactory.java | 2 - .../protobuf/ExtensionRegistryLite.java | 2 - .../java/com/google/protobuf/FieldType.java | 2 - .../com/google/protobuf/NioByteString.java | 7 +- .../java/com/google/protobuf/TextFormat.java | 69 +++++ .../com/google/protobuf/TypeRegistry.java | 1 - .../java/com/google/protobuf/UnsafeUtil.java | 21 +- .../google/protobuf/MapForProto2LiteTest.java | 165 +++++------ .../com/google/protobuf/MapForProto2Test.java | 118 ++++---- .../java/com/google/protobuf/MapLiteTest.java | 179 ++++++------ .../java/com/google/protobuf/MapTest.java | 190 ++++++------ .../com/google/protobuf/TextFormatTest.java | 88 ++++++ .../google/protobuf/util/FieldMaskTree.java | 68 +++-- .../google/protobuf/util/FieldMaskUtil.java | 8 +- .../com/google/protobuf/util/JsonFormat.java | 1 - .../protobuf/util/FieldMaskTreeTest.java | 24 +- .../protobuf/util/FieldMaskUtilTest.java | 2 +- .../google/protobuf/util/JsonFormatTest.java | 4 +- .../linux/dockerfile/test/python27/Dockerfile | 10 +- .../linux/dockerfile/test/python35/Dockerfile | 10 +- .../linux/dockerfile/test/python36/Dockerfile | 10 +- .../linux/dockerfile/test/python37/Dockerfile | 10 +- .../linux/dockerfile/test/python38/Dockerfile | 10 +- kokoro/linux/python27/continuous.cfg | 2 +- kokoro/linux/python27/presubmit.cfg | 2 +- kokoro/linux/python27_cpp/continuous.cfg | 2 +- kokoro/linux/python27_cpp/presubmit.cfg | 2 +- kokoro/linux/python35/continuous.cfg | 2 +- kokoro/linux/python35/presubmit.cfg | 2 +- kokoro/linux/python35_cpp/continuous.cfg | 2 +- kokoro/linux/python35_cpp/presubmit.cfg | 2 +- kokoro/linux/python36/continuous.cfg | 2 +- kokoro/linux/python36/presubmit.cfg | 2 +- kokoro/linux/python36_cpp/continuous.cfg | 2 +- kokoro/linux/python36_cpp/presubmit.cfg | 2 +- kokoro/linux/python37/continuous.cfg | 2 +- kokoro/linux/python37/presubmit.cfg | 2 +- kokoro/linux/python37_cpp/continuous.cfg | 2 +- kokoro/linux/python37_cpp/presubmit.cfg | 2 +- kokoro/linux/python38/continuous.cfg | 2 +- kokoro/linux/python38/presubmit.cfg | 2 +- kokoro/linux/python38_cpp/continuous.cfg | 2 +- kokoro/linux/python38_cpp/presubmit.cfg | 2 +- kokoro/macos/php5.6_mac/build.sh | 11 - kokoro/macos/php5.6_mac/continuous.cfg | 5 - kokoro/macos/php5.6_mac/presubmit.cfg | 5 - php/ext/google/protobuf/message.c | 4 +- php/ext/google/protobuf/package.xml | 20 +- php/ext/google/protobuf/protobuf.h | 4 +- php/release.sh | 4 +- python/google/protobuf/pyext/message.cc | 2 +- python/google/protobuf/text_format.py | 3 +- python/protobuf_distutils/README.md | 17 +- python/tox.ini | 5 +- src/google/protobuf/any.h | 3 +- src/google/protobuf/any_lite.cc | 3 - src/google/protobuf/any_test.cc | 8 + src/google/protobuf/arena.cc | 34 ++- src/google/protobuf/arena.h | 4 +- src/google/protobuf/arena_impl.h | 35 ++- src/google/protobuf/arenastring.h | 25 +- src/google/protobuf/arenastring_unittest.cc | 3 + .../command_line_interface_unittest.cc | 6 +- src/google/protobuf/compiler/cpp/cpp_field.h | 4 - src/google/protobuf/compiler/cpp/cpp_file.cc | 1 - .../protobuf/compiler/cpp/cpp_message.cc | 7 - .../protobuf/compiler/cpp/cpp_message.h | 3 - .../protobuf/compiler/java/java_file.cc | 1 + src/google/protobuf/compiler/java/java_file.h | 1 + .../compiler/java/java_name_resolver.cc | 70 ++++- .../compiler/java/java_name_resolver.h | 18 ++ src/google/protobuf/compiler/main.cc | 1 + .../protobuf/compiler/parser_unittest.cc | 6 + src/google/protobuf/descriptor.cc | 114 ++++---- src/google/protobuf/descriptor_database.cc | 20 +- src/google/protobuf/descriptor_unittest.cc | 35 ++- src/google/protobuf/extension_set.cc | 8 - src/google/protobuf/extension_set.h | 5 +- src/google/protobuf/extension_set_unittest.cc | 9 +- .../protobuf/generated_message_reflection.cc | 1 + src/google/protobuf/generated_message_util.cc | 17 +- src/google/protobuf/generated_message_util.h | 12 +- src/google/protobuf/has_bits.h | 2 +- src/google/protobuf/implicit_weak_message.h | 2 +- src/google/protobuf/map.h | 11 +- src/google/protobuf/map_entry.h | 2 +- src/google/protobuf/map_entry_lite.h | 21 +- src/google/protobuf/map_field.h | 22 ++ src/google/protobuf/map_field_lite.h | 2 +- src/google/protobuf/map_field_test.cc | 19 ++ src/google/protobuf/map_test.cc | 39 +++ src/google/protobuf/map_type_handler.h | 26 +- src/google/protobuf/message.cc | 2 +- src/google/protobuf/message.h | 4 +- src/google/protobuf/message_lite.h | 29 +- src/google/protobuf/metadata_lite.h | 2 +- src/google/protobuf/port_def.inc | 79 ++++- src/google/protobuf/port_undef.inc | 9 +- src/google/protobuf/reflection_ops.cc | 17 +- src/google/protobuf/repeated_field.h | 13 +- .../protobuf/repeated_field_unittest.cc | 10 + src/google/protobuf/stubs/bytestream.h | 4 +- .../protobuf/stubs/bytestream_unittest.cc | 14 +- src/google/protobuf/stubs/callback.h | 8 +- src/google/protobuf/stubs/common.cc | 10 +- src/google/protobuf/stubs/common_unittest.cc | 22 +- src/google/protobuf/stubs/status.cc | 4 +- src/google/protobuf/stubs/status.h | 4 +- src/google/protobuf/stubs/status_test.cc | 2 +- src/google/protobuf/stubs/stl_util.h | 4 +- .../protobuf/stubs/stringpiece_unittest.cc | 68 ++--- src/google/protobuf/stubs/stringprintf.cc | 14 +- src/google/protobuf/stubs/stringprintf.h | 16 +- .../protobuf/stubs/stringprintf_unittest.cc | 18 +- .../stubs/structurally_valid_unittest.cc | 5 +- src/google/protobuf/stubs/strutil.cc | 270 +++++++++--------- src/google/protobuf/stubs/strutil.h | 214 +++++++------- src/google/protobuf/stubs/strutil_unittest.cc | 40 +-- src/google/protobuf/stubs/substitute.cc | 28 +- src/google/protobuf/stubs/substitute.h | 30 +- src/google/protobuf/stubs/time.cc | 12 +- src/google/protobuf/stubs/time.h | 4 +- src/google/protobuf/testing/file.cc | 33 ++- src/google/protobuf/testing/file.h | 38 +-- src/google/protobuf/testing/googletest.cc | 36 ++- src/google/protobuf/testing/googletest.h | 14 +- src/google/protobuf/text_format.cc | 8 +- .../protobuf/unittest_custom_options.proto | 10 + src/google/protobuf/unknown_field_set.cc | 3 +- .../protobuf/util/internal/proto_writer.cc | 28 +- .../internal/protostream_objectwriter_test.cc | 5 +- .../protobuf/util/message_differencer.cc | 43 ++- src/google/protobuf/wire_format.cc | 4 +- tests.sh | 47 +-- 141 files changed, 1800 insertions(+), 1214 deletions(-) delete mode 100755 kokoro/macos/php5.6_mac/build.sh delete mode 100644 kokoro/macos/php5.6_mac/continuous.cfg delete mode 100644 kokoro/macos/php5.6_mac/presubmit.cfg diff --git a/.github/mergeable.yml b/.github/mergeable.yml index a827eb7c689a..8577f086ee21 100644 --- a/.github/mergeable.yml +++ b/.github/mergeable.yml @@ -11,8 +11,8 @@ mergeable: regex: 'release notes: yes' message: 'Please include release notes: yes' - must_include: - regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel)' - message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cleanup, conformance tests, integration.' + regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel|cmake|protoc)' + message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cmake, cleanup, conformance tests, integration, protoc.' - must_include: regex: 'release notes: no' message: 'Please include release notes: no' diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 4ef1a1bd276c..f9795e190c7e 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -13,4 +13,4 @@ jobs: with: check_filenames: true skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal - ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od" + ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od" diff --git a/BUILD b/BUILD index afad437c1002..92e4091db3a0 100644 --- a/BUILD +++ b/BUILD @@ -14,10 +14,10 @@ exports_files(["LICENSE"]) # build configuration ################################################################################ +# TODO(yannic): Remove in 3.14.0. string_flag( name = "incompatible_use_com_google_googletest", - # TODO(yannic): Flip to `true` for `3.13.0`. - build_setting_default = "false", + build_setting_default = "true", values = ["true", "false"] ) @@ -368,7 +368,15 @@ cc_library( cc_proto_blacklist_test( name = "cc_proto_blacklist_test", - deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()] + deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], + tags = [ + # Exclude this target from wildcard expansion (//...). Due to + # https://github.com/bazelbuild/bazel/issues/10590, this test has to + # be nominated using the `@com_google_protobuf//` prefix. We do that, + # e.g., in kokoro/linux/bazel/build.sh. + # See also https://github.com/protocolbuffers/protobuf/pull/7096. + "manual", + ], ) ################################################################################ @@ -756,6 +764,13 @@ cc_binary( copts = COPTS + [ "-DPYTHON_PROTO2_CPP_IMPL_V2", ], + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], linkshared = 1, linkstatic = 1, deps = select({ @@ -780,6 +795,13 @@ cc_binary( "python/", "src/", ], + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], linkshared = 1, linkstatic = 1, deps = [ diff --git a/WORKSPACE b/WORKSPACE index cb16ae882c12..5a767a97c0ac 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -29,13 +29,13 @@ bind( actual = "//util/python:python_headers", ) -# TODO(yannic): Remove in 3.13.0. +# TODO(yannic): Remove in 3.14.0. bind( name = "gtest", actual = "@com_google_googletest//:gtest", ) -# TODO(yannic): Remove in 3.13.0. +# TODO(yannic): Remove in 3.14.0. bind( name = "gtest_main", actual = "@com_google_googletest//:gtest_main", diff --git a/conformance/text_format_failure_list_java.txt b/conformance/text_format_failure_list_java.txt index 8f74bdfb7e14..71e32429ec68 100644 --- a/conformance/text_format_failure_list_java.txt +++ b/conformance/text_format_failure_list_java.txt @@ -5,14 +5,6 @@ Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput Required.Proto3.TextFormatInput.AnyField.ProtobufOutput Required.Proto3.TextFormatInput.AnyField.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index e20a8858c22a..ff81e0032f81 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -41,6 +41,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; @@ -2009,14 +2010,14 @@ private ByteBuffer slice(long begin, long end) throws IOException { int prevPos = buffer.position(); int prevLimit = buffer.limit(); try { - buffer.position(bufferPos(begin)); - buffer.limit(bufferPos(end)); + ((Buffer) buffer).position(bufferPos(begin)); + ((Buffer) buffer).limit(bufferPos(end)); return buffer.slice(); } catch (IllegalArgumentException e) { throw InvalidProtocolBufferException.truncatedMessage(); } finally { - buffer.position(prevPos); - buffer.limit(prevLimit); + ((Buffer) buffer).position(prevPos); + ((Buffer) buffer).limit(prevLimit); } } } @@ -3910,14 +3911,14 @@ private ByteBuffer slice(int begin, int end) throws IOException { int prevPos = currentByteBuffer.position(); int prevLimit = currentByteBuffer.limit(); try { - currentByteBuffer.position(begin); - currentByteBuffer.limit(end); + ((Buffer) currentByteBuffer).position(begin); + ((Buffer) currentByteBuffer).limit(end); return currentByteBuffer.slice(); } catch (IllegalArgumentException e) { throw InvalidProtocolBufferException.truncatedMessage(); } finally { - currentByteBuffer.position(prevPos); - currentByteBuffer.limit(prevLimit); + ((Buffer) currentByteBuffer).position(prevPos); + ((Buffer) currentByteBuffer).limit(prevLimit); } } } diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index f27602aeb258..c30b00ddf730 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -764,7 +764,10 @@ public boolean isExtendable() { /** * Finds a field by name. * - * @param name The unqualified name of the field (e.g. "foo"). + * @param name The unqualified name of the field (e.g. "foo"). For protocol buffer messages that + * follow Google's + * guidance on naming this will be a snake case string, such as
song_name
. * @return The field's descriptor, or {@code null} if not found. */ public FieldDescriptor findFieldByName(final String name) { diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java index 241fcbd93248..0a63fad187e8 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java @@ -46,7 +46,6 @@ final class ExtensionRegistryFactory { @Nullable */ static final Class EXTENSION_REGISTRY_CLASS = reflectExtensionRegistry(); - /* @Nullable */ static Class reflectExtensionRegistry() { try { return Class.forName(FULL_REGISTRY_CLASS_NAME); @@ -77,7 +76,6 @@ static boolean isFullRegistry(ExtensionRegistryLite registry) { && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass()); } - /* @Nullable */ private static final ExtensionRegistryLite invokeSubclassFactory(String methodName) { if (EXTENSION_REGISTRY_CLASS == null) { return null; diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java index 0c4b20ed746b..caa58e1ada67 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java @@ -84,10 +84,8 @@ public class ExtensionRegistryLite { static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension"; private static class ExtensionClassHolder { - /* @Nullable */ static final Class INSTANCE = resolveExtensionClass(); - /* @Nullable */ static Class resolveExtensionClass() { try { return Class.forName(EXTENSION_CLASS_NAME); diff --git a/java/core/src/main/java/com/google/protobuf/FieldType.java b/java/core/src/main/java/com/google/protobuf/FieldType.java index 1b8f9e5da255..72327537fd20 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldType.java +++ b/java/core/src/main/java/com/google/protobuf/FieldType.java @@ -204,7 +204,6 @@ private boolean isValidForList(Field field) { * * @return the {@link FieldType} or {@code null} if not found. */ - /* @Nullable */ public static FieldType forId(int id) { if (id < 0 || id >= VALUES.length) { return null; @@ -228,7 +227,6 @@ public static FieldType forId(int id) { * * @return the generic super class/interface, or {@code null} if not found. */ - /* @Nullable */ private static Type getGenericSuperList(Class clazz) { // First look at interfaces. Type[] genericInterfaces = clazz.getGenericInterfaces(); diff --git a/java/core/src/main/java/com/google/protobuf/NioByteString.java b/java/core/src/main/java/com/google/protobuf/NioByteString.java index 64c46be68997..1e594ff878c5 100644 --- a/java/core/src/main/java/com/google/protobuf/NioByteString.java +++ b/java/core/src/main/java/com/google/protobuf/NioByteString.java @@ -37,6 +37,7 @@ import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.OutputStream; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.InvalidMarkException; @@ -109,7 +110,7 @@ public ByteString substring(int beginIndex, int endIndex) { protected void copyToInternal( byte[] target, int sourceOffset, int targetOffset, int numberToCopy) { ByteBuffer slice = buffer.slice(); - slice.position(sourceOffset); + ((Buffer) slice).position(sourceOffset); slice.get(target, targetOffset, numberToCopy); } @@ -285,8 +286,8 @@ private ByteBuffer slice(int beginIndex, int endIndex) { } ByteBuffer slice = buffer.slice(); - slice.position(beginIndex - buffer.position()); - slice.limit(endIndex - buffer.position()); + ((Buffer) slice).position(beginIndex - buffer.position()); + ((Buffer) slice).limit(endIndex - buffer.position()); return slice; } } diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index 7f744ddba769..bbc0f8dd94fe 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import static java.nio.charset.StandardCharsets.UTF_8; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -2375,6 +2377,73 @@ public static ByteString unescapeBytes(final CharSequence charString) result[pos++] = (byte) code; break; + case 'u': + // Unicode escape + ++i; + if (i + 3 < input.size() + && isHex(input.byteAt(i)) + && isHex(input.byteAt(i + 1)) + && isHex(input.byteAt(i + 2)) + && isHex(input.byteAt(i + 3))) { + char ch = + (char) + (digitValue(input.byteAt(i)) << 12 + | digitValue(input.byteAt(i + 1)) << 8 + | digitValue(input.byteAt(i + 2)) << 4 + | digitValue(input.byteAt(i + 3))); + if (Character.isSurrogate(ch)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\u' refers to a surrogate"); + } + byte[] chUtf8 = Character.toString(ch).getBytes(UTF_8); + System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); + pos += chUtf8.length; + i += 3; + } else { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\u' with too few hex chars"); + } + break; + + case 'U': + // Unicode escape + ++i; + if (i + 7 >= input.size()) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U' with too few hex chars"); + } + int codepoint = 0; + for (int offset = i; offset < i + 8; offset++) { + byte b = input.byteAt(offset); + if (!isHex(b)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U' with too few hex chars"); + } + codepoint = (codepoint << 4) | digitValue(b); + } + if (!Character.isValidCodePoint(codepoint)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U" + + input.substring(i, i + 8).toStringUtf8() + + "' is not a valid code point value"); + } + Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(codepoint); + if (unicodeBlock.equals(Character.UnicodeBlock.LOW_SURROGATES) + || unicodeBlock.equals(Character.UnicodeBlock.HIGH_SURROGATES) + || unicodeBlock.equals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U" + + input.substring(i, i + 8).toStringUtf8() + + "' refers to a surrogate code unit"); + } + int[] codepoints = new int[1]; + codepoints[0] = codepoint; + byte[] chUtf8 = new String(codepoints, 0, 1).getBytes(UTF_8); + System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); + pos += chUtf8.length; + i += 7; + break; + default: throw new InvalidEscapeSequenceException( "Invalid escape sequence: '\\" + (char) c + '\''); diff --git a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java index 47d798bfe621..422ff1f870fc 100644 --- a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java +++ b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java @@ -70,7 +70,6 @@ public Descriptor find(String name) { /** * Find a type by its typeUrl. Returns null if it cannot be found in this {@link TypeRegistry}. */ - /* @Nullable */ public final Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException { return find(getTypeName(typeUrl)); diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java index b435327ab8b8..471238ae4325 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -41,7 +41,6 @@ /** Utility class for working with unsafe operations. */ final class UnsafeUtil { - private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName()); private static final sun.misc.Unsafe UNSAFE = getUnsafe(); private static final Class MEMORY_CLASS = Android.getMemoryClass(); private static final boolean IS_ANDROID_64 = determineAndroidSupportByAddressSize(long.class); @@ -363,9 +362,13 @@ private static boolean supportsUnsafeArrayOperations() { return true; } catch (Throwable e) { - logger.log( - Level.WARNING, - "platform method missing - proto runtime falling back to safer methods: " + e); + // Because log statements are fairly sparse in this class, this logger is initialized + // non-statically. Static initialization adds undue runtime costs to the first client to + // initialize this class. + Logger.getLogger(UnsafeUtil.class.getName()) + .log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); } return false; } @@ -397,9 +400,13 @@ private static boolean supportsUnsafeByteBufferOperations() { clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); return true; } catch (Throwable e) { - logger.log( - Level.WARNING, - "platform method missing - proto runtime falling back to safer methods: " + e); + // Because log statements are fairly sparse in this class, this logger is initialized + // non-statically. Static initialization adds undue runtime costs to the first client to + // initialize this class. + Logger.getLogger(UnsafeUtil.class.getName()) + .log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); } return false; } diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java index adca1d51b6c9..9994ad067a1e 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java @@ -77,44 +77,44 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValues(TestMap.Builder builder) { @@ -152,35 +152,35 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -206,13 +206,13 @@ public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32Field().isEmpty()); + assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); message = builder.build(); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); } public void testGetMapIsImmutable() { @@ -254,30 +254,31 @@ private void assertImmutable(Map map, K key, V value) { public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField()); + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumFieldMap()); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); + assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + builder.build().getInt32ToMessageFieldMap()); assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField()); + newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap( @@ -285,7 +286,7 @@ public void testMutableMapLifecycle() { TestMap.MessageValue.getDefaultInstance(), 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + builder.getInt32ToMessageFieldMap()); } public void testGettersAndSetters() throws Exception { @@ -415,7 +416,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -476,14 +477,14 @@ public void testUnknownEnumValues() throws Exception { TestMap message = TestMap.parseFrom(data); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); + assertEquals(1, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); + assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); + assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); } public void testIterationOrder() throws Exception { @@ -493,7 +494,7 @@ public void testIterationOrder() throws Exception { assertEquals( Arrays.asList("1", "2", "3"), - new ArrayList(message.getStringToInt32Field().keySet())); + new ArrayList(message.getStringToInt32FieldMap().keySet())); } private static Map newMap(K key1, V value1) { @@ -513,10 +514,10 @@ public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java index bb706326c4b4..b995802b4f0c 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -119,12 +119,12 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMapOrBuilder message) { @@ -236,35 +236,35 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); - - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); - - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); - - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); - - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); - - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); + + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); + + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); + + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); + + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); + + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -563,7 +563,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -698,8 +698,8 @@ public void testReflectionApi() throws Exception { builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32Field().size()); - assertEquals(0, message.getInt32ToMessageField().size()); + assertEquals(0, message.getInt32ToInt32FieldMap().size()); + assertEquals(0, message.getInt32ToMessageFieldMap().size()); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -710,10 +710,10 @@ public void testReflectionApi() throws Exception { 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - assertEquals(22, message.getInt32ToInt32Field().get(11).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(33).intValue()); - assertEquals(222, message.getInt32ToMessageField().get(111).getValue()); - assertEquals(444, message.getInt32ToMessageField().get(333).getValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue()); + assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue()); + assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue()); // Test addRepeatedField builder.addRepeatedField( @@ -726,8 +726,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -740,8 +740,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -755,9 +755,9 @@ public void testReflectionApi() throws Exception { builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32Field().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); } // See additional coverage in TextFormatTest.java. @@ -844,16 +844,16 @@ public void testUnknownEnumValues() throws Exception { TestMap message = TestMap.parseFrom(data); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); + assertEquals(1, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); // UnknownFieldSet should not be empty. assertFalse(message.getUnknownFields().asMap().isEmpty()); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); + assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); + assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); } public void testRequiredMessage() throws Exception { @@ -885,7 +885,7 @@ public void testIterationOrder() throws Exception { assertEquals( Arrays.asList("1", "2", "3"), - new ArrayList(message.getStringToInt32Field().keySet())); + new ArrayList(message.getStringToInt32FieldMap().keySet())); } public void testContains() { @@ -1172,9 +1172,9 @@ public void testGetMap() { setMapValuesUsingAccessors(builder); assertMapValuesSet(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } } diff --git a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java index d18fd13e0ace..40bb7893b313 100644 --- a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java @@ -84,44 +84,44 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValues(TestMap.Builder builder) { @@ -159,35 +159,35 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -213,12 +213,12 @@ public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32Field().isEmpty()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); message = builder.build(); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); } public void testGetMapIsImmutable() { @@ -266,30 +266,31 @@ public void testMapFieldClear() { public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField()); + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumFieldMap()); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); + assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + builder.build().getInt32ToMessageFieldMap()); assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField()); + newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap( @@ -297,7 +298,7 @@ public void testMutableMapLifecycle() { TestMap.MessageValue.getDefaultInstance(), 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + builder.getInt32ToMessageFieldMap()); } public void testGettersAndSetters() throws Exception { @@ -342,12 +343,12 @@ public void testPutAllForUnknownEnumValues() throws Exception { TestMap source = sourceBuilder.build(); TestMap.Builder destinationBuilder = TestMap.newBuilder(); - destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()); + destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()); TestMap destination = destinationBuilder.build(); - assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue()); - assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue()); - assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue()); + assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue()); + assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue()); assertEquals(3, destination.getInt32ToEnumFieldCount()); } @@ -459,7 +460,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -524,24 +525,24 @@ public void testUnknownEnumValues() throws Exception { .putInt32ToEnumFieldValue(2, 1000); // unknown value. TestMap message = builder.build(); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); builder.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value. message = builder.build(); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); @@ -550,7 +551,7 @@ public void testUnknownEnumValues() throws Exception { assertFalse(message.equals(message2)); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField()); + assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); } public void testIterationOrder() throws Exception { @@ -559,18 +560,18 @@ public void testIterationOrder() throws Exception { TestMap message = builder.build(); assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet())); + Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); } public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java index 9f1ebaed692b..f3458dd23595 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -122,44 +122,44 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { @@ -239,35 +239,35 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -468,11 +468,13 @@ public void testPutAllForUnknownEnumValues() throws Exception { .build(); TestMap destination = - TestMap.newBuilder().putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()).build(); + TestMap.newBuilder() + .putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()) + .build(); - assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue()); - assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue()); - assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue()); + assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue()); + assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue()); assertEquals(3, destination.getInt32ToEnumFieldCount()); } @@ -583,7 +585,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -644,14 +646,14 @@ public void testNestedBuilderOnChangeEventPropagation() { TestOnChangeEventPropagation.Builder parent = TestOnChangeEventPropagation.newBuilder(); parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2); TestOnChangeEventPropagation message = parent.build(); - assertEquals(2, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(2, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make a change using nested builder. parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 3); // Should be able to observe the change. message = parent.build(); - assertEquals(3, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(3, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make another change using mergeFrom() TestMap other = TestMap.newBuilder().putInt32ToInt32Field(1, 4).build(); @@ -659,14 +661,14 @@ public void testNestedBuilderOnChangeEventPropagation() { // Should be able to observe the change. message = parent.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make yet another change by clearing the nested builder. parent.getOptionalMessageBuilder().clear(); // Should be able to observe the change. message = parent.build(); - assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); } public void testNestedBuilderOnChangeEventPropagationReflection() { @@ -683,7 +685,7 @@ public void testNestedBuilderOnChangeEventPropagationReflection() { // Should be able to observe the change. TestOnChangeEventPropagation message = parentBuilder.build(); - assertEquals(1, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(1, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); // Change the entry value. entryBuilder.putInt32ToInt32Field(1, 4); @@ -692,7 +694,7 @@ public void testNestedBuilderOnChangeEventPropagationReflection() { // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Clear the nested builder. testMapBuilder = parentBuilder.getOptionalMessageBuilder(); @@ -700,7 +702,7 @@ public void testNestedBuilderOnChangeEventPropagationReflection() { // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); } // The following methods are used to test reflection API. @@ -789,8 +791,8 @@ public void testReflectionApi() throws Exception { builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32Field().size()); - assertEquals(0, message.getInt32ToMessageField().size()); + assertEquals(0, message.getInt32ToInt32FieldMap().size()); + assertEquals(0, message.getInt32ToMessageFieldMap().size()); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -801,10 +803,10 @@ public void testReflectionApi() throws Exception { 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - assertEquals(22, message.getInt32ToInt32Field().get(11).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(33).intValue()); - assertEquals(222, message.getInt32ToMessageField().get(111).getValue()); - assertEquals(444, message.getInt32ToMessageField().get(333).getValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue()); + assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue()); + assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue()); // Test addRepeatedField builder.addRepeatedField( @@ -817,8 +819,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -831,8 +833,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -846,9 +848,9 @@ public void testReflectionApi() throws Exception { builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32Field().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); } // See additional coverage in TextFormatTest.java. @@ -937,21 +939,21 @@ public void testUnknownEnumValues() throws Exception { 2, 1000)); // unknown value. TestMap message = builder.build(); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); @@ -960,7 +962,7 @@ public void testUnknownEnumValues() throws Exception { assertFalse(message.equals(message2)); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField()); + assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); } public void testUnknownEnumValuesInReflectionApi() throws Exception { @@ -991,7 +993,7 @@ public void testUnknownEnumValuesInReflectionApi() throws Exception { // Verify that enum values have been successfully updated. TestMap message = builder.build(); - for (Map.Entry entry : message.getInt32ToEnumFieldValue().entrySet()) { + for (Map.Entry entry : message.getInt32ToEnumFieldValueMap().entrySet()) { assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue()); } } @@ -1002,18 +1004,18 @@ public void testIterationOrder() throws Exception { TestMap message = builder.build(); assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet())); + Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); } public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index e229facacefd..915dddf39218 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -30,6 +30,7 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED; import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED; @@ -866,6 +867,12 @@ public void testEscape() throws Exception { assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\341\\210\\264")); assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4")); assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\xe1\\x88\\xb4")); + assertEquals("\u1234", TextFormat.unescapeText("\\u1234")); + assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\u1234")); + assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\U00001234")); + assertEquals( + new String(new int[] {0x10437}, 0, 1), TextFormat.unescapeText("\\xf0\\x90\\x90\\xb7")); + assertEquals(bytes(0xf0, 0x90, 0x90, 0xb7), TextFormat.unescapeBytes("\\U00010437")); // Handling of strings with unescaped Unicode characters > 255. final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; @@ -893,6 +900,87 @@ public void testEscape() throws Exception { } catch (TextFormat.InvalidEscapeSequenceException e) { // success } + + try { + TextFormat.unescapeText("\\u"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\ud800"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\ud800\\u1234"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\udc00"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\ud801\\udc37"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\U1234"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\U1234no more hex"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\U00110000"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U00110000' is not a valid code point value"); + } + + try { + TextFormat.unescapeText("\\U0000d801\\U00000dc37"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U0000d801' refers to a surrogate code unit"); + } } public void testParseInteger() throws Exception { diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java index 4092b30683a6..352376e01509 100644 --- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java +++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java @@ -137,11 +137,19 @@ FieldMaskTree mergeFromFieldMask(FieldMask mask) { } /** - * Remove {@code path} from the tree. + * Removes {@code path} from the tree. * - *

When removing a field path from the tree, all sub-paths will be removed. That is, after - * removing "foo.bar" from the tree, "foo.bar.baz" will be removed. Likewise, if the field path to - * remove is a non-exist sub-path, nothing will be changed. + *

    + * When removing a field path from the tree: + *
  • All sub-paths will be removed. That is, after removing "foo.bar" from the tree, + * "foo.bar.baz" will be removed. + *
  • If all children of a node has been removed, the node itself will be removed as well. + * That is, if "foo" only has one child "bar" and "foo.bar" only has one child "baz", + * removing "foo.bar.barz" would remove both "foo" and "foo.bar". + * If "foo" has both "bar" and "qux" as children, removing "foo.bar" would leave the path + * "foo.qux" intact. + *
  • If the field path to remove is a non-exist sub-path, nothing will be changed. + *
*/ @CanIgnoreReturnValue FieldMaskTree removeFieldPath(String path) { @@ -149,23 +157,35 @@ FieldMaskTree removeFieldPath(String path) { if (parts.isEmpty()) { return this; } - Node node = root; - for (int i = 0; i < parts.size(); i++) { - String key = parts.get(i); - if (!node.children.containsKey(key)) { - // Path does not exist. - return this; - } - if (i == parts.size() - 1) { - // Remove path. - node.children.remove(key); - return this; - } - node = node.children.get(key); - } + removeFieldPath(root, parts, 0); return this; } + /** + * Removes {@code parts} from {@code node} recursively. + * + * @return a boolean value indicating whether current {@code node} should be removed. + */ + @CanIgnoreReturnValue + private static boolean removeFieldPath(Node node, List parts, int index) { + String key = parts.get(index); + + // Base case 1: path not match. + if (!node.children.containsKey(key)) { + return false; + } + // Base case 2: last element in parts. + if (index == parts.size() - 1) { + node.children.remove(key); + return node.children.isEmpty(); + } + // Recursive remove sub-path. + if (removeFieldPath(node.children.get(key), parts, index + 1)) { + node.children.remove(key); + } + return node.children.isEmpty(); + } + /** Removes all field paths in {@code mask} from this tree. */ @CanIgnoreReturnValue FieldMaskTree removeFromFieldMask(FieldMask mask) { @@ -187,10 +207,8 @@ FieldMask toFieldMask() { return FieldMask.newBuilder().addAllPaths(paths).build(); } - /** - * Gathers all field paths in a sub-tree. - */ - private void getFieldPaths(Node node, String path, List paths) { + /** Gathers all field paths in a sub-tree. */ + private static void getFieldPaths(Node node, String path, List paths) { if (node.children.isEmpty()) { paths.add(path); return; @@ -247,10 +265,8 @@ void merge(Message source, Message.Builder destination, FieldMaskUtil.MergeOptio merge(root, "", source, destination, options); } - /** - * Merges all fields specified by a sub-tree from {@code source} to {@code destination}. - */ - private void merge( + /** Merges all fields specified by a sub-tree from {@code source} to {@code destination}. */ + private static void merge( Node node, String path, Message source, diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java index 0c2f90c91e06..c32d10a2639c 100644 --- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java +++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java @@ -276,7 +276,13 @@ public static FieldMask union( return maskTree.toFieldMask(); } - /** Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}. */ + /** + * Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}. + * + *

This method disregards proto structure. That is, if {@code firstMask} is "foo" and {@code + * secondMask} is "foo.bar", the response will always be "foo" without considering the internal + * proto structure of message "foo". + */ public static FieldMask subtract( FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) { FieldMaskTree maskTree = new FieldMaskTree(firstMask).removeFromFieldMask(secondMask); diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index cc3f5f658f0a..4f2fe3fcfa4b 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -525,7 +525,6 @@ public Descriptor find(String name) { return types.get(name); } - /* @Nullable */ Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException { return find(getTypeName(typeUrl)); } diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java index 7ec37d097b05..c8297226f77a 100644 --- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java @@ -77,25 +77,37 @@ public void testMergeFromFieldMask() throws Exception { public void testRemoveFieldPath() throws Exception { String initialTreeString = "bar.baz,bar.quz.bar,foo"; - FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + FieldMaskTree tree; + // Empty path. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath(""); assertEquals(initialTreeString, tree.toString()); + // Non-exist sub-path of an existing leaf. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("foo.bar"); assertEquals(initialTreeString, tree.toString()); + // Non-exist path. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar.foo"); assertEquals(initialTreeString, tree.toString()); - // Match an existing leaf node. + + // Match an existing leaf node -> remove leaf node. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("foo"); assertEquals("bar.baz,bar.quz.bar", tree.toString()); - // Match sub-path of an existing leaf node. + + // Match sub-path of an existing leaf node -> recursive removal. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar.quz.bar"); - assertEquals("bar.baz,bar.quz", tree.toString()); - // Match a non-leaf node. + assertEquals("bar.baz,foo", tree.toString()); + + // Match a non-leaf node -> remove all children. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar"); - assertThat(tree.toString()).isEmpty(); + assertEquals("foo", tree.toString()); } public void testRemoveFromFieldMask() throws Exception { diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java index 796020eaf2a3..28e43a7bf77b 100644 --- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java @@ -239,7 +239,7 @@ public void testSubstract_usingVarArgs() throws Exception { FieldMask mask3 = FieldMaskUtil.fromString("bar.quz"); FieldMask mask4 = FieldMaskUtil.fromString("foo,bar.baz"); FieldMask result = FieldMaskUtil.subtract(mask1, mask2, mask3, mask4); - assertEquals("bar", FieldMaskUtil.toString(result)); + assertThat(FieldMaskUtil.toString(result)).isEmpty(); } public void testIntersection() throws Exception { diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index f9358e522141..46d3cc4c352c 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -722,8 +722,8 @@ public void testParserAcceptNonQuotedObjectKey() throws Exception { mergeFromJson( "{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder); TestMap message = builder.build(); - assertEquals(2, message.getInt32ToInt32Map().get(1).intValue()); - assertEquals(3, message.getStringToInt32Map().get("hello").intValue()); + assertEquals(2, message.getInt32ToInt32MapMap().get(1).intValue()); + assertEquals(3, message.getStringToInt32MapMap().get("hello").intValue()); } public void testWrappers() throws Exception { diff --git a/kokoro/linux/dockerfile/test/python27/Dockerfile b/kokoro/linux/dockerfile/test/python27/Dockerfile index e41e49a6e508..6b0eaf72c862 100644 --- a/kokoro/linux/dockerfile/test/python27/Dockerfile +++ b/kokoro/linux/dockerfile/test/python27/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python35/Dockerfile b/kokoro/linux/dockerfile/test/python35/Dockerfile index 3ea4c9e188dd..50ee18453619 100644 --- a/kokoro/linux/dockerfile/test/python35/Dockerfile +++ b/kokoro/linux/dockerfile/test/python35/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python36/Dockerfile b/kokoro/linux/dockerfile/test/python36/Dockerfile index 436846065b41..742503e5a417 100644 --- a/kokoro/linux/dockerfile/test/python36/Dockerfile +++ b/kokoro/linux/dockerfile/test/python36/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python37/Dockerfile b/kokoro/linux/dockerfile/test/python37/Dockerfile index c711eb86a590..ee108dd03012 100644 --- a/kokoro/linux/dockerfile/test/python37/Dockerfile +++ b/kokoro/linux/dockerfile/test/python37/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python38/Dockerfile b/kokoro/linux/dockerfile/test/python38/Dockerfile index 48a7be5e0519..56efc9d6bf39 100644 --- a/kokoro/linux/dockerfile/test/python38/Dockerfile +++ b/kokoro/linux/dockerfile/test/python38/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/python27/continuous.cfg b/kokoro/linux/python27/continuous.cfg index e2fc4136f07e..dd98469a6fb6 100644 --- a/kokoro/linux/python27/continuous.cfg +++ b/kokoro/linux/python27/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27/presubmit.cfg b/kokoro/linux/python27/presubmit.cfg index e2fc4136f07e..dd98469a6fb6 100644 --- a/kokoro/linux/python27/presubmit.cfg +++ b/kokoro/linux/python27/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27_cpp/continuous.cfg b/kokoro/linux/python27_cpp/continuous.cfg index b1b0e550ffd4..ace22d007717 100644 --- a/kokoro/linux/python27_cpp/continuous.cfg +++ b/kokoro/linux/python27_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27_cpp/presubmit.cfg b/kokoro/linux/python27_cpp/presubmit.cfg index b1b0e550ffd4..ace22d007717 100644 --- a/kokoro/linux/python27_cpp/presubmit.cfg +++ b/kokoro/linux/python27_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35/continuous.cfg b/kokoro/linux/python35/continuous.cfg index e2fc4136f07e..2b3e12cbb0cd 100644 --- a/kokoro/linux/python35/continuous.cfg +++ b/kokoro/linux/python35/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python35/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35/presubmit.cfg b/kokoro/linux/python35/presubmit.cfg index e2fc4136f07e..2b3e12cbb0cd 100644 --- a/kokoro/linux/python35/presubmit.cfg +++ b/kokoro/linux/python35/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python35/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35_cpp/continuous.cfg b/kokoro/linux/python35_cpp/continuous.cfg index b1b0e550ffd4..ad5cc8657adc 100644 --- a/kokoro/linux/python35_cpp/continuous.cfg +++ b/kokoro/linux/python35_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35_cpp/presubmit.cfg b/kokoro/linux/python35_cpp/presubmit.cfg index b1b0e550ffd4..ad5cc8657adc 100644 --- a/kokoro/linux/python35_cpp/presubmit.cfg +++ b/kokoro/linux/python35_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36/continuous.cfg b/kokoro/linux/python36/continuous.cfg index e2fc4136f07e..ee7f4888f8c7 100644 --- a/kokoro/linux/python36/continuous.cfg +++ b/kokoro/linux/python36/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python36/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36/presubmit.cfg b/kokoro/linux/python36/presubmit.cfg index e2fc4136f07e..ee7f4888f8c7 100644 --- a/kokoro/linux/python36/presubmit.cfg +++ b/kokoro/linux/python36/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python36/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36_cpp/continuous.cfg b/kokoro/linux/python36_cpp/continuous.cfg index b1b0e550ffd4..df9e7144943a 100644 --- a/kokoro/linux/python36_cpp/continuous.cfg +++ b/kokoro/linux/python36_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36_cpp/presubmit.cfg b/kokoro/linux/python36_cpp/presubmit.cfg index b1b0e550ffd4..df9e7144943a 100644 --- a/kokoro/linux/python36_cpp/presubmit.cfg +++ b/kokoro/linux/python36_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37/continuous.cfg b/kokoro/linux/python37/continuous.cfg index e2fc4136f07e..9fa20c19757e 100644 --- a/kokoro/linux/python37/continuous.cfg +++ b/kokoro/linux/python37/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python37/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37/presubmit.cfg b/kokoro/linux/python37/presubmit.cfg index e2fc4136f07e..9fa20c19757e 100644 --- a/kokoro/linux/python37/presubmit.cfg +++ b/kokoro/linux/python37/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python37/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37_cpp/continuous.cfg b/kokoro/linux/python37_cpp/continuous.cfg index b1b0e550ffd4..49c441ffe892 100644 --- a/kokoro/linux/python37_cpp/continuous.cfg +++ b/kokoro/linux/python37_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python37_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37_cpp/presubmit.cfg b/kokoro/linux/python37_cpp/presubmit.cfg index b1b0e550ffd4..49c441ffe892 100644 --- a/kokoro/linux/python37_cpp/presubmit.cfg +++ b/kokoro/linux/python37_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python37_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38/continuous.cfg b/kokoro/linux/python38/continuous.cfg index e2fc4136f07e..76425d2f193a 100644 --- a/kokoro/linux/python38/continuous.cfg +++ b/kokoro/linux/python38/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python38/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38/presubmit.cfg b/kokoro/linux/python38/presubmit.cfg index e2fc4136f07e..76425d2f193a 100644 --- a/kokoro/linux/python38/presubmit.cfg +++ b/kokoro/linux/python38/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python38/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38_cpp/continuous.cfg b/kokoro/linux/python38_cpp/continuous.cfg index b1b0e550ffd4..1e8888cc5d1b 100644 --- a/kokoro/linux/python38_cpp/continuous.cfg +++ b/kokoro/linux/python38_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python38_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38_cpp/presubmit.cfg b/kokoro/linux/python38_cpp/presubmit.cfg index b1b0e550ffd4..1e8888cc5d1b 100644 --- a/kokoro/linux/python38_cpp/presubmit.cfg +++ b/kokoro/linux/python38_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python38_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/macos/php5.6_mac/build.sh b/kokoro/macos/php5.6_mac/build.sh deleted file mode 100755 index 74878898faa7..000000000000 --- a/kokoro/macos/php5.6_mac/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 php5.6_mac diff --git a/kokoro/macos/php5.6_mac/continuous.cfg b/kokoro/macos/php5.6_mac/continuous.cfg deleted file mode 100644 index ff345e9fc41d..000000000000 --- a/kokoro/macos/php5.6_mac/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/php5.6_mac/build.sh" -timeout_mins: 1440 diff --git a/kokoro/macos/php5.6_mac/presubmit.cfg b/kokoro/macos/php5.6_mac/presubmit.cfg deleted file mode 100644 index ff345e9fc41d..000000000000 --- a/kokoro/macos/php5.6_mac/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/php5.6_mac/build.sh" -timeout_mins: 1440 diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index b2a03063f52d..7cd16699c7c7 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -356,14 +356,14 @@ static PROTO_RETURN_VAL Message_write_property( } upb_msg_set(intern->msg, f, msgval, arena); -#if PHP_VERSION_ID < 704000 +#if PHP_VERSION_ID < 70400 return; #else return val; #endif error: -#if PHP_VERSION_ID < 704000 +#if PHP_VERSION_ID < 70400 return; #else return &EG(error_zval); diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index 037fa90d9332..e0d25c87c5db 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -10,11 +10,11 @@ protobuf-opensource@google.com yes - 2020-08-14 + 2020-10-08 - 3.13.0 - 3.13.0 + 3.13.0.1 + 3.13.0.1 stable @@ -675,5 +675,19 @@ G A release. 3-Clause BSD License GA release. + + + 3.13.0.1 + 3.13.0.1 + + + stable + stable + + 2020-10-08 + + 3-Clause BSD License + GA release. + diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 3188fe7dcbe1..195e2a797187 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -56,7 +56,7 @@ const zval *get_generated_pool(); // instead of zval* and zend_string* instead of zval* for property names. // https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39 #if PHP_VERSION_ID < 80000 -#define PROTO_VAL zval +#define PROTO_VAL zval #define PROTO_STR zval #define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj) #define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj) @@ -69,7 +69,7 @@ const zval *get_generated_pool(); #define PROTO_STRLEN_P(obj) ZSTR_LEN(obj) #endif -#define PHP_PROTOBUF_VERSION "3.13.0" +#define PHP_PROTOBUF_VERSION "3.13.0.1" // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: diff --git a/php/release.sh b/php/release.sh index ec9ec0eeb3b0..6b0baac78ff5 100755 --- a/php/release.sh +++ b/php/release.sh @@ -10,8 +10,8 @@ set -ex VERSION=$1 -git clone git@github.com:protocolbuffers/protobuf-php.git -git clone git@github.com:protocolbuffers/protobuf.git +git clone https://github.com/protocolbuffers/protobuf-php.git +git clone https://github.com/protocolbuffers/protobuf.git # Clean old files pushd protobuf-php diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index b7d73859fa6e..0301e9634daf 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -809,7 +809,7 @@ bool CheckAndSetString( return false; } - string value_string(value, value_len); + std::string value_string(value, value_len); if (append) { reflection->AddString(message, descriptor, std::move(value_string)); } else if (index < 0) { diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index 2a9a86642056..c2bec1cc6b58 100644 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -883,7 +883,8 @@ def _MergeField(self, tokenizer, message): (expanded_any_end_token,)) self._MergeField(tokenizer, expanded_any_sub_message) message.Pack(expanded_any_sub_message, - type_url_prefix=type_url_prefix) + type_url_prefix=type_url_prefix, + deterministic=True) return if tokenizer.TryConsume('['): diff --git a/python/protobuf_distutils/README.md b/python/protobuf_distutils/README.md index 2989b2ad5438..63d12b5200b5 100644 --- a/python/protobuf_distutils/README.md +++ b/python/protobuf_distutils/README.md @@ -103,4 +103,19 @@ $ python -m pip install . By default, the protoc binary (the Protobuf compiler) is found by searching the environment path. To use a specific protoc binary, its - path can be specified. + path can be specified. Resolution of the `protoc` value is as follows: + 1. If the `--protoc=VALUE` flag is passed to `generate_py_protobufs`, + then `VALUE` will be used. + For example: + ```shell + $ python setup.py generate_py_protobufs --protoc=/path/to/protoc + ``` + 2. Otherwise, if a value was set in the `options`, it will be used. + (See "Example setup.py configuration," above.) + 3. Otherwise, if the `PROTOC` environment variable is set, it will be + used. For example: + For example: + ```shell + $ PROTOC=/path/to/protoc python setup.py generate_py_protobufs + ``` + 4. Otherwise, `$PATH` will be searched. diff --git a/python/tox.ini b/python/tox.ini index 999f8ceeb8fa..56be1258ae99 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -14,7 +14,10 @@ setenv = commands = python setup.py -q build_py python: python setup.py -q build - cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + # --warnings_as_errors disabled until we update the Python C extension. See: + # https://github.com/protocolbuffers/protobuf/issues/7930 + # cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + cpp: python setup.py -q build --cpp_implementation --compile_static_extension python: python setup.py -q test -q cpp: python setup.py -q test -q --cpp_implementation python: python setup.py -q test_conformance diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h index 16a68ca687a4..e8f2cacf16c6 100644 --- a/src/google/protobuf/any.h +++ b/src/google/protobuf/any.h @@ -60,7 +60,8 @@ class PROTOBUF_EXPORT AnyMetadata { typedef ArenaStringPtr ValueType; public: // AnyMetadata does not take ownership of "type_url" and "value". - AnyMetadata(UrlType* type_url, ValueType* value); + constexpr AnyMetadata(UrlType* type_url, ValueType* value) + : type_url_(type_url), value_(value) {} // Packs a message using the default type URL prefix: "type.googleapis.com". // The resulted type URL will be "type.googleapis.com/". diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index 7501969da591..ffb26921359c 100644 --- a/src/google/protobuf/any_lite.cc +++ b/src/google/protobuf/any_lite.cc @@ -53,9 +53,6 @@ const char kAnyFullTypeName[] = "google.protobuf.Any"; const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/"; const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/"; -AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value) - : type_url_(type_url), value_(value) {} - void AnyMetadata::InternalPackFrom(const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name) { diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc index 0d8893f7b811..8aeab7602b81 100644 --- a/src/google/protobuf/any_test.cc +++ b/src/google/protobuf/any_test.cc @@ -33,10 +33,18 @@ #include +// Must be included last. +#include + namespace google { namespace protobuf { namespace { +TEST(AnyMetadataTest, ConstInit) { + PROTOBUF_CONSTINIT static internal::AnyMetadata metadata(nullptr, nullptr); + (void)metadata; +} + TEST(AnyTest, TestPackAndUnpack) { protobuf_unittest::TestAny submessage; submessage.set_int32_value(12345); diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index fce59b254513..631a08e0cee8 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -47,6 +47,10 @@ static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit. namespace google { namespace protobuf { + +PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)( + size_t) = &::operator new; + namespace internal { const size_t ArenaImpl::kBlockHeaderSize; @@ -54,7 +58,7 @@ const size_t ArenaImpl::kSerialArenaSize; const size_t ArenaImpl::kOptionsSize; -std::atomic ArenaImpl::lifecycle_id_generator_; +ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { static internal::ThreadLocalStorage* thread_cache_ = @@ -63,12 +67,13 @@ ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { } #elif defined(PROTOBUF_USE_DLLS) ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { - static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = {-1, NULL}; + static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = { + 0, static_cast(-1), nullptr}; return thread_cache_; } #else -PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, - NULL}; +PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = { + 0, static_cast(-1), nullptr}; #endif void ArenaFree(void* object, size_t size) { @@ -122,9 +127,26 @@ ArenaImpl::ArenaImpl(const ArenaOptions& options) { } void ArenaImpl::Init(bool record_allocs) { + ThreadCache& tc = thread_cache(); + auto id = tc.next_lifecycle_id; + constexpr uint64 kInc = ThreadCache::kPerThreadIds * 2; + if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) { + if (sizeof(lifecycle_id_generator_.id) == 4) { + // 2^32 is dangerous low to guarantee uniqueness. If we start dolling out + // unique id's in ranges of kInc it's unacceptably low. In this case + // we increment by 1. The additional range of kPerThreadIds that are used + // per thread effectively pushes the overflow time from weeks to years + // of continuous running. + id = lifecycle_id_generator_.id.fetch_add(1, std::memory_order_relaxed) * + kInc; + } else { + id = + lifecycle_id_generator_.id.fetch_add(kInc, std::memory_order_relaxed); + } + } + tc.next_lifecycle_id = id + 2; // We store "record_allocs" in the low bit of lifecycle_id_. - auto id = lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed); - lifecycle_id_ = (id << 1) | (record_allocs ? 1 : 0); + lifecycle_id_ = id | (record_allocs ? 1 : 0); hint_.store(nullptr, std::memory_order_relaxed); threads_.store(nullptr, std::memory_order_relaxed); space_allocated_.store(0, std::memory_order_relaxed); diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 7c5c7d00bdca..8ab4fc8e1bcb 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -142,10 +142,12 @@ struct ArenaOptions { max_block_size(kDefaultMaxBlockSize), initial_block(NULL), initial_block_size(0), - block_alloc(&::operator new), + block_alloc(kDefaultBlockAlloc), block_dealloc(&internal::ArenaFree), make_metrics_collector(nullptr) {} + PROTOBUF_EXPORT static void* (*const kDefaultBlockAlloc)(size_t); + private: // If make_metrics_collector is not nullptr, it will be called at Arena init // time. It may return a pointer to a collector instance that will be notified diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index 56ef7e1a5513..ec86daba2005 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -58,7 +58,7 @@ inline size_t AlignUpTo8(size_t n) { return (n + 7) & static_cast(-8); } -using LifecycleId = int64_t; +using LifecycleIdAtomic = uint64_t; void PROTOBUF_EXPORT ArenaFree(void* object, size_t size); @@ -328,20 +328,43 @@ class PROTOBUF_EXPORT ArenaImpl { ArenaMetricsCollector* metrics_collector; }; - struct ThreadCache { +#ifdef _MSC_VER +#pragma warning(disable:4324) +#endif + struct alignas(64) ThreadCache { #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) // If we are using the ThreadLocalStorage class to store the ThreadCache, // then the ThreadCache's default constructor has to be responsible for // initializing it. - ThreadCache() : last_lifecycle_id_seen(-1), last_serial_arena(NULL) {} + ThreadCache() + : next_lifecycle_id(0), + last_lifecycle_id_seen(-1), + last_serial_arena(NULL) {} #endif + // Number of per-thread lifecycle IDs to reserve. Must be power of two. + // To reduce contention on a global atomic, each thread reserves a batch of + // IDs. The following number is caluculated based on a stress test with + // ~6500 threads all frequently allocating a new arena. + static constexpr size_t kPerThreadIds = 256; + // Next lifecycle ID available to this thread. We need to reserve a new + // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`. + uint64 next_lifecycle_id; // The ThreadCache is considered valid as long as this matches the // lifecycle_id of the arena being used. - LifecycleId last_lifecycle_id_seen; + uint64 last_lifecycle_id_seen; SerialArena* last_serial_arena; }; - static std::atomic lifecycle_id_generator_; + // Lifecycle_id can be highly contended variable in a situation of lots of + // arena creation. Make sure that other global variables are not sharing the + // cacheline. +#ifdef _MSC_VER +#pragma warning(disable:4324) +#endif + struct alignas(64) CacheAlignedLifecycleIdGenerator { + std::atomic id; + }; + static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) // Android ndk does not support __thread keyword so we use a custom thread // local storage class we implemented. @@ -430,7 +453,7 @@ class PROTOBUF_EXPORT ArenaImpl { // Unique for each arena. Changes on Reset(). // Least-significant-bit is 1 iff allocations should be recorded. - LifecycleId lifecycle_id_; + uint64 lifecycle_id_; Options* options_ = nullptr; diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index e23459f7c290..60307b2763fa 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -87,22 +87,27 @@ class PROTOBUF_EXPORT LazyString { template class TaggedPtr { public: + TaggedPtr() = default; + explicit constexpr TaggedPtr(const std::string* ptr) + : ptr_(const_cast(ptr)) {} + void SetTagged(T* p) { Set(p); - ptr_ |= 1; + ptr_ = reinterpret_cast(as_int() | 1); } - void Set(T* p) { ptr_ = reinterpret_cast(p); } - T* Get() const { return reinterpret_cast(ptr_ & -2); } - bool IsTagged() const { return ptr_ & 1; } + void Set(T* p) { ptr_ = p; } + T* Get() const { return reinterpret_cast(as_int() & -2); } + bool IsTagged() const { return as_int() & 1; } // Returned value is only safe to dereference if IsTagged() == false. // It is safe to compare. - T* UnsafeGet() const { return reinterpret_cast(ptr_); } + T* UnsafeGet() const { return static_cast(ptr_); } - bool IsNull() { return ptr_ == 0; } + bool IsNull() { return ptr_ == nullptr; } private: - uintptr_t ptr_; + uintptr_t as_int() const { return reinterpret_cast(ptr_); } + void* ptr_; }; static_assert(std::is_trivial>::value, @@ -165,9 +170,9 @@ static_assert(std::is_trivial>::value, // single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also // requires the String tag to be 0 so we can avoid the mask before comparing.) struct PROTOBUF_EXPORT ArenaStringPtr { - // No default constructor or destructor -- we have to be POD because we go - // into a union when used in a oneof. Message code calls UnsafeReset() to zero - // the pointer when necessary instead. + ArenaStringPtr() = default; + explicit constexpr ArenaStringPtr(const std::string* default_value) + : tagged_ptr_(default_value) {} // Some methods below are overloaded on a `default_value` and on tags. // The tagged overloads help reduce code size in the callers in generated diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc index 07e7c650dd00..321b45140f3f 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -45,6 +45,9 @@ #include +// Must be included last. +#include + namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index f5d88e50224a..1987e0826884 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -123,7 +124,7 @@ class CommandLineInterfaceTest : public testing::Test { void SwitchToTempDirectory() { File::ChangeWorkingDirectory(temp_directory_); } -#else // !PROTOBUF_OPENSOURCE +#else // !PROTOBUF_OPENSOURCE // TODO(teboring): Figure out how to change and get working directory in // google3. #endif // !PROTOBUF_OPENSOURCE @@ -681,6 +682,9 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs_UnusedImport_DescriptorSetIn) { FileDescriptorProto::descriptor()->file(); descriptor_file->CopyTo(file_descriptor_set.add_file()); + FileDescriptorProto& any_proto = *file_descriptor_set.add_file(); + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + const FileDescriptor* custom_file = protobuf_unittest::AggregateMessage::descriptor()->file(); FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index 5b2f27669726..2d11f907bce0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -164,10 +164,6 @@ class FieldGenerator { return false; } - // Generate code that allocates the fields's default instance. - virtual void GenerateDefaultInstanceAllocator( - io::Printer* /*printer*/) const {} - // Generate lines to serialize this field directly to the array "target", // which are placed within the message's SerializeWithCachedSizesToArray() // method. This must also advance "target" past the written bytes. diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 1e3d2dad541e..875beec9f601 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -941,7 +941,6 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { continue; } - message_generators_[i]->GenerateFieldDefaultInstances(printer); format( "{\n" " void* ptr = &$1$;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index c6ab9ac5f9dc..7c17e456d0c8 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -1895,13 +1895,6 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { return num_field_metadata; } -void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) { - // Construct the default instances for all fields that need one. - for (auto field : FieldRange(descriptor_)) { - field_generators_.get(field).GenerateDefaultInstanceAllocator(printer); - } -} - void MessageGenerator::GenerateClassMethods(io::Printer* printer) { Formatter format(printer, variables_); if (IsMapEntryMessage(descriptor_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 0bc32b46c089..933386fbd5fc 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -82,9 +82,6 @@ class MessageGenerator { // Source file stuff. - // Generates code that creates default instances for fields. - void GenerateFieldDefaultInstances(io::Printer* printer); - // Generate all non-inline methods for this class. void GenerateClassMethods(io::Printer* printer); diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 2fc7aadff615..bb378b897c2b 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -390,6 +390,7 @@ void FileGenerator::Generate(io::Printer* printer) { printer->Print("}\n"); } + void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( io::Printer* printer) { printer->Print( diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h index bb3e4a576542..9f1f719237b0 100644 --- a/src/google/protobuf/compiler/java/java_file.h +++ b/src/google/protobuf/compiler/java/java_file.h @@ -78,6 +78,7 @@ class FileGenerator { void Generate(io::Printer* printer); + // If we aren't putting everything into one file, this will write all the // files other than the outer file (i.e. one for each message, enum, and // service type). diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc index d998f166a3ef..bc13dd8733c3 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -160,7 +160,14 @@ std::string ClassNameResolver::GetFileImmutableClassName( std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, bool immutable) { - if (immutable) { + return GetFileClassName(file, immutable, false); +} + +std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, + bool immutable, bool kotlin) { + if (kotlin) { + return GetFileImmutableClassName(file) + "Kt"; + } else if (immutable) { return GetFileImmutableClassName(file); } else { return "Mutable" + GetFileImmutableClassName(file); @@ -200,9 +207,14 @@ std::string ClassNameResolver::GetDescriptorClassName( std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, + bool immutable, bool kotlin) { std::string result = FileJavaPackage(descriptor, immutable); if (!result.empty()) result += '.'; - result += GetFileClassName(descriptor, immutable); + result += GetFileClassName(descriptor, immutable, kotlin); return result; } @@ -211,50 +223,79 @@ std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, std::string ClassNameResolver::GetClassFullName( const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file) { + return GetClassFullName(name_without_package, file, immutable, is_own_file, + false); +} + +std::string ClassNameResolver::GetClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool is_own_file, bool kotlin) { std::string result; if (is_own_file) { result = FileJavaPackage(file, immutable); } else { - result = GetClassName(file, immutable); + result = GetClassName(file, immutable, kotlin); } if (!result.empty()) { result += '.'; } result += name_without_package; + if (kotlin) result += "Kt"; return result; } std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, bool immutable) { - return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), - descriptor->file(), immutable, - MultipleJavaFiles(descriptor->file(), immutable)); + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); } std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, bool immutable) { - return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), - descriptor->file(), immutable, - MultipleJavaFiles(descriptor->file(), immutable)); + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); } std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, + bool immutable, bool kotlin) { return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), immutable, - IsOwnFile(descriptor, immutable)); + IsOwnFile(descriptor, immutable), kotlin); } // Get the Java Class style full name of a message. std::string ClassNameResolver::GetJavaClassFullName( const std::string& name_without_package, const FileDescriptor* file, bool immutable) { + return GetJavaClassFullName(name_without_package, file, immutable, false); +} + +std::string ClassNameResolver::GetJavaClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool kotlin) { std::string result; if (MultipleJavaFiles(file, immutable)) { result = FileJavaPackage(file, immutable); if (!result.empty()) result += '.'; } else { - result = GetClassName(file, immutable); + result = GetClassName(file, immutable, kotlin); if (!result.empty()) result += '$'; } result += StringReplace(name_without_package, ".", "$", true); @@ -263,7 +304,12 @@ std::string ClassNameResolver::GetJavaClassFullName( std::string ClassNameResolver::GetExtensionIdentifierName( const FieldDescriptor* descriptor, bool immutable) { - return GetClassName(descriptor->containing_type(), immutable) + "." + + return GetExtensionIdentifierName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetExtensionIdentifierName( + const FieldDescriptor* descriptor, bool immutable, bool kotlin) { + return GetClassName(descriptor->containing_type(), immutable, kotlin) + "." + descriptor->name(); } diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h index b92570c60010..8461df900975 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.h +++ b/src/google/protobuf/compiler/java/java_name_resolver.h @@ -60,6 +60,8 @@ class ClassNameResolver { // Gets the unqualified outer class name for the file. std::string GetFileClassName(const FileDescriptor* file, bool immutable); + std::string GetFileClassName(const FileDescriptor* file, bool immutable, + bool kotlin); // Gets the unqualified immutable outer class name of a file. std::string GetFileImmutableClassName(const FileDescriptor* file); // Gets the unqualified default immutable outer class name of a file @@ -80,9 +82,17 @@ class ClassNameResolver { // Gets the fully-qualified class name corresponding to the given descriptor. std::string GetClassName(const Descriptor* descriptor, bool immutable); + std::string GetClassName(const Descriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const EnumDescriptor* descriptor, bool immutable); + std::string GetClassName(const EnumDescriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable); + std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const FileDescriptor* descriptor, bool immutable); + std::string GetClassName(const FileDescriptor* descriptor, bool immutable, + bool kotlin); template std::string GetImmutableClassName(const DescriptorType* descriptor) { @@ -96,6 +106,8 @@ class ClassNameResolver { // Gets the fully qualified name of an extension identifier. std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, bool immutable); + std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, + bool immutable, bool kotlin); // Gets the fully qualified name for generated classes in Java convention. // Nested classes will be separated using '$' instead of '.' @@ -109,9 +121,15 @@ class ClassNameResolver { std::string GetClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file); + std::string GetClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool is_own_file, bool kotlin); // Get the Java Class style full name of a message. std::string GetJavaClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable); + std::string GetJavaClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool kotlin); // Caches the result to provide better performance. std::map file_immutable_outer_class_names_; diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index a702ca949531..895b47dee65d 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -65,6 +65,7 @@ int ProtobufMain(int argc, char* argv[]) { "Generate Java source file."); + // Proto2 Python python::Generator py_generator; cli.RegisterGenerator("--python_out", "--python_opt", &py_generator, diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 4a3a228e89cc..cbb24a50a58c 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -2276,6 +2277,11 @@ TEST_F(ParseDescriptorDebugTest, TestCustomOptions) { FileDescriptorProto import_proto; import->CopyTo(&import_proto); ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + + FileDescriptorProto any_import; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_import); + ASSERT_TRUE(pool_.BuildFile(any_import) != nullptr); + const FileDescriptor* actual = pool_.BuildFile(parsed); ASSERT_TRUE(actual != NULL); parsed.Clear(); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index d1d0828b583b..179df8f5dd7c 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -254,14 +255,14 @@ std::string ToCamelCase(const std::string& input, bool lower_first) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { capitalize_next = true; } else if (capitalize_next) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); capitalize_next = false; } else { - result.push_back(input[i]); + result.push_back(character); } } @@ -278,14 +279,14 @@ std::string ToJsonName(const std::string& input) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { capitalize_next = true; } else if (capitalize_next) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); capitalize_next = false; } else { - result.push_back(input[i]); + result.push_back(character); } } @@ -297,14 +298,14 @@ std::string EnumValueToPascalCase(const std::string& input) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { next_upper = true; } else { if (next_upper) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); } else { - result.push_back(ToLower(input[i])); + result.push_back(ToLower(character)); } next_upper = false; } @@ -318,9 +319,9 @@ class PrefixRemover { public: PrefixRemover(StringPiece prefix) { // Strip underscores and lower-case the prefix. - for (int i = 0; i < prefix.size(); i++) { - if (prefix[i] != '_') { - prefix_ += ascii_tolower(prefix[i]); + for (char character : prefix) { + if (character != '_') { + prefix_ += ascii_tolower(character); } } } @@ -471,16 +472,15 @@ std::set* NewAllowedProto3Extendee() { const char* kOptionNames[] = { "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions", "EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"}; - for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) { + for (const char* option_name : kOptionNames) { // descriptor.proto has a different package name in opensource. We allow // both so the opensource protocol compiler can also compile internal // proto3 files with custom options. See: b/27567912 allowed_proto3_extendees->insert(std::string("google.protobuf.") + - kOptionNames[i]); + option_name); // Split the word to trick the opensource processing scripts so they // will keep the original package name. - allowed_proto3_extendees->insert(std::string("proto") + "2." + - kOptionNames[i]); + allowed_proto3_extendees->insert(std::string("proto") + "2." + option_name); } return allowed_proto3_extendees; } @@ -1571,8 +1571,7 @@ void DescriptorPool::FindAllExtensions( std::vector numbers; if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), &numbers)) { - for (int i = 0; i < numbers.size(); ++i) { - int number = numbers[i]; + for (int number : numbers) { if (tables_->FindExtension(extendee, number) == nullptr) { TryFindExtensionInFallbackDatabase(extendee, number); } @@ -2279,34 +2278,34 @@ bool RetrieveOptionsAssumingRightPool( const Reflection* reflection = options.GetReflection(); std::vector fields; reflection->ListFields(options, &fields); - for (int i = 0; i < fields.size(); i++) { + for (const FieldDescriptor* field : fields) { int count = 1; bool repeated = false; - if (fields[i]->is_repeated()) { - count = reflection->FieldSize(options, fields[i]); + if (field->is_repeated()) { + count = reflection->FieldSize(options, field); repeated = true; } for (int j = 0; j < count; j++) { std::string fieldval; - if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { std::string tmp; TextFormat::Printer printer; printer.SetInitialIndentLevel(depth + 1); - printer.PrintFieldValueToString(options, fields[i], repeated ? j : -1, + printer.PrintFieldValueToString(options, field, repeated ? j : -1, &tmp); fieldval.append("{\n"); fieldval.append(tmp); fieldval.append(depth * 2, ' '); fieldval.append("}"); } else { - TextFormat::PrintFieldValueToString(options, fields[i], - repeated ? j : -1, &fieldval); + TextFormat::PrintFieldValueToString(options, field, repeated ? j : -1, + &fieldval); } std::string name; - if (fields[i]->is_extension()) { - name = "(." + fields[i]->full_name() + ")"; + if (field->is_extension()) { + name = "(." + field->full_name() + ")"; } else { - name = fields[i]->name(); + name = field->name(); } option_entries->push_back(name + " = " + fieldval); } @@ -2363,9 +2362,8 @@ bool FormatLineOptions(int depth, const Message& options, std::string prefix(depth * 2, ' '); std::vector all_options; if (RetrieveOptions(depth, options, pool, &all_options)) { - for (int i = 0; i < all_options.size(); i++) { - strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, - all_options[i]); + for (const std::string& option : all_options) { + strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, option); } } return !all_options.empty(); @@ -2395,8 +2393,9 @@ class SourceLocationCommentPrinter { void AddPreComment(std::string* output) { if (have_source_loc_) { // Detached leading comments. - for (int i = 0; i < source_loc_.leading_detached_comments.size(); ++i) { - *output += FormatComment(source_loc_.leading_detached_comments[i]); + for (const std::string& leading_detached_comment : + source_loc_.leading_detached_comments) { + *output += FormatComment(leading_detached_comment); *output += "\n"; } // Attached leading comments. @@ -2418,8 +2417,7 @@ class SourceLocationCommentPrinter { StripWhitespace(&stripped_comment); std::vector lines = Split(stripped_comment, "\n"); std::string output; - for (int i = 0; i < lines.size(); ++i) { - const std::string& line = lines[i]; + for (const std::string& line : lines) { strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line); } return output; @@ -3866,13 +3864,13 @@ Symbol DescriptorBuilder::LookupSymbol( static bool ValidateQualifiedName(StringPiece name) { bool last_was_period = false; - for (int i = 0; i < name.size(); i++) { + for (char character : name) { // I don't trust isalnum() due to locales. :( - if (('a' <= name[i] && name[i] <= 'z') || - ('A' <= name[i] && name[i] <= 'Z') || - ('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) { + if (('a' <= character && character <= 'z') || + ('A' <= character && character <= 'Z') || + ('0' <= character && character <= '9') || (character == '_')) { last_was_period = false; - } else if (name[i] == '.') { + } else if (character == '.') { if (last_was_period) return false; last_was_period = true; } else { @@ -4096,11 +4094,11 @@ void DescriptorBuilder::ValidateSymbolName(const std::string& name, AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "Missing name."); } else { - for (int i = 0; i < name.size(); i++) { + for (char character : name) { // I don't trust isalnum() due to locales. :( - if ((name[i] < 'a' || 'z' < name[i]) && - (name[i] < 'A' || 'Z' < name[i]) && - (name[i] < '0' || '9' < name[i]) && (name[i] != '_')) { + if ((character < 'a' || 'z' < character) && + (character < 'A' || 'Z' < character) && + (character < '0' || '9' < character) && (character != '_')) { AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "\"" + name + "\" is not a valid identifier."); } @@ -5945,12 +5943,12 @@ void DescriptorBuilder::ValidateProto3(FileDescriptor* file, static std::string ToLowercaseWithoutUnderscores(const std::string& name) { std::string result; - for (int i = 0; i < name.size(); ++i) { - if (name[i] != '_') { - if (name[i] >= 'A' && name[i] <= 'Z') { - result.push_back(name[i] - 'A' + 'a'); + for (char character : name) { + if (character != '_') { + if (character >= 'A' && character <= 'Z') { + result.push_back(character - 'A' + 'a'); } else { - result.push_back(name[i]); + result.push_back(character); } } } @@ -7067,6 +7065,18 @@ class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder public: DescriptorBuilder* builder_; + const Descriptor* FindAnyType(const Message& message, + const std::string& prefix, + const std::string& name) const override { + if (prefix != internal::kTypeGoogleApisComPrefix && + prefix != internal::kTypeGoogleProdComPrefix) { + return nullptr; + } + assert_mutex_held(builder_->pool_); + Symbol result = builder_->FindSymbol(name); + return result.type == Symbol::MESSAGE ? result.descriptor : nullptr; + } + const FieldDescriptor* FindExtension(Message* message, const std::string& name) const override { assert_mutex_held(builder_->pool_); diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index 2707ed4b580a..92f27320330a 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -552,11 +552,9 @@ class EncodedDescriptorDatabase::DescriptorIndex { bool EncodedDescriptorDatabase::Add(const void* encoded_file_descriptor, int size) { - google::protobuf::Arena arena; - auto* file = google::protobuf::Arena::CreateMessage(&arena); - if (file->ParseFromArray(encoded_file_descriptor, size)) { - return index_->AddFile(*file, - std::make_pair(encoded_file_descriptor, size)); + FileDescriptorProto file; + if (file.ParseFromArray(encoded_file_descriptor, size)) { + return index_->AddFile(file, std::make_pair(encoded_file_descriptor, size)); } else { GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to " "EncodedDescriptorDatabase::Add()."; @@ -933,8 +931,8 @@ bool DescriptorPoolDatabase::FindAllExtensionNumbers( std::vector extensions; pool_.FindAllExtensions(extendee, &extensions); - for (int i = 0; i < extensions.size(); ++i) { - output->push_back(extensions[i]->number()); + for (const FieldDescriptor* extension : extensions) { + output->push_back(extension->number()); } return true; @@ -954,8 +952,8 @@ MergedDescriptorDatabase::~MergedDescriptorDatabase() {} bool MergedDescriptorDatabase::FindFileByName(const std::string& filename, FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileByName(filename, output)) { + for (DescriptorDatabase* source : sources_) { + if (source->FindFileByName(filename, output)) { return true; } } @@ -1012,8 +1010,8 @@ bool MergedDescriptorDatabase::FindAllExtensionNumbers( std::vector results; bool success = false; - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) { + for (DescriptorDatabase* source : sources_) { + if (source->FindAllExtensionNumbers(extendee_type, &results)) { std::copy(results.begin(), results.end(), std::insert_iterator >(merged_results, merged_results.begin())); diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 278b07f9f27f..331a0c5b6fab 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -287,9 +288,8 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector { break; } - strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", - filename, element_name, location_name, - message); + strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename, + element_name, location_name, message); } }; @@ -3148,6 +3148,11 @@ TEST(CustomOptions, OptionsFromOtherFile) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + // We have to import the Any dependency. + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3206,6 +3211,10 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3283,6 +3292,10 @@ TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3363,6 +3376,10 @@ TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3463,6 +3480,10 @@ TEST(CustomOptions, AggregateOptions) { message_set_extension) .s()); + protobuf_unittest::AggregateMessageSetElement any_payload; + ASSERT_TRUE(file_options.any().UnpackTo(&any_payload)); + EXPECT_EQ("EmbeddedMessageSetElement", any_payload.s()); + // Simple tests for all the other types of annotations EXPECT_EQ("MessageAnnotation", msg->options().GetExtension(protobuf_unittest::msgopt).s()); @@ -3485,6 +3506,10 @@ TEST(CustomOptions, UnusedImportError) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -7182,8 +7207,8 @@ class SourceLocationTest : public testing::Test { static std::string PrintSourceLocation(const SourceLocation& loc) { return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line, - 1 + loc.start_column, 1 + loc.end_line, - 1 + loc.end_column); + 1 + loc.start_column, 1 + loc.end_line, + 1 + loc.end_column); } private: diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 0dcabb0f4766..bfa1c42a88ad 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -192,14 +192,6 @@ ExtensionSet::ExtensionSet(Arena* arena) ? NULL : Arena::CreateArray(arena_, flat_capacity_)} {} -ExtensionSet::ExtensionSet() - : arena_(NULL), - flat_capacity_(0), - flat_size_(0), - map_{flat_capacity_ == 0 - ? NULL - : Arena::CreateArray(arena_, flat_capacity_)} {} - ExtensionSet::~ExtensionSet() { // Deletes all allocated extensions. if (arena_ == NULL) { diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index b30a9608af5b..b3a6e3a07b5e 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -173,7 +173,7 @@ class MessageSetFieldSkipper; // off to the ExtensionSet for parsing. Etc. class PROTOBUF_EXPORT ExtensionSet { public: - ExtensionSet(); + constexpr ExtensionSet(); explicit ExtensionSet(Arena* arena); ~ExtensionSet(); @@ -850,6 +850,9 @@ class PROTOBUF_EXPORT ExtensionSet { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); }; +constexpr ExtensionSet::ExtensionSet() + : arena_(nullptr), flat_capacity_(0), flat_size_(0), map_{nullptr} {} + // These are just for convenience... inline void ExtensionSet::SetString(int number, FieldType type, std::string value, diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index 3e6ecefe01c9..2c299c15cafc 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -46,13 +46,15 @@ #include #include #include - #include #include #include #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -1324,6 +1326,11 @@ TEST(ExtensionSetTest, BoolExtension) { EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension)); } +TEST(ExtensionSetTest, ConstInit) { + PROTOBUF_CONSTINIT static ExtensionSet set{}; + EXPECT_EQ(set.NumExtensions(), 0); +} + } // namespace } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 3ff93152771f..e8b19c862b6d 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -1065,6 +1065,7 @@ void Reflection::ListFieldsMayFailOnStripped( output->push_back(field); } } else if (has_bits && has_bits_indices[i] != -1) { + CheckInvalidAccess(schema_, field); // Equivalent to: HasBit(message, field) if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) { output->push_back(field); diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index aaeadc78cacf..f1f6f88332c7 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -68,16 +68,25 @@ void DestroyString(const void* s) { static_cast(s)->~basic_string(); } -ExplicitlyConstructed fixed_address_empty_string; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EmptyString + fixed_address_empty_string; // NOLINT +PROTOBUF_CONSTINIT std::atomic init_protobuf_defaults_state{false}; static bool InitProtobufDefaultsImpl() { - fixed_address_empty_string.DefaultConstruct(); - OnShutdownDestroyString(fixed_address_empty_string.get_mutable()); + ::new (static_cast(&fixed_address_empty_string.value)) std::string(); + OnShutdownDestroyString(&fixed_address_empty_string.value); + + // Verify that we can indeed get the address during constant evaluation. + PROTOBUF_CONSTINIT static const std::string& fixed_address_empty_string_test = + GetEmptyStringAlreadyInited(); + (void)fixed_address_empty_string_test; + + init_protobuf_defaults_state.store(true, std::memory_order_release); return true; } -void InitProtobufDefaults() { +void InitProtobufDefaultsSlow() { static bool is_inited = InitProtobufDefaultsImpl(); (void)is_inited; } diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 7cae4e126654..bae0c1f760a4 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -85,7 +85,17 @@ inline To DownCast(From& f) { } -PROTOBUF_EXPORT void InitProtobufDefaults(); +// This fastpath inlines a single branch instead of having to make the +// InitProtobufDefaults function call. +// It also generates less inlined code than a function-scope static initializer. +PROTOBUF_EXPORT extern std::atomic init_protobuf_defaults_state; +PROTOBUF_EXPORT void InitProtobufDefaultsSlow(); +PROTOBUF_EXPORT inline void InitProtobufDefaults() { + if (PROTOBUF_PREDICT_FALSE( + !init_protobuf_defaults_state.load(std::memory_order_acquire))) { + InitProtobufDefaultsSlow(); + } +} // This used by proto1 PROTOBUF_EXPORT inline const std::string& GetEmptyString() { diff --git a/src/google/protobuf/has_bits.h b/src/google/protobuf/has_bits.h index 540cac282f02..1144b9f4618c 100644 --- a/src/google/protobuf/has_bits.h +++ b/src/google/protobuf/has_bits.h @@ -47,7 +47,7 @@ namespace internal { template class HasBits { public: - HasBits() PROTOBUF_ALWAYS_INLINE { Clear(); } + constexpr HasBits() PROTOBUF_ALWAYS_INLINE : has_bits_{} {} void Clear() PROTOBUF_ALWAYS_INLINE { memset(has_bits_, 0, sizeof(has_bits_)); diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h index ec028eb5cd83..bfa6a813b3a6 100644 --- a/src/google/protobuf/implicit_weak_message.h +++ b/src/google/protobuf/implicit_weak_message.h @@ -129,7 +129,7 @@ class ImplicitWeakTypeHandler { template struct WeakRepeatedPtrField { using TypeHandler = internal::ImplicitWeakTypeHandler; - WeakRepeatedPtrField() : weak() {} + constexpr WeakRepeatedPtrField() : weak() {} explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {} ~WeakRepeatedPtrField() { weak.template Destroy(); } diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 29c370c24cbe..390455e8d893 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -105,8 +105,8 @@ class MapAllocator { using size_type = size_t; using difference_type = ptrdiff_t; - MapAllocator() : arena_(nullptr) {} - explicit MapAllocator(Arena* arena) : arena_(arena) {} + constexpr MapAllocator() : arena_(nullptr) {} + explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {} template MapAllocator(const MapAllocator& allocator) // NOLINT(runtime/explicit) : arena_(allocator.arena()) {} @@ -382,7 +382,7 @@ class Map { using size_type = size_t; using hasher = typename internal::TransparentSupport::hash; - Map() : elements_(nullptr) {} + constexpr Map() : elements_(nullptr) {} explicit Map(Arena* arena) : elements_(arena) {} Map(const Map& other) : Map() { insert(other.begin(), other.end()); } @@ -450,11 +450,11 @@ class Map { // otherwise. This avoids unnecessary copies of string keys, for example. class InnerMap : private hasher { public: - explicit InnerMap(Arena* arena) + explicit constexpr InnerMap(Arena* arena) : hasher(), num_elements_(0), num_buckets_(internal::kGlobalEmptyTableSize), - seed_(Seed()), + seed_(0), index_of_first_non_null_(num_buckets_), table_(const_cast(internal::kGlobalEmptyTable)), alloc_(arena) {} @@ -919,6 +919,7 @@ class Map { // Just overwrite with a new one. No need to transfer or free anything. num_buckets_ = index_of_first_non_null_ = kMinTableSize; table_ = CreateEmptyTable(num_buckets_); + seed_ = Seed(); return; } diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 180ff0e70a9d..9e35795f9b53 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -93,7 +93,7 @@ template { public: - MapEntry() : _internal_metadata_(NULL) {} + constexpr MapEntry() : _internal_metadata_() {} explicit MapEntry(Arena* arena) : MapEntryImpl(arena), diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 92cb4ac4d1e2..1caf59dfedc5 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -182,17 +182,16 @@ class MapEntryImpl : public Base { static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType; static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType; - MapEntryImpl() { - KeyTypeHandler::Initialize(&key_, NULL); - ValueTypeHandler::Initialize(&value_, NULL); - _has_bits_[0] = 0; - } + constexpr MapEntryImpl() + : key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} - explicit MapEntryImpl(Arena* arena) : Base(arena) { - KeyTypeHandler::Initialize(&key_, arena); - ValueTypeHandler::Initialize(&value_, arena); - _has_bits_[0] = 0; - } + explicit MapEntryImpl(Arena* arena) + : Base(arena), + key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} ~MapEntryImpl() { if (Base::GetArena() != NULL) return; @@ -523,7 +522,7 @@ class MapEntryLite : public MapEntryImpl SuperType; - MapEntryLite() {} + constexpr MapEntryLite() {} explicit MapEntryLite(Arena* arena) : SuperType(arena) {} ~MapEntryLite() { MessageLite::_internal_metadata_.Delete(); } void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); } diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index f4e034cd3d08..9fbd06ade976 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -324,6 +324,16 @@ class PROTOBUF_EXPORT MapFieldBase { public: MapFieldBase() : arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + // Except in MSVC, where we can't have a constinit mutex. + explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized) + : arena_(nullptr), + repeated_field_(nullptr), + mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED), + state_(STATE_MODIFIED_MAP) {} explicit MapFieldBase(Arena* arena) : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) { // Mutex's destructor needs to be called explicitly to release resources @@ -466,6 +476,12 @@ template class TypeDefinedMapFieldBase : public MapFieldBase { public: TypeDefinedMapFieldBase() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag) + : MapFieldBase(tag) {} explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {} ~TypeDefinedMapFieldBase() override {} void MapBegin(MapIterator* map_iter) const override; @@ -521,6 +537,12 @@ class MapField : public TypeDefinedMapFieldBase { typedef Map MapType; MapField() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr MapField(ConstantInitialized tag) + : TypeDefinedMapFieldBase(tag), impl_() {} explicit MapField(Arena* arena) : TypeDefinedMapFieldBase(arena), impl_(arena) {} diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index a47b87710ac5..665cb0eebe87 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h @@ -63,7 +63,7 @@ class MapFieldLite { typedef Map MapType; typedef EntryType EntryTypeTrait; - MapFieldLite() {} + constexpr MapFieldLite() {} explicit MapFieldLite(Arena* arena) : map_(arena) {} diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 39544a3d24b3..f6274c0da32a 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -45,6 +45,9 @@ #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -478,6 +481,22 @@ TEST_P(MapFieldStateTest, MutableMapField) { } } +class MyMapField + : public MapField { + public: + constexpr MyMapField() + : MyMapField::MapField(internal::ConstantInitialized{}) {} +}; + +TEST(MapFieldTest, ConstInit) { + // This tests that `MapField` and all its base classes can be constant + // initialized. + PROTOBUF_CONSTINIT static MyMapField field; // NOLINT + EXPECT_EQ(field.size(), 0); +} + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index f2a5b93b8b3a..9c53b510f487 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -80,6 +80,7 @@ #include +// Must be included last. #include namespace google { @@ -1180,6 +1181,11 @@ TEST_F(MapImplTest, TransparentLookupForString) { TestTransparent(std::cref(abc), std::cref(lkj)); } +TEST_F(MapImplTest, ConstInit) { + PROTOBUF_CONSTINIT static Map map; // NOLINT + EXPECT_TRUE(map.empty()); +} + // Map Field Reflection Test ======================================== static int Func(int i, int j) { return i * j; } @@ -2047,6 +2053,39 @@ TEST_F(MapFieldReflectionTest, UninitializedEntry) { EXPECT_FALSE(message.IsInitialized()); } +class MyMapEntry + : public internal::MapEntry { + public: + constexpr MyMapEntry() {} + MyMapEntry(Arena*) { std::abort(); } + Metadata GetMetadata() const override { std::abort(); } + static bool ValidateKey(void*) { return true; } + static bool ValidateValue(void*) { return true; } +}; + +class MyMapEntryLite + : public internal::MapEntryLite { + public: + constexpr MyMapEntryLite() {} + explicit MyMapEntryLite(Arena*) { std::abort(); } + static bool ValidateKey(void*) { return true; } + static bool ValidateValue(void*) { return true; } +}; + +TEST(MapEntryTest, ConstInit) { + // This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be + // constant initialized. + PROTOBUF_CONSTINIT static MyMapEntry entry{}; + EXPECT_NE(entry.SpaceUsed(), 0); + + PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{}; // NOLINT + EXPECT_TRUE(entry_lite.IsInitialized()); +} + // Generated Message Test =========================================== TEST(GeneratedMapFieldTest, Accessors) { diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index 9c1a5940e69c..8b8fd14c2d49 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -157,7 +157,7 @@ class MapTypeHandler { static inline void DeleteNoArena(const Type* x); static inline void Merge(const Type& from, Type** to, Arena* arena); static inline void Clear(Type** value, Arena* arena); - static inline void Initialize(Type** x, Arena* arena); + static constexpr TypeOnMemory Constinit(); static inline Type* EnsureMutable(Type** value, Arena* arena); // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding @@ -207,7 +207,7 @@ class MapTypeHandler { const TypeOnMemory& value); \ static inline bool IsInitialized(const TypeOnMemory& value); \ static void DeleteNoArena(TypeOnMemory& value); \ - static inline void Initialize(TypeOnMemory* value, Arena* arena); \ + static constexpr TypeOnMemory Constinit(); \ static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ Arena* arena); \ }; @@ -522,9 +522,9 @@ void MapTypeHandler::DeleteNoArena( } template -inline void MapTypeHandler::Initialize( - Type** x, Arena* /* arena */) { - *x = NULL; +constexpr auto MapTypeHandler::Constinit() + -> TypeOnMemory { + return nullptr; } template @@ -583,10 +583,10 @@ inline bool MapTypeHandler::IsInitialized( value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited()); \ } \ template \ - inline void \ - MapTypeHandler::Initialize( \ - TypeOnMemory* value, Arena* /* arena */) { \ - value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited()); \ + constexpr auto \ + MapTypeHandler::Constinit() \ + ->TypeOnMemory { \ + return TypeOnMemory(&internal::GetEmptyStringAlreadyInited()); \ } \ template \ inline typename MapTypeHandler::DeleteNoArena(TypeOnMemory& /* x */) {} \ template \ - inline void \ - MapTypeHandler::Initialize( \ - TypeOnMemory* value, Arena* /* arena */) { \ - *value = 0; \ + constexpr auto \ + MapTypeHandler::Constinit() \ + ->TypeOnMemory { \ + return 0; \ } \ template \ inline typename MapTypeHandlerSpaceUsedLong(*this); } -size_t Message::GetInvariantPerBuild(size_t salt) { +uint64 Message::GetInvariantPerBuild(uint64 salt) { return salt; } diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 8f5fef122089..4e7ac9d06200 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -231,7 +231,7 @@ bool CreateUnknownEnumValues(const FieldDescriptor* field); // the internal library are allowed to create subclasses. class PROTOBUF_EXPORT Message : public MessageLite { public: - inline Message() {} + constexpr Message() = default; // Basic Operations ------------------------------------------------ @@ -367,7 +367,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { protected: - static size_t GetInvariantPerBuild(size_t salt); + static uint64 GetInvariantPerBuild(uint64 salt); private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 1cce5d9b085a..a76c16e5a492 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -74,6 +74,12 @@ class ZeroCopyOutputStream; } // namespace io namespace internal { +// Tag type used to invoke the constinit constructor overload of some classes. +// Such constructors are internal implementation details of the library. +struct ConstantInitialized { + explicit ConstantInitialized() = default; +}; + // See parse_context.h for explanation class ParseContext; @@ -145,14 +151,27 @@ class ExplicitlyConstructed { } union_; }; +PROTOBUF_DISABLE_MSVC_UNION_WARNING +// We need a publicly accessible `value` object to allow constexpr +// support in C++11. +// A constexpr accessor does not work portably. +union EmptyString { + constexpr EmptyString() : dummy{} {} + ~EmptyString() {} + + // We need a dummy object for constant initialization. + std::false_type dummy; + std::string value; +}; +PROTOBUF_ENABLE_MSVC_UNION_WARNING + // Default empty string object. Don't use this directly. Instead, call // GetEmptyString() to get the reference. -PROTOBUF_EXPORT extern ExplicitlyConstructed - fixed_address_empty_string; +PROTOBUF_EXPORT extern EmptyString fixed_address_empty_string; -PROTOBUF_EXPORT inline const std::string& GetEmptyStringAlreadyInited() { - return fixed_address_empty_string.get(); +PROTOBUF_EXPORT constexpr const std::string& GetEmptyStringAlreadyInited() { + return fixed_address_empty_string.value; } PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str); @@ -187,7 +206,7 @@ PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str); // the internal library are allowed to create subclasses. class PROTOBUF_EXPORT MessageLite { public: - inline MessageLite() {} + constexpr MessageLite() = default; virtual ~MessageLite() = default; // Basic Operations ------------------------------------------------ diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h index 781a1f54e7ce..ec5f92389074 100644 --- a/src/google/protobuf/metadata_lite.h +++ b/src/google/protobuf/metadata_lite.h @@ -58,7 +58,7 @@ namespace internal { // pointer. class InternalMetadata { public: - InternalMetadata() : ptr_(nullptr) {} + constexpr InternalMetadata() : ptr_(nullptr) {} explicit InternalMetadata(Arena* arena) : ptr_(arena) {} template diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index d879a863b08d..8b39d698962a 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -139,6 +139,21 @@ #ifdef PROTOBUF_FINAL #error PROTOBUF_FINAL was previously defined #endif +#ifdef PROTOBUF_DISABLE_MSVC_UNION_WARNING +#error PROTOBUF_DISABLE_MSVC_UNION_WARNING was previously defined +#endif +#ifdef PROTOBUF_ENABLE_MSVC_UNION_WARNING +#error PROTOBUF_ENABLE_MSVC_UNION_WARNING was previously defined +#endif +#ifdef PROTOBUF_CONSTINIT +#error PROTOBUF_CONSTINIT was previously defined +#endif +#ifdef PROTOBUF_MAYBE_CONSTEXPR +#error PROTOBUF_MAYBE_CONSTEXPR was previously defined +#endif +#ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY +#error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined +#endif #define PROTOBUF_NAMESPACE "google::protobuf" @@ -428,6 +443,10 @@ #undef min #pragma push_macro("max") #undef max +#pragma push_macro("NEAR") +#undef NEAR +#pragma push_macro("NO_DATA") +#undef NO_DATA #pragma push_macro("REASON_UNKNOWN") #undef REASON_UNKNOWN #pragma push_macro("SERVICE_DISABLED") @@ -443,10 +462,6 @@ #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) // Don't let Objective-C Macros interfere with proto identifiers with the same // name. -#pragma push_macro("YES") -#undef YES -#pragma push_macro("NO") -#undef NO #pragma push_macro("DEBUG") #undef DEBUG #pragma push_macro("TRUE") @@ -533,3 +548,59 @@ // This experiment is purely for the purpose of gathering data. All code guarded // by this flag is supposed to be removed after this experiment. // #define PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT + +#if defined(__cpp_constinit) +#define PROTOBUF_CONSTINIT constinit +#elif defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::require_constant_initialization) +#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] +#endif +#endif +#ifndef PROTOBUF_CONSTINIT +#define PROTOBUF_CONSTINIT +#endif + +// Some constructors can't be constexpr under MSVC, but given that MSVC will not +// do constant initialization of globals anyway we can omit `constexpr` from +// them. These constructors are marked with PROTOBUF_MAYBE_CONSTEXPR +#if defined(_MSC_VER) +#define PROTOBUF_MAYBE_CONSTEXPR +#else +#define PROTOBUF_MAYBE_CONSTEXPR constexpr +#endif + +#if _MSC_VER +#define PROTOBUF_DISABLE_MSVC_UNION_WARNING \ + __pragma(warning(push)) \ + __pragma(warning(disable : 4582)) \ + __pragma(warning(disable : 4583)) + +#define PROTOBUF_ENABLE_MSVC_UNION_WARNING \ + __pragma(warning(pop)) +#else +#define PROTOBUF_DISABLE_MSVC_UNION_WARNING +#define PROTOBUF_ENABLE_MSVC_UNION_WARNING +#endif + +#if defined(__cpp_constinit) +#define PROTOBUF_CONSTINIT constinit +#elif defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::require_constant_initialization) +#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] +#endif +#endif +#ifndef PROTOBUF_CONSTINIT +#define PROTOBUF_CONSTINIT +#endif + +// Some globals with an empty non-trivial destructor are annotated with +// no_destroy for performance reasons. It reduces the cost of these globals in +// non-opt mode and under sanitizers. +#if defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::no_destroy) +#define PROTOBUF_ATTRIBUTE_NO_DESTROY [[clang::no_destroy]] +#endif +#endif +#if !defined(PROTOBUF_ATTRIBUTE_NO_DESTROY) +#define PROTOBUF_ATTRIBUTE_NO_DESTROY +#endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index fd080a4875a5..d1414285e4fc 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -72,6 +72,11 @@ #undef PROTOBUF_FINAL #undef PROTOBUF_THREAD_LOCAL #undef PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT +#undef PROTOBUF_DISABLE_MSVC_UNION_WARNING +#undef PROTOBUF_ENABLE_MSVC_UNION_WARNING +#undef PROTOBUF_CONSTINIT +#undef PROTOBUF_MAYBE_CONSTEXPR +#undef PROTOBUF_ATTRIBUTE_NO_DESTROY // Restore macro that may have been #undef'd in port_def.inc. #ifdef _MSC_VER @@ -88,6 +93,8 @@ #pragma pop_macro("OPTIONAL") #pragma pop_macro("min") #pragma pop_macro("max") +#pragma pop_macro("NEAR") +#pragma pop_macro("NO_DATA") #pragma pop_macro("NO_ERROR") #pragma pop_macro("REASON_UNKNOWN") #pragma pop_macro("SERVICE_DISABLED") @@ -97,8 +104,6 @@ #endif #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) -#pragma pop_macro("YES") -#pragma pop_macro("NO") #pragma pop_macro("DEBUG") #pragma pop_macro("TRUE") #pragma pop_macro("FALSE") diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index c913ea0d1999..29fc5dbaaf45 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -85,9 +85,7 @@ void ReflectionOps::Merge(const Message& from, Message* to) { std::vector fields; from_reflection->ListFieldsOmitStripped(from, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - + for (const FieldDescriptor* field : fields) { if (field->is_repeated()) { // Use map reflection if both are in map status and have the // same map type to avoid sync with repeated field. @@ -180,8 +178,8 @@ void ReflectionOps::Clear(Message* message) { std::vector fields; reflection->ListFieldsOmitStripped(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - reflection->ClearField(message, fields[i]); + for (const FieldDescriptor* field : fields) { + reflection->ClearField(message, field); } reflection->MutableUnknownFields(message)->Clear(); @@ -270,8 +268,7 @@ bool ReflectionOps::IsInitialized(const Message& message) { // Should be safe to skip stripped fields because required fields are not // stripped. reflection->ListFieldsOmitStripped(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + for (const FieldDescriptor* field : fields) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->is_map()) { @@ -329,8 +326,7 @@ void ReflectionOps::DiscardUnknownFields(Message* message) { // messages present. std::vector fields; reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + for (const FieldDescriptor* field : fields) { // Skip over non-message fields. if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { continue; @@ -401,8 +397,7 @@ void ReflectionOps::FindInitializationErrors(const Message& message, // Check sub-messages. std::vector fields; reflection->ListFieldsOmitStripped(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + for (const FieldDescriptor* field : fields) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->is_repeated()) { diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index c1c4774685ed..26d58473312c 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -169,7 +169,7 @@ class RepeatedField final { "We only support types that have an alignment smaller than Arena"); public: - RepeatedField(); + constexpr RepeatedField(); explicit RepeatedField(Arena* arena); RepeatedField(const RepeatedField& other); template @@ -577,7 +577,7 @@ struct IsMovable // }; class PROTOBUF_EXPORT RepeatedPtrFieldBase { protected: - RepeatedPtrFieldBase(); + constexpr RepeatedPtrFieldBase(); explicit RepeatedPtrFieldBase(Arena* arena); ~RepeatedPtrFieldBase() { #ifndef NDEBUG @@ -920,7 +920,7 @@ class StringTypeHandler { template class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { public: - RepeatedPtrField(); + constexpr RepeatedPtrField(); explicit RepeatedPtrField(Arena* arena); RepeatedPtrField(const RepeatedPtrField& other); @@ -1180,7 +1180,7 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // implementation ==================================================== template -inline RepeatedField::RepeatedField() +constexpr RepeatedField::RepeatedField() : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {} template @@ -1647,7 +1647,7 @@ struct ElementCopier { namespace internal { -inline RepeatedPtrFieldBase::RepeatedPtrFieldBase() +constexpr RepeatedPtrFieldBase::RepeatedPtrFieldBase() : arena_(NULL), current_size_(0), total_size_(0), rep_(NULL) {} inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(Arena* arena) @@ -2090,7 +2090,8 @@ class RepeatedPtrField::TypeHandler : public internal::StringTypeHandler {}; template -inline RepeatedPtrField::RepeatedPtrField() : RepeatedPtrFieldBase() {} +constexpr RepeatedPtrField::RepeatedPtrField() + : RepeatedPtrFieldBase() {} template inline RepeatedPtrField::RepeatedPtrField(Arena* arena) diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 8de9504dc08b..4072f47b6cf1 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -65,6 +65,11 @@ namespace { using ::protobuf_unittest::TestAllTypes; using ::testing::ElementsAre; +TEST(RepeatedField, ConstInit) { + PROTOBUF_CONSTINIT static RepeatedField field{}; // NOLINT + EXPECT_TRUE(field.empty()); +} + // Test operations on a small RepeatedField. TEST(RepeatedField, Small) { RepeatedField field; @@ -827,6 +832,11 @@ TEST(RepeatedField, TestSAddFromSelf) { // RepeatedPtrField tests. These pretty much just mirror the RepeatedField // tests above. +TEST(RepeatedPtrField, ConstInit) { + PROTOBUF_CONSTINIT static RepeatedPtrField field{}; // NOLINT + EXPECT_TRUE(field.empty()); +} + TEST(RepeatedPtrField, Small) { RepeatedPtrField field; diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h index 0193301a225e..c7a48dea544a 100644 --- a/src/google/protobuf/stubs/bytestream.h +++ b/src/google/protobuf/stubs/bytestream.h @@ -256,11 +256,11 @@ class PROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink { // class PROTOBUF_EXPORT StringByteSink : public ByteSink { public: - explicit StringByteSink(string* dest) : dest_(dest) {} + explicit StringByteSink(std::string* dest) : dest_(dest) {} virtual void Append(const char* data, size_t n) override; private: - string* dest_; + std::string* dest_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringByteSink); }; diff --git a/src/google/protobuf/stubs/bytestream_unittest.cc b/src/google/protobuf/stubs/bytestream_unittest.cc index 06f114abc702..cb11825ef72e 100644 --- a/src/google/protobuf/stubs/bytestream_unittest.cc +++ b/src/google/protobuf/stubs/bytestream_unittest.cc @@ -64,7 +64,7 @@ class MockByteSource : public ByteSource { TEST(ByteSourceTest, CopyTo) { StringPiece data("Hello world!"); MockByteSource source(data, 3); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size()); @@ -75,7 +75,7 @@ TEST(ByteSourceTest, CopySubstringTo) { StringPiece data("Hello world!"); MockByteSource source(data, 3); source.Skip(1); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size() - 2); @@ -92,7 +92,7 @@ TEST(ByteSourceTest, LimitByteSource) { EXPECT_EQ(5, limit_source.Available()); { - string str; + std::string str; StringByteSink sink(&str); limit_source.CopyTo(&sink, limit_source.Available()); EXPECT_EQ("ello ", str); @@ -101,7 +101,7 @@ TEST(ByteSourceTest, LimitByteSource) { } { - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, source.Available()); EXPECT_EQ("world!", str); @@ -112,7 +112,7 @@ TEST(ByteSourceTest, LimitByteSource) { TEST(ByteSourceTest, CopyToStringByteSink) { StringPiece data("Hello world!"); MockByteSource source(data, 3); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size()); EXPECT_EQ(data, str); @@ -121,7 +121,7 @@ TEST(ByteSourceTest, CopyToStringByteSink) { // Verify that ByteSink is subclassable and Flush() overridable. class FlushingByteSink : public StringByteSink { public: - explicit FlushingByteSink(string* dest) : StringByteSink(dest) {} + explicit FlushingByteSink(std::string* dest) : StringByteSink(dest) {} virtual void Flush() { Append("z", 1); } private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FlushingByteSink); @@ -134,7 +134,7 @@ void WriteAndFlush(ByteSink* s) { } TEST(ByteSinkTest, Flush) { - string str; + std::string str; FlushingByteSink f_sink(&str); WriteAndFlush(&f_sink); EXPECT_STREQ("abcz", str.c_str()); diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h index b7a3a82910e1..43d546d19987 100644 --- a/src/google/protobuf/stubs/callback.h +++ b/src/google/protobuf/stubs/callback.h @@ -62,12 +62,12 @@ namespace protobuf { // Note that NewCallback() is a bit touchy regarding argument types. Generally, // the values you provide for the parameter bindings must exactly match the // types accepted by the callback function. For example: -// void Foo(string s); +// void Foo(std::string s); // NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string -// NewCallback(&Foo, string("foo")); // WORKS +// NewCallback(&Foo, std::string("foo")); // WORKS // Also note that the arguments cannot be references: -// void Foo(const string& s); -// string my_str; +// void Foo(const std::string& s); +// std::string my_str; // NewCallback(&Foo, my_str); // WON'T WORK: Can't use references. // However, correctly-typed pointers will work just fine. class PROTOBUF_EXPORT Closure { diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index 30802b1bb480..bc150f56a90d 100644 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -96,7 +96,7 @@ void VerifyVersion(int headerVersion, } } -string VersionString(int version) { +std::string VersionString(int version) { int major = version / 1000000; int minor = (version / 1000) % 1000; int micro = version % 1000; @@ -127,7 +127,7 @@ namespace internal { #if defined(__ANDROID__) inline void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { return; } @@ -162,7 +162,7 @@ inline void DefaultLogHandler(LogLevel level, const char* filename, int line, #else void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { return; } @@ -177,14 +177,14 @@ void DefaultLogHandler(LogLevel level, const char* filename, int line, #endif void NullLogHandler(LogLevel /* level */, const char* /* filename */, - int /* line */, const string& /* message */) { + int /* line */, const std::string& /* message */) { // Nothing. } static LogHandler* log_handler_ = &DefaultLogHandler; static std::atomic log_silencer_count_ = ATOMIC_VAR_INIT(0); -LogMessage& LogMessage::operator<<(const string& value) { +LogMessage& LogMessage::operator<<(const std::string& value) { message_ += value; return *this; } diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc index 585245892299..c55e45250574 100644 --- a/src/google/protobuf/stubs/common_unittest.cc +++ b/src/google/protobuf/stubs/common_unittest.cc @@ -53,7 +53,7 @@ TEST(VersionTest, VersionMatchesConfig) { // Verify that the version string specified in config.h matches the one // in common.h. The config.h version is a string which may have a suffix // like "beta" or "rc1", so we remove that. - string version = PACKAGE_VERSION; + std::string version = PACKAGE_VERSION; int pos = 0; while (pos < version.size() && (ascii_isdigit(version[pos]) || version[pos] == '.')) { @@ -77,10 +77,10 @@ TEST(CommonTest, IntMinMaxConstants) { EXPECT_EQ(0, kuint64max + 1); } -std::vector captured_messages_; +std::vector captured_messages_; void CaptureLog(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { captured_messages_.push_back( strings::Substitute("$0 $1:$2: $3", implicit_cast(level), filename, line, message)); @@ -93,7 +93,7 @@ TEST(LoggingTest, DefaultLogging) { GOOGLE_LOG(WARNING) << "A warning."; GOOGLE_LOG(ERROR ) << "An error."; - string text = GetCapturedTestStderr(); + std::string text = GetCapturedTestStderr(); EXPECT_EQ( "[libprotobuf INFO " __FILE__ ":" + SimpleItoa(line + 1) + "] A message.\n" "[libprotobuf WARNING " __FILE__ ":" + SimpleItoa(line + 2) + "] A warning.\n" @@ -111,7 +111,7 @@ TEST(LoggingTest, NullLogging) { EXPECT_TRUE(SetLogHandler(old_handler) == nullptr); - string text = GetCapturedTestStderr(); + std::string text = GetCapturedTestStderr(); EXPECT_EQ("", text); } @@ -167,10 +167,10 @@ class ClosureTest : public testing::Test { static void SetA123Function() { current_instance_->a_ = 123; } void SetAMethod(int a) { a_ = a; } - void SetCMethod(string c) { c_ = c; } + void SetCMethod(std::string c) { c_ = c; } static void SetAFunction(int a) { current_instance_->a_ = a; } - static void SetCFunction(string c) { current_instance_->c_ = c; } + static void SetCFunction(std::string c) { current_instance_->c_ = c; } void SetABMethod(int a, const char* b) { a_ = a; b_ = b; } static void SetABFunction(int a, const char* b) { @@ -192,7 +192,7 @@ class ClosureTest : public testing::Test { int a_; const char* b_; - string c_; + std::string c_; Closure* permanent_closure_; static ClosureTest* current_instance_; @@ -231,15 +231,15 @@ TEST_F(ClosureTest, TestClosureMethod1) { } TEST_F(ClosureTest, TestClosureFunction1String) { - Closure* closure = NewCallback(&SetCFunction, string("test")); + Closure* closure = NewCallback(&SetCFunction, std::string("test")); EXPECT_NE("test", c_); closure->Run(); EXPECT_EQ("test", c_); } TEST_F(ClosureTest, TestClosureMethod1String) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetCMethod, string("test")); + Closure* closure = NewCallback(current_instance_, &ClosureTest::SetCMethod, + std::string("test")); EXPECT_NE("test", c_); closure->Run(); EXPECT_EQ("test", c_); diff --git a/src/google/protobuf/stubs/status.cc b/src/google/protobuf/stubs/status.cc index 2bfbe0b42b8e..03b37c365b83 100644 --- a/src/google/protobuf/stubs/status.cc +++ b/src/google/protobuf/stubs/status.cc @@ -38,7 +38,7 @@ namespace google { namespace protobuf { namespace util { namespace error { -inline string CodeEnumToString(error::Code code) { +inline std::string CodeEnumToString(error::Code code) { switch (code) { case OK: return "OK"; @@ -111,7 +111,7 @@ bool Status::operator==(const Status& x) const { error_message_ == x.error_message_; } -string Status::ToString() const { +std::string Status::ToString() const { if (error_code_ == error::OK) { return "OK"; } else { diff --git a/src/google/protobuf/stubs/status.h b/src/google/protobuf/stubs/status.h index 04ecc633bc9f..bededad541c5 100644 --- a/src/google/protobuf/stubs/status.h +++ b/src/google/protobuf/stubs/status.h @@ -106,11 +106,11 @@ class PROTOBUF_EXPORT Status { } // Return a combination of the error code name and message. - string ToString() const; + std::string ToString() const; private: error::Code error_code_; - string error_message_; + std::string error_message_; }; // Prints a human-readable representation of 'x' to 'os'. diff --git a/src/google/protobuf/stubs/status_test.cc b/src/google/protobuf/stubs/status_test.cc index 9a18778fba81..8f4398c9c988 100644 --- a/src/google/protobuf/stubs/status_test.cc +++ b/src/google/protobuf/stubs/status_test.cc @@ -101,7 +101,7 @@ TEST(Status, AssignEmpty) { util::Status a(util::error::UNKNOWN, "message"); util::Status b; a = b; - ASSERT_EQ(string("OK"), a.ToString()); + ASSERT_EQ(std::string("OK"), a.ToString()); ASSERT_TRUE(b.ok()); ASSERT_TRUE(a.ok()); } diff --git a/src/google/protobuf/stubs/stl_util.h b/src/google/protobuf/stubs/stl_util.h index aa81eb6f7234..d01f9ec944f6 100644 --- a/src/google/protobuf/stubs/stl_util.h +++ b/src/google/protobuf/stubs/stl_util.h @@ -44,7 +44,7 @@ namespace protobuf { // improve performance. However, since it's totally non-portable it has no // place in open source code. Feel free to fill this function in with your // own disgusting hack if you want the perf boost. -inline void STLStringResizeUninitialized(string* s, size_t new_size) { +inline void STLStringResizeUninitialized(std::string* s, size_t new_size) { s->resize(new_size); } @@ -60,7 +60,7 @@ inline void STLStringResizeUninitialized(string* s, size_t new_size) { // (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) // proposes this as the method. According to Matt Austern, this should // already work on all current implementations. -inline char* string_as_array(string* str) { +inline char* string_as_array(std::string* str) { // DO NOT USE const_cast(str->data())! See the unittest for why. return str->empty() ? nullptr : &*str->begin(); } diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc index d9a32d03aa68..846e1aed3d36 100644 --- a/src/google/protobuf/stubs/stringpiece_unittest.cc +++ b/src/google/protobuf/stubs/stringpiece_unittest.cc @@ -87,7 +87,7 @@ TEST(StringPiece, Ctor) { #if defined(HAS_GLOBAL_STRING) { // ::string - string bonjour = "bonjour"; + std::string bonjour = "bonjour"; StringPiece s40(bonjour); EXPECT_TRUE(s40.data() == bonjour.data()); EXPECT_EQ(7, s40.length()); @@ -100,9 +100,9 @@ TEST(StringPiece, Ctor) { } TEST(StringPiece, STLComparator) { - string s1("foo"); - string s2("bar"); - string s3("baz"); + std::string s1("foo"); + std::string s2("bar"); + std::string s3("baz"); StringPiece p1(s1); StringPiece p2(s2); @@ -207,13 +207,13 @@ TEST(StringPiece, ComparisonOperators) { COMPARE(true, >, "b", "aa"); COMPARE(true, >, "bb", "aa"); - string x; + std::string x; for (int i = 0; i < 256; i++) { x += 'a'; - string y = x; + std::string y = x; COMPARE(true, ==, x, y); for (int j = 0; j < i; j++) { - string z = x; + std::string z = x; z[j] = 'b'; // Differs in position 'j' COMPARE(false, ==, x, z); COMPARE(true, <, x, z); @@ -240,7 +240,7 @@ TEST(StringPiece, STL1) { const StringPiece c("xyz"); const StringPiece d("foobar"); const StringPiece e; - string temp("123"); + std::string temp("123"); temp += '\0'; temp += "456"; const StringPiece f(temp); @@ -315,7 +315,7 @@ TEST(StringPiece, STL2) { EXPECT_TRUE(d.data() == nullptr); EXPECT_TRUE(d.begin() == d.end()); - EXPECT_EQ(StringPiece::npos, string::npos); + EXPECT_EQ(StringPiece::npos, std::string::npos); EXPECT_EQ(a.find(b), 0); EXPECT_EQ(a.find(b, 1), StringPiece::npos); @@ -336,15 +336,15 @@ TEST(StringPiece, STL2) { EXPECT_EQ(d.find(b, 4), StringPiece::npos); EXPECT_EQ(e.find(b, 7), StringPiece::npos); - size_t empty_search_pos = string().find(string()); + size_t empty_search_pos = std::string().find(std::string()); EXPECT_EQ(d.find(d), empty_search_pos); EXPECT_EQ(d.find(e), empty_search_pos); EXPECT_EQ(e.find(d), empty_search_pos); EXPECT_EQ(e.find(e), empty_search_pos); - EXPECT_EQ(d.find(d, 4), string().find(string(), 4)); - EXPECT_EQ(d.find(e, 4), string().find(string(), 4)); - EXPECT_EQ(e.find(d, 4), string().find(string(), 4)); - EXPECT_EQ(e.find(e, 4), string().find(string(), 4)); + EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); EXPECT_EQ(a.find('a'), 0); EXPECT_EQ(a.find('c'), 2); @@ -376,8 +376,8 @@ TEST(StringPiece, STL2) { EXPECT_EQ(a.rfind(c, 0), StringPiece::npos); EXPECT_EQ(b.rfind(c), StringPiece::npos); EXPECT_EQ(b.rfind(c, 0), StringPiece::npos); - EXPECT_EQ(a.rfind(d), a.as_string().rfind(string())); - EXPECT_EQ(a.rfind(e), a.as_string().rfind(string())); + EXPECT_EQ(a.rfind(d), a.as_string().rfind(std::string())); + EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string())); EXPECT_EQ(a.rfind(d, 12), 12); EXPECT_EQ(a.rfind(e, 17), 17); EXPECT_EQ(a.rfind(g), StringPiece::npos); @@ -386,14 +386,14 @@ TEST(StringPiece, STL2) { EXPECT_EQ(d.rfind(b, 4), StringPiece::npos); EXPECT_EQ(e.rfind(b, 7), StringPiece::npos); // empty string nonsense - EXPECT_EQ(d.rfind(d, 4), string().rfind(string())); - EXPECT_EQ(e.rfind(d, 7), string().rfind(string())); - EXPECT_EQ(d.rfind(e, 4), string().rfind(string())); - EXPECT_EQ(e.rfind(e, 7), string().rfind(string())); - EXPECT_EQ(d.rfind(d), string().rfind(string())); - EXPECT_EQ(e.rfind(d), string().rfind(string())); - EXPECT_EQ(d.rfind(e), string().rfind(string())); - EXPECT_EQ(e.rfind(e), string().rfind(string())); + EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e), std::string().rfind(std::string())); EXPECT_EQ(g.rfind('o'), 8); EXPECT_EQ(g.rfind('q'), StringPiece::npos); @@ -566,7 +566,7 @@ TEST(StringPiece, STL2) { // empty string nonsense EXPECT_EQ(StringPiece(d, 0, 99), e); // Verify that they work taking an actual string, not just a StringPiece. - string a2 = a.as_string(); + std::string a2 = a.as_string(); EXPECT_EQ(StringPiece(a2, 0, 3), b); EXPECT_EQ(StringPiece(a2, 23), c); EXPECT_EQ(StringPiece(a2, 23, 3), c); @@ -577,12 +577,12 @@ TEST(StringPiece, STL2) { TEST(StringPiece, Custom) { StringPiece a("foobar"); - string s1("123"); + std::string s1("123"); s1 += '\0'; s1 += "456"; StringPiece b(s1); StringPiece e; - string s2; + std::string s2; // CopyToString a.CopyToString(&s2); @@ -666,16 +666,16 @@ TEST(StringPiece, Custom) { EXPECT_NE(c, a); // as_string - string s3(a.as_string().c_str(), 7); + std::string s3(a.as_string().c_str(), 7); EXPECT_EQ(c, s3); - string s4(e.as_string()); + std::string s4(e.as_string()); EXPECT_TRUE(s4.empty()); // ToString { - string s5(a.ToString().c_str(), 7); + std::string s5(a.ToString().c_str(), 7); EXPECT_EQ(c, s5); - string s6(e.ToString()); + std::string s6(e.ToString()); EXPECT_TRUE(s6.empty()); } @@ -747,12 +747,12 @@ TEST(StringPiece, Comparisons2) { } TEST(ComparisonOpsTest, StringCompareNotAmbiguous) { - EXPECT_EQ("hello", string("hello")); - EXPECT_LT("hello", string("world")); + EXPECT_EQ("hello", std::string("hello")); + EXPECT_LT("hello", std::string("world")); } TEST(ComparisonOpsTest, HeterogenousStringPieceEquals) { - EXPECT_EQ(StringPiece("hello"), string("hello")); + EXPECT_EQ(StringPiece("hello"), std::string("hello")); EXPECT_EQ("hello", StringPiece("hello")); } diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc index e6019fc66416..260316493647 100644 --- a/src/google/protobuf/stubs/stringprintf.cc +++ b/src/google/protobuf/stubs/stringprintf.cc @@ -54,7 +54,7 @@ enum { IS_COMPILER_MSVC = 1 }; enum { IS_COMPILER_MSVC = 0 }; #endif -void StringAppendV(string* dst, const char* format, va_list ap) { +void StringAppendV(std::string* dst, const char* format, va_list ap) { // First try with a small fixed size buffer static const int kSpaceLength = 1024; char space[kSpaceLength]; @@ -105,17 +105,16 @@ void StringAppendV(string* dst, const char* format, va_list ap) { delete[] buf; } - -string StringPrintf(const char* format, ...) { +std::string StringPrintf(const char* format, ...) { va_list ap; va_start(ap, format); - string result; + std::string result; StringAppendV(&result, format, ap); va_end(ap); return result; } -const string& SStringPrintf(string* dst, const char* format, ...) { +const std::string& SStringPrintf(std::string* dst, const char* format, ...) { va_list ap; va_start(ap, format); dst->clear(); @@ -124,7 +123,7 @@ const string& SStringPrintf(string* dst, const char* format, ...) { return *dst; } -void StringAppendF(string* dst, const char* format, ...) { +void StringAppendF(std::string* dst, const char* format, ...) { va_list ap; va_start(ap, format); StringAppendV(dst, format, ap); @@ -139,7 +138,8 @@ const int kStringPrintfVectorMaxArgs = 32; // and we can fix the problem or protect against an attack. static const char string_printf_empty_block[256] = { '\0' }; -string StringPrintfVector(const char* format, const std::vector& v) { +std::string StringPrintfVector(const char* format, + const std::vector& v) { GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs) << "StringPrintfVector currently only supports up to " << kStringPrintfVectorMaxArgs << " arguments. " diff --git a/src/google/protobuf/stubs/stringprintf.h b/src/google/protobuf/stubs/stringprintf.h index 253d736a2160..e3858be13012 100644 --- a/src/google/protobuf/stubs/stringprintf.h +++ b/src/google/protobuf/stubs/stringprintf.h @@ -52,18 +52,20 @@ namespace google { namespace protobuf { // Return a C++ string -PROTOBUF_EXPORT extern string StringPrintf(const char* format, ...); +PROTOBUF_EXPORT extern std::string StringPrintf(const char* format, ...); // Store result into a supplied string and return it -PROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, - const char* format, ...); +PROTOBUF_EXPORT extern const std::string& SStringPrintf(std::string* dst, + const char* format, + ...); // Append result to a supplied string -PROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...); +PROTOBUF_EXPORT extern void StringAppendF(std::string* dst, const char* format, + ...); // Lower-level routine that takes a va_list and appends to a specified // string. All other routines are just convenience wrappers around it. -PROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, +PROTOBUF_EXPORT extern void StringAppendV(std::string* dst, const char* format, va_list ap); // The max arguments supported by StringPrintfVector @@ -72,8 +74,8 @@ PROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs; // You can use this version when all your arguments are strings, but // you don't know how many arguments you'll have at compile time. // StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs -PROTOBUF_EXPORT extern string StringPrintfVector(const char* format, - const std::vector& v); +PROTOBUF_EXPORT extern std::string StringPrintfVector( + const char* format, const std::vector& v); } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/stringprintf_unittest.cc b/src/google/protobuf/stubs/stringprintf_unittest.cc index 7fcbf500eb7e..37172a9d9702 100644 --- a/src/google/protobuf/stubs/stringprintf_unittest.cc +++ b/src/google/protobuf/stubs/stringprintf_unittest.cc @@ -49,7 +49,7 @@ TEST(StringPrintfTest, Empty) { // so we do not allow them in google3. EXPECT_EQ("", StringPrintf("")); #endif - EXPECT_EQ("", StringPrintf("%s", string().c_str())); + EXPECT_EQ("", StringPrintf("%s", std::string().c_str())); EXPECT_EQ("", StringPrintf("%s", "")); } @@ -61,26 +61,26 @@ TEST(StringPrintfTest, Misc) { } TEST(StringAppendFTest, Empty) { - string value("Hello"); + std::string value("Hello"); const char* empty = ""; StringAppendF(&value, "%s", empty); EXPECT_EQ("Hello", value); } TEST(StringAppendFTest, EmptyString) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, "%s", ""); EXPECT_EQ("Hello", value); } TEST(StringAppendFTest, String) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, " %s", "World"); EXPECT_EQ("Hello World", value); } TEST(StringAppendFTest, Int) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, " %d", 123); EXPECT_EQ("Hello 123", value); } @@ -96,7 +96,7 @@ TEST(StringPrintfTest, Multibyte) { setlocale(LC_CTYPE, "en_US.utf8"); const char kInvalidCodePoint[] = "\375\067s"; - string value = StringPrintf("%.*s", 3, kInvalidCodePoint); + std::string value = StringPrintf("%.*s", 3, kInvalidCodePoint); // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf // returns error given an invalid codepoint. Other versions @@ -122,7 +122,7 @@ TEST(StringPrintfTest, NoMultibyte) { // No multibyte handling, but the string contains funny chars. char* old_locale = setlocale(LC_CTYPE, nullptr); setlocale(LC_CTYPE, "POSIX"); - string value = StringPrintf("%.*s", 3, "\375\067s"); + std::string value = StringPrintf("%.*s", 3, "\375\067s"); setlocale(LC_CTYPE, old_locale); EXPECT_EQ("\375\067s", value); } @@ -132,7 +132,7 @@ TEST(StringPrintfTest, DontOverwriteErrno) { // something significantly larger than what people are normally // printing in their badly written PLOG() statements. errno = ECHILD; - string value = StringPrintf("Hello, %s!", "World"); + std::string value = StringPrintf("Hello, %s!", "World"); EXPECT_EQ(ECHILD, errno); } @@ -142,7 +142,7 @@ TEST(StringPrintfTest, LargeBuf) { char* buf = new char[n+1]; memset(buf, ' ', n); buf[n] = 0; - string value = StringPrintf("%s", buf); + std::string value = StringPrintf("%s", buf); EXPECT_EQ(buf, value); delete[] buf; } diff --git a/src/google/protobuf/stubs/structurally_valid_unittest.cc b/src/google/protobuf/stubs/structurally_valid_unittest.cc index eec07a87abfa..ebd9c42306ba 100644 --- a/src/google/protobuf/stubs/structurally_valid_unittest.cc +++ b/src/google/protobuf/stubs/structurally_valid_unittest.cc @@ -43,7 +43,8 @@ TEST(StructurallyValidTest, ValidUTF8String) { // On GCC, this string can be written as: // "abcd 1234 - \u2014\u2013\u2212" // MSVC seems to interpret \u differently. - string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); + std::string valid_str( + "abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(), valid_str.size())); // Additional check for pointer alignment @@ -54,7 +55,7 @@ TEST(StructurallyValidTest, ValidUTF8String) { } TEST(StructurallyValidTest, InvalidUTF8String) { - const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); + const std::string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(), invalid_str.size())); // Additional check for pointer alignment diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index 27225942ac47..2ecdb2bf72bf 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -84,7 +84,7 @@ inline bool isprint(char c) { // Replaces any occurrence of the character 'remove' (or the characters // in 'remove') with the character 'replacewith'. // ---------------------------------------------------------------------- -void ReplaceCharacters(string *s, const char *remove, char replacewith) { +void ReplaceCharacters(std::string *s, const char *remove, char replacewith) { const char *str_start = s->c_str(); const char *str = str_start; for (str = strpbrk(str, remove); @@ -94,7 +94,7 @@ void ReplaceCharacters(string *s, const char *remove, char replacewith) { } } -void StripWhitespace(string* str) { +void StripWhitespace(std::string *str) { int str_length = str->length(); // Strip off leading whitespace. @@ -118,7 +118,7 @@ void StripWhitespace(string* str) { --last; } if (last != (str_length - 1) && last >= 0) { - str->erase(last + 1, string::npos); + str->erase(last + 1, std::string::npos); } } @@ -129,19 +129,19 @@ void StripWhitespace(string* str) { // it only replaces the first instance of "old." // ---------------------------------------------------------------------- -void StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all, - string* res) { +void StringReplace(const std::string &s, const std::string &oldsub, + const std::string &newsub, bool replace_all, + std::string *res) { if (oldsub.empty()) { res->append(s); // if empty, append the given string. return; } - string::size_type start_pos = 0; - string::size_type pos; + std::string::size_type start_pos = 0; + std::string::size_type pos; do { pos = s.find(oldsub, start_pos); - if (pos == string::npos) { + if (pos == std::string::npos) { break; } res->append(s, start_pos, pos - start_pos); @@ -160,9 +160,9 @@ void StringReplace(const string& s, const string& oldsub, // happened or not. // ---------------------------------------------------------------------- -string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all) { - string ret; +std::string StringReplace(const std::string &s, const std::string &oldsub, + const std::string &newsub, bool replace_all) { + std::string ret; StringReplace(s, oldsub, newsub, replace_all, &ret); return ret; } @@ -195,11 +195,11 @@ static inline void SplitStringToIteratorUsing(StringPiece full, return; } - string::size_type begin_index, end_index; + std::string::size_type begin_index, end_index; begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { + while (begin_index != std::string::npos) { end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { + if (end_index == std::string::npos) { *result++ = std::string(full.substr(begin_index)); return; } @@ -210,8 +210,8 @@ static inline void SplitStringToIteratorUsing(StringPiece full, } void SplitStringUsing(StringPiece full, const char *delim, - std::vector *result) { - std::back_insert_iterator< std::vector > it(*result); + std::vector *result) { + std::back_insert_iterator > it(*result); SplitStringToIteratorUsing(full, delim, it); } @@ -230,12 +230,12 @@ template static inline void SplitStringToIteratorAllowEmpty(StringPiece full, const char *delim, int pieces, ITR &result) { - string::size_type begin_index, end_index; + std::string::size_type begin_index, end_index; begin_index = 0; for (int i = 0; (i < pieces-1) || (pieces == 0); i++) { end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { + if (end_index == std::string::npos) { *result++ = std::string(full.substr(begin_index)); return; } @@ -247,8 +247,8 @@ static inline void SplitStringToIteratorAllowEmpty(StringPiece full, } void SplitStringAllowEmpty(StringPiece full, const char *delim, - std::vector *result) { - std::back_insert_iterator > it(*result); + std::vector *result) { + std::back_insert_iterator > it(*result); SplitStringToIteratorAllowEmpty(full, delim, 0, it); } @@ -259,10 +259,8 @@ void SplitStringAllowEmpty(StringPiece full, const char *delim, // // ---------------------------------------------------------------------- template -static void JoinStringsIterator(const ITERATOR& start, - const ITERATOR& end, - const char* delim, - string* result) { +static void JoinStringsIterator(const ITERATOR &start, const ITERATOR &end, + const char *delim, std::string *result) { GOOGLE_CHECK(result != nullptr); result->clear(); int delim_length = strlen(delim); @@ -286,9 +284,8 @@ static void JoinStringsIterator(const ITERATOR& start, } } -void JoinStrings(const std::vector& components, - const char* delim, - string * result) { +void JoinStrings(const std::vector &components, const char *delim, + std::string *result) { JoinStringsIterator(components.begin(), components.end(), delim, result); } @@ -314,8 +311,8 @@ int UnescapeCEscapeSequences(const char* source, char* dest) { return UnescapeCEscapeSequences(source, dest, nullptr); } -int UnescapeCEscapeSequences(const char* source, char* dest, - std::vector *errors) { +int UnescapeCEscapeSequences(const char *source, char *dest, + std::vector *errors) { GOOGLE_DCHECK(errors == nullptr) << "Error reporting not implemented."; char* d = dest; @@ -370,8 +367,10 @@ int UnescapeCEscapeSequences(const char* source, char* dest, while (isxdigit(p[1])) // arbitrarily many hex digits ch = (ch << 4) + hex_digit_to_int(*++p); if (ch > 0xFF) - LOG_STRING(ERROR, errors) << "Value of " << - "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits"; + LOG_STRING(ERROR, errors) + << "Value of " + << "\\" << std::string(hex_start, p + 1 - hex_start) + << " exceeds 8 bits"; *d++ = ch; break; } @@ -386,7 +385,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, } else { LOG_STRING(ERROR, errors) << "\\u must be followed by 4 hex digits: \\" - << string(hex_start, p+1-hex_start); + << std::string(hex_start, p+1-hex_start); break; } } @@ -405,7 +404,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, if (newrune > 0x10FFFF) { LOG_STRING(ERROR, errors) << "Value of \\" - << string(hex_start, p + 1 - hex_start) + << std::string(hex_start, p + 1 - hex_start) << " exceeds Unicode limit (0x10FFFF)"; break; } else { @@ -414,7 +413,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, } else { LOG_STRING(ERROR, errors) << "\\U must be followed by 8 hex digits: \\" - << string(hex_start, p+1-hex_start); + << std::string(hex_start, p+1-hex_start); break; } } @@ -446,12 +445,12 @@ int UnescapeCEscapeSequences(const char* source, char* dest, // In the first and second calls, the length of dest is returned. In the // the third call, the new string is returned. // ---------------------------------------------------------------------- -int UnescapeCEscapeString(const string& src, string* dest) { +int UnescapeCEscapeString(const std::string &src, std::string *dest) { return UnescapeCEscapeString(src, dest, nullptr); } -int UnescapeCEscapeString(const string& src, string* dest, - std::vector *errors) { +int UnescapeCEscapeString(const std::string &src, std::string *dest, + std::vector *errors) { std::unique_ptr unescaped(new char[src.size() + 1]); int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); GOOGLE_CHECK(dest); @@ -459,10 +458,10 @@ int UnescapeCEscapeString(const string& src, string* dest, return len; } -string UnescapeCEscapeString(const string& src) { +std::string UnescapeCEscapeString(const std::string &src) { std::unique_ptr unescaped(new char[src.size() + 1]); int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), nullptr); - return string(unescaped.get(), len); + return std::string(unescaped.get(), len); } // ---------------------------------------------------------------------- @@ -559,7 +558,7 @@ static inline size_t CEscapedLength(StringPiece src) { // the required space using a lookup table, and also does not do any special // handling for Hex or UTF-8 characters. // ---------------------------------------------------------------------- -void CEscapeAndAppend(StringPiece src, string* dest) { +void CEscapeAndAppend(StringPiece src, std::string *dest) { size_t escaped_len = CEscapedLength(src); if (escaped_len == src.size()) { dest->append(src.data(), src.size()); @@ -593,30 +592,30 @@ void CEscapeAndAppend(StringPiece src, string* dest) { } } -string CEscape(const string& src) { - string dest; +std::string CEscape(const std::string &src) { + std::string dest; CEscapeAndAppend(src, &dest); return dest; } namespace strings { -string Utf8SafeCEscape(const string& src) { +std::string Utf8SafeCEscape(const std::string &src) { const int dest_length = src.size() * 4 + 1; // Maximum possible expansion std::unique_ptr dest(new char[dest_length]); const int len = CEscapeInternal(src.data(), src.size(), dest.get(), dest_length, false, true); GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); + return std::string(dest.get(), len); } -string CHexEscape(const string& src) { +std::string CHexEscape(const std::string &src) { const int dest_length = src.size() * 4 + 1; // Maximum possible expansion std::unique_ptr dest(new char[dest_length]); const int len = CEscapeInternal(src.data(), src.size(), dest.get(), dest_length, true, false); GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); + return std::string(dest.get(), len); } } // namespace strings @@ -664,8 +663,8 @@ uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { return static_cast(result); } -inline bool safe_parse_sign(string* text /*inout*/, - bool* negative_ptr /*output*/) { +inline bool safe_parse_sign(std::string *text /*inout*/, + bool *negative_ptr /*output*/) { const char* start = text->data(); const char* end = start + text->size(); @@ -692,9 +691,8 @@ inline bool safe_parse_sign(string* text /*inout*/, return true; } -template -bool safe_parse_positive_int( - string text, IntType* value_p) { +template +bool safe_parse_positive_int(std::string text, IntType *value_p) { int base = 10; IntType value = 0; const IntType vmax = std::numeric_limits::max(); @@ -726,9 +724,8 @@ bool safe_parse_positive_int( return true; } -template -bool safe_parse_negative_int( - const string& text, IntType* value_p) { +template +bool safe_parse_negative_int(const std::string &text, IntType *value_p) { int base = 10; IntType value = 0; const IntType vmin = std::numeric_limits::min(); @@ -767,8 +764,8 @@ bool safe_parse_negative_int( return true; } -template -bool safe_int_internal(string text, IntType* value_p) { +template +bool safe_int_internal(std::string text, IntType *value_p) { *value_p = 0; bool negative; if (!safe_parse_sign(&text, &negative)) { @@ -781,8 +778,8 @@ bool safe_int_internal(string text, IntType* value_p) { } } -template -bool safe_uint_internal(string text, IntType* value_p) { +template +bool safe_uint_internal(std::string text, IntType *value_p) { *value_p = 0; bool negative; if (!safe_parse_sign(&text, &negative) || negative) { @@ -1116,46 +1113,46 @@ char* FastInt64ToBufferLeft(int64 i, char* buffer) { // Return value: string // ---------------------------------------------------------------------- -string SimpleItoa(int i) { +std::string SimpleItoa(int i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned int i) { +std::string SimpleItoa(unsigned int i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } -string SimpleItoa(long i) { +std::string SimpleItoa(long i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned long i) { +std::string SimpleItoa(unsigned long i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } -string SimpleItoa(long long i) { +std::string SimpleItoa(long long i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned long long i) { +std::string SimpleItoa(unsigned long long i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } // ---------------------------------------------------------------------- @@ -1199,12 +1196,12 @@ string SimpleItoa(unsigned long long i) { // implementation. // ---------------------------------------------------------------------- -string SimpleDtoa(double value) { +std::string SimpleDtoa(double value) { char buffer[kDoubleToBufferSize]; return DoubleToBuffer(value, buffer); } -string SimpleFtoa(float value) { +std::string SimpleFtoa(float value) { char buffer[kFloatToBufferSize]; return FloatToBuffer(value, buffer); } @@ -1344,19 +1341,19 @@ bool safe_strtod(const char* str, double* value) { return *str != '\0' && *endptr == '\0'; } -bool safe_strto32(const string& str, int32* value) { +bool safe_strto32(const std::string &str, int32 *value) { return safe_int_internal(str, value); } -bool safe_strtou32(const string& str, uint32* value) { +bool safe_strtou32(const std::string &str, uint32 *value) { return safe_uint_internal(str, value); } -bool safe_strto64(const string& str, int64* value) { +bool safe_strto64(const std::string &str, int64 *value) { return safe_int_internal(str, value); } -bool safe_strtou64(const string& str, uint64* value) { +bool safe_strtou64(const std::string &str, uint64 *value) { return safe_uint_internal(str, value); } @@ -1472,8 +1469,8 @@ static char *Append4(char *out, const AlphaNum &x1, const AlphaNum &x2, return out; } -string StrCat(const AlphaNum &a, const AlphaNum &b) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b) { + std::string result; result.resize(a.size() + b.size()); char *const begin = &*result.begin(); char *out = Append2(begin, a, b); @@ -1481,8 +1478,8 @@ string StrCat(const AlphaNum &a, const AlphaNum &b) { return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { + std::string result; result.resize(a.size() + b.size() + c.size()); char *const begin = &*result.begin(); char *out = Append2(begin, a, b); @@ -1491,9 +1488,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size()); char *const begin = &*result.begin(); char *out = Append4(begin, a, b, c, d); @@ -1501,9 +1498,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size()); char *const begin = &*result.begin(); char *out = Append4(begin, a, b, c, d); @@ -1512,9 +1509,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size()); char *const begin = &*result.begin(); @@ -1524,10 +1521,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size()); char *const begin = &*result.begin(); @@ -1538,10 +1535,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g, const AlphaNum &h) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size() + h.size()); char *const begin = &*result.begin(); @@ -1551,10 +1548,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size() + h.size() + i.size()); char *const begin = &*result.begin(); @@ -1573,27 +1570,27 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \ uintptr_t((dest).size())) -void StrAppend(string *result, const AlphaNum &a) { +void StrAppend(std::string *result, const AlphaNum &a) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); result->append(a.data(), a.size()); } -void StrAppend(string *result, const AlphaNum &a, const AlphaNum &b) { +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size()); char *const begin = &*result->begin(); char *out = Append2(begin + old_size, a, b); GOOGLE_DCHECK_EQ(out, begin + result->size()); } -void StrAppend(string *result, - const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b, + const AlphaNum &c) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); GOOGLE_DCHECK_NO_OVERLAP(*result, c); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size() + c.size()); char *const begin = &*result->begin(); char *out = Append2(begin + old_size, a, b); @@ -1601,32 +1598,29 @@ void StrAppend(string *result, GOOGLE_DCHECK_EQ(out, begin + result->size()); } -void StrAppend(string *result, - const AlphaNum &a, const AlphaNum &b, +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, const AlphaNum &d) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); GOOGLE_DCHECK_NO_OVERLAP(*result, c); GOOGLE_DCHECK_NO_OVERLAP(*result, d); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size() + c.size() + d.size()); char *const begin = &*result->begin(); char *out = Append4(begin + old_size, a, b, c, d); GOOGLE_DCHECK_EQ(out, begin + result->size()); } -int GlobalReplaceSubstring(const string& substring, - const string& replacement, - string* s) { +int GlobalReplaceSubstring(const std::string &substring, + const std::string &replacement, std::string *s) { GOOGLE_CHECK(s != nullptr); if (s->empty() || substring.empty()) return 0; - string tmp; + std::string tmp; int num_replacements = 0; int pos = 0; for (int match_pos = s->find(substring.data(), pos, substring.length()); - match_pos != string::npos; - pos = match_pos + substring.length(), + match_pos != std::string::npos; pos = match_pos + substring.length(), match_pos = s->find(substring.data(), pos, substring.length())) { ++num_replacements; // Append the original content before the match. @@ -2057,8 +2051,8 @@ int WebSafeBase64Unescape(const char *src, int szsrc, char *dest, int szdest) { return Base64UnescapeInternal(src, szsrc, dest, szdest, kUnWebSafeBase64); } -static bool Base64UnescapeInternal(const char* src, int slen, string* dest, - const signed char* unbase64) { +static bool Base64UnescapeInternal(const char *src, int slen, std::string *dest, + const signed char *unbase64) { // Determine the size of the output string. Base64 encodes every 3 bytes into // 4 characters. any leftover chars are added directly for good measure. // This is documented in the base64 RFC: http://tools.ietf.org/html/rfc3548 @@ -2082,11 +2076,11 @@ static bool Base64UnescapeInternal(const char* src, int slen, string* dest, return true; } -bool Base64Unescape(StringPiece src, string* dest) { +bool Base64Unescape(StringPiece src, std::string *dest) { return Base64UnescapeInternal(src.data(), src.size(), dest, kUnBase64); } -bool WebSafeBase64Unescape(StringPiece src, string* dest) { +bool WebSafeBase64Unescape(StringPiece src, std::string *dest) { return Base64UnescapeInternal(src.data(), src.size(), dest, kUnWebSafeBase64); } @@ -2205,9 +2199,9 @@ int WebSafeBase64Escape(const unsigned char *src, int szsrc, char *dest, kWebSafeBase64Chars, do_padding); } -void Base64EscapeInternal(const unsigned char* src, int szsrc, - string* dest, bool do_padding, - const char* base64_chars) { +void Base64EscapeInternal(const unsigned char *src, int szsrc, + std::string *dest, bool do_padding, + const char *base64_chars) { const int calc_escaped_size = CalculateBase64EscapedLen(szsrc, do_padding); dest->resize(calc_escaped_size); @@ -2220,27 +2214,27 @@ void Base64EscapeInternal(const unsigned char* src, int szsrc, dest->erase(escaped_len); } -void Base64Escape(const unsigned char *src, int szsrc, - string* dest, bool do_padding) { +void Base64Escape(const unsigned char *src, int szsrc, std::string *dest, + bool do_padding) { Base64EscapeInternal(src, szsrc, dest, do_padding, kBase64Chars); } -void WebSafeBase64Escape(const unsigned char *src, int szsrc, - string *dest, bool do_padding) { +void WebSafeBase64Escape(const unsigned char *src, int szsrc, std::string *dest, + bool do_padding) { Base64EscapeInternal(src, szsrc, dest, do_padding, kWebSafeBase64Chars); } -void Base64Escape(StringPiece src, string* dest) { +void Base64Escape(StringPiece src, std::string *dest) { Base64Escape(reinterpret_cast(src.data()), src.size(), dest, true); } -void WebSafeBase64Escape(StringPiece src, string* dest) { +void WebSafeBase64Escape(StringPiece src, std::string *dest) { WebSafeBase64Escape(reinterpret_cast(src.data()), src.size(), dest, false); } -void WebSafeBase64EscapeWithPadding(StringPiece src, string* dest) { +void WebSafeBase64EscapeWithPadding(StringPiece src, std::string *dest) { WebSafeBase64Escape(reinterpret_cast(src.data()), src.size(), dest, true); } @@ -2336,19 +2330,19 @@ int UTF8FirstLetterNumBytes(const char* src, int len) { // (1) determines the presence of LF (first one is ok) // (2) if yes, removes any CR, else convert every CR to LF -void CleanStringLineEndings(const string &src, string *dst, +void CleanStringLineEndings(const std::string &src, std::string *dst, bool auto_end_last_line) { if (dst->empty()) { dst->append(src); CleanStringLineEndings(dst, auto_end_last_line); } else { - string tmp = src; + std::string tmp = src; CleanStringLineEndings(&tmp, auto_end_last_line); dst->append(tmp); } } -void CleanStringLineEndings(string *str, bool auto_end_last_line) { +void CleanStringLineEndings(std::string *str, bool auto_end_last_line) { ptrdiff_t output_pos = 0; bool r_seen = false; ptrdiff_t len = str->size(); @@ -2379,7 +2373,7 @@ void CleanStringLineEndings(string *str, bool auto_end_last_line) { continue; } } - string::const_reference in = p[input_pos]; + std::string::const_reference in = p[input_pos]; if (in == '\r') { if (r_seen) p[output_pos++] = '\n'; r_seen = true; diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index c070a05fd4e6..8ce81f28c398 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h @@ -118,7 +118,8 @@ inline bool HasPrefixString(StringPiece str, StringPiece prefix) { memcmp(str.data(), prefix.data(), prefix.size()) == 0; } -inline string StripPrefixString(const string& str, const string& prefix) { +inline std::string StripPrefixString(const std::string& str, + const std::string& prefix) { if (HasPrefixString(str, prefix)) { return str.substr(prefix.size()); } else { @@ -140,7 +141,8 @@ inline bool HasSuffixString(StringPiece str, StringPiece suffix) { suffix.size()) == 0; } -inline string StripSuffixString(const string& str, const string& suffix) { +inline std::string StripSuffixString(const std::string& str, + const std::string& suffix) { if (HasSuffixString(str, suffix)) { return str.substr(0, str.size() - suffix.size()); } else { @@ -157,10 +159,10 @@ inline string StripSuffixString(const string& str, const string& suffix) { // StripWhitespace // Removes whitespaces from both ends of the given string. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void ReplaceCharacters(string* s, const char* remove, +PROTOBUF_EXPORT void ReplaceCharacters(std::string* s, const char* remove, char replacewith); -PROTOBUF_EXPORT void StripWhitespace(string* s); +PROTOBUF_EXPORT void StripWhitespace(std::string* s); // ---------------------------------------------------------------------- // LowerString() @@ -172,26 +174,26 @@ PROTOBUF_EXPORT void StripWhitespace(string* s); // strings. // ---------------------------------------------------------------------- -inline void LowerString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { +inline void LowerString(std::string* s) { + std::string::iterator end = s->end(); + for (std::string::iterator i = s->begin(); i != end; ++i) { // tolower() changes based on locale. We don't want this! if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A'; } } -inline void UpperString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { +inline void UpperString(std::string* s) { + std::string::iterator end = s->end(); + for (std::string::iterator i = s->begin(); i != end; ++i) { // toupper() changes based on locale. We don't want this! if ('a' <= *i && *i <= 'z') *i += 'A' - 'a'; } } -inline void ToUpper(string* s) { UpperString(s); } +inline void ToUpper(std::string* s) { UpperString(s); } -inline string ToUpper(const string& s) { - string out = s; +inline std::string ToUpper(const std::string& s) { + std::string out = s; UpperString(&out); return out; } @@ -204,8 +206,10 @@ inline string ToUpper(const string& s) { // happened or not. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all); +PROTOBUF_EXPORT std::string StringReplace(const std::string& s, + const std::string& oldsub, + const std::string& newsub, + bool replace_all); // ---------------------------------------------------------------------- // SplitStringUsing() @@ -214,7 +218,7 @@ PROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, // over all of them. // ---------------------------------------------------------------------- PROTOBUF_EXPORT void SplitStringUsing(StringPiece full, const char* delim, - std::vector* res); + std::vector* res); // Split a string using one or more byte delimiters, presented // as a nul-terminated c string. Append the components to 'result'. @@ -225,15 +229,15 @@ PROTOBUF_EXPORT void SplitStringUsing(StringPiece full, const char* delim, // If "full" is the empty string, yields an empty string as the only value. // ---------------------------------------------------------------------- PROTOBUF_EXPORT void SplitStringAllowEmpty(StringPiece full, const char* delim, - std::vector* result); + std::vector* result); // ---------------------------------------------------------------------- // Split() // Split a string using a character delimiter. // ---------------------------------------------------------------------- -inline std::vector Split(StringPiece full, const char* delim, - bool skip_empty = true) { - std::vector result; +inline std::vector Split(StringPiece full, const char* delim, + bool skip_empty = true) { + std::vector result; if (skip_empty) { SplitStringUsing(full, delim, &result); } else { @@ -250,12 +254,12 @@ inline std::vector Split(StringPiece full, const char* delim, // another takes a pointer to the target string. In the latter case the // target string is cleared and overwritten. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void JoinStrings(const std::vector& components, - const char* delim, string* result); +PROTOBUF_EXPORT void JoinStrings(const std::vector& components, + const char* delim, std::string* result); -inline string JoinStrings(const std::vector& components, - const char* delim) { - string result; +inline std::string JoinStrings(const std::vector& components, + const char* delim) { + std::string result; JoinStrings(components, delim, &result); return result; } @@ -293,7 +297,7 @@ inline string JoinStrings(const std::vector& components, PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, - std::vector* errors); + std::vector* errors); // ---------------------------------------------------------------------- // UnescapeCEscapeString() @@ -310,10 +314,12 @@ PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, // the third call, the new string is returned. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest); -PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest, - std::vector* errors); -PROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); +PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src, + std::string* dest); +PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src, + std::string* dest, + std::vector* errors); +PROTOBUF_EXPORT std::string UnescapeCEscapeString(const std::string& src); // ---------------------------------------------------------------------- // CEscape() @@ -322,21 +328,21 @@ PROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); // // Escaped chars: \n, \r, \t, ", ', \, and !isprint(). // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string CEscape(const string& src); +PROTOBUF_EXPORT std::string CEscape(const std::string& src); // ---------------------------------------------------------------------- // CEscapeAndAppend() // Escapes 'src' using C-style escape sequences, and appends the escaped // string to 'dest'. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, string* dest); +PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, std::string* dest); namespace strings { // Like CEscape() but does not escape bytes with the upper bit set. -PROTOBUF_EXPORT string Utf8SafeCEscape(const string& src); +PROTOBUF_EXPORT std::string Utf8SafeCEscape(const std::string& src); // Like CEscape() but uses hex (\x) escapes instead of octals. -PROTOBUF_EXPORT string CHexEscape(const string& src); +PROTOBUF_EXPORT std::string CHexEscape(const std::string& src); } // namespace strings // ---------------------------------------------------------------------- @@ -393,31 +399,31 @@ inline uint64 strtou64(const char *nptr, char **endptr, int base) { // ---------------------------------------------------------------------- PROTOBUF_EXPORT bool safe_strtob(StringPiece str, bool* value); -PROTOBUF_EXPORT bool safe_strto32(const string& str, int32* value); -PROTOBUF_EXPORT bool safe_strtou32(const string& str, uint32* value); +PROTOBUF_EXPORT bool safe_strto32(const std::string& str, int32* value); +PROTOBUF_EXPORT bool safe_strtou32(const std::string& str, uint32* value); inline bool safe_strto32(const char* str, int32* value) { - return safe_strto32(string(str), value); + return safe_strto32(std::string(str), value); } inline bool safe_strto32(StringPiece str, int32* value) { return safe_strto32(str.ToString(), value); } inline bool safe_strtou32(const char* str, uint32* value) { - return safe_strtou32(string(str), value); + return safe_strtou32(std::string(str), value); } inline bool safe_strtou32(StringPiece str, uint32* value) { return safe_strtou32(str.ToString(), value); } -PROTOBUF_EXPORT bool safe_strto64(const string& str, int64* value); -PROTOBUF_EXPORT bool safe_strtou64(const string& str, uint64* value); +PROTOBUF_EXPORT bool safe_strto64(const std::string& str, int64* value); +PROTOBUF_EXPORT bool safe_strtou64(const std::string& str, uint64* value); inline bool safe_strto64(const char* str, int64* value) { - return safe_strto64(string(str), value); + return safe_strto64(std::string(str), value); } inline bool safe_strto64(StringPiece str, int64* value) { return safe_strto64(str.ToString(), value); } inline bool safe_strtou64(const char* str, uint64* value) { - return safe_strtou64(string(str), value); + return safe_strtou64(std::string(str), value); } inline bool safe_strtou64(StringPiece str, uint64* value) { return safe_strtou64(str.ToString(), value); @@ -425,10 +431,10 @@ inline bool safe_strtou64(StringPiece str, uint64* value) { PROTOBUF_EXPORT bool safe_strtof(const char* str, float* value); PROTOBUF_EXPORT bool safe_strtod(const char* str, double* value); -inline bool safe_strtof(const string& str, float* value) { +inline bool safe_strtof(const std::string& str, float* value) { return safe_strtof(str.c_str(), value); } -inline bool safe_strtod(const string& str, double* value) { +inline bool safe_strtod(const std::string& str, double* value) { return safe_strtod(str.c_str(), value); } inline bool safe_strtof(StringPiece str, float* value) { @@ -521,9 +527,7 @@ inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { return buffer; } -inline string SimpleBtoa(bool value) { - return value ? "true" : "false"; -} +inline std::string SimpleBtoa(bool value) { return value ? "true" : "false"; } // ---------------------------------------------------------------------- // SimpleItoa() @@ -531,12 +535,12 @@ inline string SimpleBtoa(bool value) { // // Return value: string // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string SimpleItoa(int i); -PROTOBUF_EXPORT string SimpleItoa(unsigned int i); -PROTOBUF_EXPORT string SimpleItoa(long i); -PROTOBUF_EXPORT string SimpleItoa(unsigned long i); -PROTOBUF_EXPORT string SimpleItoa(long long i); -PROTOBUF_EXPORT string SimpleItoa(unsigned long long i); +PROTOBUF_EXPORT std::string SimpleItoa(int i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned int i); +PROTOBUF_EXPORT std::string SimpleItoa(long i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned long i); +PROTOBUF_EXPORT std::string SimpleItoa(long long i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned long long i); // ---------------------------------------------------------------------- // SimpleDtoa() @@ -557,8 +561,8 @@ PROTOBUF_EXPORT string SimpleItoa(unsigned long long i); // // Return value: string // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string SimpleDtoa(double value); -PROTOBUF_EXPORT string SimpleFtoa(float value); +PROTOBUF_EXPORT std::string SimpleDtoa(double value); +PROTOBUF_EXPORT std::string SimpleFtoa(float value); PROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer); PROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer); @@ -654,7 +658,7 @@ struct PROTOBUF_EXPORT AlphaNum { // TODO: Add a string_ref constructor, eventually // AlphaNum(const StringPiece &pc) : piece(pc) {} - AlphaNum(const string& str) + AlphaNum(const std::string& str) : piece_data_(str.data()), piece_size_(str.size()) {} AlphaNum(StringPiece str) @@ -702,32 +706,34 @@ using strings::AlphaNum; // be a reference into str. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g, const AlphaNum& h); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g, const AlphaNum& h, - const AlphaNum& i); - -inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h, + const AlphaNum& i); + +inline std::string StrCat(const AlphaNum& a) { + return std::string(a.data(), a.size()); +} // ---------------------------------------------------------------------- // StrAppend() @@ -750,12 +756,12 @@ inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } // worked around as consecutive calls to StrAppend are quite efficient. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a); +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d); @@ -765,8 +771,8 @@ PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, // the C-string "delim" as a separator between components. // ---------------------------------------------------------------------- template -void Join(Iterator start, Iterator end, - const char* delim, string* result) { +void Join(Iterator start, Iterator end, const char* delim, + std::string* result) { for (Iterator it = start; it != end; ++it) { if (it != start) { result->append(delim); @@ -776,9 +782,8 @@ void Join(Iterator start, Iterator end, } template -string Join(const Range& components, - const char* delim) { - string result; +std::string Join(const Range& components, const char* delim) { + std::string result; Join(components.begin(), components.end(), delim, &result); return result; } @@ -787,7 +792,7 @@ string Join(const Range& components, // ToHex() // Return a lower-case hex string representation of the given integer. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string ToHex(uint64 num); +PROTOBUF_EXPORT std::string ToHex(uint64 num); // ---------------------------------------------------------------------- // GlobalReplaceSubstring() @@ -796,9 +801,9 @@ PROTOBUF_EXPORT string ToHex(uint64 num); // // NOTE: The string pieces must not overlap s. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT int GlobalReplaceSubstring(const string& substring, - const string& replacement, - string* s); +PROTOBUF_EXPORT int GlobalReplaceSubstring(const std::string& substring, + const std::string& replacement, + std::string* s); // ---------------------------------------------------------------------- // Base64Unescape() @@ -806,7 +811,7 @@ PROTOBUF_EXPORT int GlobalReplaceSubstring(const string& substring, // writes it to "dest". If src contains invalid characters, dest is cleared // and the function returns false. Returns true on success. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, string* dest); +PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, std::string* dest); // ---------------------------------------------------------------------- // WebSafeBase64Unescape() @@ -821,7 +826,7 @@ PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, string* dest); // ---------------------------------------------------------------------- PROTOBUF_EXPORT int WebSafeBase64Unescape(const char* src, int slen, char* dest, int szdest); -PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, string* dest); +PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, std::string* dest); // Return the length to use for the output buffer given to the base64 escape // routines. Make sure to use the same value for do_padding in both. @@ -849,17 +854,17 @@ PROTOBUF_EXPORT int WebSafeBase64Escape(const unsigned char* src, int slen, char* dest, int szdest, bool do_padding); // Encode src into dest with padding. -PROTOBUF_EXPORT void Base64Escape(StringPiece src, string* dest); +PROTOBUF_EXPORT void Base64Escape(StringPiece src, std::string* dest); // Encode src into dest web-safely without padding. -PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, string* dest); +PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, std::string* dest); // Encode src into dest web-safely with padding. PROTOBUF_EXPORT void WebSafeBase64EscapeWithPadding(StringPiece src, - string* dest); + std::string* dest); PROTOBUF_EXPORT void Base64Escape(const unsigned char* src, int szsrc, - string* dest, bool do_padding); + std::string* dest, bool do_padding); PROTOBUF_EXPORT void WebSafeBase64Escape(const unsigned char* src, int szsrc, - string* dest, bool do_padding); + std::string* dest, bool do_padding); inline bool IsValidCodePoint(uint32 code_point) { return code_point < 0xD800 || @@ -915,11 +920,12 @@ PROTOBUF_EXPORT int UTF8FirstLetterNumBytes(const char* src, int len); // // (1) determines the presence of LF (first one is ok) // (2) if yes, removes any CR, else convert every CR to LF -PROTOBUF_EXPORT void CleanStringLineEndings(const string& src, string* dst, +PROTOBUF_EXPORT void CleanStringLineEndings(const std::string& src, + std::string* dst, bool auto_end_last_line); // Same as above, but transforms the argument in place. -PROTOBUF_EXPORT void CleanStringLineEndings(string* str, +PROTOBUF_EXPORT void CleanStringLineEndings(std::string* str, bool auto_end_last_line); namespace strings { diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc index 141d263a401a..fc9a63f3f252 100644 --- a/src/google/protobuf/stubs/strutil_unittest.cc +++ b/src/google/protobuf/stubs/strutil_unittest.cc @@ -52,7 +52,7 @@ TEST(StringUtilityTest, ImmuneToLocales) { // Remember the old locale. char* old_locale_cstr = setlocale(LC_NUMERIC, nullptr); ASSERT_TRUE(old_locale_cstr != nullptr); - string old_locale = old_locale_cstr; + std::string old_locale = old_locale_cstr; // Set the locale to "C". ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != nullptr); @@ -442,7 +442,7 @@ TEST(Base64, EscapeAndUnescape) { char decode_buffer[100]; int decode_length; int cypher_length; - string decode_str; + std::string decode_str; const unsigned char* unsigned_plaintext = reinterpret_cast(base64_tests[i].plaintext); @@ -491,13 +491,13 @@ TEST(Base64, EscapeAndUnescape) { EXPECT_EQ(plaintext, decode_str); // Let's try with a pre-populated string. - string encoded("this junk should be ignored"); - Base64Escape(string(base64_tests[i].plaintext, - base64_tests[i].plain_length), - &encoded); - EXPECT_EQ(encoded, string(encode_buffer, cypher_length)); + std::string encoded("this junk should be ignored"); + Base64Escape( + std::string(base64_tests[i].plaintext, base64_tests[i].plain_length), + &encoded); + EXPECT_EQ(encoded, std::string(encode_buffer, cypher_length)); - string decoded("this junk should be ignored"); + std::string decoded("this junk should be ignored"); EXPECT_TRUE(Base64Unescape( StringPiece(encode_buffer, cypher_length), &decoded)); EXPECT_EQ(decoded.size(), base64_tests[i].plain_length); @@ -514,7 +514,7 @@ TEST(Base64, EscapeAndUnescape) { // Try chopping off the equals sign(s) entirely. The decoder // should still be okay with this. - string decoded2("this junk should also be ignored"); + std::string decoded2("this junk should also be ignored"); *first_equals = '\0'; EXPECT_TRUE(Base64Unescape( StringPiece(encode_buffer, first_equals - encode_buffer), &decoded2)); @@ -730,7 +730,7 @@ TEST(Base64, EscapeAndUnescape) { EXPECT_STREQ(encode_buffer, websafe); // Let's try the (other) string version of the encoder - string plain(base64_tests[i].plaintext, base64_tests[i].plain_length); + std::string plain(base64_tests[i].plaintext, base64_tests[i].plain_length); encoded = "this junk should be ignored"; WebSafeBase64Escape(plain, &encoded); EXPECT_EQ(encoded.size(), cypher_length); @@ -798,7 +798,7 @@ TEST(Base64, EscapeAndUnescape) { // Verify the behavior when decoding bad data { const char* bad_data = "ab-/"; - string buf; + std::string buf; EXPECT_FALSE(Base64Unescape(StringPiece(bad_data), &buf)); EXPECT_TRUE(!WebSafeBase64Unescape(bad_data, &buf)); EXPECT_TRUE(buf.empty()); @@ -819,7 +819,7 @@ TEST(StrCat, Ints) { const size_t size = 10; const intptr_t intptr = -12; const uintptr_t uintptr = 13; - string answer; + std::string answer; answer = StrCat(s, us); EXPECT_EQ(answer, "-12"); answer = StrCat(i, ui); @@ -836,12 +836,13 @@ TEST(StrCat, Ints) { EXPECT_EQ(answer, "130"); } -class ReplaceChars : public ::testing::TestWithParam< - std::tuple> {}; +class ReplaceChars + : public ::testing::TestWithParam< + std::tuple> {}; TEST_P(ReplaceChars, ReplacesAllOccurencesOfAnyCharInReplaceWithAReplaceChar) { - string expected = std::get<0>(GetParam()); - string string_to_replace_in = std::get<1>(GetParam()); + std::string expected = std::get<0>(GetParam()); + std::string string_to_replace_in = std::get<1>(GetParam()); const char* what_to_replace = std::get<2>(GetParam()); char replacement = std::get<3>(GetParam()); ReplaceCharacters(&string_to_replace_in, what_to_replace, replacement); @@ -864,11 +865,12 @@ INSTANTIATE_TEST_CASE_P( std::make_tuple("qvvvvvng v T", "queueing a T", "aeiou", 'v'))); // replace all voewls -class StripWs : public ::testing::TestWithParam> {}; +class StripWs + : public ::testing::TestWithParam> {}; TEST_P(StripWs, AlwaysStripsLeadingAndTrailingWhitespace) { - string expected = std::get<0>(GetParam()); - string string_to_strip = std::get<1>(GetParam()); + std::string expected = std::get<0>(GetParam()); + std::string string_to_strip = std::get<1>(GetParam()); StripWhitespace(&string_to_strip); ASSERT_EQ(expected, string_to_strip); } diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc index a36f2f026c5e..92107416eb1b 100644 --- a/src/google/protobuf/stubs/substitute.cc +++ b/src/google/protobuf/stubs/substitute.cc @@ -52,26 +52,24 @@ static int CountSubstituteArgs(const SubstituteArg* const* args_array) { return count; } -string Substitute( - const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - string result; +std::string Substitute(const char* format, const SubstituteArg& arg0, + const SubstituteArg& arg1, const SubstituteArg& arg2, + const SubstituteArg& arg3, const SubstituteArg& arg4, + const SubstituteArg& arg5, const SubstituteArg& arg6, + const SubstituteArg& arg7, const SubstituteArg& arg8, + const SubstituteArg& arg9) { + std::string result; SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); return result; } -void SubstituteAndAppend( - string* output, const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { +void SubstituteAndAppend(std::string* output, const char* format, + const SubstituteArg& arg0, const SubstituteArg& arg1, + const SubstituteArg& arg2, const SubstituteArg& arg3, + const SubstituteArg& arg4, const SubstituteArg& arg5, + const SubstituteArg& arg6, const SubstituteArg& arg7, + const SubstituteArg& arg8, const SubstituteArg& arg9) { const SubstituteArg* const args_array[] = { &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, nullptr }; diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h index 267dead236b3..d4e72e1c5166 100644 --- a/src/google/protobuf/stubs/substitute.h +++ b/src/google/protobuf/stubs/substitute.h @@ -90,8 +90,8 @@ class SubstituteArg { public: inline SubstituteArg(const char* value) : text_(value), size_(strlen(text_)) {} - inline SubstituteArg(const string& value) - : text_(value.data()), size_(value.size()) {} + inline SubstituteArg(const std::string& value) + : text_(value.data()), size_(value.size()) {} // Indicates that no argument was given. inline explicit SubstituteArg() @@ -139,21 +139,21 @@ class SubstituteArg { } // namespace internal -PROTOBUF_EXPORT string -Substitute(const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); +PROTOBUF_EXPORT std::string Substitute( + const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); PROTOBUF_EXPORT void SubstituteAndAppend( - string* output, const char* format, + std::string* output, const char* format, const internal::SubstituteArg& arg0 = internal::SubstituteArg(), const internal::SubstituteArg& arg1 = internal::SubstituteArg(), const internal::SubstituteArg& arg2 = internal::SubstituteArg(), diff --git a/src/google/protobuf/stubs/time.cc b/src/google/protobuf/stubs/time.cc index 64f3ceb9f6fb..922be76d1ba3 100644 --- a/src/google/protobuf/stubs/time.cc +++ b/src/google/protobuf/stubs/time.cc @@ -130,7 +130,7 @@ int64 SecondsSinceCommonEra(const DateTime& time) { // Format nanoseconds with either 3, 6, or 9 digits depending on the required // precision to represent the exact value. -string FormatNanos(int32 nanos) { +std::string FormatNanos(int32 nanos) { if (nanos % kNanosPerMillisecond == 0) { return StringPrintf("%03d", nanos / kNanosPerMillisecond); } else if (nanos % kNanosPerMicrosecond == 0) { @@ -268,21 +268,21 @@ void GetCurrentTime(int64* seconds, int32* nanos) { *nanos = 0; } -string FormatTime(int64 seconds, int32 nanos) { +std::string FormatTime(int64 seconds, int32 nanos) { DateTime time; if (nanos < 0 || nanos > 999999999 || !SecondsToDateTime(seconds, &time)) { return "InvalidTime"; } - string result = StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", - time.year, time.month, time.day, - time.hour, time.minute, time.second); + std::string result = + StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", time.year, time.month, + time.day, time.hour, time.minute, time.second); if (nanos != 0) { result += "." + FormatNanos(nanos); } return result + "Z"; } -bool ParseTime(const string& value, int64* seconds, int32* nanos) { +bool ParseTime(const std::string& value, int64* seconds, int32* nanos) { DateTime time; const char* data = value.c_str(); // We only accept: diff --git a/src/google/protobuf/stubs/time.h b/src/google/protobuf/stubs/time.h index b52f3f963290..b06117689e58 100644 --- a/src/google/protobuf/stubs/time.h +++ b/src/google/protobuf/stubs/time.h @@ -65,10 +65,10 @@ void PROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos); // value. // // Note that "nanos" must in the range of [0, 999999999]. -string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos); +std::string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos); // Parses a time string. This method accepts RFC3339 date/time string with UTC // offset. For example, "2015-05-20T13:29:35.120-08:00". -bool PROTOBUF_EXPORT ParseTime(const string& value, int64* seconds, +bool PROTOBUF_EXPORT ParseTime(const std::string& value, int64* seconds, int32* nanos); } // namespace internal diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc index 7d3708e3d64d..7b628879c64e 100644 --- a/src/google/protobuf/testing/file.cc +++ b/src/google/protobuf/testing/file.cc @@ -66,11 +66,12 @@ using google::protobuf::io::win32::mkdir; using google::protobuf::io::win32::stat; #endif -bool File::Exists(const string& name) { +bool File::Exists(const std::string& name) { return access(name.c_str(), F_OK) == 0; } -bool File::ReadFileToString(const string& name, string* output, bool text_mode) { +bool File::ReadFileToString(const std::string& name, std::string* output, + bool text_mode) { char buffer[1024]; FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb"); if (file == NULL) return false; @@ -86,11 +87,12 @@ bool File::ReadFileToString(const string& name, string* output, bool text_mode) return error == 0; } -void File::ReadFileToStringOrDie(const string& name, string* output) { +void File::ReadFileToStringOrDie(const std::string& name, std::string* output) { GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name; } -bool File::WriteStringToFile(const string& contents, const string& name) { +bool File::WriteStringToFile(const std::string& contents, + const std::string& name) { FILE* file = fopen(name.c_str(), "wb"); if (file == NULL) { GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno); @@ -109,7 +111,8 @@ bool File::WriteStringToFile(const string& contents, const string& name) { return true; } -void File::WriteStringToFileOrDie(const string& contents, const string& name) { +void File::WriteStringToFileOrDie(const std::string& contents, + const std::string& name) { FILE* file = fopen(name.c_str(), "wb"); GOOGLE_CHECK(file != NULL) << "fopen(" << name << ", \"wb\"): " << strerror(errno); @@ -120,21 +123,21 @@ void File::WriteStringToFileOrDie(const string& contents, const string& name) { << "fclose(" << name << "): " << strerror(errno); } -bool File::CreateDir(const string& name, int mode) { +bool File::CreateDir(const std::string& name, int mode) { if (!name.empty()) { GOOGLE_CHECK_OK(name[name.size() - 1] != '.'); } return mkdir(name.c_str(), mode) == 0; } -bool File::RecursivelyCreateDir(const string& path, int mode) { +bool File::RecursivelyCreateDir(const std::string& path, int mode) { if (CreateDir(path, mode)) return true; if (Exists(path)) return false; // Try creating the parent. - string::size_type slashpos = path.find_last_of('/'); - if (slashpos == string::npos) { + std::string::size_type slashpos = path.find_last_of('/'); + if (slashpos == std::string::npos) { // No parent given. return false; } @@ -143,8 +146,8 @@ bool File::RecursivelyCreateDir(const string& path, int mode) { CreateDir(path, mode); } -void File::DeleteRecursively(const string& name, - void* dummy1, void* dummy2) { +void File::DeleteRecursively(const std::string& name, void* dummy1, + void* dummy2) { if (name.empty()) return; // We don't care too much about error checking here since this is only used @@ -162,9 +165,9 @@ void File::DeleteRecursively(const string& name, } do { - string entry_name = find_data.cFileName; + std::string entry_name = find_data.cFileName; if (entry_name != "." && entry_name != "..") { - string path = name + "/" + entry_name; + std::string path = name + "/" + entry_name; if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { DeleteRecursively(path, NULL, NULL); RemoveDirectoryA(path.c_str()); @@ -188,7 +191,7 @@ void File::DeleteRecursively(const string& name, while (true) { struct dirent* entry = readdir(dir); if (entry == NULL) break; - string entry_name = entry->d_name; + std::string entry_name = entry->d_name; if (entry_name != "." && entry_name != "..") { DeleteRecursively(name + "/" + entry_name, NULL, NULL); } @@ -204,7 +207,7 @@ void File::DeleteRecursively(const string& name, #endif } -bool File::ChangeWorkingDirectory(const string& new_working_directory) { +bool File::ChangeWorkingDirectory(const std::string& new_working_directory) { return chdir(new_working_directory.c_str()) == 0; } diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h index 45989967c979..f18f68586521 100644 --- a/src/google/protobuf/testing/file.h +++ b/src/google/protobuf/testing/file.h @@ -46,52 +46,54 @@ const int DEFAULT_FILE_MODE = 0777; class File { public: // Check if the file exists. - static bool Exists(const string& name); + static bool Exists(const std::string& name); // Read an entire file to a string. Return true if successful, false // otherwise. - static bool ReadFileToString(const string& name, string* output, bool text_mode = false); + static bool ReadFileToString(const std::string& name, std::string* output, + bool text_mode = false); // Same as above, but crash on failure. - static void ReadFileToStringOrDie(const string& name, string* output); + static void ReadFileToStringOrDie(const std::string& name, + std::string* output); // Create a file and write a string to it. - static bool WriteStringToFile(const string& contents, - const string& name); + static bool WriteStringToFile(const std::string& contents, + const std::string& name); // Same as above, but crash on failure. - static void WriteStringToFileOrDie(const string& contents, - const string& name); + static void WriteStringToFileOrDie(const std::string& contents, + const std::string& name); // Create a directory. - static bool CreateDir(const string& name, int mode); + static bool CreateDir(const std::string& name, int mode); // Create a directory and all parent directories if necessary. - static bool RecursivelyCreateDir(const string& path, int mode); + static bool RecursivelyCreateDir(const std::string& path, int mode); // If "name" is a file, we delete it. If it is a directory, we // call DeleteRecursively() for each file or directory (other than // dot and double-dot) within it, and then delete the directory itself. // The "dummy" parameters have a meaning in the original version of this // method but they are not used anywhere in protocol buffers. - static void DeleteRecursively(const string& name, - void* dummy1, void* dummy2); + static void DeleteRecursively(const std::string& name, void* dummy1, + void* dummy2); // Change working directory to given directory. - static bool ChangeWorkingDirectory(const string& new_working_directory); + static bool ChangeWorkingDirectory(const std::string& new_working_directory); - static bool GetContents( - const string& name, string* output, bool /*is_default*/) { + static bool GetContents(const std::string& name, std::string* output, + bool /*is_default*/) { return ReadFileToString(name, output); } - static bool GetContentsAsText( - const string& name, string* output, bool /*is_default*/) { + static bool GetContentsAsText(const std::string& name, std::string* output, + bool /*is_default*/) { return ReadFileToString(name, output, true); } - static bool SetContents( - const string& name, const string& contents, bool /*is_default*/) { + static bool SetContents(const std::string& name, const std::string& contents, + bool /*is_default*/) { return WriteStringToFile(contents, name); } diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc index 1856971cb8b3..88343f934761 100644 --- a/src/google/protobuf/testing/googletest.cc +++ b/src/google/protobuf/testing/googletest.cc @@ -70,7 +70,7 @@ using google::protobuf::io::win32::open; #endif #endif -string TestSourceDir() { +std::string TestSourceDir() { #ifndef GOOGLE_THIRD_PARTY_PROTOBUF #ifdef GOOGLE_PROTOBUF_TEST_SOURCE_PATH return GOOGLE_PROTOBUF_TEST_SOURCE_PATH; @@ -84,7 +84,7 @@ string TestSourceDir() { #endif // _MSC_VER // Look for the "src" directory. - string prefix = "."; + std::string prefix = "."; // Keep looking further up the directory tree until we find // src/.../descriptor.cc. It is important to look for a particular file, @@ -107,12 +107,12 @@ string TestSourceDir() { namespace { -string GetTemporaryDirectoryName() { +std::string GetTemporaryDirectoryName() { // Tests run under Bazel "should not" use /tmp. Bazel sets this environment // variable for tests to use instead. char *from_environment = getenv("TEST_TMPDIR"); if (from_environment != NULL && from_environment[0] != '\0') { - return string(from_environment) + "/protobuf_tmpdir"; + return std::string(from_environment) + "/protobuf_tmpdir"; } // tmpnam() is generally not considered safe but we're only using it for @@ -121,7 +121,7 @@ string GetTemporaryDirectoryName() { char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - string result = tmpnam(b); + std::string result = tmpnam(b); #pragma GCC diagnostic pop #ifdef _WIN32 // Avoid a trailing dot by changing it to an underscore. On Win32 the names of @@ -166,7 +166,7 @@ class TempDirDeleter { } } - string GetTempDir() { + std::string GetTempDir() { if (name_.empty()) { name_ = GetTemporaryDirectoryName(); GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno); @@ -179,21 +179,19 @@ class TempDirDeleter { } private: - string name_; + std::string name_; }; TempDirDeleter temp_dir_deleter_; } // namespace -string TestTempDir() { - return temp_dir_deleter_.GetTempDir(); -} +std::string TestTempDir() { return temp_dir_deleter_.GetTempDir(); } // TODO(kenton): Share duplicated code below. Too busy/lazy for now. -static string stdout_capture_filename_; -static string stderr_capture_filename_; +static std::string stdout_capture_filename_; +static std::string stderr_capture_filename_; static int original_stdout_ = -1; static int original_stderr_ = -1; @@ -227,14 +225,14 @@ void CaptureTestStderr() { close(fd); } -string GetCapturedTestStdout() { +std::string GetCapturedTestStdout() { GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing."; close(1); dup2(original_stdout_, 1); original_stdout_ = -1; - string result; + std::string result; File::ReadFileToStringOrDie(stdout_capture_filename_, &result); remove(stdout_capture_filename_.c_str()); @@ -242,14 +240,14 @@ string GetCapturedTestStdout() { return result; } -string GetCapturedTestStderr() { +std::string GetCapturedTestStderr() { GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing."; close(2); dup2(original_stderr_, 2); original_stderr_ = -1; - string result; + std::string result; File::ReadFileToStringOrDie(stderr_capture_filename_, &result); remove(stderr_capture_filename_.c_str()); @@ -270,14 +268,14 @@ ScopedMemoryLog::~ScopedMemoryLog() { active_log_ = NULL; } -const std::vector& ScopedMemoryLog::GetMessages(LogLevel level) { +const std::vector& ScopedMemoryLog::GetMessages(LogLevel level) { GOOGLE_CHECK(level == ERROR || level == WARNING); return messages_[level]; } -void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, - int line, const string& message) { +void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, int line, + const std::string& message) { GOOGLE_CHECK(active_log_ != NULL); if (level == ERROR || level == WARNING) { active_log_->messages_[level].push_back(message); diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h index 4e0cb83a8502..6a0c694e71a6 100644 --- a/src/google/protobuf/testing/googletest.h +++ b/src/google/protobuf/testing/googletest.h @@ -49,19 +49,19 @@ namespace google { namespace protobuf { // When running unittests, get the directory containing the source code. -string TestSourceDir(); +std::string TestSourceDir(); // When running unittests, get a directory where temporary files may be // placed. -string TestTempDir(); +std::string TestTempDir(); // Capture all text written to stdout or stderr. void CaptureTestStdout(); void CaptureTestStderr(); // Stop capturing stdout or stderr and return the text captured. -string GetCapturedTestStdout(); -string GetCapturedTestStderr(); +std::string GetCapturedTestStdout(); +std::string GetCapturedTestStderr(); // For use with ScopedMemoryLog::GetMessages(). Inside Google the LogLevel // constants don't have the LOGLEVEL_ prefix, so the code that used @@ -84,14 +84,14 @@ class ScopedMemoryLog { virtual ~ScopedMemoryLog(); // Fetches all messages with the given severity level. - const std::vector& GetMessages(LogLevel error); + const std::vector& GetMessages(LogLevel error); private: - std::map > messages_; + std::map > messages_; LogHandler* old_handler_; static void HandleLog(LogLevel level, const char* filename, int line, - const string& message); + const std::string& message); static ScopedMemoryLog* active_log_; diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 323b0e099918..f47d4e8d013a 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -2052,8 +2052,8 @@ void TextFormat::Printer::Print(const Message& message, if (print_message_fields_in_index_order_) { std::sort(fields.begin(), fields.end(), FieldIndexSorter()); } - for (int i = 0; i < fields.size(); i++) { - PrintField(message, reflection, fields[i], generator); + for (const FieldDescriptor* field : fields) { + PrintField(message, reflection, field, generator); } if (!hide_unknown_fields_) { PrintUnknownFields(reflection->GetUnknownFields(message), generator, @@ -2312,8 +2312,8 @@ void TextFormat::Printer::PrintField(const Message& message, } if (need_release) { - for (int j = 0; j < sorted_map_field.size(); ++j) { - delete sorted_map_field[j]; + for (const Message* message_to_delete : sorted_map_field) { + delete message_to_delete; } } } diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto index 50bb99600244..f774c766e31b 100644 --- a/src/google/protobuf/unittest_custom_options.proto +++ b/src/google/protobuf/unittest_custom_options.proto @@ -45,6 +45,7 @@ option py_generic_services = true; // A custom file option (defined below). option (file_opt1) = 9876543210; +import "google/protobuf/any.proto"; import "google/protobuf/descriptor.proto"; // We don't put this in a package within proto2 because we need to make sure @@ -329,6 +330,9 @@ message Aggregate { // An embedded message set optional AggregateMessageSet mset = 5; + + // An any + optional google.protobuf.Any any = 6; } // Allow Aggregate to be used as an option at all possible locations @@ -376,6 +380,12 @@ option (fileopt) = { s: 'EmbeddedMessageSetElement' } } + + any { + [type.googleapis.com/protobuf_unittest.AggregateMessageSetElement] { + s: 'EmbeddedMessageSetElement' + } + } }; message AggregateMessage { diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index 451209c79750..f40a577cb2d2 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc @@ -108,8 +108,7 @@ size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const { size_t total_size = sizeof(fields_) + sizeof(UnknownField) * fields_.size(); - for (int i = 0; i < fields_.size(); i++) { - const UnknownField& field = (fields_)[i]; + for (const UnknownField& field : fields_) { switch (field.type()) { case UnknownField::TYPE_LENGTH_DELIMITED: total_size += sizeof(*field.data_.length_delimited_.string_value) + diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index 240db516a426..24a71425cafe 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -69,6 +69,7 @@ ProtoWriter::ProtoWriter(TypeResolver* type_resolver, ignore_unknown_enum_values_(false), use_lower_camel_for_enums_(false), case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), element_(nullptr), size_insert_(), output_(output), @@ -90,6 +91,7 @@ ProtoWriter::ProtoWriter(const TypeInfo* typeinfo, ignore_unknown_enum_values_(false), use_lower_camel_for_enums_(false), case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), element_(nullptr), size_insert_(), output_(output), @@ -618,26 +620,12 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( // Pushing a ProtoElement and then pop it off at the end for 2 purposes: // error location reporting and required field accounting. // - // For proto3, since there is no required field tracking, we only need to push - // ProtoElement for error cases. + // For proto3, since there is no required field tracking, we only need to + // push ProtoElement for error cases. if (!element_->proto3()) { element_.reset(new ProtoElement(element_.release(), &field, type, false)); } - if (field.kind() == google::protobuf::Field::TYPE_UNKNOWN || - field.kind() == google::protobuf::Field::TYPE_MESSAGE) { - // Push a ProtoElement for location reporting purposes. - if (element_->proto3()) { - element_.reset(new ProtoElement(element_.release(), &field, type, false)); - } - InvalidValue(field.type_url().empty() - ? google::protobuf::Field_Kind_Name(field.kind()) - : field.type_url(), - data.ValueAsStringOrDefault("")); - element_.reset(element()->pop()); - return this; - } - switch (field.kind()) { case google::protobuf::Field::TYPE_INT32: { status = WriteInt32(field.number(), data, stream_.get()); @@ -706,9 +694,9 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( case_insensitive_enum_parsing_, ignore_unknown_enum_values_); break; } - default: // TYPE_GROUP or TYPE_MESSAGE + default: // TYPE_GROUP, TYPE_MESSAGE, TYPE_UNKNOWN. status = util::Status(util::error::INVALID_ARGUMENT, - data.ToString().value()); + data.ValueAsStringOrDefault("")); } if (!status.ok()) { @@ -716,7 +704,9 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( if (element_->proto3()) { element_.reset(new ProtoElement(element_.release(), &field, type, false)); } - InvalidValue(google::protobuf::Field_Kind_Name(field.kind()), + InvalidValue(field.type_url().empty() + ? google::protobuf::Field_Kind_Name(field.kind()) + : field.type_url(), status.message()); element_.reset(element()->pop()); return this; diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 564050f4f661..211b7bcbf8f5 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -1000,7 +1000,10 @@ TEST_P(ProtoStreamObjectWriterTest, Proto3Message expected; EXPECT_CALL( listener_, - InvalidValue(_, StringPiece("TYPE_ENUM"), + InvalidValue(_, + StringPiece( + "type.googleapis.com/" + "proto_util_converter.testing.Proto3Message.NestedEnum"), StringPiece("\"someunknownvalueyouwillneverknow\""))) .With(Args<0>(HasObjectLocation("enum_value"))); ow_->StartObject("") diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 1388e9d33a9d..12cbf945ef10 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -112,8 +112,8 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator : message_differencer_(message_differencer), key_field_paths_(key_field_paths) { GOOGLE_CHECK(!key_field_paths_.empty()); - for (int i = 0; i < key_field_paths_.size(); ++i) { - GOOGLE_CHECK(!key_field_paths_[i].empty()); + for (const auto& path : key_field_paths_) { + GOOGLE_CHECK(!path.empty()); } } MultipleFieldsMapKeyComparator(MessageDifferencer* message_differencer, @@ -125,9 +125,8 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator } bool IsMatch(const Message& message1, const Message& message2, const std::vector& parent_fields) const override { - for (int i = 0; i < key_field_paths_.size(); ++i) { - if (!IsMatchInternal(message1, message2, parent_fields, - key_field_paths_[i], 0)) { + for (const auto& path : key_field_paths_) { + if (!IsMatchInternal(message1, message2, parent_fields, path, 0)) { return false; } } @@ -276,11 +275,11 @@ MessageDifferencer::MessageDifferencer() MatchIndicesPostProcessorForSmartList) {} MessageDifferencer::~MessageDifferencer() { - for (int i = 0; i < owned_key_comparators_.size(); ++i) { - delete owned_key_comparators_[i]; + for (MapKeyComparator* comparator : owned_key_comparators_) { + delete comparator; } - for (int i = 0; i < ignore_criteria_.size(); ++i) { - delete ignore_criteria_[i]; + for (IgnoreCriteria* criteria : ignore_criteria_) { + delete criteria; } } @@ -380,9 +379,9 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey( const FieldDescriptor* field, const std::vector& key_fields) { std::vector > key_field_paths; - for (int i = 0; i < key_fields.size(); ++i) { + for (const FieldDescriptor* key_filed : key_fields) { std::vector key_field_path; - key_field_path.push_back(key_fields[i]); + key_field_path.push_back(key_filed); key_field_paths.push_back(key_field_path); } TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths); @@ -395,9 +394,7 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey( << "Field must be repeated: " << field->full_name(); GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) << "Field has to be message type. Field name is: " << field->full_name(); - for (int i = 0; i < key_field_paths.size(); ++i) { - const std::vector& key_field_path = - key_field_paths[i]; + for (const auto& key_field_path : key_field_paths) { for (int j = 0; j < key_field_path.size(); ++j) { const FieldDescriptor* parent_field = j == 0 ? field : key_field_path[j - 1]; @@ -1236,10 +1233,11 @@ bool MessageDifferencer::CompareFieldValueUsingParentFields( bool MessageDifferencer::CheckPathChanged( const std::vector& field_path) { - for (int i = 0; i < field_path.size(); ++i) { + for (const SpecificField& specific_field : field_path) { // Don't check indexes for map entries -- maps are unordered. - if (field_path[i].field != NULL && field_path[i].field->is_map()) continue; - if (field_path[i].index != field_path[i].new_index) return true; + if (specific_field.field != nullptr && specific_field.field->is_map()) + continue; + if (specific_field.index != specific_field.new_index) return true; } return false; } @@ -1286,9 +1284,8 @@ bool MessageDifferencer::IsIgnored( if (ignored_fields_.find(field) != ignored_fields_.end()) { return true; } - for (int i = 0; i < ignore_criteria_.size(); ++i) { - if (ignore_criteria_[i]->IsIgnored(message1, message2, field, - parent_fields)) { + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsIgnored(message1, message2, field, parent_fields)) { return true; } } @@ -1299,9 +1296,9 @@ bool MessageDifferencer::IsUnknownFieldIgnored( const Message& message1, const Message& message2, const SpecificField& field, const std::vector& parent_fields) { - for (int i = 0; i < ignore_criteria_.size(); ++i) { - if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field, - parent_fields)) { + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsUnknownFieldIgnored(message1, message2, field, + parent_fields)) { return true; } } diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index 2f40d21eca3e..2f5908ee1fe4 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -1462,8 +1462,8 @@ size_t WireFormat::ByteSize(const Message& message) { message_reflection->ListFields(message, &fields); } - for (int i = 0; i < fields.size(); i++) { - our_size += FieldByteSize(fields[i], message); + for (const FieldDescriptor* field : fields) { + our_size += FieldByteSize(field, message); } if (descriptor->options().message_set_wire_format()) { diff --git a/tests.sh b/tests.sh index 8b499d0a3e11..5113e4a73163 100755 --- a/tests.sh +++ b/tests.sh @@ -316,7 +316,7 @@ build_python() { else envlist=py\{27,36\}-python fi - tox -e $envlist + python -m tox -e $envlist cd .. } @@ -324,7 +324,7 @@ build_python_version() { internal_build_cpp cd python envlist=$1 - tox -e $envlist + python -m tox -e $envlist cd .. } @@ -467,45 +467,6 @@ use_php_zts() { internal_build_cpp } -build_php5.5() { - use_php 5.5 - - pushd php - rm -rf vendor - composer update - composer test - popd - (cd conformance && make test_php) -} - -build_php5.6() { - use_php 5.6 - pushd php - rm -rf vendor - composer update - composer test - popd - (cd conformance && make test_php) -} - -build_php5.6_mac() { - # Install PHP - curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6 - PHP_FOLDER=`find /usr/local -type d -name "php5-5.6*"` # The folder name may change upon time - test ! -z "$PHP_FOLDER" - export PATH="$PHP_FOLDER/bin:$PATH" - - internal_build_cpp - - # Run pure-PHP tests only. - pushd php - rm -rf vendor - composer update - composer test - popd - (cd conformance && make test_php) -} - build_php7.0() { use_php 7.0 pushd php @@ -747,8 +708,6 @@ build_php8.0_all() { } build_php_all_32() { - build_php5.5 - build_php5.6 build_php7.0 build_php7.1 build_php7.4 @@ -803,8 +762,6 @@ Usage: $0 { cpp | ruby27 | jruby | ruby_all | - php5.5 | - php5.6 | php7.0 | php7.0_c | php_compatibility | From 3fff95e1bd59209a17cd6e3f7e0218eacb35cd88 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 23 Oct 2020 11:04:54 -0700 Subject: [PATCH 06/15] Updated changelog. --- CHANGES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index e02fa98c97a4..a4d2ac0622d9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,7 @@ Unreleased Changes * The proto compiler no longer requires a .proto filename when it is not generating code. * Added flag `--deterministic_output` to `protoc --encode=...`. + * Fixed deadlock when using google.protobuf.Any embedded in aggregate options. C++ * Arenas are now unconditionally enabled. cc_enable_arenas no longer has @@ -25,6 +26,8 @@ Unreleased Changes * Fix a crash in BuildFile when passing in invalid descriptor proto. * Parser security fix when operating with CodedInputStream. * Warn against the use of AllowUnknownExtension. + * Migrated to C++11 for-range loops instead of index-based loops where + possible. This fixes a lot of warnings when compiling with -Wsign-compare. Java * Bugfix in mergeFrom() when a oneof has multiple message fields. @@ -32,6 +35,9 @@ Unreleased Changes 0 bytes when not at EOF. * Redefine remove(Object) on primitive repeated field Lists to avoid autoboxing. + * Support "\u" escapes in textformat string literals. + * Trailing empty spaces are no longer ignored for FieldMask. + * Fix FieldMaskUtil.subtract to recursively remove mask. Python * Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is From b70695dd68488e0a9bc847de69dadc6b47e251e9 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 23 Oct 2020 11:07:04 -0700 Subject: [PATCH 07/15] Sync from Piper @338707351 PROTOBUF_SYNC_PIPER --- .../Google.Protobuf/Google.Protobuf.csproj | 2 +- java/pom.xml | 2 +- objectivec/DevTools/full_mac_build.sh | 6 +- .../project.pbxproj | 8 +- objectivec/Tests/GPBTestUtilities.m | 2 +- .../protobuf/internal/api_implementation.py | 7 +- python/google/protobuf/text_format.py | 4 +- src/google/protobuf/arena.cc | 88 ++-- src/google/protobuf/arena.h | 24 +- src/google/protobuf/arena_impl.h | 454 +++++++++--------- src/google/protobuf/arena_unittest.cc | 1 + .../csharp/csharp_bootstrap_unittest.cc | 24 +- .../compiler/csharp/csharp_doc_comment.cc | 25 +- .../protobuf/compiler/csharp/csharp_enum.cc | 7 +- .../compiler/csharp/csharp_field_base.cc | 12 +- .../compiler/csharp/csharp_field_base.h | 7 +- .../compiler/csharp/csharp_generator.cc | 14 +- .../compiler/csharp/csharp_generator.h | 4 +- .../compiler/csharp/csharp_helpers.cc | 19 +- .../protobuf/compiler/csharp/csharp_helpers.h | 2 +- .../compiler/csharp/csharp_message.cc | 10 +- .../protobuf/compiler/csharp/csharp_names.h | 16 +- .../protobuf/compiler/java/java_enum.cc | 5 +- .../protobuf/compiler/java/java_enum_lite.cc | 5 +- .../protobuf/compiler/java/java_file.cc | 5 +- .../compiler/objectivec/objectivec_enum.cc | 10 +- .../compiler/objectivec/objectivec_enum.h | 4 +- .../objectivec/objectivec_enum_field.cc | 8 +- .../objectivec/objectivec_enum_field.h | 3 +- .../objectivec/objectivec_extension.cc | 20 +- .../objectivec/objectivec_extension.h | 8 +- .../compiler/objectivec/objectivec_field.cc | 18 +- .../compiler/objectivec/objectivec_field.h | 19 +- .../compiler/objectivec/objectivec_file.cc | 23 +- .../compiler/objectivec/objectivec_file.h | 7 +- .../objectivec/objectivec_generator.cc | 16 +- .../objectivec/objectivec_generator.h | 11 +- .../compiler/objectivec/objectivec_helpers.cc | 388 +++++++-------- .../compiler/objectivec/objectivec_helpers.h | 149 +++--- .../objectivec/objectivec_helpers_unittest.cc | 40 +- .../objectivec/objectivec_map_field.cc | 20 +- .../objectivec/objectivec_map_field.h | 6 +- .../compiler/objectivec/objectivec_message.cc | 31 +- .../compiler/objectivec/objectivec_message.h | 15 +- .../objectivec/objectivec_message_field.cc | 15 +- .../objectivec/objectivec_message_field.h | 12 +- .../compiler/objectivec/objectivec_oneof.cc | 10 +- .../compiler/objectivec/objectivec_oneof.h | 6 +- .../objectivec/objectivec_primitive_field.cc | 4 +- .../protobuf/compiler/php/php_generator.cc | 162 ++++--- .../protobuf/compiler/php/php_generator.h | 8 +- .../compiler/ruby/ruby_generator_unittest.cc | 16 +- src/google/protobuf/descriptor.cc | 3 - 53 files changed, 911 insertions(+), 874 deletions(-) diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index 082a398bfe8e..706d836a3d08 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -30,7 +30,7 @@ - + diff --git a/java/pom.xml b/java/pom.xml index bb91146fd205..80e76add8af3 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -75,7 +75,7 @@ junit junit - 4.13 + 4.13.1 test diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh index 4df131408eb8..9319b5587176 100755 --- a/objectivec/DevTools/full_mac_build.sh +++ b/objectivec/DevTools/full_mac_build.sh @@ -289,7 +289,7 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then -disable-concurrent-destination-testing ) ;; - 11.*) + 11.* | 12.*) # Dropped 32bit as Apple doesn't seem support the simulators either. XCODEBUILD_TEST_BASE_IOS+=( -destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit @@ -352,10 +352,8 @@ if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then echo "ERROR: Xcode 10.0 or higher is required to build the test suite." 1>&2 exit 11 ;; - 10.* | 11.* ) + 10.* | 11.* | 12.*) XCODEBUILD_TEST_BASE_TVOS+=( - # Test on the oldest and current. - -destination "platform=tvOS Simulator,name=Apple TV,OS=11.0" -destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest" ) ;; diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj index 12d0ffd61a7f..f0f82c828937 100644 --- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj +++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj @@ -856,13 +856,11 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; - ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", "$(inherited)", ); INFOPLIST_FILE = "Tests/UnitTests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -889,13 +887,11 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; - ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", "$(inherited)", ); INFOPLIST_FILE = "Tests/UnitTests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -972,7 +968,7 @@ GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_PROFILING_CODE = NO; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; ONLY_ACTIVE_ARCH = YES; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; @@ -1041,7 +1037,7 @@ GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_PROFILING_CODE = NO; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; diff --git a/objectivec/Tests/GPBTestUtilities.m b/objectivec/Tests/GPBTestUtilities.m index 0362bdde647c..48d75e794ab8 100644 --- a/objectivec/Tests/GPBTestUtilities.m +++ b/objectivec/Tests/GPBTestUtilities.m @@ -779,7 +779,7 @@ - (void)setAllFields:(TestAllTypes *)message repeatedCount:(uint32_t)count { [message.repeatedSfixed64Array addValue:210 + i * 100]; [message.repeatedFloatArray addValue:211 + i * 100]; [message.repeatedDoubleArray addValue:212 + i * 100]; - [message.repeatedBoolArray addValue:(i % 2)]; + [message.repeatedBoolArray addValue:(BOOL)(i % 2)]; NSString *string = [[NSString alloc] initWithFormat:@"%d", 215 + i * 100]; [message.repeatedStringArray addObject:string]; [string release]; diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py index e8448e88a62b..7592be4eed3d 100644 --- a/python/google/protobuf/internal/api_implementation.py +++ b/python/google/protobuf/internal/api_implementation.py @@ -60,11 +60,16 @@ raise ImportError('_use_fast_cpp_protos import succeeded but was None') del _use_fast_cpp_protos _api_version = 2 + # Can not import both use_fast_cpp_protos and use_pure_python. + from google.protobuf import use_pure_python + raise RuntimeError( + 'Conflict depend on both use_fast_cpp_protos and use_pure_python') except ImportError: try: # pylint: disable=g-import-not-at-top - from google.protobuf.internal import use_pure_python + from google.protobuf import use_pure_python del use_pure_python # Avoids a pylint error and namespace pollution. + _api_version = 0 except ImportError: # TODO(b/74017912): It's unsafe to enable :use_fast_cpp_protos by default; # it can cause data loss if you have any Python-only extensions to any diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index c2bec1cc6b58..9ebe8b46b17e 100644 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -882,9 +882,11 @@ def _MergeField(self, tokenizer, message): raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (expanded_any_end_token,)) self._MergeField(tokenizer, expanded_any_sub_message) + deterministic = False + message.Pack(expanded_any_sub_message, type_url_prefix=type_url_prefix, - deterministic=True) + deterministic=deterministic) return if tokenizer.TryConsume('['): diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 631a08e0cee8..414e0234f75c 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -53,10 +53,6 @@ PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)( namespace internal { -const size_t ArenaImpl::kBlockHeaderSize; -const size_t ArenaImpl::kSerialArenaSize; -const size_t ArenaImpl::kOptionsSize; - ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) @@ -108,7 +104,8 @@ ArenaImpl::ArenaImpl(const ArenaOptions& options) { // Create the special block. const bool special = true; const bool user_owned = (mem == options.initial_block); - auto block = new (mem) Block(mem_size, nullptr, special, user_owned); + auto block = + new (mem) SerialArena::Block(mem_size, nullptr, special, user_owned); // Options occupy the beginning of the initial block. options_ = new (block->Pointer(block->pos())) Options; @@ -152,7 +149,7 @@ void ArenaImpl::Init(bool record_allocs) { space_allocated_.store(0, std::memory_order_relaxed); } -void ArenaImpl::SetInitialBlock(Block* block) { +void ArenaImpl::SetInitialBlock(SerialArena::Block* block) { // Calling thread owns the first block. This allows the single-threaded case // to allocate on the first block without having to perform atomic operations. SerialArena* serial = SerialArena::New(block, &thread_cache(), this); @@ -174,7 +171,7 @@ ArenaImpl::~ArenaImpl() { deallocator = options_->block_dealloc; } - PerBlock([deallocator](Block* b) { + PerBlock([deallocator](SerialArena::Block* b) { #ifdef ADDRESS_SANITIZER // This memory was provided by the underlying allocator as unpoisoned, so // return it in an unpoisoned state. @@ -201,25 +198,26 @@ uint64 ArenaImpl::Reset() { // Discard all blocks except the special block (if present). uint64 space_allocated = 0; - Block* special_block = nullptr; + SerialArena::Block* special_block = nullptr; auto deallocator = (options_ ? options_->block_dealloc : &ArenaFree); - PerBlock([&space_allocated, &special_block, deallocator](Block* b) { - space_allocated += b->size(); + PerBlock( + [&space_allocated, &special_block, deallocator](SerialArena::Block* b) { + space_allocated += b->size(); #ifdef ADDRESS_SANITIZER - // This memory was provided by the underlying allocator as unpoisoned, so - // return it in an unpoisoned state. - ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); + // This memory was provided by the underlying allocator as unpoisoned, + // so return it in an unpoisoned state. + ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); #endif // ADDRESS_SANITIZER - if (!b->special()) { - (*deallocator)(b, b->size()); - } else { - // Prepare special block for reuse. - // Note: if options_ is present, it occupies the beginning of the - // block and therefore pos is advanced past it. - GOOGLE_DCHECK(special_block == nullptr); - special_block = b; - } - }); + if (!b->special()) { + (*deallocator)(b, b->size()); + } else { + // Prepare special block for reuse. + // Note: if options_ is present, it occupies the beginning of the + // block and therefore pos is advanced past it. + GOOGLE_DCHECK(special_block == nullptr); + special_block = b; + } + }); Init(record_allocs()); if (special_block != nullptr) { @@ -233,12 +231,13 @@ uint64 ArenaImpl::Reset() { return space_allocated; } -ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) { +std::pair ArenaImpl::NewBuffer(size_t last_size, + size_t min_bytes) { size_t size; - if (last_block) { + if (last_size != -1) { // Double the current block size, up to a limit. auto max_size = options_ ? options_->max_block_size : kDefaultMaxBlockSize; - size = std::min(2 * last_block->size(), max_size); + size = std::min(2 * last_size, max_size); } else { size = options_ ? options_->start_block_size : kDefaultStartBlockSize; } @@ -247,14 +246,22 @@ ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) { size = std::max(size, kBlockHeaderSize + min_bytes); void* mem = options_ ? (*options_->block_alloc)(size) : ::operator new(size); - Block* b = new (mem) Block(size, last_block, false, false); space_allocated_.fetch_add(size, std::memory_order_relaxed); + return {mem, size}; +} + +SerialArena::Block* SerialArena::NewBlock(SerialArena::Block* last_block, + size_t min_bytes, ArenaImpl* arena) { + void* mem; + size_t size; + std::tie(mem, size) = + arena->NewBuffer(last_block ? last_block->size() : -1, min_bytes); + Block* b = new (mem) Block(size, last_block, false, false); return b; } PROTOBUF_NOINLINE -void ArenaImpl::SerialArena::AddCleanupFallback(void* elem, - void (*cleanup)(void*)) { +void SerialArena::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { size_t size = cleanup_ ? cleanup_->size * 2 : kMinCleanupListElements; size = std::min(size, kMaxCleanupListElements); size_t bytes = internal::AlignUpTo8(CleanupChunk::SizeOf(size)); @@ -306,11 +313,11 @@ void ArenaImpl::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { } PROTOBUF_NOINLINE -void* ArenaImpl::SerialArena::AllocateAlignedFallback(size_t n) { +void* SerialArena::AllocateAlignedFallback(size_t n) { // Sync back to current's pos. head_->set_pos(head_->size() - (limit_ - ptr_)); - head_ = arena_->NewBlock(head_, n); + head_ = NewBlock(head_, n, arena_); ptr_ = head_->Pointer(head_->pos()); limit_ = head_->Pointer(head_->size()); @@ -338,7 +345,7 @@ uint64 ArenaImpl::SpaceUsed() const { return space_used; } -uint64 ArenaImpl::SerialArena::SpaceUsed() const { +uint64 SerialArena::SpaceUsed() const { // Get current block's size from ptr_ (since we can't trust head_->pos(). uint64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize); // Get subsequent block size from b->pos(). @@ -346,7 +353,7 @@ uint64 ArenaImpl::SerialArena::SpaceUsed() const { space_used += (b->pos() - kBlockHeaderSize); } // Remove the overhead of the SerialArena itself. - space_used -= kSerialArenaSize; + space_used -= ArenaImpl::kSerialArenaSize; return space_used; } @@ -360,13 +367,13 @@ void ArenaImpl::CleanupList() { } } -void ArenaImpl::SerialArena::CleanupList() { +void SerialArena::CleanupList() { if (cleanup_ != NULL) { CleanupListFallback(); } } -void ArenaImpl::SerialArena::CleanupListFallback() { +void SerialArena::CleanupListFallback() { // The first chunk might be only partially full, so calculate its size // from cleanup_ptr_. Subsequent chunks are always full, so use list->size. size_t n = cleanup_ptr_ - &cleanup_->nodes[0]; @@ -386,12 +393,11 @@ void ArenaImpl::SerialArena::CleanupListFallback() { } } -ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner, - ArenaImpl* arena) { +SerialArena* SerialArena::New(Block* b, void* owner, ArenaImpl* arena) { auto pos = b->pos(); - GOOGLE_DCHECK_LE(pos + kSerialArenaSize, b->size()); + GOOGLE_DCHECK_LE(pos + ArenaImpl::kSerialArenaSize, b->size()); SerialArena* serial = reinterpret_cast(b->Pointer(pos)); - b->set_pos(pos + kSerialArenaSize); + b->set_pos(pos + ArenaImpl::kSerialArenaSize); serial->arena_ = arena; serial->owner_ = owner; serial->head_ = b; @@ -404,7 +410,7 @@ ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner, } PROTOBUF_NOINLINE -ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { +SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { // Look for this SerialArena in our linked list. SerialArena* serial = threads_.load(std::memory_order_acquire); for (; serial; serial = serial->next()) { @@ -416,7 +422,7 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { if (!serial) { // This thread doesn't have any SerialArena, which also means it doesn't // have any blocks yet. So we'll allocate its first block now. - Block* b = NewBlock(NULL, kSerialArenaSize); + SerialArena::Block* b = SerialArena::NewBlock(NULL, kSerialArenaSize, this); serial = SerialArena::New(b, me, this); SerialArena* head = threads_.load(std::memory_order_relaxed); diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 8ab4fc8e1bcb..f28bebfd3437 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -486,15 +486,23 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // when allocation recording is enabled. template PROTOBUF_ALWAYS_INLINE void* AllocateInternal(bool skip_explicit_ownership) { - static_assert(alignof(T) <= 8, "T is overaligned, see b/151247138"); const size_t n = internal::AlignUpTo8(sizeof(T)); - impl_.RecordAlloc(RTTI_TYPE_ID(T), n); // Monitor allocation if needed. + impl_.RecordAlloc(RTTI_TYPE_ID(T), n); if (skip_explicit_ownership) { - return AllocateAlignedNoHook(n); + return AllocateAlignedTo(sizeof(T)); } else { - return impl_.AllocateAlignedAndAddCleanup( - n, &internal::arena_destruct_object); + if (alignof(T) <= 8) { + return impl_.AllocateAlignedAndAddCleanup( + n, &internal::arena_destruct_object); + } else { + auto ptr = + reinterpret_cast(impl_.AllocateAlignedAndAddCleanup( + sizeof(T) + alignof(T) - 8, + &internal::arena_destruct_object)); + return reinterpret_cast((ptr + alignof(T) - 8) & + (~alignof(T) + 1)); + } } } @@ -549,10 +557,12 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { PROTOBUF_ALWAYS_INLINE T* CreateInternalRawArray(size_t num_elements) { GOOGLE_CHECK_LE(num_elements, std::numeric_limits::max() / sizeof(T)) << "Requested size is too large to fit into size_t."; + // We count on compiler to realize that if sizeof(T) is a multiple of + // 8 AlignUpTo can be elided. const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements); // Monitor allocation if needed. impl_.RecordAlloc(RTTI_TYPE_ID(T), n); - return static_cast(AllocateAlignedNoHook(n)); + return static_cast(AllocateAlignedTo(n)); } template @@ -655,7 +665,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // TODO(b/151247138): if the pointer would have been aligned already, // this is wasting space. We should pass the alignment down. uintptr_t ptr = reinterpret_cast(AllocateAligned(n + Align - 8)); - ptr = (ptr + Align - 1) & -Align; + ptr = (ptr + Align - 1) & (~Align + 1); return reinterpret_cast(ptr); } diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index ec86daba2005..31f31384be3d 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -90,6 +90,164 @@ class PROTOBUF_EXPORT ArenaMetricsCollector { uint64 alloc_size) = 0; }; +class ArenaImpl; + +// A thread-unsafe Arena that can only be used within its owning thread. +class PROTOBUF_EXPORT SerialArena { + public: + // Blocks are variable length malloc-ed objects. The following structure + // describes the common header for all blocks. + class PROTOBUF_EXPORT Block { + public: + Block(size_t size, Block* next, bool special, bool user_owned) + : next_and_bits_(reinterpret_cast(next) | (special ? 1 : 0) | + (user_owned ? 2 : 0)), + pos_(kBlockHeaderSize), + size_(size) { + GOOGLE_DCHECK_EQ(reinterpret_cast(next) & 3, 0u); + } + + char* Pointer(size_t n) { + GOOGLE_DCHECK(n <= size_); + return reinterpret_cast(this) + n; + } + + // One of the blocks may be special. This is either a user-supplied + // initial block, or a block we created at startup to hold Options info. + // A special block is not deleted by Reset. + bool special() const { return (next_and_bits_ & 1) != 0; } + + // Whether or not this current block is owned by the user. + // Only special blocks can be user_owned. + bool user_owned() const { return (next_and_bits_ & 2) != 0; } + + Block* next() const { + const uintptr_t bottom_bits = 3; + return reinterpret_cast(next_and_bits_ & ~bottom_bits); + } + + void clear_next() { + next_and_bits_ &= 3; // Set next to nullptr, preserve bottom bits. + } + + size_t pos() const { return pos_; } + size_t size() const { return size_; } + void set_pos(size_t pos) { pos_ = pos; } + + private: + // Holds pointer to next block for this thread + special/user_owned bits. + uintptr_t next_and_bits_; + + size_t pos_; + size_t size_; + // data follows + }; + + // The allocate/free methods here are a little strange, since SerialArena is + // allocated inside a Block which it also manages. This is to avoid doing + // an extra allocation for the SerialArena itself. + + // Creates a new SerialArena inside Block* and returns it. + static SerialArena* New(Block* b, void* owner, ArenaImpl* arena); + + void CleanupList(); + uint64 SpaceUsed() const; + + bool HasSpace(size_t n) { return n <= static_cast(limit_ - ptr_); } + + void* AllocateAligned(size_t n) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + GOOGLE_DCHECK_GE(limit_, ptr_); + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { + return AllocateAlignedFallback(n); + } + void* ret = ptr_; + ptr_ += n; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); +#endif // ADDRESS_SANITIZER + return ret; + } + + // Allocate space if the current region provides enough space. + bool MaybeAllocateAligned(size_t n, void** out) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + GOOGLE_DCHECK_GE(limit_, ptr_); + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false; + void* ret = ptr_; + ptr_ += n; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); +#endif // ADDRESS_SANITIZER + *out = ret; + return true; + } + + void AddCleanup(void* elem, void (*cleanup)(void*)) { + if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) { + AddCleanupFallback(elem, cleanup); + return; + } + cleanup_ptr_->elem = elem; + cleanup_ptr_->cleanup = cleanup; + cleanup_ptr_++; + } + + void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)) { + void* ret = AllocateAligned(n); + AddCleanup(ret, cleanup); + return ret; + } + + Block* head() const { return head_; } + void* owner() const { return owner_; } + SerialArena* next() const { return next_; } + void set_next(SerialArena* next) { next_ = next; } + static Block* NewBlock(Block* last_block, size_t min_bytes, ArenaImpl* arena); + + private: + // Node contains the ptr of the object to be cleaned up and the associated + // cleanup function ptr. + struct CleanupNode { + void* elem; // Pointer to the object to be cleaned up. + void (*cleanup)(void*); // Function pointer to the destructor or deleter. + }; + + // Cleanup uses a chunked linked list, to reduce pointer chasing. + struct CleanupChunk { + static size_t SizeOf(size_t i) { + return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1)); + } + size_t size; // Total elements in the list. + CleanupChunk* next; // Next node in the list. + CleanupNode nodes[1]; // True length is |size|. + }; + + ArenaImpl* arena_; // Containing arena. + void* owner_; // &ThreadCache of this thread; + Block* head_; // Head of linked list of blocks. + CleanupChunk* cleanup_; // Head of cleanup list. + SerialArena* next_; // Next SerialArena in this linked list. + + // Next pointer to allocate from. Always 8-byte aligned. Points inside + // head_ (and head_->pos will always be non-canonical). We keep these + // here to reduce indirection. + char* ptr_; + char* limit_; + + // Next CleanupList members to append to. These point inside cleanup_. + CleanupNode* cleanup_ptr_; + CleanupNode* cleanup_limit_; + + void* AllocateAlignedFallback(size_t n); + void AddCleanupFallback(void* elem, void (*cleanup)(void*)); + void CleanupListFallback(); + + public: + static constexpr size_t kBlockHeaderSize = + (sizeof(Block) + 7) & static_cast(-8); +}; + // This class provides the core Arena memory allocation library. Different // implementations only need to implement the public interface below. // Arena is not a template type as that would only be useful if all protos @@ -109,7 +267,7 @@ class PROTOBUF_EXPORT ArenaImpl { // Ignore initial block if it is too small. if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) { - SetInitialBlock(new (mem) Block(size, nullptr, true, true)); + SetInitialBlock(new (mem) SerialArena::Block(size, nullptr, true, true)); } } @@ -160,165 +318,17 @@ class PROTOBUF_EXPORT ArenaImpl { } } - private: - friend class ArenaBenchmark; - - void* AllocateAlignedFallback(size_t n); - void* AllocateAlignedAndAddCleanupFallback(size_t n, void (*cleanup)(void*)); - void AddCleanupFallback(void* elem, void (*cleanup)(void*)); - - // Node contains the ptr of the object to be cleaned up and the associated - // cleanup function ptr. - struct CleanupNode { - void* elem; // Pointer to the object to be cleaned up. - void (*cleanup)(void*); // Function pointer to the destructor or deleter. - }; - - // Cleanup uses a chunked linked list, to reduce pointer chasing. - struct CleanupChunk { - static size_t SizeOf(size_t i) { - return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1)); - } - size_t size; // Total elements in the list. - CleanupChunk* next; // Next node in the list. - CleanupNode nodes[1]; // True length is |size|. - }; - - class Block; - - // A thread-unsafe Arena that can only be used within its owning thread. - class PROTOBUF_EXPORT SerialArena { - public: - // The allocate/free methods here are a little strange, since SerialArena is - // allocated inside a Block which it also manages. This is to avoid doing - // an extra allocation for the SerialArena itself. - - // Creates a new SerialArena inside Block* and returns it. - static SerialArena* New(Block* b, void* owner, ArenaImpl* arena); - - void CleanupList(); - uint64 SpaceUsed() const; - - bool HasSpace(size_t n) { return n <= static_cast(limit_ - ptr_); } - - void* AllocateAligned(size_t n) { - GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. - GOOGLE_DCHECK_GE(limit_, ptr_); - if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { - return AllocateAlignedFallback(n); - } - void* ret = ptr_; - ptr_ += n; -#ifdef ADDRESS_SANITIZER - ASAN_UNPOISON_MEMORY_REGION(ret, n); -#endif // ADDRESS_SANITIZER - return ret; - } - - // Allocate space if the current region provides enough space. - bool MaybeAllocateAligned(size_t n, void** out) { - GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. - GOOGLE_DCHECK_GE(limit_, ptr_); - if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false; - void* ret = ptr_; - ptr_ += n; -#ifdef ADDRESS_SANITIZER - ASAN_UNPOISON_MEMORY_REGION(ret, n); -#endif // ADDRESS_SANITIZER - *out = ret; - return true; - } - - void AddCleanup(void* elem, void (*cleanup)(void*)) { - if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) { - AddCleanupFallback(elem, cleanup); - return; - } - cleanup_ptr_->elem = elem; - cleanup_ptr_->cleanup = cleanup; - cleanup_ptr_++; - } - - void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)) { - void* ret = AllocateAligned(n); - AddCleanup(ret, cleanup); - return ret; - } - - Block* head() const { return head_; } - void* owner() const { return owner_; } - SerialArena* next() const { return next_; } - void set_next(SerialArena* next) { next_ = next; } - - private: - void* AllocateAlignedFallback(size_t n); - void AddCleanupFallback(void* elem, void (*cleanup)(void*)); - void CleanupListFallback(); - - ArenaImpl* arena_; // Containing arena. - void* owner_; // &ThreadCache of this thread; - Block* head_; // Head of linked list of blocks. - CleanupChunk* cleanup_; // Head of cleanup list. - SerialArena* next_; // Next SerialArena in this linked list. - - // Next pointer to allocate from. Always 8-byte aligned. Points inside - // head_ (and head_->pos will always be non-canonical). We keep these - // here to reduce indirection. - char* ptr_; - char* limit_; - - // Next CleanupList members to append to. These point inside cleanup_. - CleanupNode* cleanup_ptr_; - CleanupNode* cleanup_limit_; - }; - - // Blocks are variable length malloc-ed objects. The following structure - // describes the common header for all blocks. - class PROTOBUF_EXPORT Block { - public: - Block(size_t size, Block* next, bool special, bool user_owned) - : next_and_bits_(reinterpret_cast(next) | (special ? 1 : 0) | - (user_owned ? 2 : 0)), - pos_(kBlockHeaderSize), - size_(size) { - GOOGLE_DCHECK_EQ(reinterpret_cast(next) & 3, 0u); - } - - char* Pointer(size_t n) { - GOOGLE_DCHECK(n <= size_); - return reinterpret_cast(this) + n; - } - - // One of the blocks may be special. This is either a user-supplied - // initial block, or a block we created at startup to hold Options info. - // A special block is not deleted by Reset. - bool special() const { return (next_and_bits_ & 1) != 0; } + std::pair NewBuffer(size_t last_size, size_t min_bytes); - // Whether or not this current block is owned by the user. - // Only special blocks can be user_owned. - bool user_owned() const { return (next_and_bits_ & 2) != 0; } - - Block* next() const { - const uintptr_t bottom_bits = 3; - return reinterpret_cast(next_and_bits_ & ~bottom_bits); - } - - void clear_next() { - next_and_bits_ &= 3; // Set next to nullptr, preserve bottom bits. - } - - size_t pos() const { return pos_; } - size_t size() const { return size_; } - void set_pos(size_t pos) { pos_ = pos; } - - private: - // Holds pointer to next block for this thread + special/user_owned bits. - uintptr_t next_and_bits_; + private: + // Pointer to a linked list of SerialArena. + std::atomic threads_; + std::atomic hint_; // Fast thread-local block access + std::atomic space_allocated_; // Total size of all allocated blocks. - size_t pos_; - size_t size_; - // data follows - }; + // Unique for each arena. Changes on Reset(). + // Least-significant-bit is 1 iff allocations should be recorded. + uint64 lifecycle_id_; struct Options { size_t start_block_size; @@ -328,59 +338,15 @@ class PROTOBUF_EXPORT ArenaImpl { ArenaMetricsCollector* metrics_collector; }; -#ifdef _MSC_VER -#pragma warning(disable:4324) -#endif - struct alignas(64) ThreadCache { -#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) - // If we are using the ThreadLocalStorage class to store the ThreadCache, - // then the ThreadCache's default constructor has to be responsible for - // initializing it. - ThreadCache() - : next_lifecycle_id(0), - last_lifecycle_id_seen(-1), - last_serial_arena(NULL) {} -#endif + Options* options_ = nullptr; - // Number of per-thread lifecycle IDs to reserve. Must be power of two. - // To reduce contention on a global atomic, each thread reserves a batch of - // IDs. The following number is caluculated based on a stress test with - // ~6500 threads all frequently allocating a new arena. - static constexpr size_t kPerThreadIds = 256; - // Next lifecycle ID available to this thread. We need to reserve a new - // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`. - uint64 next_lifecycle_id; - // The ThreadCache is considered valid as long as this matches the - // lifecycle_id of the arena being used. - uint64 last_lifecycle_id_seen; - SerialArena* last_serial_arena; - }; - // Lifecycle_id can be highly contended variable in a situation of lots of - // arena creation. Make sure that other global variables are not sharing the - // cacheline. -#ifdef _MSC_VER -#pragma warning(disable:4324) -#endif - struct alignas(64) CacheAlignedLifecycleIdGenerator { - std::atomic id; - }; - static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_; -#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) - // Android ndk does not support __thread keyword so we use a custom thread - // local storage class we implemented. - // iOS also does not support the __thread keyword. - static ThreadCache& thread_cache(); -#elif defined(PROTOBUF_USE_DLLS) - // Thread local variables cannot be exposed through DLL interface but we can - // wrap them in static functions. - static ThreadCache& thread_cache(); -#else - static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_; - static ThreadCache& thread_cache() { return thread_cache_; } -#endif + void* AllocateAlignedFallback(size_t n); + void* AllocateAlignedAndAddCleanupFallback(size_t n, void (*cleanup)(void*)); + void AddCleanupFallback(void* elem, void (*cleanup)(void*)); void Init(bool record_allocs); - void SetInitialBlock(Block* block); // Can be called right after Init() + void SetInitialBlock( + SerialArena::Block* block); // Can be called right after Init() // Return true iff allocations should be recorded in a metrics collector. inline bool record_allocs() const { return lifecycle_id_ & 1; } @@ -395,8 +361,8 @@ class PROTOBUF_EXPORT ArenaImpl { // fn() may delete blocks and arenas, so fetch next pointers before fn(); SerialArena* cur = serial; serial = serial->next(); - for (Block* block = cur->head(); block != nullptr;) { - Block* b = block; + for (auto* block = cur->head(); block != nullptr;) { + auto* b = block; block = b->next(); fn(b); } @@ -416,13 +382,6 @@ class PROTOBUF_EXPORT ArenaImpl { hint_.store(serial, std::memory_order_release); } - std::atomic - threads_; // Pointer to a linked list of SerialArena. - std::atomic hint_; // Fast thread-local block access - std::atomic space_allocated_; // Total size of all allocated blocks. - - Block* NewBlock(Block* last_block, size_t min_bytes); - PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) { if (GetSerialArenaFromThreadCache(arena)) return true; @@ -451,11 +410,57 @@ class PROTOBUF_EXPORT ArenaImpl { } SerialArena* GetSerialArenaFallback(void* me); - // Unique for each arena. Changes on Reset(). - // Least-significant-bit is 1 iff allocations should be recorded. - uint64 lifecycle_id_; +#ifdef _MSC_VER +#pragma warning(disable : 4324) +#endif + struct alignas(64) ThreadCache { +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // If we are using the ThreadLocalStorage class to store the ThreadCache, + // then the ThreadCache's default constructor has to be responsible for + // initializing it. + ThreadCache() + : next_lifecycle_id(0), + last_lifecycle_id_seen(-1), + last_serial_arena(NULL) {} +#endif - Options* options_ = nullptr; + // Number of per-thread lifecycle IDs to reserve. Must be power of two. + // To reduce contention on a global atomic, each thread reserves a batch of + // IDs. The following number is caluculated based on a stress test with + // ~6500 threads all frequently allocating a new arena. + static constexpr size_t kPerThreadIds = 256; + // Next lifecycle ID available to this thread. We need to reserve a new + // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`. + uint64 next_lifecycle_id; + // The ThreadCache is considered valid as long as this matches the + // lifecycle_id of the arena being used. + uint64 last_lifecycle_id_seen; + SerialArena* last_serial_arena; + }; + + // Lifecycle_id can be highly contended variable in a situation of lots of + // arena creation. Make sure that other global variables are not sharing the + // cacheline. +#ifdef _MSC_VER +#pragma warning(disable : 4324) +#endif + struct alignas(64) CacheAlignedLifecycleIdGenerator { + std::atomic id; + }; + static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_; +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // Android ndk does not support __thread keyword so we use a custom thread + // local storage class we implemented. + // iOS also does not support the __thread keyword. + static ThreadCache& thread_cache(); +#elif defined(PROTOBUF_USE_DLLS) + // Thread local variables cannot be exposed through DLL interface but we can + // wrap them in static functions. + static ThreadCache& thread_cache(); +#else + static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_; + static ThreadCache& thread_cache() { return thread_cache_; } +#endif GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl); // All protos have pointers back to the arena hence Arena must have @@ -466,11 +471,10 @@ class PROTOBUF_EXPORT ArenaImpl { public: // kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8 // to protect the invariant that pos is always at a multiple of 8. - static const size_t kBlockHeaderSize = - (sizeof(Block) + 7) & static_cast(-8); - static const size_t kSerialArenaSize = + static constexpr size_t kBlockHeaderSize = SerialArena::kBlockHeaderSize; + static constexpr size_t kSerialArenaSize = (sizeof(SerialArena) + 7) & static_cast(-8); - static const size_t kOptionsSize = + static constexpr size_t kOptionsSize = (sizeof(Options) + 7) & static_cast(-8); static_assert(kBlockHeaderSize % 8 == 0, "kBlockHeaderSize must be a multiple of 8."); diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 46952811977f..829c6a070391 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc index 978fdf02b6fb..86bacf8103bd 100644 --- a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -65,11 +65,11 @@ class MockErrorCollector : public MultiFileErrorCollector { MockErrorCollector() {} ~MockErrorCollector() {} - string text_; + std::string text_; // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, int line, int column, - const string& message) { + void AddError(const std::string& filename, int line, int column, + const std::string& message) { strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, message); } @@ -77,14 +77,14 @@ class MockErrorCollector : public MultiFileErrorCollector { class MockGeneratorContext : public GeneratorContext { public: - void ExpectFileMatches(const string& virtual_filename, - const string& physical_filename) { + void ExpectFileMatches(const std::string& virtual_filename, + const std::string& physical_filename) { auto it = files_.find(virtual_filename); ASSERT_TRUE(it != files_.end()) << "Generator failed to generate file: " << virtual_filename; - string expected_contents = *it->second; + std::string expected_contents = *it->second; - string actual_contents; + std::string actual_contents; GOOGLE_CHECK_OK( File::GetContentsAsText(TestSourceDir() + "/" + physical_filename, &actual_contents, true)) @@ -97,7 +97,7 @@ class MockGeneratorContext : public GeneratorContext { // implements GeneratorContext -------------------------------------- - virtual io::ZeroCopyOutputStream* Open(const string& filename) { + virtual io::ZeroCopyOutputStream* Open(const std::string& filename) { auto& map_slot = files_[filename]; map_slot.reset(new std::string); return new io::StringOutputStream(map_slot.get()); @@ -110,7 +110,7 @@ class MockGeneratorContext : public GeneratorContext { class GenerateAndTest { public: GenerateAndTest() {} - void Run(const FileDescriptor* proto_file, string file1, string file2) { + void Run(const FileDescriptor* proto_file, std::string file1, std::string file2) { ASSERT_TRUE(proto_file != NULL) << TestSourceDir(); ASSERT_TRUE(generator_.Generate(proto_file, parameter_, &context_, &error_)); @@ -123,14 +123,14 @@ class GenerateAndTest { private: Generator generator_; MockGeneratorContext context_; - string error_; - string parameter_; + std::string error_; + std::string parameter_; }; TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) { // Skip this whole test if the csharp directory doesn't exist (i.e., a C++11 // only distribution). - string descriptor_file_name = + std::string descriptor_file_name = "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs"; if (!File::Exists(TestSourceDir() + "/" + descriptor_file_name)) { return; diff --git a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc index a4e9ff407832..225d6dc54ea1 100644 --- a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc +++ b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc @@ -47,7 +47,7 @@ namespace csharp { // is inlined in the relevant code. If more control is required, that code can be moved here. void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { - string comments = location.leading_comments.empty() ? + std::string comments = location.leading_comments.empty() ? location.trailing_comments : location.leading_comments; if (comments.empty()) { return; @@ -56,7 +56,7 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { // node of a summary element, not part of an attribute. comments = StringReplace(comments, "&", "&", true); comments = StringReplace(comments, "<", "<", true); - std::vector lines; + std::vector lines; lines = Split(comments, "\n", false); // TODO: We really should work out which part to put in the summary and which to put in the remarks... // but that needs to be part of a bigger effort to understand the markdown better anyway. @@ -66,17 +66,18 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { // to preserve the blank lines themselves, as this is relevant in the markdown. // Note that we can't remove leading or trailing whitespace as *that's* relevant in markdown too. // (We don't skip "just whitespace" lines, either.) - for (std::vector::iterator it = lines.begin(); it != lines.end(); ++it) { - string line = *it; - if (line.empty()) { - last_was_empty = true; - } else { - if (last_was_empty) { - printer->Print("///\n"); - } - last_was_empty = false; - printer->Print("///$line$\n", "line", *it); + for (std::vector::iterator it = lines.begin(); + it != lines.end(); ++it) { + std::string line = *it; + if (line.empty()) { + last_was_empty = true; + } else { + if (last_was_empty) { + printer->Print("///\n"); } + last_was_empty = false; + printer->Print("///$line$\n", "line", *it); + } } printer->Print("/// \n"); } diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc index 2baefd84ed93..6d379235ce2c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum.cc +++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc @@ -61,12 +61,13 @@ void EnumGenerator::Generate(io::Printer* printer) { "access_level", class_access_level(), "name", descriptor_->name()); printer->Indent(); - std::set used_names; + std::set used_names; std::set used_number; for (int i = 0; i < descriptor_->value_count(); i++) { WriteEnumValueDocComment(printer, descriptor_->value(i)); - string original_name = descriptor_->value(i)->name(); - string name = GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name()); + std::string original_name = descriptor_->value(i)->name(); + std::string name = + GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name()); // Make sure we don't get any duplicate names due to prefix removal. while (!used_names.insert(name).second) { // It's possible we'll end up giving this warning multiple times, but that's better than not at all. diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index b824c92f0200..f5f4c2391ea7 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -51,7 +51,7 @@ namespace compiler { namespace csharp { void FieldGeneratorBase::SetCommonFieldVariables( - std::map* variables) { + std::map* variables) { // Note: this will be valid even though the tag emitted for packed and unpacked versions of // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which // never effects the tag size. @@ -63,7 +63,7 @@ void FieldGeneratorBase::SetCommonFieldVariables( uint tag = internal::WireFormat::MakeTag(descriptor_); uint8 tag_array[5]; io::CodedOutputStream::WriteTagToArray(tag, tag_array); - string tag_bytes = StrCat(tag_array[0]); + std::string tag_bytes = StrCat(tag_array[0]); for (int i = 1; i < part_tag_size; i++) { tag_bytes += ", " + StrCat(tag_array[i]); } @@ -108,8 +108,8 @@ void FieldGeneratorBase::SetCommonFieldVariables( (*variables)["has_not_property_check"] = "!" + (*variables)["has_property_check"]; (*variables)["other_has_not_property_check"] = "!" + (*variables)["other_has_property_check"]; if (presenceIndex_ != -1) { - string hasBitsNumber = StrCat(presenceIndex_ / 32); - string hasBitsMask = StrCat(1 << (presenceIndex_ % 32)); + std::string hasBitsNumber = StrCat(presenceIndex_ / 32); + std::string hasBitsMask = StrCat(1 << (presenceIndex_ % 32)); (*variables)["has_field_check"] = "(_hasBits" + hasBitsNumber + " & " + hasBitsMask + ") != 0"; (*variables)["set_has_field"] = "_hasBits" + hasBitsNumber + " |= " + hasBitsMask; (*variables)["clear_has_field"] = "_hasBits" + hasBitsNumber + " &= ~" + hasBitsMask; @@ -123,7 +123,7 @@ void FieldGeneratorBase::SetCommonFieldVariables( } void FieldGeneratorBase::SetCommonOneofFieldVariables( - std::map* variables) { + std::map* variables) { (*variables)["oneof_name"] = oneof_name(); if (SupportsPresenceApi(descriptor_)) { (*variables)["has_property_check"] = "Has" + property_name(); @@ -216,7 +216,7 @@ std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) { if (IsWrapperType(descriptor)) { const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0); - string wrapped_field_type_name = type_name(wrapped_field); + std::string wrapped_field_type_name = type_name(wrapped_field); // String and ByteString go to the same type; other wrapped types // go to the nullable equivalent. if (wrapped_field->type() == FieldDescriptor::TYPE_STRING || diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index d22a4b6cbb66..f875fa11ace4 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -74,14 +74,15 @@ class FieldGeneratorBase : public SourceGeneratorBase { protected: const FieldDescriptor* descriptor_; const int presenceIndex_; - std::map variables_; + std::map variables_; void AddDeprecatedFlag(io::Printer* printer); void AddNullCheck(io::Printer* printer); void AddNullCheck(io::Printer* printer, const std::string& name); void AddPublicMemberAttributes(io::Printer* printer); - void SetCommonOneofFieldVariables(std::map* variables); + void SetCommonOneofFieldVariables( + std::map* variables); std::string oneof_property_name(); std::string oneof_name(); @@ -96,7 +97,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { std::string capitalized_type_name(); private: - void SetCommonFieldVariables(std::map* variables); + void SetCommonFieldVariables(std::map* variables); std::string GetStringDefaultValueInternal(const FieldDescriptor* descriptor); std::string GetBytesDefaultValueInternal(const FieldDescriptor* descriptor); }; diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc index 8d90a1d36620..5ce0651738b2 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc @@ -61,13 +61,11 @@ void GenerateFile(const FileDescriptor* file, io::Printer* printer, reflectionClassGenerator.Generate(printer); } -bool Generator::Generate( - const FileDescriptor* file, - const string& parameter, - GeneratorContext* generator_context, - string* error) const { - - std::vector > options; +bool Generator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const { + std::vector > options; ParseGeneratorParameter(parameter, &options); struct Options cli_options; @@ -88,7 +86,7 @@ bool Generator::Generate( } } - string filename_error = ""; + std::string filename_error = ""; std::string filename = GetOutputFile(file, cli_options.file_extension, cli_options.base_namespace_specified, diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.h b/src/google/protobuf/compiler/csharp/csharp_generator.h index 8875d4caacf6..f41f9b8358ad 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.h +++ b/src/google/protobuf/compiler/csharp/csharp_generator.h @@ -54,9 +54,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { ~Generator(); bool Generate( const FileDescriptor* file, - const string& parameter, + const std::string& parameter, GeneratorContext* generator_context, - string* error) const override; + std::string* error) const override; uint64_t GetSupportedFeatures() const override; }; diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index c7a0d4fa9839..32ef3994f16e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -143,7 +143,7 @@ std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor) { std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter, bool preserve_period) { - string result; + std::string result; // Note: I distrust ctype.h due to locales. for (int i = 0; i < input.size(); i++) { if ('a' <= input[i] && input[i] <= 'z') { @@ -195,7 +195,7 @@ std::string UnderscoresToPascalCase(const std::string& input) { // Lower letter Alphanumeric Same as current // Upper letter Alphanumeric Lower std::string ShoutyToPascalCase(const std::string& input) { - string result; + std::string result; // Simple way of implementing "always start with upper" char previous = '_'; for (int i = 0; i < input.size(); i++) { @@ -325,7 +325,7 @@ std::string ToCSharpName(const std::string& name, const FileDescriptor* file) { if (!result.empty()) { result += '.'; } - string classname; + std::string classname; if (file->package().empty()) { classname = name; } else { @@ -396,19 +396,20 @@ std::string GetPropertyName(const FieldDescriptor* descriptor) { std::string GetOutputFile(const FileDescriptor* descriptor, const std::string file_extension, const bool generate_directories, - const std::string base_namespace, string* error) { - string relative_filename = GetFileNameBase(descriptor) + file_extension; + const std::string base_namespace, + std::string* error) { + std::string relative_filename = GetFileNameBase(descriptor) + file_extension; if (!generate_directories) { return relative_filename; } - string ns = GetFileNamespace(descriptor); - string namespace_suffix = ns; + std::string ns = GetFileNamespace(descriptor); + std::string namespace_suffix = ns; if (!base_namespace.empty()) { // Check that the base_namespace is either equal to or a leading part of // the file namespace. This isn't just a simple prefix; "Foo.B" shouldn't // be regarded as a prefix of "Foo.Bar". The simplest option is to add "." // to both. - string extended_ns = ns + "."; + std::string extended_ns = ns + "."; if (extended_ns.find(base_namespace + ".") != 0) { *error = "Namespace " + ns + " is not a prefix namespace of base namespace " + base_namespace; return ""; // This will be ignored, because we've set an error. @@ -419,7 +420,7 @@ std::string GetOutputFile(const FileDescriptor* descriptor, } } - string namespace_dir = StringReplace(namespace_suffix, ".", "/", true); + std::string namespace_dir = StringReplace(namespace_suffix, ".", "/", true); if (!namespace_dir.empty()) { namespace_dir += "/"; } diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h index 90ead89c11f3..a6009c8b1e4e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -138,7 +138,7 @@ inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) { if (!IsDescriptorProto(descriptor->file())) { return false; } - const string name = descriptor->full_name(); + const std::string name = descriptor->full_name(); return name == "google.protobuf.FileOptions" || name == "google.protobuf.MessageOptions" || name == "google.protobuf.FieldOptions" || diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index d5d2b670cda7..5aec7ca743e0 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -112,7 +112,7 @@ void MessageGenerator::AddSerializableAttribute(io::Printer* printer) { } void MessageGenerator::Generate(io::Printer* printer) { - std::map vars; + std::map vars; vars["class_name"] = class_name(); vars["access_level"] = class_access_level(); @@ -374,7 +374,7 @@ bool MessageGenerator::HasNestedGeneratedTypes() } void MessageGenerator::GenerateCloningCode(io::Printer* printer) { - std::map vars; + std::map vars; WriteGeneratedCodeAttributes(printer); vars["class_name"] = class_name(); printer->Print( @@ -438,7 +438,7 @@ void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { } void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { - std::map vars; + std::map vars; vars["class_name"] = class_name(); // Equality @@ -605,7 +605,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { // Note: These are separate from GenerateMessageSerializationMethods() // because they need to be generated even for messages that are optimized // for code size. - std::map vars; + std::map vars; vars["class_name"] = class_name(); WriteGeneratedCodeAttributes(printer); @@ -685,7 +685,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { } void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_parse_context) { - std::map vars; + std::map vars; vars["maybe_ref_input"] = use_parse_context ? "ref input" : "input"; printer->Print( diff --git a/src/google/protobuf/compiler/csharp/csharp_names.h b/src/google/protobuf/compiler/csharp/csharp_names.h index 44852721a85e..67e53b640108 100644 --- a/src/google/protobuf/compiler/csharp/csharp_names.h +++ b/src/google/protobuf/compiler/csharp/csharp_names.h @@ -60,14 +60,14 @@ namespace csharp { // // Returns: // The namespace to use for given file descriptor. -string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor); +std::string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor); // Requires: // descriptor != NULL // // Returns: // The fully-qualified C# class name. -string PROTOC_EXPORT GetClassName(const Descriptor* descriptor); +std::string PROTOC_EXPORT GetClassName(const Descriptor* descriptor); // Requires: // descriptor != NULL @@ -76,7 +76,8 @@ string PROTOC_EXPORT GetClassName(const Descriptor* descriptor); // The fully-qualified name of the C# class that provides // access to the file descriptor. Proto compiler generates // such class for each .proto file processed. -string PROTOC_EXPORT GetReflectionClassName(const FileDescriptor* descriptor); +std::string PROTOC_EXPORT +GetReflectionClassName(const FileDescriptor* descriptor); // Generates output file name for given file descriptor. If generate_directories // is true, the output file will be put under directory corresponding to file's @@ -92,10 +93,11 @@ string PROTOC_EXPORT GetReflectionClassName(const FileDescriptor* descriptor); // The file name to use as output file for given file descriptor. In case // of failure, this function will return empty string and error parameter // will contain the error message. -string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor, - const string file_extension, - const bool generate_directories, - const string base_namespace, string* error); +std::string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor, + const std::string file_extension, + const bool generate_directories, + const std::string base_namespace, + std::string* error); } // namespace csharp } // namespace compiler diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index 8622ff0507e3..51032c2742b3 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -77,9 +77,10 @@ void EnumGenerator::Generate(io::Printer* printer) { WriteEnumDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); printer->Print( - "public enum $classname$\n" + "$deprecation$public enum $classname$\n" " implements com.google.protobuf.ProtocolMessageEnum {\n", - "classname", descriptor_->name()); + "classname", descriptor_->name(), "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""); printer->Annotate("classname", descriptor_); printer->Indent(); diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index 226fa4fb5163..aa64c97127a5 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -78,9 +78,10 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { WriteEnumDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); printer->Print( - "public enum $classname$\n" + "$deprecation$public enum $classname$\n" " implements com.google.protobuf.Internal.EnumLite {\n", - "classname", descriptor_->name()); + "classname", descriptor_->name(), "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""); printer->Annotate("classname", descriptor_); printer->Indent(); diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index bb378b897c2b..fb00110c4183 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -76,7 +76,6 @@ struct FieldDescriptorCompare { typedef std::set FieldDescriptorSet; - // Recursively searches the given message to collect extensions. // Returns true if all the extensions can be recognized. The extensions will be // appended in to the extensions parameter. @@ -86,9 +85,7 @@ bool CollectExtensions(const Message& message, FieldDescriptorSet* extensions) { const Reflection* reflection = message.GetReflection(); // There are unknown fields that could be extensions, thus this call fails. - UnknownFieldSet unknown_fields; - unknown_fields.MergeFrom(reflection->GetUnknownFields(message)); - if (unknown_fields.field_count() > 0) return false; + if (reflection->GetUnknownFields(message).field_count() > 0) return false; std::vector fields; reflection->ListFields(message, &fields); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc index f2967683ee01..12c475ff5a5b 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc @@ -65,7 +65,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) base_values_.push_back(value); value_names.insert(EnumValueName(value)); } else { - string value_name(EnumValueName(value)); + std::string value_name(EnumValueName(value)); if (value_names.find(value_name) != value_names.end()) { alias_values_to_skip_.insert(value); } else { @@ -79,7 +79,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) EnumGenerator::~EnumGenerator() {} void EnumGenerator::GenerateHeader(io::Printer* printer) { - string enum_comments; + std::string enum_comments; SourceLocation location; if (descriptor_->GetSourceLocation(&location)) { enum_comments = BuildCommentsString(location, true); @@ -129,7 +129,7 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) { } SourceLocation location; if (all_values_[i]->GetSourceLocation(&location)) { - string comments = BuildCommentsString(location, true).c_str(); + std::string comments = BuildCommentsString(location, true).c_str(); if (comments.length() > 0) { if (i > 0) { printer->Print("\n"); @@ -172,11 +172,11 @@ void EnumGenerator::GenerateSource(io::Printer* printer) { // will be zero. TextFormatDecodeData text_format_decode_data; int enum_value_description_key = -1; - string text_blob; + std::string text_blob; for (int i = 0; i < all_values_.size(); i++) { ++enum_value_description_key; - string short_name(EnumValueShortName(all_values_[i])); + std::string short_name(EnumValueShortName(all_values_[i])); text_blob += short_name + '\0'; if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) { text_format_decode_data.AddString(enum_value_description_key, short_name, diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.h b/src/google/protobuf/compiler/objectivec/objectivec_enum.h index 50a656447979..1d5741a53ce2 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.h @@ -53,14 +53,14 @@ class EnumGenerator { void GenerateHeader(io::Printer* printer); void GenerateSource(io::Printer* printer); - const string& name() const { return name_; } + const std::string& name() const { return name_; } private: const EnumDescriptor* descriptor_; std::vector base_values_; std::vector all_values_; std::set alias_values_to_skip_; - const string name_; + const std::string name_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index 3893801fa4e3..ff69f39f484f 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -44,8 +44,8 @@ namespace objectivec { namespace { void SetEnumVariables(const FieldDescriptor* descriptor, - std::map* variables) { - string type = EnumName(descriptor->enum_type()); + std::map* variables) { + std::string type = EnumName(descriptor->enum_type()); (*variables)["storage_type"] = type; // For non repeated fields, if it was defined in a different file, the // property decls need to use "enum NAME" rather than just "NAME" to support @@ -116,14 +116,14 @@ void EnumFieldGenerator::GenerateCFunctionImplementations( } void EnumFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls); // If it is an enum defined in a different file, then we'll need a forward // declaration for it. When it is in our file, all the enums are output // before the message, so it will be declared before it is needed. if (descriptor_->file() != descriptor_->enum_type()->file()) { // Enum name is already in "storage_type". - const string& name = variable("storage_type"); + const std::string& name = variable("storage_type"); fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 5a69c9786710..f89a7bf22fb0 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -50,7 +50,8 @@ class EnumFieldGenerator : public SingleFieldGenerator { public: virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; virtual void GenerateCFunctionImplementations(io::Printer* printer) const; - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; protected: EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc index b514b8a72a6e..9cebcb22afa6 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc @@ -41,7 +41,7 @@ namespace protobuf { namespace compiler { namespace objectivec { -ExtensionGenerator::ExtensionGenerator(const string& root_class_name, +ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name, const FieldDescriptor* descriptor) : method_name_(ExtensionMethodName(descriptor)), root_class_and_method_name_(root_class_name + "_" + method_name_), @@ -59,7 +59,7 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name, ExtensionGenerator::~ExtensionGenerator() {} void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { - std::map vars; + std::map vars; vars["method_name"] = method_name_; if (IsRetainedName(method_name_)) { vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -82,13 +82,13 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { void ExtensionGenerator::GenerateStaticVariablesInitialization( io::Printer* printer) { - std::map vars; + std::map vars; vars["root_class_and_method_name"] = root_class_and_method_name_; - const string containing_type = ClassName(descriptor_->containing_type()); + const std::string containing_type = ClassName(descriptor_->containing_type()); vars["extended_type"] = ObjCClass(containing_type); vars["number"] = StrCat(descriptor_->number()); - std::vector options; + std::vector options; if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated"); if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked"); if (descriptor_->containing_type()->options().message_set_wire_format()) { @@ -110,8 +110,8 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( } else { vars["default"] = DefaultValue(descriptor_); } - string type = GetCapitalizedType(descriptor_); - vars["extension_type"] = string("GPBDataType") + type; + std::string type = GetCapitalizedType(descriptor_); + vars["extension_type"] = std::string("GPBDataType") + type; if (objc_type == OBJECTIVECTYPE_ENUM) { vars["enum_desc_func_name"] = @@ -134,12 +134,12 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( } void ExtensionGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) { - string extended_type = ClassName(descriptor_->containing_type()); + std::set* fwd_decls) { + std::string extended_type = ClassName(descriptor_->containing_type()); fwd_decls->insert(ObjCClassDeclaration(extended_type)); ObjectiveCType objc_type = GetObjectiveCType(descriptor_); if (objc_type == OBJECTIVECTYPE_MESSAGE) { - string message_type = ClassName(descriptor_->message_type()); + std::string message_type = ClassName(descriptor_->message_type()); fwd_decls->insert(ObjCClassDeclaration(message_type)); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.h b/src/google/protobuf/compiler/objectivec/objectivec_extension.h index 1bc19d818770..d412f4a9f2a8 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_extension.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.h @@ -41,7 +41,7 @@ namespace objectivec { class ExtensionGenerator { public: - ExtensionGenerator(const string& root_class_name, + ExtensionGenerator(const std::string& root_class_name, const FieldDescriptor* descriptor); ~ExtensionGenerator(); @@ -51,11 +51,11 @@ class ExtensionGenerator { void GenerateMembersHeader(io::Printer* printer); void GenerateStaticVariablesInitialization(io::Printer* printer); void GenerateRegistrationSource(io::Printer* printer); - void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); + void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); private: - string method_name_; - string root_class_and_method_name_; + std::string method_name_; + std::string root_class_and_method_name_; const FieldDescriptor* descriptor_; }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc index e8360a515ba9..9d5fa9933a61 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -48,16 +48,16 @@ namespace objectivec { namespace { void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map* variables) { - string camel_case_name = FieldName(descriptor); - string raw_field_name; + std::map* variables) { + std::string camel_case_name = FieldName(descriptor); + std::string raw_field_name; if (descriptor->type() == FieldDescriptor::TYPE_GROUP) { raw_field_name = descriptor->message_type()->name(); } else { raw_field_name = descriptor->name(); } // The logic here has to match -[GGPBFieldDescriptor textFormatName]. - const string un_camel_case_name( + const std::string un_camel_case_name( UnCamelCaseFieldName(camel_case_name, descriptor)); const bool needs_custom_name = (raw_field_name != un_camel_case_name); @@ -67,10 +67,10 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } else { (*variables)["comments"] = "\n"; } - const string& classname = ClassName(descriptor->containing_type()); + const std::string& classname = ClassName(descriptor->containing_type()); (*variables)["classname"] = classname; (*variables)["name"] = camel_case_name; - const string& capitalized_name = FieldNameCapitalized(descriptor); + const std::string& capitalized_name = FieldNameCapitalized(descriptor); (*variables)["capitalized_name"] = capitalized_name; (*variables)["raw_field_name"] = raw_field_name; (*variables)["field_number_name"] = @@ -78,7 +78,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["field_number"] = StrCat(descriptor->number()); (*variables)["field_type"] = GetCapitalizedType(descriptor); (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor); - std::vector field_flags; + std::vector field_flags; if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated"); if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired"); if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional"); @@ -185,12 +185,12 @@ void FieldGenerator::GenerateCFunctionImplementations( } void FieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { // Nothing } void FieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { // Nothing } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h index 2ebe55b2fcac..0b0e3058f9c9 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -65,8 +65,10 @@ class FieldGenerator { virtual void GenerateCFunctionImplementations(io::Printer* printer) const; // Exposed for subclasses, should always call it on the parent class also. - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; // Used during generation, not intended to be extended by subclasses. void GenerateFieldDescription( @@ -81,16 +83,17 @@ class FieldGenerator { virtual void SetExtraRuntimeHasBitsBase(int index_base); void SetOneofIndexBase(int index_base); - string variable(const char* key) const { + std::string variable(const char* key) const { return variables_.find(key)->second; } bool needs_textformat_name_support() const { - const string& field_flags = variable("fieldflags"); - return field_flags.find("GPBFieldTextFormatNameCustom") != string::npos; + const std::string& field_flags = variable("fieldflags"); + return field_flags.find("GPBFieldTextFormatNameCustom") != + std::string::npos; } - string generated_objc_name() const { return variable("name"); } - string raw_field_name() const { return variable("raw_field_name"); } + std::string generated_objc_name() const { return variable("name"); } + std::string raw_field_name() const { return variable("raw_field_name"); } protected: FieldGenerator(const FieldDescriptor* descriptor, const Options& options); @@ -99,7 +102,7 @@ class FieldGenerator { bool WantsHasProperty(void) const; const FieldDescriptor* descriptor_; - std::map variables_; + std::map variables_; }; class SingleFieldGenerator : public FieldGenerator { diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index ce4a12c98705..417733ef4727 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -209,7 +209,7 @@ FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options) FileGenerator::~FileGenerator() {} void FileGenerator::GenerateHeader(io::Printer *printer) { - std::vector headers; + std::vector headers; // Generated files bundled with the library get minimal imports, everything // else gets the wrapper so everything is usable. if (is_bundled_proto_) { @@ -244,7 +244,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { options_.named_framework_to_proto_path_mappings_path, options_.runtime_import_prefix, is_bundled_proto_); - const string header_extension(kHeaderExtension); + const std::string header_extension(kHeaderExtension); for (int i = 0; i < file_->public_dependency_count(); i++) { import_writer.AddFile(file_->public_dependency(i), header_extension); } @@ -264,11 +264,11 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { "CF_EXTERN_C_BEGIN\n" "\n"); - std::set fwd_decls; + std::set fwd_decls; for (const auto& generator : message_generators_) { generator->DetermineForwardDeclarations(&fwd_decls); } - for (std::set::const_iterator i(fwd_decls.begin()); + for (std::set::const_iterator i(fwd_decls.begin()); i != fwd_decls.end(); ++i) { printer->Print("$value$;\n", "value", *i); } @@ -338,7 +338,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { void FileGenerator::GenerateSource(io::Printer *printer) { // #import the runtime support. - std::vector headers; + std::vector headers; headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); PrintFileRuntimePreamble(printer, headers); @@ -358,14 +358,14 @@ void FileGenerator::GenerateSource(io::Printer *printer) { options_.named_framework_to_proto_path_mappings_path, options_.runtime_import_prefix, is_bundled_proto_); - const string header_extension(kHeaderExtension); + const std::string header_extension(kHeaderExtension); // #import the header for this proto file. import_writer.AddFile(file_, header_extension); // #import the headers for anything that a plain dependency of this proto // file (that means they were just an include, not a "public" include). - std::set public_import_names; + std::set public_import_names; for (int i = 0; i < file_->public_dependency_count(); i++) { public_import_names.insert(file_->public_dependency(i)->name()); } @@ -400,7 +400,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { } } - std::set fwd_decls; + std::set fwd_decls; for (const auto& generator : message_generators_) { generator->DetermineObjectiveCClassDefinitions(&fwd_decls); } @@ -501,7 +501,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { for (std::vector::iterator iter = deps_with_extensions.begin(); iter != deps_with_extensions.end(); ++iter) { - const string root_class_name(FileClassName((*iter))); + const std::string root_class_name(FileClassName((*iter))); printer->Print( "[registry addExtensions:[$dependency$ extensionRegistry]];\n", "dependency", root_class_name); @@ -531,7 +531,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // File descriptor only needed if there are messages to use it. if (!message_generators_.empty()) { - std::map vars; + std::map vars; vars["root_class_name"] = root_class_name_; vars["package"] = file_->package(); vars["objc_prefix"] = FileClassPrefix(file_); @@ -592,7 +592,8 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // files. This currently only supports the runtime coming from a framework // as defined by the official CocoaPod. void FileGenerator::PrintFileRuntimePreamble( - io::Printer* printer, const std::vector& headers_to_import) const { + io::Printer* printer, + const std::vector& headers_to_import) const { printer->Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "// source: $filename$\n" diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h index 258bd13dc622..cecbda2e336c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -58,11 +58,11 @@ class FileGenerator { void GenerateSource(io::Printer* printer); void GenerateHeader(io::Printer* printer); - const string& RootClassName() const { return root_class_name_; } + const std::string& RootClassName() const { return root_class_name_; } private: const FileDescriptor* file_; - string root_class_name_; + std::string root_class_name_; bool is_bundled_proto_; std::vector> enum_generators_; @@ -72,7 +72,8 @@ class FileGenerator { const Options options_; void PrintFileRuntimePreamble( - io::Printer* printer, const std::vector& headers_to_import) const; + io::Printer* printer, + const std::vector& headers_to_import) const; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index a1a6f529e40e..c02e3775ece4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -50,17 +50,17 @@ bool ObjectiveCGenerator::HasGenerateAll() const { } bool ObjectiveCGenerator::Generate(const FileDescriptor* file, - const string& parameter, + const std::string& parameter, GeneratorContext* context, - string* error) const { + std::string* error) const { *error = "Unimplemented Generate() method. Call GenerateAll() instead."; return false; } -bool ObjectiveCGenerator::GenerateAll(const std::vector& files, - const string& parameter, - GeneratorContext* context, - string* error) const { +bool ObjectiveCGenerator::GenerateAll( + const std::vector& files, + const std::string& parameter, GeneratorContext* context, + std::string* error) const { // ----------------------------------------------------------------- // Parse generator options. These options are passed to the compiler using the // --objc_opt flag. The options are passed as a comma separated list of @@ -71,7 +71,7 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& Options generation_options; - std::vector > options; + std::vector > options; ParseGeneratorParameter(parameter, &options); for (int i = 0; i < options.size(); i++) { if (options[i].first == "expected_prefixes_path") { @@ -154,7 +154,7 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& for (int i = 0; i < files.size(); i++) { const FileDescriptor* file = files[i]; FileGenerator file_generator(file, generation_options); - string filepath = FilePath(file); + std::string filepath = FilePath(file); // Generate header. { diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/src/google/protobuf/compiler/objectivec/objectivec_generator.h index d1e490c8c959..1dbc666af16f 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.h @@ -58,14 +58,11 @@ class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- bool HasGenerateAll() const override; - bool Generate(const FileDescriptor* file, - const string& parameter, - GeneratorContext* context, - string* error) const override; + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override; bool GenerateAll(const std::vector& files, - const string& parameter, - GeneratorContext* context, - string* error) const override; + const std::string& parameter, GeneratorContext* context, + std::string* error) const override; uint64_t GetSupportedFeatures() const override { return FEATURE_PROTO3_OPTIONAL; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 77fe084b73e1..26ef63f021e3 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -85,8 +85,9 @@ Options::Options() { namespace { -std::unordered_set MakeWordsMap(const char* const words[], size_t num_words) { - std::unordered_set result; +std::unordered_set MakeWordsMap(const char* const words[], + size_t num_words) { + std::unordered_set result; for (int i = 0; i < num_words; i++) { result.insert(words[i]); } @@ -95,7 +96,7 @@ std::unordered_set MakeWordsMap(const char* const words[], size_t num_wo const char* const kUpperSegmentsList[] = {"url", "http", "https"}; -std::unordered_set kUpperSegments = +std::unordered_set kUpperSegments = MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList)); bool ascii_isnewline(char c) { @@ -105,9 +106,10 @@ bool ascii_isnewline(char c) { // Internal helper for name handing. // Do not expose this outside of helpers, stick to having functions for specific // cases (ClassName(), FieldName()), so there is always consistent suffix rules. -string UnderscoresToCamelCase(const string& input, bool first_capitalized) { - std::vector values; - string current; +std::string UnderscoresToCamelCase(const std::string& input, + bool first_capitalized) { + std::vector values; + std::string current; bool last_char_was_number = false; bool last_char_was_lower = false; @@ -145,10 +147,11 @@ string UnderscoresToCamelCase(const string& input, bool first_capitalized) { } values.push_back(current); - string result; + std::string result; bool first_segment_forces_upper = false; - for (std::vector::iterator i = values.begin(); i != values.end(); ++i) { - string value = *i; + for (std::vector::iterator i = values.begin(); i != values.end(); + ++i) { + std::string value = *i; bool all_upper = (kUpperSegments.count(value) > 0); if (all_upper && (result.length() == 0)) { first_segment_forces_upper = true; @@ -234,7 +237,7 @@ const char* const kReservedWordList[] = { // but this verifies and allows for future expansion if we decide to redefine what a // reserved C identifier is (for example the GNU list // https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html ) -bool IsReservedCIdentifier(const string& input) { +bool IsReservedCIdentifier(const std::string& input) { if (input.length() > 2) { if (input.at(0) == '_') { if (isupper(input.at(1)) || input.at(1) == '_') { @@ -245,15 +248,15 @@ bool IsReservedCIdentifier(const string& input) { return false; } -string SanitizeNameForObjC(const string& prefix, - const string& input, - const string& extension, - string* out_suffix_added) { - static const std::unordered_set kReservedWords = +std::string SanitizeNameForObjC(const std::string& prefix, + const std::string& input, + const std::string& extension, + std::string* out_suffix_added) { + static const std::unordered_set kReservedWords = MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList)); - static const std::unordered_set kNSObjectMethods = + static const std::unordered_set kNSObjectMethods = MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList)); - string sanitized; + std::string sanitized; // We add the prefix in the cases where the string is missing a prefix. // We define "missing a prefix" as where 'input': // a) Doesn't start with the prefix or @@ -278,7 +281,7 @@ string SanitizeNameForObjC(const string& prefix, return sanitized; } -string NameFromFieldDescriptor(const FieldDescriptor* field) { +std::string NameFromFieldDescriptor(const FieldDescriptor* field) { if (field->type() == FieldDescriptor::TYPE_GROUP) { return field->message_type()->name(); } else { @@ -286,9 +289,10 @@ string NameFromFieldDescriptor(const FieldDescriptor* field) { } } -void PathSplit(const string& path, string* directory, string* basename) { - string::size_type last_slash = path.rfind('/'); - if (last_slash == string::npos) { +void PathSplit(const std::string& path, std::string* directory, + std::string* basename) { + std::string::size_type last_slash = path.rfind('/'); + if (last_slash == std::string::npos) { if (directory) { *directory = ""; } @@ -305,7 +309,7 @@ void PathSplit(const string& path, string* directory, string* basename) { } } -bool IsSpecialName(const string& name, const string* special_names, +bool IsSpecialName(const std::string& name, const std::string* special_names, size_t count) { for (size_t i = 0; i < count; ++i) { size_t length = special_names[i].length(); @@ -323,7 +327,7 @@ bool IsSpecialName(const string& name, const string* special_names, return false; } -string GetZeroEnumNameForFlagType(const FlagType flag_type) { +std::string GetZeroEnumNameForFlagType(const FlagType flag_type) { switch(flag_type) { case FLAGTYPE_DESCRIPTOR_INITIALIZATION: return "GPBDescriptorInitializationFlag_None"; @@ -337,7 +341,7 @@ string GetZeroEnumNameForFlagType(const FlagType flag_type) { } } -string GetEnumNameForFlagType(const FlagType flag_type) { +std::string GetEnumNameForFlagType(const FlagType flag_type) { switch(flag_type) { case FLAGTYPE_DESCRIPTOR_INITIALIZATION: return "GPBDescriptorInitializationFlags"; @@ -347,18 +351,18 @@ string GetEnumNameForFlagType(const FlagType flag_type) { return "GPBFieldFlags"; default: GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } } } // namespace // Escape C++ trigraphs by escaping question marks to \? -string EscapeTrigraphs(const string& to_escape) { +std::string EscapeTrigraphs(const std::string& to_escape) { return StringReplace(to_escape, "?", "\\?", true); } -string StripProto(const string& filename) { +std::string StripProto(const std::string& filename) { if (HasSuffixString(filename, ".protodevel")) { return StripSuffixString(filename, ".protodevel"); } else { @@ -375,38 +379,37 @@ void TrimWhitespace(StringPiece* input) { } } - -bool IsRetainedName(const string& name) { +bool IsRetainedName(const std::string& name) { // List of prefixes from // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html - static const string retained_names[] = {"new", "alloc", "copy", - "mutableCopy"}; + static const std::string retained_names[] = {"new", "alloc", "copy", + "mutableCopy"}; return IsSpecialName(name, retained_names, sizeof(retained_names) / sizeof(retained_names[0])); } -bool IsInitName(const string& name) { - static const string init_names[] = {"init"}; +bool IsInitName(const std::string& name) { + static const std::string init_names[] = {"init"}; return IsSpecialName(name, init_names, sizeof(init_names) / sizeof(init_names[0])); } -string BaseFileName(const FileDescriptor* file) { - string basename; +std::string BaseFileName(const FileDescriptor* file) { + std::string basename; PathSplit(file->name(), NULL, &basename); return basename; } -string FileClassPrefix(const FileDescriptor* file) { +std::string FileClassPrefix(const FileDescriptor* file) { // Default is empty string, no need to check has_objc_class_prefix. - string result = file->options().objc_class_prefix(); + std::string result = file->options().objc_class_prefix(); return result; } -string FilePath(const FileDescriptor* file) { - string output; - string basename; - string directory; +std::string FilePath(const FileDescriptor* file) { + std::string output; + std::string basename; + std::string directory; PathSplit(file->name(), &directory, &basename); if (directory.length() > 0) { output = directory + "/"; @@ -420,10 +423,10 @@ string FilePath(const FileDescriptor* file) { return output; } -string FilePathBasename(const FileDescriptor* file) { - string output; - string basename; - string directory; +std::string FilePathBasename(const FileDescriptor* file) { + std::string output; + std::string basename; + std::string directory; PathSplit(file->name(), &directory, &basename); basename = StripProto(basename); @@ -433,16 +436,17 @@ string FilePathBasename(const FileDescriptor* file) { return output; } -string FileClassName(const FileDescriptor* file) { - const string prefix = FileClassPrefix(file); - const string name = UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; +std::string FileClassName(const FileDescriptor* file) { + const std::string prefix = FileClassPrefix(file); + const std::string name = + UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; // There aren't really any reserved words that end in "Root", but playing // it safe and checking. return SanitizeNameForObjC(prefix, name, "_RootClass", NULL); } -string ClassNameWorker(const Descriptor* descriptor) { - string name; +std::string ClassNameWorker(const Descriptor* descriptor) { + std::string name; if (descriptor->containing_type() != NULL) { name = ClassNameWorker(descriptor->containing_type()); name += "_"; @@ -450,8 +454,8 @@ string ClassNameWorker(const Descriptor* descriptor) { return name + descriptor->name(); } -string ClassNameWorker(const EnumDescriptor* descriptor) { - string name; +std::string ClassNameWorker(const EnumDescriptor* descriptor) { + std::string name; if (descriptor->containing_type() != NULL) { name = ClassNameWorker(descriptor->containing_type()); name += "_"; @@ -459,19 +463,20 @@ string ClassNameWorker(const EnumDescriptor* descriptor) { return name + descriptor->name(); } -string ClassName(const Descriptor* descriptor) { +std::string ClassName(const Descriptor* descriptor) { return ClassName(descriptor, NULL); } -string ClassName(const Descriptor* descriptor, string* out_suffix_added) { +std::string ClassName(const Descriptor* descriptor, + std::string* out_suffix_added) { // 1. Message names are used as is (style calls for CamelCase, trust it). // 2. Check for reserved word at the very end and then suffix things. - const string prefix = FileClassPrefix(descriptor->file()); - const string name = ClassNameWorker(descriptor); + const std::string prefix = FileClassPrefix(descriptor->file()); + const std::string name = ClassNameWorker(descriptor); return SanitizeNameForObjC(prefix, name, "_Class", out_suffix_added); } -string EnumName(const EnumDescriptor* descriptor) { +std::string EnumName(const EnumDescriptor* descriptor) { // 1. Enum names are used as is (style calls for CamelCase, trust it). // 2. Check for reserved word at the every end and then suffix things. // message Fixed { @@ -480,27 +485,28 @@ string EnumName(const EnumDescriptor* descriptor) { // ... // } // yields Fixed_Class, Fixed_Size. - const string prefix = FileClassPrefix(descriptor->file()); - const string name = ClassNameWorker(descriptor); + const std::string prefix = FileClassPrefix(descriptor->file()); + const std::string name = ClassNameWorker(descriptor); return SanitizeNameForObjC(prefix, name, "_Enum", NULL); } -string EnumValueName(const EnumValueDescriptor* descriptor) { +std::string EnumValueName(const EnumValueDescriptor* descriptor) { // Because of the Switch enum compatibility, the name on the enum has to have // the suffix handing, so it slightly diverges from how nested classes work. // enum Fixed { // FOO = 1 // } // yields Fixed_Enum and Fixed_Enum_Foo (not Fixed_Foo). - const string class_name = EnumName(descriptor->type()); - const string value_str = UnderscoresToCamelCase(descriptor->name(), true); - const string name = class_name + "_" + value_str; + const std::string class_name = EnumName(descriptor->type()); + const std::string value_str = + UnderscoresToCamelCase(descriptor->name(), true); + const std::string name = class_name + "_" + value_str; // There aren't really any reserved words with an underscore and a leading // capital letter, but playing it safe and checking. return SanitizeNameForObjC("", name, "_Value", NULL); } -string EnumValueShortName(const EnumValueDescriptor* descriptor) { +std::string EnumValueShortName(const EnumValueDescriptor* descriptor) { // Enum value names (EnumValueName above) are the enum name turned into // a class name and then the value name is CamelCased and concatenated; the // whole thing then gets sanitized for reserved words. @@ -513,14 +519,14 @@ string EnumValueShortName(const EnumValueDescriptor* descriptor) { // So the right way to get the short name is to take the full enum name // and then strip off the enum name (leaving the value name and anything // done by sanitize). - const string class_name = EnumName(descriptor->type()); - const string long_name_prefix = class_name + "_"; - const string long_name = EnumValueName(descriptor); + const std::string class_name = EnumName(descriptor->type()); + const std::string long_name_prefix = class_name + "_"; + const std::string long_name = EnumValueName(descriptor); return StripPrefixString(long_name, long_name_prefix); } -string UnCamelCaseEnumShortName(const string& name) { - string result; +std::string UnCamelCaseEnumShortName(const std::string& name) { + std::string result; for (int i = 0; i < name.size(); i++) { char c = name[i]; if (i > 0 && ascii_isupper(c)) { @@ -531,15 +537,15 @@ string UnCamelCaseEnumShortName(const string& name) { return result; } -string ExtensionMethodName(const FieldDescriptor* descriptor) { - const string name = NameFromFieldDescriptor(descriptor); - const string result = UnderscoresToCamelCase(name, false); +std::string ExtensionMethodName(const FieldDescriptor* descriptor) { + const std::string name = NameFromFieldDescriptor(descriptor); + const std::string result = UnderscoresToCamelCase(name, false); return SanitizeNameForObjC("", result, "_Extension", NULL); } -string FieldName(const FieldDescriptor* field) { - const string name = NameFromFieldDescriptor(field); - string result = UnderscoresToCamelCase(name, false); +std::string FieldName(const FieldDescriptor* field) { + const std::string name = NameFromFieldDescriptor(field); + std::string result = UnderscoresToCamelCase(name, false); if (field->is_repeated() && !field->is_map()) { // Add "Array" before do check for reserved worlds. result += "Array"; @@ -552,50 +558,50 @@ string FieldName(const FieldDescriptor* field) { return SanitizeNameForObjC("", result, "_p", NULL); } -string FieldNameCapitalized(const FieldDescriptor* field) { +std::string FieldNameCapitalized(const FieldDescriptor* field) { // Want the same suffix handling, so upcase the first letter of the other // name. - string result = FieldName(field); + std::string result = FieldName(field); if (result.length() > 0) { result[0] = ascii_toupper(result[0]); } return result; } -string OneofEnumName(const OneofDescriptor* descriptor) { +std::string OneofEnumName(const OneofDescriptor* descriptor) { const Descriptor* fieldDescriptor = descriptor->containing_type(); - string name = ClassName(fieldDescriptor); + std::string name = ClassName(fieldDescriptor); name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase"; // No sanitize needed because the OS never has names that end in _OneOfCase. return name; } -string OneofName(const OneofDescriptor* descriptor) { - string name = UnderscoresToCamelCase(descriptor->name(), false); +std::string OneofName(const OneofDescriptor* descriptor) { + std::string name = UnderscoresToCamelCase(descriptor->name(), false); // No sanitize needed because it gets OneOfCase added and that shouldn't // ever conflict. return name; } -string OneofNameCapitalized(const OneofDescriptor* descriptor) { +std::string OneofNameCapitalized(const OneofDescriptor* descriptor) { // Use the common handling and then up-case the first letter. - string result = OneofName(descriptor); + std::string result = OneofName(descriptor); if (result.length() > 0) { result[0] = ascii_toupper(result[0]); } return result; } -string ObjCClass(const string& class_name) { - return string("GPBObjCClass(") + class_name + ")"; +std::string ObjCClass(const std::string& class_name) { + return std::string("GPBObjCClass(") + class_name + ")"; } -string ObjCClassDeclaration(const string& class_name) { - return string("GPBObjCClassDeclaration(") + class_name + ");"; +std::string ObjCClassDeclaration(const std::string& class_name) { + return std::string("GPBObjCClassDeclaration(") + class_name + ");"; } -string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { - string worker(name); +std::string UnCamelCaseFieldName(const std::string& name, const FieldDescriptor* field) { + std::string worker(name); if (HasSuffixString(worker, "_p")) { worker = StripSuffixString(worker, "_p"); } @@ -610,7 +616,7 @@ string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { } return worker; } else { - string result; + std::string result; for (int i = 0; i < worker.size(); i++) { char c = worker[i]; if (ascii_isupper(c)) { @@ -626,7 +632,7 @@ string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { } } -string GetCapitalizedType(const FieldDescriptor* field) { +std::string GetCapitalizedType(const FieldDescriptor* field) { switch (field->type()) { case FieldDescriptor::TYPE_INT32: return "Int32"; @@ -669,7 +675,7 @@ string GetCapitalizedType(const FieldDescriptor* field) { // Some compilers report reaching end of function even though all cases of // the enum are handed in the switch. GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type) { @@ -743,7 +749,8 @@ bool IsReferenceType(const FieldDescriptor* field) { return !IsPrimitiveType(field); } -static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) { +static std::string HandleExtremeFloatingPoint(std::string val, + bool add_float_suffix) { if (val == "nan") { return "NAN"; } else if (val == "inf") { @@ -752,16 +759,16 @@ static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) { return "-INFINITY"; } else { // float strings with ., e or E need to have f appended - if (add_float_suffix && - (val.find(".") != string::npos || val.find("e") != string::npos || - val.find("E") != string::npos)) { + if (add_float_suffix && (val.find(".") != std::string::npos || + val.find("e") != std::string::npos || + val.find("E") != std::string::npos)) { val += "f"; } return val; } } -string GPBGenericValueFieldName(const FieldDescriptor* field) { +std::string GPBGenericValueFieldName(const FieldDescriptor* field) { // Returns the field within the GPBGenericValue union to use for the given // field. if (field->is_repeated()) { @@ -797,11 +804,11 @@ string GPBGenericValueFieldName(const FieldDescriptor* field) { // Some compilers report reaching end of function even though all cases of // the enum are handed in the switch. GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } -string DefaultValue(const FieldDescriptor* field) { +std::string DefaultValue(const FieldDescriptor* field) { // Repeated fields don't have defaults. if (field->is_repeated()) { return "nil"; @@ -836,7 +843,7 @@ string DefaultValue(const FieldDescriptor* field) { return field->default_value_bool() ? "YES" : "NO"; case FieldDescriptor::CPPTYPE_STRING: { const bool has_default_value = field->has_default_value(); - const string& default_string = field->default_value_string(); + const std::string& default_string = field->default_value_string(); if (!has_default_value || default_string.length() == 0) { // If the field is defined as being the empty string, // then we will just assign to nil, as the empty string is the @@ -853,7 +860,7 @@ string DefaultValue(const FieldDescriptor* field) { // Must convert to a standard byte order for packing length into // a cstring. uint32 length = ghtonl(default_string.length()); - string bytes((const char*)&length, sizeof(length)); + std::string bytes((const char*)&length, sizeof(length)); bytes.append(default_string); return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\""; } else { @@ -869,7 +876,7 @@ string DefaultValue(const FieldDescriptor* field) { // Some compilers report reaching end of function even though all cases of // the enum are handed in the switch. GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } bool HasNonZeroDefaultValue(const FieldDescriptor* field) { @@ -902,7 +909,7 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) { case FieldDescriptor::CPPTYPE_BOOL: return field->default_value_bool(); case FieldDescriptor::CPPTYPE_STRING: { - const string& default_string = field->default_value_string(); + const std::string& default_string = field->default_value_string(); return default_string.length() != 0; } case FieldDescriptor::CPPTYPE_ENUM: @@ -917,14 +924,14 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) { return false; } -string BuildFlagsString(const FlagType flag_type, - const std::vector& strings) { +std::string BuildFlagsString(const FlagType flag_type, + const std::vector& strings) { if (strings.empty()) { return GetZeroEnumNameForFlagType(flag_type); } else if (strings.size() == 1) { return strings[0]; } - string string("(" + GetEnumNameForFlagType(flag_type) + ")("); + std::string string("(" + GetEnumNameForFlagType(flag_type) + ")("); for (size_t i = 0; i != strings.size(); ++i) { if (i > 0) { string.append(" | "); @@ -935,12 +942,12 @@ string BuildFlagsString(const FlagType flag_type, return string; } -string BuildCommentsString(const SourceLocation& location, +std::string BuildCommentsString(const SourceLocation& location, bool prefer_single_line) { - const string& comments = location.leading_comments.empty() + const std::string& comments = location.leading_comments.empty() ? location.trailing_comments : location.leading_comments; - std::vector lines; + std::vector lines; lines = Split(comments, "\n", false); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); @@ -950,10 +957,10 @@ string BuildCommentsString(const SourceLocation& location, return ""; } - string prefix; - string suffix; - string final_comments; - string epilogue; + std::string prefix; + std::string suffix; + std::string final_comments; + std::string epilogue; bool add_leading_space = false; @@ -969,7 +976,7 @@ string BuildCommentsString(const SourceLocation& location, } for (int i = 0; i < lines.size(); i++) { - string line = StripPrefixString(lines[i], " "); + std::string line = StripPrefixString(lines[i], " "); // HeaderDoc and appledoc use '\' and '@' for markers; escape them. line = StringReplace(line, "\\", "\\\\", true); line = StringReplace(line, "@", "\\@", true); @@ -993,9 +1000,9 @@ string BuildCommentsString(const SourceLocation& location, // use a different value; so it isn't as simple as a option. const char* const ProtobufLibraryFrameworkName = "Protobuf"; -string ProtobufFrameworkImportSymbol(const string& framework_name) { +std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) { // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS - string result = string("GPB_USE_"); + std::string result = std::string("GPB_USE_"); result += ToUpper(framework_name); result += "_FRAMEWORK_IMPORTS"; return result; @@ -1005,7 +1012,7 @@ bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) { // We don't check the name prefix or proto package because some files // (descriptor.proto), aren't shipped generated by the library, so this // seems to be the safest way to only catch the ones shipped. - const string name = file->name(); + const std::string name = file->name(); if (name == "google/protobuf/any.proto" || name == "google/protobuf/api.proto" || name == "google/protobuf/duration.proto" || @@ -1044,21 +1051,21 @@ namespace { class ExpectedPrefixesCollector : public LineConsumer { public: - ExpectedPrefixesCollector(std::map* inout_package_to_prefix_map) + ExpectedPrefixesCollector(std::map* inout_package_to_prefix_map) : prefix_map_(inout_package_to_prefix_map) {} - virtual bool ConsumeLine(const StringPiece& line, string* out_error); + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error); private: - std::map* prefix_map_; + std::map* prefix_map_; }; bool ExpectedPrefixesCollector::ConsumeLine( - const StringPiece& line, string* out_error) { + const StringPiece& line, std::string* out_error) { int offset = line.find('='); if (offset == StringPiece::npos) { - *out_error = string("Expected prefixes file line without equal sign: '") + - string(line) + "'."; + *out_error = std::string("Expected prefixes file line without equal sign: '") + + std::string(line) + "'."; return false; } StringPiece package = line.substr(0, offset); @@ -1067,13 +1074,13 @@ bool ExpectedPrefixesCollector::ConsumeLine( TrimWhitespace(&prefix); // Don't really worry about error checking the package/prefix for // being valid. Assume the file is validated when it is created/edited. - (*prefix_map_)[string(package)] = string(prefix); + (*prefix_map_)[std::string(package)] = std::string(prefix); return true; } -bool LoadExpectedPackagePrefixes(const Options &generation_options, - std::map* prefix_map, - string* out_error) { +bool LoadExpectedPackagePrefixes(const Options& generation_options, + std::map* prefix_map, + std::string* out_error) { if (generation_options.expected_prefixes_path.empty()) { return true; } @@ -1084,19 +1091,18 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options, } bool ValidateObjCClassPrefix( - const FileDescriptor* file, - const string& expected_prefixes_path, - const std::map& expected_package_prefixes, - string* out_error) { - const string prefix = file->options().objc_class_prefix(); - const string package = file->package(); + const FileDescriptor* file, const std::string& expected_prefixes_path, + const std::map& expected_package_prefixes, + std::string* out_error) { + const std::string prefix = file->options().objc_class_prefix(); + const std::string package = file->package(); // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for warnings. // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). - std::map::const_iterator package_match = + std::map::const_iterator package_match = expected_package_prefixes.find(package); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... @@ -1126,7 +1132,7 @@ bool ValidateObjCClassPrefix( // to Apple's rules (the checks above implicitly whitelist anything that // doesn't meet these rules). if (!ascii_isupper(prefix[0])) { - std::cerr << std::endl + std::cerr << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" << prefix << "\";' in '" << file->name() << "';" << " it should start with a capital letter." << std::endl; @@ -1135,7 +1141,7 @@ bool ValidateObjCClassPrefix( if (prefix.length() < 3) { // Apple reserves 2 character prefixes for themselves. They do use some // 3 character prefixes, but they haven't updated the rules/docs. - std::cerr << std::endl + std::cerr << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" << prefix << "\";' in '" << file->name() << "';" << " Apple recommends they should be at least 3 characters long." @@ -1144,8 +1150,9 @@ bool ValidateObjCClassPrefix( } // Look for any other package that uses the same prefix. - string other_package_for_prefix; - for (std::map::const_iterator i = expected_package_prefixes.begin(); + std::string other_package_for_prefix; + for (std::map::const_iterator i = + expected_package_prefixes.begin(); i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; @@ -1159,7 +1166,7 @@ bool ValidateObjCClassPrefix( // The file does not have a package and ... if (other_package_for_prefix.empty()) { // ... no other package has declared that prefix. - std::cerr << std::endl + std::cerr << "protoc:0: warning: File '" << file->name() << "' has no " << "package. Consider adding a new package to the proto and adding '" << "new.package = " << prefix << "' to the expected prefixes file (" @@ -1167,7 +1174,7 @@ bool ValidateObjCClassPrefix( std::cerr.flush(); } else { // ... another package has declared the same prefix. - std::cerr << std::endl + std::cerr << "protoc:0: warning: File '" << file->name() << "' has no package " << "and package '" << other_package_for_prefix << "' already uses '" << prefix << "' as its prefix. Consider either adding a new package " @@ -1196,7 +1203,7 @@ bool ValidateObjCClassPrefix( // Check: Warning - If the given package/prefix pair wasn't expected, issue a // warning issue a warning suggesting it gets added to the file. if (!expected_package_prefixes.empty()) { - std::cerr << std::endl + std::cerr << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" << prefix << "\";' in '" << file->name() << "';" << " consider adding it to the expected prefixes file (" @@ -1211,9 +1218,9 @@ bool ValidateObjCClassPrefix( bool ValidateObjCClassPrefixes(const std::vector& files, const Options& generation_options, - string* out_error) { + std::string* out_error) { // Load the expected package prefixes, if available, to validate against. - std::map expected_package_prefixes; + std::map expected_package_prefixes; if (!LoadExpectedPackagePrefixes(generation_options, &expected_package_prefixes, out_error)) { @@ -1247,8 +1254,8 @@ TextFormatDecodeData::TextFormatDecodeData() { } TextFormatDecodeData::~TextFormatDecodeData() { } void TextFormatDecodeData::AddString(int32 key, - const string& input_for_decode, - const string& desired_output) { + const std::string& input_for_decode, + const std::string& desired_output) { for (std::vector::const_iterator i = entries_.begin(); i != entries_.end(); ++i) { if (i->first == key) { @@ -1260,12 +1267,12 @@ void TextFormatDecodeData::AddString(int32 key, } } - const string& data = TextFormatDecodeData::DecodeDataForString( + const std::string& data = TextFormatDecodeData::DecodeDataForString( input_for_decode, desired_output); entries_.push_back(DataEntry(key, data)); } -string TextFormatDecodeData::Data() const { +std::string TextFormatDecodeData::Data() const { std::ostringstream data_stringstream; if (num_entries() > 0) { @@ -1296,7 +1303,7 @@ class DecodeDataBuilder { Push(); need_underscore_ = true; } - string Finish() { + std::string Finish() { Push(); return decode_data_; } @@ -1352,7 +1359,7 @@ class DecodeDataBuilder { uint8 op_; int segment_len_; - string decode_data_; + std::string decode_data_; }; bool DecodeDataBuilder::AddCharacter(const char desired, const char input) { @@ -1393,8 +1400,8 @@ bool DecodeDataBuilder::AddCharacter(const char desired, const char input) { // If decode data can't be generated, a directive for the raw string // is used instead. -string DirectDecodeString(const string& str) { - string result; +std::string DirectDecodeString(const std::string& str) { + std::string result; result += (char)'\0'; // Marker for full string. result += str; result += (char)'\0'; // End of string. @@ -1404,8 +1411,8 @@ string DirectDecodeString(const string& str) { } // namespace // static -string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode, - const string& desired_output) { +std::string TextFormatDecodeData::DecodeDataForString( + const std::string& input_for_decode, const std::string& desired_output) { if (input_for_decode.empty() || desired_output.empty()) { std::cerr << "error: got empty string for making TextFormat data, input: \"" << input_for_decode << "\", desired: \"" << desired_output << "\"." @@ -1413,8 +1420,8 @@ string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode, std::cerr.flush(); abort(); } - if ((input_for_decode.find('\0') != string::npos) || - (desired_output.find('\0') != string::npos)) { + if ((input_for_decode.find('\0') != std::string::npos) || + (desired_output.find('\0') != std::string::npos)) { std::cerr << "error: got a null char in a string for making TextFormat data," << " input: \"" << CEscape(input_for_decode) << "\", desired: \"" << CEscape(desired_output) << "\"." << std::endl; @@ -1469,21 +1476,21 @@ class Parser { bool Finish(); int last_line() const { return line_; } - string error_str() const { return error_str_; } + std::string error_str() const { return error_str_; } private: bool ParseLoop(); LineConsumer* line_consumer_; int line_; - string error_str_; + std::string error_str_; StringPiece p_; - string leftover_; + std::string leftover_; }; bool Parser::ParseChunk(StringPiece chunk) { if (!leftover_.empty()) { - leftover_ += string(chunk); + leftover_ += std::string(chunk); p_ = StringPiece(leftover_); } else { p_ = chunk; @@ -1492,7 +1499,7 @@ bool Parser::ParseChunk(StringPiece chunk) { if (p_.empty()) { leftover_.clear(); } else { - leftover_ = string(p_); + leftover_ = std::string(p_); } return result; } @@ -1532,15 +1539,15 @@ LineConsumer::LineConsumer() {} LineConsumer::~LineConsumer() {} -bool ParseSimpleFile( - const string& path, LineConsumer* line_consumer, string* out_error) { +bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer, + std::string* out_error) { int fd; do { fd = posix::open(path.c_str(), O_RDONLY); } while (fd < 0 && errno == EINTR); if (fd < 0) { - *out_error = - string("error: Unable to open \"") + path + "\", " + strerror(errno); + *out_error = std::string("error: Unable to open \"") + path + "\", " + + strerror(errno); return false; } io::FileInputStream file_stream(fd); @@ -1556,7 +1563,7 @@ bool ParseSimpleFile( if (!parser.ParseChunk(StringPiece(static_cast(buf), buf_len))) { *out_error = - string("error: ") + path + + std::string("error: ") + path + " Line " + StrCat(parser.last_line()) + ", " + parser.error_str(); return false; } @@ -1565,29 +1572,27 @@ bool ParseSimpleFile( } ImportWriter::ImportWriter( - const string& generate_for_named_framework, - const string& named_framework_to_proto_path_mappings_path, - const string& runtime_import_prefix, - bool include_wkt_imports) + const std::string& generate_for_named_framework, + const std::string& named_framework_to_proto_path_mappings_path, + const std::string& runtime_import_prefix, bool include_wkt_imports) : generate_for_named_framework_(generate_for_named_framework), named_framework_to_proto_path_mappings_path_( named_framework_to_proto_path_mappings_path), runtime_import_prefix_(runtime_import_prefix), include_wkt_imports_(include_wkt_imports), - need_to_parse_mapping_file_(true) { -} + need_to_parse_mapping_file_(true) {} ImportWriter::~ImportWriter() {} void ImportWriter::AddFile(const FileDescriptor* file, - const string& header_extension) { + const std::string& header_extension) { if (IsProtobufLibraryBundledProtoFile(file)) { // The imports of the WKTs are only needed within the library itself, // in other cases, they get skipped because the generated code already // import GPBProtocolBuffers.h and hence proves them. if (include_wkt_imports_) { - const string header_name = - "GPB" + FilePathBasename(file) + header_extension; + const std::string header_name = + "GPB" + FilePathBasename(file) + header_extension; protobuf_imports_.push_back(header_name); } return; @@ -1598,7 +1603,7 @@ void ImportWriter::AddFile(const FileDescriptor* file, ParseFrameworkMappings(); } - std::map::iterator proto_lookup = + std::map::iterator proto_lookup = proto_file_to_framework_name_.find(file->name()); if (proto_lookup != proto_file_to_framework_name_.end()) { other_framework_imports_.push_back( @@ -1630,7 +1635,8 @@ void ImportWriter::Print(io::Printer* printer) const { printer->Print("\n"); } - for (std::vector::const_iterator iter = other_framework_imports_.begin(); + for (std::vector::const_iterator iter = + other_framework_imports_.begin(); iter != other_framework_imports_.end(); ++iter) { printer->Print( "#import <$header$>\n", @@ -1645,7 +1651,7 @@ void ImportWriter::Print(io::Printer* printer) const { printer->Print("\n"); } - for (std::vector::const_iterator iter = other_imports_.begin(); + for (std::vector::const_iterator iter = other_imports_.begin(); iter != other_imports_.end(); ++iter) { printer->Print( "#import \"$header$\"\n", @@ -1655,11 +1661,8 @@ void ImportWriter::Print(io::Printer* printer) const { } void ImportWriter::PrintRuntimeImports( - io::Printer* printer, - const std::vector& header_to_import, - const string& runtime_import_prefix, - bool default_cpp_symbol) { - + io::Printer* printer, const std::vector& header_to_import, + const std::string& runtime_import_prefix, bool default_cpp_symbol) { // Given an override, use that. if (!runtime_import_prefix.empty()) { for (const auto& header : header_to_import) { @@ -1671,8 +1674,8 @@ void ImportWriter::PrintRuntimeImports( return; } - const string framework_name(ProtobufLibraryFrameworkName); - const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); + const std::string framework_name(ProtobufLibraryFrameworkName); + const std::string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); if (default_cpp_symbol) { printer->Print( @@ -1712,7 +1715,7 @@ void ImportWriter::ParseFrameworkMappings() { } ProtoFrameworkCollector collector(&proto_file_to_framework_name_); - string parse_error; + std::string parse_error; if (!ParseSimpleFile(named_framework_to_proto_path_mappings_path_, &collector, &parse_error)) { std::cerr << "error parsing " << named_framework_to_proto_path_mappings_path_ @@ -1722,12 +1725,12 @@ void ImportWriter::ParseFrameworkMappings() { } bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( - const StringPiece& line, string* out_error) { + const StringPiece& line, std::string* out_error) { int offset = line.find(':'); if (offset == StringPiece::npos) { *out_error = - string("Framework/proto file mapping line without colon sign: '") + - string(line) + "'."; + std::string("Framework/proto file mapping line without colon sign: '") + + std::string(line) + "'."; return false; } StringPiece framework_name = line.substr(0, offset); @@ -1744,12 +1747,12 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( StringPiece proto_file = proto_file_list.substr(start, offset - start); TrimWhitespace(&proto_file); if (!proto_file.empty()) { - std::map::iterator existing_entry = + std::map::iterator existing_entry = map_->find(string(proto_file)); if (existing_entry != map_->end()) { std::cerr << "warning: duplicate proto file reference, replacing " "framework entry for '" - << string(proto_file) << "' with '" << string(framework_name) + << std::string(proto_file) << "' with '" << std::string(framework_name) << "' (was '" << existing_entry->second << "')." << std::endl; std::cerr.flush(); } @@ -1757,11 +1760,11 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( if (proto_file.find(' ') != StringPiece::npos) { std::cerr << "note: framework mapping file had a proto file with a " "space in, hopefully that isn't a missing comma: '" - << string(proto_file) << "'" << std::endl; + << std::string(proto_file) << "'" << std::endl; std::cerr.flush(); } - (*map_)[string(proto_file)] = string(framework_name); + (*map_)[std::string(proto_file)] = std::string(framework_name); } start = offset + 1; @@ -1770,7 +1773,6 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( return true; } - } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 02f540f87480..1414152bca25 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -49,83 +49,83 @@ namespace objectivec { // Generator options (see objectivec_generator.cc for a description of each): struct Options { Options(); - string expected_prefixes_path; - std::vector expected_prefixes_suppressions; - string generate_for_named_framework; - string named_framework_to_proto_path_mappings_path; - string runtime_import_prefix; + std::string expected_prefixes_path; + std::vector expected_prefixes_suppressions; + std::string generate_for_named_framework; + std::string named_framework_to_proto_path_mappings_path; + std::string runtime_import_prefix; }; // Escape C++ trigraphs by escaping question marks to "\?". -string PROTOC_EXPORT EscapeTrigraphs(const string& to_escape); +std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& to_escape); // Strips ".proto" or ".protodevel" from the end of a filename. -string PROTOC_EXPORT StripProto(const string& filename); +std::string PROTOC_EXPORT StripProto(const std::string& filename); // Remove white space from either end of a StringPiece. void PROTOC_EXPORT TrimWhitespace(StringPiece* input); // Returns true if the name requires a ns_returns_not_retained attribute applied // to it. -bool PROTOC_EXPORT IsRetainedName(const string& name); +bool PROTOC_EXPORT IsRetainedName(const std::string& name); // Returns true if the name starts with "init" and will need to have special // handling under ARC. -bool PROTOC_EXPORT IsInitName(const string& name); +bool PROTOC_EXPORT IsInitName(const std::string& name); // Gets the objc_class_prefix. -string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file); +std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file); // Gets the path of the file we're going to generate (sans the .pb.h // extension). The path will be dependent on the objectivec package // declared in the proto package. -string PROTOC_EXPORT FilePath(const FileDescriptor* file); +std::string PROTOC_EXPORT FilePath(const FileDescriptor* file); // Just like FilePath(), but without the directory part. -string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file); +std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file); // Gets the name of the root class we'll generate in the file. This class // is not meant for external consumption, but instead contains helpers that // the rest of the classes need -string PROTOC_EXPORT FileClassName(const FileDescriptor* file); +std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file); // These return the fully-qualified class name corresponding to the given // descriptor. -string PROTOC_EXPORT ClassName(const Descriptor* descriptor); -string PROTOC_EXPORT ClassName(const Descriptor* descriptor, - string* out_suffix_added); -string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor); +std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor); +std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor, + std::string* out_suffix_added); +std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor); // Returns the fully-qualified name of the enum value corresponding to the // the descriptor. -string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor); +std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor); // Returns the name of the enum value corresponding to the descriptor. -string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor); +std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor); // Reverse what an enum does. -string PROTOC_EXPORT UnCamelCaseEnumShortName(const string& name); +std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name); // Returns the name to use for the extension (used as the method off the file's // Root class). -string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor); +std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor); // Returns the transformed field name. -string PROTOC_EXPORT FieldName(const FieldDescriptor* field); -string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field); +std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field); +std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field); // Returns the transformed oneof name. -string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor); -string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor); -string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor); +std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor); +std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor); +std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor); // Returns a symbol that can be used in C code to refer to an Objective C // class without initializing the class. -string PROTOC_EXPORT ObjCClass(const string& class_name); +std::string PROTOC_EXPORT ObjCClass(const std::string& class_name); // Declares an Objective C class without initializing the class so that it can // be refrerred to by ObjCClass. -string PROTOC_EXPORT ObjCClassDeclaration(const string& class_name); +std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name); inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) { return file->syntax() == FileDescriptor::SYNTAX_PROTO3; @@ -136,8 +136,8 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) { } // Reverse of the above. -string PROTOC_EXPORT UnCamelCaseFieldName(const string& name, - const FieldDescriptor* field); +std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name, + const FieldDescriptor* field); enum ObjectiveCType { OBJECTIVECTYPE_INT32, @@ -159,11 +159,11 @@ enum FlagType { FLAGTYPE_FIELD }; -template -string GetOptionalDeprecatedAttribute( - const TDescriptor* descriptor, - const FileDescriptor* file = NULL, - bool preSpace = true, bool postNewline = false) { +template +std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, + const FileDescriptor* file = NULL, + bool preSpace = true, + bool postNewline = false) { bool isDeprecated = descriptor->options().deprecated(); // The file is only passed when checking Messages & Enums, so those types // get tagged. At the moment, it doesn't seem to make sense to tag every @@ -174,7 +174,7 @@ string GetOptionalDeprecatedAttribute( isDeprecated = isFileLevelDeprecation; } if (isDeprecated) { - string message; + std::string message; const FileDescriptor* sourceFile = descriptor->file(); if (isFileLevelDeprecation) { message = sourceFile->name() + " is deprecated."; @@ -183,7 +183,7 @@ string GetOptionalDeprecatedAttribute( sourceFile->name() + ")."; } - string result = string("GPB_DEPRECATED_MSG(\"") + message + "\")"; + std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")"; if (preSpace) { result.insert(0, " "); } @@ -196,7 +196,7 @@ string GetOptionalDeprecatedAttribute( } } -string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field); +std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field); ObjectiveCType PROTOC_EXPORT GetObjectiveCType(FieldDescriptor::Type field_type); @@ -208,25 +208,26 @@ inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) { bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field); bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field); -string PROTOC_EXPORT GPBGenericValueFieldName(const FieldDescriptor* field); -string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field); +std::string PROTOC_EXPORT +GPBGenericValueFieldName(const FieldDescriptor* field); +std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field); bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field); -string PROTOC_EXPORT BuildFlagsString(const FlagType type, - const std::vector& strings); +std::string PROTOC_EXPORT +BuildFlagsString(const FlagType type, const std::vector& strings); // Builds HeaderDoc/appledoc style comments out of the comments in the .proto // file. -string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location, - bool prefer_single_line); +std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location, + bool prefer_single_line); // The name the commonly used by the library when built as a framework. // This lines up to the name used in the CocoaPod. extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName; // Returns the CPP symbol name to use as the gate for framework style imports // for the given framework name to use. -string PROTOC_EXPORT -ProtobufFrameworkImportSymbol(const string& framework_name); +std::string PROTOC_EXPORT +ProtobufFrameworkImportSymbol(const std::string& framework_name); // Checks if the file is one of the proto's bundled with the library. bool PROTOC_EXPORT @@ -235,9 +236,9 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); // Checks the prefix for the given files and outputs any warnings as needed. If // there are flat out errors, then out_error is filled in with the first error // and the result is false. -bool PROTOC_EXPORT -ValidateObjCClassPrefixes(const std::vector& files, - const Options& generation_options, string* out_error); +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector& files, + const Options& generation_options, std::string* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. @@ -249,16 +250,16 @@ class PROTOC_EXPORT TextFormatDecodeData { TextFormatDecodeData(const TextFormatDecodeData&) = delete; TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete; - void AddString(int32 key, const string& input_for_decode, - const string& desired_output); + void AddString(int32 key, const std::string& input_for_decode, + const std::string& desired_output); size_t num_entries() const { return entries_.size(); } - string Data() const; + std::string Data() const; - static string DecodeDataForString(const string& input_for_decode, - const string& desired_output); + static std::string DecodeDataForString(const std::string& input_for_decode, + const std::string& desired_output); private: - typedef std::pair DataEntry; + typedef std::pair DataEntry; std::vector entries_; }; @@ -267,55 +268,55 @@ class PROTOC_EXPORT LineConsumer { public: LineConsumer(); virtual ~LineConsumer(); - virtual bool ConsumeLine(const StringPiece& line, string* out_error) = 0; + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) = 0; }; -bool PROTOC_EXPORT ParseSimpleFile(const string& path, +bool PROTOC_EXPORT ParseSimpleFile(const std::string& path, LineConsumer* line_consumer, - string* out_error); + std::string* out_error); // Helper class for parsing framework import mappings and generating // import statements. class PROTOC_EXPORT ImportWriter { public: - ImportWriter(const string& generate_for_named_framework, - const string& named_framework_to_proto_path_mappings_path, - const string& runtime_import_prefix, + ImportWriter(const std::string& generate_for_named_framework, + const std::string& named_framework_to_proto_path_mappings_path, + const std::string& runtime_import_prefix, bool include_wkt_imports); ~ImportWriter(); - void AddFile(const FileDescriptor* file, const string& header_extension); + void AddFile(const FileDescriptor* file, const std::string& header_extension); void Print(io::Printer *printer) const; static void PrintRuntimeImports(io::Printer *printer, - const std::vector& header_to_import, - const string& runtime_import_prefix, + const std::vector& header_to_import, + const std::string& runtime_import_prefix, bool default_cpp_symbol = false); private: class ProtoFrameworkCollector : public LineConsumer { public: - ProtoFrameworkCollector(std::map* inout_proto_file_to_framework_name) + ProtoFrameworkCollector(std::map* inout_proto_file_to_framework_name) : map_(inout_proto_file_to_framework_name) {} - virtual bool ConsumeLine(const StringPiece& line, string* out_error); + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error); private: - std::map* map_; + std::map* map_; }; void ParseFrameworkMappings(); - const string generate_for_named_framework_; - const string named_framework_to_proto_path_mappings_path_; - const string runtime_import_prefix_; + const std::string generate_for_named_framework_; + const std::string named_framework_to_proto_path_mappings_path_; + const std::string runtime_import_prefix_; const bool include_wkt_imports_; - std::map proto_file_to_framework_name_; + std::map proto_file_to_framework_name_; bool need_to_parse_mapping_file_; - std::vector protobuf_imports_; - std::vector other_framework_imports_; - std::vector other_imports_; + std::vector protobuf_imports_; + std::vector other_framework_imports_; + std::vector other_imports_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc index dc1cef556f35..0aef94fe3f82 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc @@ -39,21 +39,21 @@ namespace objectivec { namespace { TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { - string input_for_decode("abcdefghIJ"); - string desired_output_for_decode; - string expected; - string result; + std::string input_for_decode("abcdefghIJ"); + std::string desired_output_for_decode; + std::string expected; + std::string result; // Different data, can't transform. desired_output_for_decode = "zbcdefghIJ"; - expected = string("\0zbcdefghIJ\0", 12); + expected = std::string("\0zbcdefghIJ\0", 12); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); desired_output_for_decode = "abcdezghIJ"; - expected = string("\0abcdezghIJ\0", 12); + expected = std::string("\0abcdezghIJ\0", 12); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -61,7 +61,7 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { // Shortened data, can't transform. desired_output_for_decode = "abcdefghI"; - expected = string("\0abcdefghI\0", 11); + expected = std::string("\0abcdefghI\0", 11); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -69,32 +69,32 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { // Extra data, can't transform. desired_output_for_decode = "abcdefghIJz"; - expected = string("\0abcdefghIJz\0", 13); + expected = std::string("\0abcdefghIJz\0", 13); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); } TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) { - string input_for_decode("abcdefghIJ"); - string desired_output_for_decode; - string expected; - string result; + std::string input_for_decode("abcdefghIJ"); + std::string desired_output_for_decode; + std::string expected; + std::string result; desired_output_for_decode = "abcdefghIJ"; - expected = string("\x0A\x0", 2); + expected = std::string("\x0A\x0", 2); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); desired_output_for_decode = "_AbcdefghIJ"; - expected = string("\xCA\x0", 2); + expected = std::string("\xCA\x0", 2); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); desired_output_for_decode = "ABCD__EfghI_j"; - expected = string("\x64\x80\xC5\xA1\x0", 5); + expected = std::string("\x64\x80\xC5\xA1\x0", 5); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -105,7 +105,7 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) { "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000"; desired_output_for_decode = "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000"; - expected = string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9); + expected = std::string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -128,7 +128,7 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) { // Null char in the string. - string str_with_null_char("ab\0c", 4); + std::string str_with_null_char("ab\0c", 4); EXPECT_EXIT( TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"), ::testing::KilledBySignal(SIGABRT), @@ -160,7 +160,7 @@ TEST(ObjCHelper, TextFormatDecodeData_RawStrings) { 0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0, 0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0, }; - string expected((const char*)expected_data, sizeof(expected_data)); + std::string expected((const char*)expected_data, sizeof(expected_data)); EXPECT_EQ(expected, decode_data.Data()); } @@ -196,7 +196,7 @@ TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) { // underscore, as is + 3 (00 op) 0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0, }; - string expected((const char*)expected_data, sizeof(expected_data)); + std::string expected((const char*)expected_data, sizeof(expected_data)); EXPECT_EQ(expected, decode_data.Data()); } @@ -221,7 +221,7 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) { // Null char in the string. - string str_with_null_char("ab\0c", 4); + std::string str_with_null_char("ab\0c", 4); EXPECT_EXIT( decode_data.AddString(1, str_with_null_char, "def"), ::testing::KilledBySignal(SIGABRT), diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index 545660db77a2..746224ff86b2 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -96,20 +96,21 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, variables_["default_name"] = value_field_generator_->variable("default_name"); // Build custom field flags. - std::vector field_flags; + std::vector field_flags; field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor)); // Pull over the current text format custom name values that was calculated. if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") != - string::npos) { + std::string::npos) { field_flags.push_back("GPBFieldTextFormatNameCustom"); } // Pull over some info from the value's flags. - const string& value_field_flags = + const std::string& value_field_flags = value_field_generator_->variable("fieldflags"); - if (value_field_flags.find("GPBFieldHasDefaultValue") != string::npos) { + if (value_field_flags.find("GPBFieldHasDefaultValue") != std::string::npos) { field_flags.push_back("GPBFieldHasDefaultValue"); } - if (value_field_flags.find("GPBFieldHasEnumDescriptor") != string::npos) { + if (value_field_flags.find("GPBFieldHasEnumDescriptor") != + std::string::npos) { field_flags.push_back("GPBFieldHasEnumDescriptor"); } @@ -127,7 +128,7 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, "NSMutableDictionaryvariable("storage_type") + "*>"; } else { - string class_name("GPB"); + std::string class_name("GPB"); class_name += MapEntryTypeName(key_descriptor, true); class_name += MapEntryTypeName(value_descriptor, false); class_name += "Dictionary"; @@ -160,19 +161,19 @@ void MapFieldGenerator::FinishInitialization(void) { } void MapFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); const FieldDescriptor* value_descriptor = descriptor_->message_type()->FindFieldByName("value"); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { - const string& value_storage_type = + const std::string& value_storage_type = value_field_generator_->variable("storage_type"); fwd_decls->insert("@class " + value_storage_type); } } void MapFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { // Class name is already in "storage_type". const FieldDescriptor* value_descriptor = descriptor_->message_type()->FindFieldByName("value"); @@ -182,7 +183,6 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions( } } - } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index da18d579f556..55fd56c125d2 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -54,8 +54,10 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); virtual ~MapFieldGenerator(); - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; private: std::unique_ptr value_field_generator_; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 0684021c2a65..917cc64861e8 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -170,16 +170,15 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { } } // namespace -MessageGenerator::MessageGenerator(const string& root_classname, +MessageGenerator::MessageGenerator(const std::string& root_classname, const Descriptor* descriptor, const Options& options) : root_classname_(root_classname), descriptor_(descriptor), field_generators_(descriptor, options), class_name_(ClassName(descriptor_)), - deprecated_attribute_( - GetOptionalDeprecatedAttribute(descriptor, descriptor->file(), false, true)) { - + deprecated_attribute_(GetOptionalDeprecatedAttribute( + descriptor, descriptor->file(), false, true)) { for (int i = 0; i < descriptor_->extension_count(); i++) { extension_generators_.emplace_back( new ExtensionGenerator(class_name_, descriptor_->extension(i))); @@ -217,7 +216,8 @@ void MessageGenerator::GenerateStaticVariablesInitialization( } } -void MessageGenerator::DetermineForwardDeclarations(std::set* fwd_decls) { +void MessageGenerator::DetermineForwardDeclarations( + std::set* fwd_decls) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); @@ -231,7 +231,8 @@ void MessageGenerator::DetermineForwardDeclarations(std::set* fwd_decls) } } -void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set* fwd_decls) { +void MessageGenerator::DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); @@ -250,7 +251,7 @@ void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set* fwd const Descriptor* containing_descriptor = descriptor_->containing_type(); if (containing_descriptor != NULL) { - string containing_class = ClassName(containing_descriptor); + std::string containing_class = ClassName(containing_descriptor); fwd_decls->insert(ObjCClassDeclaration(containing_class)); } } @@ -325,7 +326,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { generator->GenerateCaseEnum(printer); } - string message_comments; + std::string message_comments; SourceLocation location; if (descriptor_->GetSourceLocation(&location)) { message_comments = BuildCommentsString(location, false); @@ -473,7 +474,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { TextFormatDecodeData text_format_decode_data; bool has_fields = descriptor_->field_count() > 0; bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault(); - string field_description_type; + std::string field_description_type; if (need_defaults) { field_description_type = "GPBMessageFieldDescriptionWithDefault"; } else { @@ -503,7 +504,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { printer->Outdent(); } - std::map vars; + std::map vars; vars["classname"] = class_name_; vars["rootclassname"] = root_classname_; vars["fields"] = has_fields ? "fields" : "NULL"; @@ -514,7 +515,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { vars["fields_count"] = "0"; } - std::vector init_flags; + std::vector init_flags; init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs"); init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown"); if (need_defaults) { @@ -551,7 +552,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { "first_has_index", oneof_generators_[0]->HasIndexAsString()); } if (text_format_decode_data.num_entries() != 0) { - const string text_format_data_str(text_format_decode_data.Data()); + const std::string text_format_data_str(text_format_decode_data.Data()); printer->Print( "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n" " static const char *extraTextFormatInfo ="); @@ -581,13 +582,13 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n"); } if (descriptor_->containing_type() != NULL) { - string containing_class = ClassName(descriptor_->containing_type()); - string parent_class_ref = ObjCClass(containing_class); + std::string containing_class = ClassName(descriptor_->containing_type()); + std::string parent_class_ref = ObjCClass(containing_class); printer->Print( " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n", "parent_class_ref", parent_class_ref); } - string suffix_added; + std::string suffix_added; ClassName(descriptor_, &suffix_added); if (!suffix_added.empty()) { printer->Print( diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h index 138e62020638..01108d29e75a 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -50,9 +50,8 @@ class EnumGenerator; class MessageGenerator { public: - MessageGenerator(const string& root_classname, - const Descriptor* descriptor, - const Options& options); + MessageGenerator(const std::string& root_classname, + const Descriptor* descriptor, const Options& options); ~MessageGenerator(); MessageGenerator(const MessageGenerator&) = delete; @@ -63,8 +62,8 @@ class MessageGenerator { void GenerateMessageHeader(io::Printer* printer); void GenerateSource(io::Printer* printer); void GenerateExtensionRegistrationSource(io::Printer* printer); - void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); - void DetermineForwardDeclarations(std::set* fwd_decls); + void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); + void DetermineForwardDeclarations(std::set* fwd_decls); // Checks if the message or a nested message includes a oneof definition. bool IncludesOneOfDefinition() const; @@ -81,11 +80,11 @@ class MessageGenerator { void GenerateDescriptionOneFieldSource(io::Printer* printer, const FieldDescriptor* field); - const string root_classname_; + const std::string root_classname_; const Descriptor* descriptor_; FieldGeneratorMap field_generators_; - const string class_name_; - const string deprecated_attribute_; + const std::string class_name_; + const std::string deprecated_attribute_; std::vector> extension_generators_; std::vector> enum_generators_; std::vector> nested_message_generators_; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index 7bf33f4c120a..299a20b152ee 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -44,9 +44,10 @@ namespace objectivec { namespace { void SetMessageVariables(const FieldDescriptor* descriptor, - std::map* variables) { - const string& message_type = ClassName(descriptor->message_type()); - const string& containing_class = ClassName(descriptor->containing_type()); + std::map* variables) { + const std::string& message_type = ClassName(descriptor->message_type()); + const std::string& containing_class = + ClassName(descriptor->containing_type()); (*variables)["type"] = message_type; (*variables)["containing_class"] = containing_class; (*variables)["storage_type"] = message_type; @@ -66,14 +67,14 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls); // Class name is already in "storage_type". fwd_decls->insert("@class " + variable("storage_type")); } void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); } @@ -89,14 +90,14 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); // Class name is already in "storage_type". fwd_decls->insert("@class " + variable("storage_type")); } void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index a53c4a540cf3..01dd6ed21f0c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -54,8 +54,10 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { virtual ~MessageFieldGenerator(); public: - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; }; class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { @@ -71,8 +73,10 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete; public: - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc index badebf55b9b3..1bef293e2885 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc @@ -50,7 +50,7 @@ OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor) const Descriptor* msg_descriptor = descriptor_->containing_type(); variables_["owning_message_class"] = ClassName(msg_descriptor); - string comments; + std::string comments; SourceLocation location; if (descriptor_->GetSourceLocation(&location)) { comments = BuildCommentsString(location, true); @@ -76,10 +76,10 @@ void OneofGenerator::GenerateCaseEnum(io::Printer* printer) { printer->Print( variables_, "$enum_name$_GPBUnsetOneOfCase = 0,\n"); - string enum_name = variables_["enum_name"]; + std::string enum_name = variables_["enum_name"]; for (int j = 0; j < descriptor_->field_count(); j++) { const FieldDescriptor* field = descriptor_->field(j); - string field_name = FieldNameCapitalized(field); + std::string field_name = FieldNameCapitalized(field); printer->Print( "$enum_name$_$field_name$ = $field_number$,\n", "enum_name", enum_name, @@ -126,11 +126,11 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) { "}\n"); } -string OneofGenerator::DescriptorName(void) const { +std::string OneofGenerator::DescriptorName(void) const { return variables_.find("name")->second; } -string OneofGenerator::HasIndexAsString(void) const { +std::string OneofGenerator::HasIndexAsString(void) const { return variables_.find("index")->second; } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h index 852ef02241cb..034f07fb3306 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h @@ -60,12 +60,12 @@ class OneofGenerator { void GeneratePropertyImplementation(io::Printer* printer); void GenerateClearFunctionImplementation(io::Printer* printer); - string DescriptorName(void) const; - string HasIndexAsString(void) const; + std::string DescriptorName(void) const; + std::string HasIndexAsString(void) const; private: const OneofDescriptor* descriptor_; - std::map variables_; + std::map variables_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index 0511b37dd7eb..e198c5c182ca 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -116,7 +116,7 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) { } void SetPrimitiveVariables(const FieldDescriptor* descriptor, - std::map* variables) { + std::map* variables) { std::string primitive_name = PrimitiveTypeName(descriptor); (*variables)["type"] = primitive_name; (*variables)["storage_type"] = primitive_name; @@ -172,7 +172,7 @@ RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( : RepeatedFieldGenerator(descriptor, options) { SetPrimitiveVariables(descriptor, &variables_); - string base_name = PrimitiveArrayTypeName(descriptor); + std::string base_name = PrimitiveArrayTypeName(descriptor); if (base_name.length()) { variables_["array_storage_type"] = "GPB" + base_name + "Array"; } else { diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 365cb64e5327..6f100a054bf9 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -82,18 +82,20 @@ namespace php { std::string PhpName(const std::string& full_name, bool is_descriptor); std::string DefaultForField(FieldDescriptor* field); std::string IntToString(int32 value); -std::string FilenameToClassname(const string& filename); +std::string FilenameToClassname(const std::string& filename); std::string GeneratedMetadataFileName(const FileDescriptor* file, bool is_descriptor); std::string LabelForField(FieldDescriptor* field); std::string TypeName(FieldDescriptor* field); -std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter); -std::string BinaryToHex(const string& binary); +std::string UnderscoresToCamelCase(const std::string& name, + bool cap_first_letter); +std::string BinaryToHex(const std::string& binary); void Indent(io::Printer* printer); void Outdent(io::Printer* printer); -void GenerateAddFilesToPool(const FileDescriptor* file, - const std::set& aggregate_metadata_prefixes, - io::Printer* printer); +void GenerateAddFilesToPool( + const FileDescriptor* file, + const std::set& aggregate_metadata_prefixes, + io::Printer* printer); void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, int is_descriptor); void GenerateMessageConstructorDocComment(io::Printer* printer, @@ -114,11 +116,11 @@ void GenerateServiceDocComment(io::Printer* printer, void GenerateServiceMethodDocComment(io::Printer* printer, const MethodDescriptor* method); -std::string ReservedNamePrefix(const string& classname, +std::string ReservedNamePrefix(const std::string& classname, const FileDescriptor* file) { bool is_reserved = false; - string lower = classname; + std::string lower = classname; std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (int i = 0; i < kReservedNamesSize; i++) { @@ -151,9 +153,9 @@ std::string DescriptorFullName(const DescriptorType* desc, bool is_descriptor) { } template -std::string ClassNamePrefix(const string& classname, +std::string ClassNamePrefix(const std::string& classname, const DescriptorType* desc) { - const string& prefix = (desc->file()->options()).php_class_prefix(); + const std::string& prefix = (desc->file()->options()).php_class_prefix(); if (!prefix.empty()) { return prefix; } @@ -201,8 +203,8 @@ std::string LegacyGeneratedClassName(const DescriptorType* desc) { return ClassNamePrefix(classname, desc) + classname; } -std::string ClassNamePrefix(const string& classname) { - string lower = classname; +std::string ClassNamePrefix(const std::string& classname) { + std::string lower = classname; std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (int i = 0; i < kReservedNamesSize; i++) { @@ -214,10 +216,10 @@ std::string ClassNamePrefix(const string& classname) { return ""; } -std::string ConstantNamePrefix(const string& classname) { +std::string ConstantNamePrefix(const std::string& classname) { bool is_reserved = false; - string lower = classname; + std::string lower = classname; std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (int i = 0; i < kReservedNamesSize; i++) { @@ -244,7 +246,7 @@ std::string ConstantNamePrefix(const string& classname) { template std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { if (desc->file()->options().has_php_namespace()) { - const string& php_namespace = desc->file()->options().php_namespace(); + const std::string& php_namespace = desc->file()->options().php_namespace(); if (!php_namespace.empty()) { return php_namespace; } @@ -259,8 +261,8 @@ std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { template std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { - string classname = GeneratedClassNameImpl(desc); - string php_namespace = RootPhpNamespace(desc, is_descriptor); + std::string classname = GeneratedClassNameImpl(desc); + std::string php_namespace = RootPhpNamespace(desc, is_descriptor); if (!php_namespace.empty()) { return php_namespace + "\\" + classname; } @@ -269,8 +271,8 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { template std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) { - string classname = LegacyGeneratedClassName(desc); - string php_namespace = RootPhpNamespace(desc, is_descriptor); + std::string classname = LegacyGeneratedClassName(desc); + std::string php_namespace = RootPhpNamespace(desc, is_descriptor); if (!php_namespace.empty()) { return php_namespace + "\\" + classname; } @@ -328,7 +330,7 @@ std::string DefaultForField(const FieldDescriptor* field) { std::string GeneratedMetadataFileName(const FileDescriptor* file, bool is_descriptor) { - const string& proto_file = file->name(); + const std::string& proto_file = file->name(); int start_index = 0; int first_index = proto_file.find_first_of("/", start_index); std::string result = ""; @@ -351,7 +353,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, } if (file->options().has_php_metadata_namespace()) { - const string& php_metadata_namespace = + const std::string& php_metadata_namespace = file->options().php_metadata_namespace(); if (!php_metadata_namespace.empty() && php_metadata_namespace != "\\") { result += php_metadata_namespace; @@ -362,7 +364,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, } } else { result += "GPBMetadata/"; - while (first_index != string::npos) { + while (first_index != std::string::npos) { segment = UnderscoresToCamelCase( file_no_suffix.substr(start_index, first_index - start_index), true); result += ReservedNamePrefix(segment, file) + segment + "/"; @@ -373,7 +375,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, // Append file name. int file_name_start = file_no_suffix.find_last_of("/"); - if (file_name_start == string::npos) { + if (file_name_start == std::string::npos) { file_name_start = 0; } else { file_name_start += 1; @@ -463,7 +465,7 @@ std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) if (field->is_map()) { return "array|\\Google\\Protobuf\\Internal\\MapField"; } - string type; + std::string type; switch (field->type()) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_UINT32: @@ -553,7 +555,8 @@ std::string EnumOrMessageSuffix( // Converts a name to camel-case. If cap_first_letter is true, capitalize the // first letter. -std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter) { +std::string UnderscoresToCamelCase(const std::string& name, + bool cap_first_letter) { std::string result; for (int i = 0; i < name.size(); i++) { if ('a' <= name[i] && name[i] <= 'z') { @@ -587,8 +590,8 @@ std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter) { return result; } -std::string BinaryToHex(const string& binary) { - string dest; +std::string BinaryToHex(const std::string& binary) { + std::string dest; size_t i; unsigned char symbol[16] = { '0', '1', '2', '3', @@ -844,15 +847,16 @@ void GenerateServiceMethod(const MethodDescriptor* method, ); } -void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, - io::Printer* printer) { +void GenerateMessageToPool(const std::string& name_prefix, + const Descriptor* message, io::Printer* printer) { // Don't generate MapEntry messages -- we use the PHP extension's native // support for map fields instead. if (message->options().map_entry()) { return; } - string class_name = (name_prefix.empty() ? "" : name_prefix + "\\") + - ReservedNamePrefix(message->name(), message->file()) + message->name(); + std::string class_name = + (name_prefix.empty() ? "" : name_prefix + "\\") + + ReservedNamePrefix(message->name(), message->file()) + message->name(); printer->Print( "$pool->addMessage('^message^', " @@ -926,10 +930,8 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, } void GenerateAddFileToPool( - const FileDescriptor* file, - bool is_descriptor, - bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, + const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, + const std::set& aggregate_metadata_prefixes, io::Printer* printer) { printer->Print( "public static $is_initialized = false;\n\n" @@ -978,8 +980,9 @@ void GenerateAddFileToPool( file->CopyTo(file_proto); // Filter out descriptor.proto as it cannot be depended on for now. - RepeatedPtrField* dependency = file_proto->mutable_dependency(); - for (RepeatedPtrField::iterator it = dependency->begin(); + RepeatedPtrField* dependency = + file_proto->mutable_dependency(); + for (RepeatedPtrField::iterator it = dependency->begin(); it != dependency->end(); ++it) { if (*it != kDescriptorFile) { dependency->erase(it); @@ -996,7 +999,7 @@ void GenerateAddFileToPool( it->clear_extension(); } - string files_data; + std::string files_data; files.SerializeToString(&files_data); printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n"); @@ -1053,7 +1056,7 @@ static void AnalyzeDependencyForFile( static bool NeedsUnwrapping( const FileDescriptor* file, - const std::set& aggregate_metadata_prefixes) { + const std::set& aggregate_metadata_prefixes) { bool has_aggregate_metadata_prefix = false; if (aggregate_metadata_prefixes.empty()) { has_aggregate_metadata_prefix = true; @@ -1071,7 +1074,7 @@ static bool NeedsUnwrapping( void GenerateAddFilesToPool( const FileDescriptor* file, - const std::set& aggregate_metadata_prefixes, + const std::set& aggregate_metadata_prefixes, io::Printer* printer) { printer->Print( "$pool = \\Google\\Protobuf\\Internal\\" @@ -1108,8 +1111,9 @@ void GenerateAddFilesToPool( file->CopyTo(file_proto); // Filter out descriptor.proto as it cannot be depended on for now. - RepeatedPtrField* dependency = file_proto->mutable_dependency(); - for (RepeatedPtrField::iterator it = dependency->begin(); + RepeatedPtrField* dependency = + file_proto->mutable_dependency(); + for (RepeatedPtrField::iterator it = dependency->begin(); it != dependency->end(); ++it) { if (*it != kDescriptorFile) { dependency->erase(it); @@ -1134,7 +1138,7 @@ void GenerateAddFilesToPool( } } - string files_data; + std::string files_data; sorted_file_set.SerializeToString(&files_data); printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n"); @@ -1177,7 +1181,7 @@ void GenerateHead(const FileDescriptor* file, io::Printer* printer) { "filename", file->name()); } -std::string FilenameToClassname(const string& filename) { +std::string FilenameToClassname(const std::string& filename) { int lastindex = filename.find_last_of("."); std::string result = filename.substr(0, lastindex); for (int i = 0; i < result.size(); i++) { @@ -1188,11 +1192,10 @@ std::string FilenameToClassname(const string& filename) { return result; } -void GenerateMetadataFile(const FileDescriptor* file, - bool is_descriptor, - bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, - GeneratorContext* generator_context) { +void GenerateMetadataFile( + const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, + const std::set& aggregate_metadata_prefixes, + GeneratorContext* generator_context) { std::string filename = GeneratedMetadataFileName(file, is_descriptor); std::unique_ptr output( generator_context->Open(filename)); @@ -1203,7 +1206,7 @@ void GenerateMetadataFile(const FileDescriptor* file, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1277,7 +1280,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1289,7 +1292,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, GenerateEnumDocComment(&printer, en, is_descriptor); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { fullname = fullname.substr(lastindex + 1); } @@ -1389,7 +1392,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1398,7 +1401,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, GenerateUseDeclaration(is_descriptor, &printer); GenerateMessageDocComment(&printer, message, is_descriptor); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { fullname = fullname.substr(lastindex + 1); } @@ -1497,7 +1500,7 @@ void GenerateServiceFile(const FileDescriptor* file, if (!file->options().php_namespace().empty() || (!file->options().has_php_namespace() && !file->package().empty()) || - lastindex != string::npos) { + lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1505,13 +1508,13 @@ void GenerateServiceFile(const FileDescriptor* file, GenerateServiceDocComment(&printer, service); - if (lastindex != string::npos) { - printer.Print( + if (lastindex != std::string::npos) { + printer.Print( "interface ^name^\n" "{\n", "name", fullname.substr(lastindex + 1)); } else { - printer.Print( + printer.Print( "interface ^name^\n" "{\n", "name", fullname); @@ -1531,7 +1534,7 @@ void GenerateServiceFile(const FileDescriptor* file, void GenerateFile(const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, + const std::set& aggregate_metadata_prefixes, GeneratorContext* generator_context) { GenerateMetadataFile(file, is_descriptor, aggregate_metadata, aggregate_metadata_prefixes, generator_context); @@ -1553,13 +1556,13 @@ void GenerateFile(const FileDescriptor* file, bool is_descriptor, } } -static string EscapePhpdoc(const string& input) { - string result; +static std::string EscapePhpdoc(const std::string& input) { + std::string result; result.reserve(input.size() * 2); char prev = '*'; - for (string::size_type i = 0; i < input.size(); i++) { + for (std::string::size_type i = 0; i < input.size(); i++) { char c = input[i]; switch (c) { case '*': @@ -1598,8 +1601,9 @@ static string EscapePhpdoc(const string& input) { static void GenerateDocCommentBodyForLocation( io::Printer* printer, const SourceLocation& location, bool trailingNewline, int indentCount) { - string comments = location.leading_comments.empty() ? - location.trailing_comments : location.leading_comments; + std::string comments = location.leading_comments.empty() + ? location.trailing_comments + : location.leading_comments; if (!comments.empty()) { // TODO(teboring): Ideally we should parse the comment text as Markdown and // write it back as HTML, but this requires a Markdown parser. For now @@ -1609,7 +1613,7 @@ static void GenerateDocCommentBodyForLocation( // HTML-escape them so that they don't accidentally close the doc comment. comments = EscapePhpdoc(comments); - std::vector lines = Split(comments, "\n", true); + std::vector lines = Split(comments, "\n", true); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); } @@ -1640,11 +1644,11 @@ static void GenerateDocCommentBody( } } -static string FirstLineOf(const string& value) { - string result = value; +static std::string FirstLineOf(const std::string& value) { + std::string result = value; - string::size_type pos = result.find_first_of('\n'); - if (pos != string::npos) { + std::string::size_type pos = result.find_first_of('\n'); + if (pos != std::string::npos) { result.erase(pos); } @@ -1801,20 +1805,18 @@ void GenerateServiceMethodDocComment(io::Printer* printer, "return_type", EscapePhpdoc(FullClassName(method->output_type(), false))); } -bool Generator::Generate(const FileDescriptor* file, const string& parameter, +bool Generator::Generate(const FileDescriptor* file, + const std::string& parameter, GeneratorContext* generator_context, - string* error) const { - return Generate(file, false, false, std::set(), + std::string* error) const { + return Generate(file, false, false, std::set(), generator_context, error); } bool Generator::Generate( - const FileDescriptor* file, - bool is_descriptor, - bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, - GeneratorContext* generator_context, - string* error) const { + const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, + const std::set& aggregate_metadata_prefixes, + GeneratorContext* generator_context, std::string* error) const { if (is_descriptor && file->name() != kDescriptorFile) { *error = "Can only generate PHP code for google/protobuf/descriptor.proto.\n"; @@ -1840,12 +1842,12 @@ bool Generator::GenerateAll(const std::vector& files, std::string* error) const { bool is_descriptor = false; bool aggregate_metadata = false; - std::set aggregate_metadata_prefixes; + std::set aggregate_metadata_prefixes; for (const auto& option : Split(parameter, ",", true)) { const std::vector option_pair = Split(option, "=", true); if (HasPrefixString(option_pair[0], "aggregate_metadata")) { - string options_string = option_pair[1]; + std::string options_string = option_pair[1]; const std::vector options = Split(options_string, "#", false); aggregate_metadata = true; diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index f67bb4041760..a3ca6092f996 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -47,9 +47,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { public: virtual bool Generate( const FileDescriptor* file, - const string& parameter, + const std::string& parameter, GeneratorContext* generator_context, - string* error) const override; + std::string* error) const override; bool GenerateAll(const std::vector& files, const std::string& parameter, @@ -65,9 +65,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata, - const std::set& aggregate_metadata_prefixes, + const std::set& aggregate_metadata_prefixes, GeneratorContext* generator_context, - string* error) const; + std::string* error) const; }; // To skip reserved keywords in php, some generated classname are prefixed. diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index d93a68d9afd1..27439a737bba 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -46,7 +46,7 @@ namespace compiler { namespace ruby { namespace { -string FindRubyTestDir() { +std::string FindRubyTestDir() { return TestSourceDir() + "/google/protobuf/compiler/ruby"; } @@ -58,7 +58,7 @@ string FindRubyTestDir() { // extensions to the point where we can do this test in a more automated way. void RubyTest(string proto_file) { - string ruby_tests = FindRubyTestDir(); + std::string ruby_tests = FindRubyTestDir(); google::protobuf::compiler::CommandLineInterface cli; cli.SetInputsAreProtoPathRelative(true); @@ -67,7 +67,7 @@ void RubyTest(string proto_file) { cli.RegisterGenerator("--ruby_out", &ruby_generator, ""); // Copy generated_code.proto to the temporary test directory. - string test_input; + std::string test_input; GOOGLE_CHECK_OK(File::GetContents( ruby_tests + proto_file + ".proto", &test_input, @@ -78,9 +78,9 @@ void RubyTest(string proto_file) { true)); // Invoke the proto compiler (we will be inside TestTempDir() at this point). - string ruby_out = "--ruby_out=" + TestTempDir(); - string proto_path = "--proto_path=" + TestTempDir(); - string proto_target = TestTempDir() + proto_file + ".proto"; + std::string ruby_out = "--ruby_out=" + TestTempDir(); + std::string proto_path = "--proto_path=" + TestTempDir(); + std::string proto_target = TestTempDir() + proto_file + ".proto"; const char* argv[] = { "protoc", ruby_out.c_str(), @@ -91,12 +91,12 @@ void RubyTest(string proto_file) { EXPECT_EQ(0, cli.Run(4, argv)); // Load the generated output and compare to the expected result. - string output; + std::string output; GOOGLE_CHECK_OK(File::GetContentsAsText( TestTempDir() + proto_file + "_pb.rb", &output, true)); - string expected_output; + std::string expected_output; GOOGLE_CHECK_OK(File::GetContentsAsText( ruby_tests + proto_file + "_pb.rb", &expected_output, diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 179df8f5dd7c..8998e1bd7832 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -3438,7 +3438,6 @@ class DescriptorBuilder { void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields); - // A helper function that adds an error at the specified location of the // option we're currently interpreting, and returns false. bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, @@ -6381,7 +6380,6 @@ DescriptorBuilder::OptionInterpreter::OptionInterpreter( DescriptorBuilder::OptionInterpreter::~OptionInterpreter() {} - bool DescriptorBuilder::OptionInterpreter::InterpretOptions( OptionsToInterpret* options_to_interpret) { // Note that these may be in different pools, so we can't use the same @@ -6462,7 +6460,6 @@ bool DescriptorBuilder::OptionInterpreter::InterpretOptions( } } - return !failed; } From 90021b813f3024537d1becb6927cd956ec87ed71 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 23 Oct 2020 11:11:46 -0700 Subject: [PATCH 08/15] Updated changelog. --- CHANGES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index a4d2ac0622d9..3fa4e07aa6ef 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -38,6 +38,8 @@ Unreleased Changes * Support "\u" escapes in textformat string literals. * Trailing empty spaces are no longer ignored for FieldMask. * Fix FieldMaskUtil.subtract to recursively remove mask. + * Mark enums with `@java.lang.Deprecated` if the proto enum has option + `deprecated = true;`. Python * Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is From 981be5be209d00674cd7359b2015050d67091264 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 23 Oct 2020 11:59:56 -0700 Subject: [PATCH 09/15] Python/C++ text_format conformance test fix. Pass the Python/C++ text_format failure list to the conformance runner. --- conformance/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 6815c733a522..5aecf96cdc2d 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -362,7 +362,7 @@ test_python: protoc_middleman conformance-test-runner ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py test_python_cpp: protoc_middleman conformance-test-runner - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js From 4cd56bdef81527df885d7fd408f40cdc71149c36 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 23 Oct 2020 12:03:10 -0700 Subject: [PATCH 10/15] Sync from Piper @338718276 PROTOBUF_SYNC_PIPER --- src/google/protobuf/arena_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index 31f31384be3d..137726862160 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -426,7 +426,7 @@ class PROTOBUF_EXPORT ArenaImpl { // Number of per-thread lifecycle IDs to reserve. Must be power of two. // To reduce contention on a global atomic, each thread reserves a batch of - // IDs. The following number is caluculated based on a stress test with + // IDs. The following number is calculated based on a stress test with // ~6500 threads all frequently allocating a new arena. static constexpr size_t kPerThreadIds = 256; // Next lifecycle ID available to this thread. We need to reserve a new From 56ae807dbd10d6bfaec61e8a004149f0ad3c6190 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 23 Oct 2020 14:23:43 -0700 Subject: [PATCH 11/15] Sync from Piper @338744130 PROTOBUF_SYNC_PIPER --- src/google/protobuf/map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 390455e8d893..17090f0063b1 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -455,7 +455,7 @@ class Map { num_elements_(0), num_buckets_(internal::kGlobalEmptyTableSize), seed_(0), - index_of_first_non_null_(num_buckets_), + index_of_first_non_null_(internal::kGlobalEmptyTableSize), table_(const_cast(internal::kGlobalEmptyTable)), alloc_(arena) {} From 036865fa7f5a5026d6b44fdc877741b5888abab7 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 28 Oct 2020 09:49:55 -0700 Subject: [PATCH 12/15] Add C++ text format failure list, and a Python 2.7 text format failure list. --- conformance/Makefile.am | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 5aecf96cdc2d..11e261f33902 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -333,7 +333,7 @@ conformance-php-c: # Targets for actually running tests. test_cpp: protoc_middleman conformance-test-runner conformance-cpp - ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt ./conformance-cpp + ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt --text_format_failure_list text_format_failure_list_cpp.txt ./conformance-cpp test_java: protoc_middleman conformance-test-runner conformance-java ./conformance-test-runner --enforce_recommended --failure_list failure_list_java.txt --text_format_failure_list text_format_failure_list_java.txt ./conformance-java @@ -359,7 +359,14 @@ test_php_c_32: protoc_middleman conformance-test-runner conformance-php-c $(othe # These depend on library paths being properly set up. The easiest way to # run them is to just use "tox" from the python dir. test_python: protoc_middleman conformance-test-runner - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py + VERSION="$(shell python --version 2>&1)"; \ + if [[ "$$VERSION" == "Python 2.7"* ]]; then \ + echo "Using Python 2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python_2.7.txt ./conformance_python.py; \ + else \ + echo "Using Python >2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py; \ + fi test_python_cpp: protoc_middleman conformance-test-runner ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py From ee68c9b29c7ceaa5ab824c16c33411faae132dc8 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 28 Oct 2020 10:05:07 -0700 Subject: [PATCH 13/15] Added text format failure list for Python 2.7. --- .../text_format_failure_list_python_2.7.txt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 conformance/text_format_failure_list_python_2.7.txt diff --git a/conformance/text_format_failure_list_python_2.7.txt b/conformance/text_format_failure_list_python_2.7.txt new file mode 100644 index 000000000000..cada2bc03b2e --- /dev/null +++ b/conformance/text_format_failure_list_python_2.7.txt @@ -0,0 +1,36 @@ +# This is the list of text format conformance tests that are known to fail right +# now. +# TODO: These should be fixed. +Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput +Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput + +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString From 69b245e63a826fd402667ca7c0f98e70b31add99 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 28 Oct 2020 10:35:06 -0700 Subject: [PATCH 14/15] Added Python 2.7-specific failure list for Python/C++ also. --- conformance/Makefile.am | 9 +++++- ...ext_format_failure_list_python_cpp_2.7.txt | 30 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 conformance/text_format_failure_list_python_cpp_2.7.txt diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 11e261f33902..830bda6c0b7f 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -369,7 +369,14 @@ test_python: protoc_middleman conformance-test-runner fi test_python_cpp: protoc_middleman conformance-test-runner - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py + VERSION="$(shell python --version 2>&1)"; \ + if [[ "$$VERSION" == "Python 2.7"* ]]; then \ + echo "Using Python 2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp_2.7.txt ./conformance_python.py \ + else \ + echo "Using Python >2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py; \ + fi test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js diff --git a/conformance/text_format_failure_list_python_cpp_2.7.txt b/conformance/text_format_failure_list_python_cpp_2.7.txt new file mode 100644 index 000000000000..ba2089bcaad3 --- /dev/null +++ b/conformance/text_format_failure_list_python_cpp_2.7.txt @@ -0,0 +1,30 @@ +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString From 709775b67e1994796a86dc356e35b1414d8696d6 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 28 Oct 2020 10:56:51 -0700 Subject: [PATCH 15/15] Added missing semicolon. --- conformance/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 830bda6c0b7f..5b82a4241e69 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -372,7 +372,7 @@ test_python_cpp: protoc_middleman conformance-test-runner VERSION="$(shell python --version 2>&1)"; \ if [[ "$$VERSION" == "Python 2.7"* ]]; then \ echo "Using Python 2.7 failure list."; \ - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp_2.7.txt ./conformance_python.py \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp_2.7.txt ./conformance_python.py; \ else \ echo "Using Python >2.7 failure list."; \ ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py; \