diff --git a/CHANGES.txt b/CHANGES.txt index 52eee948ef..770f859163 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -69,6 +69,7 @@ * Make message-type extensions merge from wire-format instead of building up instances and merging afterwards. This has much better performance. * Fix TextFormat parser to build up recurring (but supposedly not repeated) sub-messages directly from text rather than building a new sub-message and merging the fully formed message into the existing field. * Fix bug in nested builder caching logic where cleared sub-field builders would remain dirty after a clear and build in a parent layer. https://github.com/protocolbuffers/protobuf/issues/10624 + * Performance test for TextFormat to verify fix for https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-h4h5-3hr4-j3g2 Python * Changes ordering of printed fields in .pyi files from lexicographic to the same ordering found in the proto descriptor. diff --git a/conformance/conformance.proto b/conformance/conformance.proto index a213437f89..bee04d160d 100644 --- a/conformance/conformance.proto +++ b/conformance/conformance.proto @@ -58,7 +58,7 @@ enum WireFormat { UNSPECIFIED = 0; PROTOBUF = 1; JSON = 2; - JSPB = 3; // Google internal only. Opensource testees just skip it. + JSPB = 3; // Only used inside Google. Opensource testees just skip it. TEXT_FORMAT = 4; } @@ -72,8 +72,8 @@ enum TestCategory { // https://developers.google.com/protocol-buffers/docs/proto3#json_options // for more detail. JSON_IGNORE_UNKNOWN_PARSING_TEST = 3; - // Test jspb wire format. Google internal only. Opensource testees just skip - // it. + // Test jspb wire format. Only used inside Google. Opensource testees just + // skip it. JSPB_TEST = 4; // Test text format. For cpp, java and python, testees can already deal with // this type. Testees of other languages can simply skip it. @@ -99,7 +99,7 @@ message ConformanceRequest { oneof payload { bytes protobuf_payload = 1; string json_payload = 2; - // Google internal only. Opensource testees just skip it. + // Only used inside Google. Opensource testees just skip it. string jspb_payload = 7; string text_payload = 8; } @@ -163,8 +163,8 @@ message ConformanceResponse { string skipped = 5; // If the input was successfully parsed and the requested output was JSPB, - // serialize to JSPB and set it in this field. JSPB is google internal only - // format. Opensource testees can just skip it. + // serialize to JSPB and set it in this field. JSPB is only used inside + // Google. Opensource testees can just skip it. string jspb_payload = 7; // If the input was successfully parsed and the requested output was diff --git a/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs b/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs index f3651df397..82f59b1abb 100644 --- a/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs +++ b/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs @@ -67,7 +67,10 @@ namespace Google.Protobuf // We build the code with GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE to avoid the use of ref struct in the generated code. var compatibilityFlag = "-define:GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE"; var sources = "*.cs"; // the generated sources from the TestProtos project - var args = $"-langversion:3 -target:library {compatibilityFlag} -reference:{testProtosOutputDir}\\Google.Protobuf.dll -out:{testProtosOutputDir}\\TestProtos.RefStructCompatibilityTest.OldCompiler.dll {sources}"; + // We suppress CS1691, which flags a warning for the generated line of + // #pragma warning disable 1591, 0612, 3021, 8981 + // because CS8981 is unknown to this version of the compiler. + var args = $"-langversion:3 -nologo -nowarn:1691 -target:library {compatibilityFlag} -reference:{testProtosOutputDir}\\Google.Protobuf.dll -out:{testProtosOutputDir}\\TestProtos.RefStructCompatibilityTest.OldCompiler.dll {sources}"; RunOldCsharpCompilerAndCheckSuccess(args, testProtosProjectDir); } diff --git a/generate_changelog.py b/generate_changelog.py index fe7e95bc42..7117ef8ff2 100755 --- a/generate_changelog.py +++ b/generate_changelog.py @@ -1,4 +1,33 @@ #!/usr/bin/env python +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Generates a friendly list of changes per language since the last release.""" diff --git a/java/core/src/main/java/com/google/protobuf/ByteString.java b/java/core/src/main/java/com/google/protobuf/ByteString.java index 1acbad08b4..2569d5dad4 100644 --- a/java/core/src/main/java/com/google/protobuf/ByteString.java +++ b/java/core/src/main/java/com/google/protobuf/ByteString.java @@ -432,7 +432,10 @@ public abstract class ByteString implements Iterable, Serializable { return copyFrom(bytes, 0, bytes.length); } - /** Wraps the given bytes into a {@code ByteString}. Intended for internal only usage. */ + /** + * Wraps the given bytes into a {@code ByteString}. Intended for internal usage within the + * library. + */ static ByteString wrap(ByteBuffer buffer) { if (buffer.hasArray()) { final int offset = buffer.arrayOffset(); @@ -443,8 +446,8 @@ public abstract class ByteString implements Iterable, Serializable { } /** - * Wraps the given bytes into a {@code ByteString}. Intended for internal only usage to force a - * classload of ByteString before LiteralByteString. + * Wraps the given bytes into a {@code ByteString}. Intended for internal usage within the library + * to force a classload of ByteString before LiteralByteString. */ static ByteString wrap(byte[] bytes) { // TODO(dweis): Return EMPTY when bytes are empty to reduce allocations? @@ -452,8 +455,8 @@ public abstract class ByteString implements Iterable, Serializable { } /** - * Wraps the given bytes into a {@code ByteString}. Intended for internal only usage to force a - * classload of ByteString before BoundedByteString and LiteralByteString. + * Wraps the given bytes into a {@code ByteString}. Intended for internal usage within the library + * to force a classload of ByteString before BoundedByteString and LiteralByteString. */ static ByteString wrap(byte[] bytes, int offset, int length) { return new BoundedByteString(bytes, offset, length); diff --git a/python/setup.py b/python/setup.py index 9a95ff8f88..2b6d281426 100755 --- a/python/setup.py +++ b/python/setup.py @@ -1,4 +1,33 @@ #! /usr/bin/env python +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # See README for usage instructions. diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 6b6ca1b498..7cff1e3563 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -34,6 +34,8 @@ #include "google/protobuf/compiler/command_line_interface.h" +#include "absl/container/flat_hash_map.h" + #include "google/protobuf/stubs/platform_macros.h" #include @@ -425,7 +427,7 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { // The files_ field maps from path keys to file content values. It's a map // instead of an unordered_map so that files are written in order (good when // writing zips). - std::map files_; + absl::flat_hash_map files_; const std::vector& parsed_files_; bool had_error_; }; @@ -1493,19 +1495,15 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( // Make sure each plugin option has a matching plugin output. bool foundUnknownPluginOption = false; - for (std::map::const_iterator i = - plugin_parameters_.begin(); - i != plugin_parameters_.end(); ++i) { - if (plugins_.find(i->first) != plugins_.end()) { + for (const auto& kv : plugin_parameters_) { + if (plugins_.find(kv.first) != plugins_.end()) { continue; } bool foundImplicitPlugin = false; - for (std::vector::const_iterator j = - output_directives_.begin(); - j != output_directives_.end(); ++j) { - if (j->generator == nullptr) { - std::string plugin_name = PluginName(plugin_prefix_, j->name); - if (plugin_name == i->first) { + for (const auto& d : output_directives_) { + if (d.generator == nullptr) { + std::string plugin_name = PluginName(plugin_prefix_, d.name); + if (plugin_name == kv.first) { foundImplicitPlugin = true; break; } @@ -1514,7 +1512,7 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( if (!foundImplicitPlugin) { std::cerr << "Unknown flag: " // strip prefix + "gen-" and add back "_opt" - << "--" + i->first.substr(plugin_prefix_.size() + 4) + "_opt" + << "--" + kv.first.substr(plugin_prefix_.size() + 4) + "_opt" << std::endl; foundUnknownPluginOption = true; } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 92454145b7..7e1cd58f5d 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -367,9 +367,9 @@ class PROTOC_EXPORT CommandLineInterface { // flag. For example, if the user invokes the compiler with: // protoc --foo_out=outputdir --foo_opt=enable_bar ... // Then there will be an entry ("--foo_out", "enable_bar") in this map. - std::map generator_parameters_; + absl::flat_hash_map generator_parameters_; // Similar to generator_parameters_, but stores the parameters for plugins. - std::map plugin_parameters_; + absl::flat_hash_map plugin_parameters_; // See AllowPlugins(). If this is empty, plugins aren't allowed. std::string plugin_prefix_; @@ -377,7 +377,7 @@ class PROTOC_EXPORT CommandLineInterface { // Maps specific plugin names to files. When executing a plugin, this map // is searched first to find the plugin executable. If not found here, the // PATH (or other OS-specific search strategy) is searched. - std::map plugins_; + absl::flat_hash_map plugins_; // Stuff parsed from command line. enum Mode { diff --git a/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc index 3ea5d733dc..8d2b60e9ad 100644 --- a/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc @@ -63,7 +63,7 @@ namespace compiler { namespace cpp { namespace { std::string FindWithDefault( - const absl::flat_hash_map& m, + const absl::flat_hash_map& m, const std::string& k, const std::string& v) { auto it = m.find(k); if (it == m.end()) return v; @@ -138,8 +138,8 @@ const char* test_protos[][2] = { TEST(BootstrapTest, GeneratedFilesMatch) { // We need a mapping from the actual file to virtual and actual path // of the data to compare to. - absl::flat_hash_map vpath_map; - absl::flat_hash_map rpath_map; + absl::flat_hash_map vpath_map; + absl::flat_hash_map rpath_map; rpath_map["third_party/protobuf/test_messages_proto2"] = "net/proto2/z_generated_example/test_messages_proto2"; rpath_map["third_party/protobuf/test_messages_proto3"] = diff --git a/src/google/protobuf/compiler/cpp/enum.cc b/src/google/protobuf/compiler/cpp/enum.cc index c000b48212..7d03aa56e4 100644 --- a/src/google/protobuf/compiler/cpp/enum.cc +++ b/src/google/protobuf/compiler/cpp/enum.cc @@ -54,7 +54,7 @@ namespace protobuf { namespace compiler { namespace cpp { namespace { -absl::flat_hash_map EnumVars( +absl::flat_hash_map EnumVars( const EnumDescriptor* enum_, const Options& options, const EnumValueDescriptor* min, const EnumValueDescriptor* max) { auto classname = ClassName(enum_, false); diff --git a/src/google/protobuf/compiler/cpp/enum.h b/src/google/protobuf/compiler/cpp/enum.h index 158a548976..49a262d40d 100644 --- a/src/google/protobuf/compiler/cpp/enum.h +++ b/src/google/protobuf/compiler/cpp/enum.h @@ -35,7 +35,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ -#include #include #include diff --git a/src/google/protobuf/compiler/cpp/enum_field.cc b/src/google/protobuf/compiler/cpp/enum_field.cc index 0ac1451c7d..10768f9041 100644 --- a/src/google/protobuf/compiler/cpp/enum_field.cc +++ b/src/google/protobuf/compiler/cpp/enum_field.cc @@ -34,8 +34,10 @@ #include "google/protobuf/compiler/cpp/enum_field.h" -#include "google/protobuf/io/printer.h" +#include + #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/cpp/field.h" #include "google/protobuf/compiler/cpp/helpers.h" @@ -46,9 +48,10 @@ namespace cpp { namespace { -void SetEnumVariables(const FieldDescriptor* descriptor, - std::map* variables, - const Options& options) { +void SetEnumVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables, + const Options& options) { SetCommonFieldVariables(descriptor, variables, options); const EnumValueDescriptor* default_value = descriptor->default_value_enum(); (*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options); diff --git a/src/google/protobuf/compiler/cpp/extension.cc b/src/google/protobuf/compiler/cpp/extension.cc index 9b6ddc8938..ada93f7697 100644 --- a/src/google/protobuf/compiler/cpp/extension.cc +++ b/src/google/protobuf/compiler/cpp/extension.cc @@ -34,8 +34,6 @@ #include "google/protobuf/compiler/cpp/extension.h" -#include - #include "google/protobuf/io/printer.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" diff --git a/src/google/protobuf/compiler/cpp/extension.h b/src/google/protobuf/compiler/cpp/extension.h index 1c0e020b99..4d7d081194 100644 --- a/src/google/protobuf/compiler/cpp/extension.h +++ b/src/google/protobuf/compiler/cpp/extension.h @@ -38,6 +38,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/port.h" @@ -84,7 +85,7 @@ class ExtensionGenerator { Options options_; MessageSCCAnalyzer* scc_analyzer_; - std::map variables_; + absl::flat_hash_map variables_; }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc index 1ec6bf7421..50f86e1e7f 100644 --- a/src/google/protobuf/compiler/cpp/field.cc +++ b/src/google/protobuf/compiler/cpp/field.cc @@ -38,6 +38,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" @@ -46,7 +47,6 @@ #include "google/protobuf/compiler/cpp/string_field.h" #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" -#include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" #include "google/protobuf/compiler/cpp/enum_field.h" #include "google/protobuf/compiler/cpp/map_field.h" @@ -62,12 +62,12 @@ using internal::WireFormat; namespace { -void MaySetAnnotationVariable(const Options& options, - absl::string_view annotation_name, - absl::string_view substitute_template_prefix, - absl::string_view prepared_template, - int field_index, absl::string_view access_type, - std::map* variables) { +void MaySetAnnotationVariable( + const Options& options, absl::string_view annotation_name, + absl::string_view substitute_template_prefix, + absl::string_view prepared_template, int field_index, + absl::string_view access_type, + absl::flat_hash_map* variables) { if (options.field_listener_options.forbidden_field_listener_events.count( std::string(annotation_name))) return; @@ -124,9 +124,9 @@ std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor, } // namespace -void AddAccessorAnnotations(const FieldDescriptor* descriptor, - const Options& options, - std::map* variables) { +void AddAccessorAnnotations( + const FieldDescriptor* descriptor, const Options& options, + absl::flat_hash_map* variables) { // Can be expanded to include more specific calls, for example, for arena or // clear calls. static constexpr const char* kAccessorsAnnotations[] = { @@ -232,10 +232,10 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, "OnAddMutable", variables); } -absl::flat_hash_map FieldVars( +absl::flat_hash_map FieldVars( const FieldDescriptor* desc, const Options& opts) { bool split = ShouldSplit(desc, opts); - absl::flat_hash_map vars = { + absl::flat_hash_map vars = { {"ns", Namespace(desc, opts)}, {"name", FieldName(desc)}, {"index", absl::StrCat(desc->index())}, @@ -261,7 +261,7 @@ absl::flat_hash_map FieldVars( // TODO(b/245791219): Refactor AddAccessorAnnotations to avoid this // workaround. - std::map workaround = { + absl::flat_hash_map workaround = { {"field", vars["field"]}, {"tracker", "Impl_::_tracker_"}, }; @@ -273,9 +273,10 @@ absl::flat_hash_map FieldVars( return vars; } -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map* variables, - const Options& options) { +void SetCommonFieldVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables, + const Options& options) { SetCommonMessageDataVariables(descriptor->containing_type(), variables); for (auto& pair : FieldVars(descriptor, options)) { @@ -283,7 +284,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } } -absl::flat_hash_map OneofFieldVars( +absl::flat_hash_map OneofFieldVars( const FieldDescriptor* descriptor) { if (descriptor->containing_oneof() == nullptr) { return {}; @@ -294,7 +295,7 @@ absl::flat_hash_map OneofFieldVars( void SetCommonOneofFieldVariables( const FieldDescriptor* descriptor, - std::map* variables) { + absl::flat_hash_map* variables) { for (auto& pair : OneofFieldVars(descriptor)) { variables->emplace(pair); } diff --git a/src/google/protobuf/compiler/cpp/field.h b/src/google/protobuf/compiler/cpp/field.h index db0d64d30e..a10d552cd9 100644 --- a/src/google/protobuf/compiler/cpp/field.h +++ b/src/google/protobuf/compiler/cpp/field.h @@ -36,11 +36,11 @@ #define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ #include -#include #include #include #include "google/protobuf/descriptor.h" +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/options.h" @@ -57,23 +57,24 @@ namespace protobuf { namespace compiler { namespace cpp { -absl::flat_hash_map FieldVars( +absl::flat_hash_map FieldVars( const FieldDescriptor* desc, const Options& opts); -absl::flat_hash_map OneofFieldVars( +absl::flat_hash_map OneofFieldVars( const FieldDescriptor* descriptor); // Helper function: set variables in the map that are the same for all // field code generators. // ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size', // 'deprecation']. -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map* variables, - const Options& options); +void SetCommonFieldVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables, + const Options& options); void SetCommonOneofFieldVariables( const FieldDescriptor* descriptor, - std::map* variables); + absl::flat_hash_map* variables); class FieldGenerator { public: @@ -226,7 +227,7 @@ class FieldGenerator { protected: const FieldDescriptor* descriptor_; const Options& options_; - std::map variables_; + absl::flat_hash_map variables_; }; // Convenience class which constructs FieldGenerators for a Descriptor. diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index d3dac8b113..759b43d12a 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -35,7 +35,6 @@ #include "google/protobuf/compiler/cpp/file.h" #include -#include #include #include #include @@ -71,7 +70,7 @@ namespace protobuf { namespace compiler { namespace cpp { namespace { -absl::flat_hash_map FileVars( +absl::flat_hash_map FileVars( const FileDescriptor* file, const Options& options) { return { {"filename", file->name()}, diff --git a/src/google/protobuf/compiler/cpp/file.h b/src/google/protobuf/compiler/cpp/file.h index cd38345043..3cb297e4a6 100644 --- a/src/google/protobuf/compiler/cpp/file.h +++ b/src/google/protobuf/compiler/cpp/file.h @@ -44,6 +44,7 @@ #include "google/protobuf/stubs/common.h" #include "google/protobuf/compiler/scc.h" +#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "google/protobuf/compiler/cpp/enum.h" #include "google/protobuf/compiler/cpp/extension.h" @@ -195,7 +196,7 @@ class FileGenerator { // This member is unused and should be deleted once all old-style variable // maps are gone. // TODO(b/245791219) - std::map variables_; + absl::flat_hash_map variables_; // Contains the post-order walk of all the messages (and child messages) in // this file. If you need a pre-order walk just reverse iterate. diff --git a/src/google/protobuf/compiler/cpp/generator.cc b/src/google/protobuf/compiler/cpp/generator.cc index 737441ca5a..278354ca06 100644 --- a/src/google/protobuf/compiler/cpp/generator.cc +++ b/src/google/protobuf/compiler/cpp/generator.cc @@ -55,7 +55,7 @@ std::string NumberedCcFileName(absl::string_view basename, int number) { return absl::StrCat(basename, ".out/", number, ".cc"); } -absl::flat_hash_map CommonVars( +absl::flat_hash_map CommonVars( const Options& options) { bool is_oss = options.opensource_runtime; return { diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index 383629f4f1..d32d4c1a6c 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -232,7 +231,7 @@ bool IsLazilyVerifiedLazy(const FieldDescriptor* field, return false; } -absl::flat_hash_map MessageVars( +absl::flat_hash_map MessageVars( const Descriptor* desc) { absl::string_view prefix = IsMapEntryMessage(desc) ? "" : "_impl_."; return { @@ -252,13 +251,13 @@ absl::flat_hash_map MessageVars( void SetCommonMessageDataVariables( const Descriptor* descriptor, - std::map* variables) { + absl::flat_hash_map* variables) { for (auto& pair : MessageVars(descriptor)) { variables->emplace(pair); } } -absl::flat_hash_map UnknownFieldsVars( +absl::flat_hash_map UnknownFieldsVars( const Descriptor* desc, const Options& opts) { std::string proto_ns = ProtobufNamespace(opts); @@ -286,9 +285,9 @@ absl::flat_hash_map UnknownFieldsVars( }; } -void SetUnknownFieldsVariable(const Descriptor* descriptor, - const Options& options, - std::map* variables) { +void SetUnknownFieldsVariable( + const Descriptor* descriptor, const Options& options, + absl::flat_hash_map* variables) { for (auto& pair : UnknownFieldsVars(descriptor, options)) { variables->emplace(pair); } @@ -1362,7 +1361,7 @@ bool GetBootstrapBasename(const Options& options, const std::string& basename, static const auto* bootstrap_mapping = // TODO(b/242858704) Replace these with string_view once we remove // StringPiece. - new absl::flat_hash_map{ + new absl::flat_hash_map{ {"net/proto2/proto/descriptor", "third_party/protobuf/descriptor"}, {"net/proto2/compiler/proto/plugin", diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index 4967452ca8..fbce6003ce 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -88,20 +88,20 @@ inline std::string DeprecatedAttribute(const Options& /* options */, extern const char kThickSeparator[]; extern const char kThinSeparator[]; -absl::flat_hash_map MessageVars( +absl::flat_hash_map MessageVars( const Descriptor* desc); // Variables to access message data from the message scope. void SetCommonMessageDataVariables( const Descriptor* descriptor, - std::map* variables); + absl::flat_hash_map* variables); -absl::flat_hash_map UnknownFieldsVars( +absl::flat_hash_map UnknownFieldsVars( const Descriptor* desc, const Options& opts); -void SetUnknownFieldsVariable(const Descriptor* descriptor, - const Options& options, - std::map* variables); +void SetUnknownFieldsVariable( + const Descriptor* descriptor, const Options& options, + absl::flat_hash_map* variables); bool GetBootstrapBasename(const Options& options, const std::string& basename, std::string* bootstrap_basename); @@ -794,15 +794,15 @@ class PROTOC_EXPORT Formatter { public: explicit Formatter(io::Printer* printer) : printer_(printer) {} Formatter(io::Printer* printer, - const std::map& vars) + const absl::flat_hash_map& vars) : printer_(printer), vars_(vars) {} template - void Set(const std::string& key, const T& value) { + void Set(absl::string_view key, const T& value) { vars_[key] = ToString(value); } - void AddMap(const std::map& vars) { + void AddMap(const absl::flat_hash_map& vars) { for (const auto& keyval : vars) vars_[keyval.first] = keyval.second; } @@ -844,12 +844,12 @@ class PROTOC_EXPORT Formatter { private: Formatter* format_; - std::map vars_; + absl::flat_hash_map vars_; }; private: io::Printer* printer_; - std::map vars_; + absl::flat_hash_map vars_; // Convenience overloads to accept different types as arguments. static std::string ToString(const std::string& s) { return s; } diff --git a/src/google/protobuf/compiler/cpp/map_field.cc b/src/google/protobuf/compiler/cpp/map_field.cc index e320a435b8..529a54f060 100644 --- a/src/google/protobuf/compiler/cpp/map_field.cc +++ b/src/google/protobuf/compiler/cpp/map_field.cc @@ -30,18 +30,22 @@ #include "google/protobuf/compiler/cpp/map_field.h" +#include + #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/ascii.h" -#include "google/protobuf/compiler/cpp/helpers.h" #include "absl/strings/str_cat.h" +#include "google/protobuf/compiler/cpp/helpers.h" namespace google { namespace protobuf { namespace compiler { namespace cpp { -void SetMessageVariables(const FieldDescriptor* descriptor, - std::map* variables, - const Options& options) { +void SetMessageVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables, + const Options& options) { SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = ClassName(descriptor->message_type(), false); (*variables)["full_name"] = descriptor->full_name(); diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 51f94d10be..bf54fb4289 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -36,10 +36,10 @@ #include #include +#include #include #include #include -#include #include #include #include @@ -52,6 +52,7 @@ #include "google/protobuf/wire_format.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/ascii.h" +#include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" @@ -277,10 +278,11 @@ bool HasHasMethod(const FieldDescriptor* field) { } // Collects map entry message type information. -void CollectMapInfo(const Options& options, const Descriptor* descriptor, - std::map* variables) { +void CollectMapInfo( + const Options& options, const Descriptor* descriptor, + absl::flat_hash_map* variables) { GOOGLE_CHECK(IsMapEntryMessage(descriptor)); - std::map& vars = *variables; + absl::flat_hash_map& vars = *variables; const FieldDescriptor* key = descriptor->map_key(); const FieldDescriptor* val = descriptor->map_value(); vars["key_cpp"] = PrimitiveTypeName(options, key->cpp_type()); @@ -429,7 +431,7 @@ class ColdChunkSkipper { const std::vector& has_bit_indices_; const AccessInfoMap* access_info_map_; const double cold_threshold_; - std::map variables_; + absl::flat_hash_map variables_; int limit_chunk_ = -1; }; @@ -509,7 +511,7 @@ bool ColdChunkSkipper::OnEndChunk(int chunk, io::Printer* p) { } void AnnotationVar(const Descriptor* desc, const Options& options, - absl::flat_hash_map& vars, + absl::flat_hash_map& vars, absl::string_view name, absl::string_view val) { if (!HasTracker(desc, options) || options.field_listener_options.forbidden_field_listener_events.count( @@ -520,9 +522,9 @@ void AnnotationVar(const Descriptor* desc, const Options& options, vars.emplace(name, absl::StrCat(absl::StripAsciiWhitespace(val), "\n")); } -absl::flat_hash_map ClassVars(const Descriptor* desc, - Options opts) { - absl::flat_hash_map vars = MessageVars(desc); +absl::flat_hash_map ClassVars( + const Descriptor* desc, Options opts) { + absl::flat_hash_map vars = MessageVars(desc); vars.emplace("classname", ClassName(desc, false)); vars.emplace("classtype", QualifiedClassName(desc, opts)); vars.emplace("full_name", desc->full_name()); @@ -640,11 +642,11 @@ absl::flat_hash_map ClassVars(const Descriptor* desc, // =================================================================== -MessageGenerator::MessageGenerator(const Descriptor* descriptor, - const std::map&, - int index_in_file_messages, - const Options& options, - MessageSCCAnalyzer* scc_analyzer) +MessageGenerator::MessageGenerator( + const Descriptor* descriptor, + const absl::flat_hash_map&, + int index_in_file_messages, const Options& options, + MessageSCCAnalyzer* scc_analyzer) : descriptor_(descriptor), index_in_file_messages_(index_in_file_messages), options_(options), @@ -779,7 +781,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* p) { for (auto field : ordered_fields) { Formatter::SaveState save(&format); - std::map vars; + absl::flat_hash_map vars; SetCommonFieldVariables(field, &vars, options_); auto v = p->WithVars(std::move(vars)); format(" ${1$$2$$}$ = $number$,\n", field, FieldConstantName(field)); @@ -1290,7 +1292,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { Formatter format(p); if (IsMapEntryMessage(descriptor_)) { - std::map vars; + absl::flat_hash_map vars; CollectMapInfo(options_, descriptor_, &vars); vars["lite"] = HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite"; @@ -3749,7 +3751,7 @@ void MessageGenerator::GenerateSerializeOneField(io::Printer* p, void MessageGenerator::GenerateSerializeOneExtensionRange( io::Printer* p, const Descriptor::ExtensionRange* range) { - std::map vars = variables_; + absl::flat_hash_map vars = variables_; vars["start"] = absl::StrCat(range->start); vars["end"] = absl::StrCat(range->end); Formatter format(p, vars); diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 019660692a..5de18734d0 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -60,10 +60,11 @@ namespace compiler { namespace cpp { class MessageGenerator { public: - MessageGenerator(const Descriptor* descriptor, - const std::map& ignored, - int index_in_file_messages, const Options& options, - MessageSCCAnalyzer* scc_analyzer); + MessageGenerator( + const Descriptor* descriptor, + const absl::flat_hash_map& ignored, + int index_in_file_messages, const Options& options, + MessageSCCAnalyzer* scc_analyzer); MessageGenerator(const MessageGenerator&) = delete; MessageGenerator& operator=(const MessageGenerator&) = delete; @@ -214,7 +215,7 @@ class MessageGenerator { MessageSCCAnalyzer* scc_analyzer_; - std::map variables_; + absl::flat_hash_map variables_; }; diff --git a/src/google/protobuf/compiler/cpp/message_field.cc b/src/google/protobuf/compiler/cpp/message_field.cc index e8d2a74dae..aad0f7e32f 100644 --- a/src/google/protobuf/compiler/cpp/message_field.cc +++ b/src/google/protobuf/compiler/cpp/message_field.cc @@ -35,9 +35,10 @@ #include "google/protobuf/compiler/cpp/message_field.h" #include "google/protobuf/io/printer.h" +#include "absl/container/flat_hash_map.h" +#include "absl/strings/str_cat.h" #include "google/protobuf/compiler/cpp/field.h" #include "google/protobuf/compiler/cpp/helpers.h" -#include "absl/strings/str_cat.h" namespace google { namespace protobuf { @@ -55,28 +56,34 @@ std::string ReinterpretCast(const std::string& type, } } -void SetMessageVariables(const FieldDescriptor* descriptor, - const Options& options, bool implicit_weak, - std::map* variables) { +void SetMessageVariables( + const FieldDescriptor* descriptor, const Options& options, + bool implicit_weak, + absl::flat_hash_map* variables) { SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = FieldMessageTypeName(descriptor, options); - (*variables)["casted_member"] = ReinterpretCast( - (*variables)["type"] + "*", (*variables)["field"], implicit_weak); - (*variables)["casted_member_const"] = - ReinterpretCast("const " + (*variables)["type"] + "&", - "*" + (*variables)["field"], implicit_weak); + variables->insert( + {"casted_member", ReinterpretCast(absl::StrCat((*variables)["type"], "*"), + (*variables)["field"], implicit_weak)}); + variables->insert( + {"casted_member_const", + ReinterpretCast(absl::StrCat("const ", (*variables)["type"], "&"), + absl::StrCat("*", (*variables)["field"]), + implicit_weak)}); (*variables)["type_default_instance"] = QualifiedDefaultInstanceName(descriptor->message_type(), options); (*variables)["type_default_instance_ptr"] = ReinterpretCast( "const ::PROTOBUF_NAMESPACE_ID::MessageLite*", QualifiedDefaultInstancePtr(descriptor->message_type(), options), implicit_weak); - (*variables)["type_reference_function"] = - implicit_weak ? (" ::" + ProtobufNamespace(options) + - "::internal::StrongReference(reinterpret_cast(\n" + - (*variables)["type_default_instance"] + "));\n") - : ""; + variables->insert( + {"type_reference_function", + implicit_weak + ? absl::StrCat(" ::", ProtobufNamespace(options), + "::internal::StrongReference(reinterpret_cast(\n", + (*variables)["type_default_instance"], "));\n") + : ""}); // NOTE: Escaped here to unblock proto1->proto2 migration. // TODO(liujisi): Extend this to apply for other conflicting methods. (*variables)["release_name"] = diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index 74a9a9899d..04db1a6ee5 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -32,12 +32,12 @@ #include #include -#include #include #include #include #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/generated_message_tctable_gen.h" @@ -109,7 +109,7 @@ ParseFunctionGenerator::ParseFunctionGenerator( const std::vector& has_bit_indices, const std::vector& inlined_string_indices, const Options& options, MessageSCCAnalyzer* scc_analyzer, - const std::map& vars) + const absl::flat_hash_map& vars) : descriptor_(descriptor), scc_analyzer_(scc_analyzer), options_(options), diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.h b/src/google/protobuf/compiler/cpp/parse_function_generator.h index b55feda112..f3198b5f0f 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.h +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.h @@ -38,6 +38,7 @@ #include "google/protobuf/io/printer.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/wire_format_lite.h" +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/generated_message_tctable_gen.h" @@ -51,12 +52,12 @@ namespace cpp { // (and any associated supporting members). class ParseFunctionGenerator { public: - ParseFunctionGenerator(const Descriptor* descriptor, int max_has_bit_index, - const std::vector& has_bit_indices, - const std::vector& inlined_string_indices, - const Options& options, - MessageSCCAnalyzer* scc_analyzer, - const std::map& vars); + ParseFunctionGenerator( + const Descriptor* descriptor, int max_has_bit_index, + const std::vector& has_bit_indices, + const std::vector& inlined_string_indices, const Options& options, + MessageSCCAnalyzer* scc_analyzer, + const absl::flat_hash_map& vars); // Emits class-level method declarations to `printer`: void GenerateMethodDecls(io::Printer* printer); @@ -126,7 +127,7 @@ class ParseFunctionGenerator { const Descriptor* descriptor_; MessageSCCAnalyzer* scc_analyzer_; const Options& options_; - std::map variables_; + absl::flat_hash_map variables_; std::unique_ptr tc_table_info_; std::vector inlined_string_indices_; const std::vector ordered_fields_; diff --git a/src/google/protobuf/compiler/cpp/primitive_field.cc b/src/google/protobuf/compiler/cpp/primitive_field.cc index b2144c3111..5b0f97164b 100644 --- a/src/google/protobuf/compiler/cpp/primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/primitive_field.cc @@ -34,8 +34,11 @@ #include "google/protobuf/compiler/cpp/primitive_field.h" +#include + #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/cpp/helpers.h" @@ -98,9 +101,10 @@ int FixedSize(FieldDescriptor::Type type) { return -1; } -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - std::map* variables, - const Options& options) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables, + const Options& options) { SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type()); (*variables)["default"] = DefaultValue(options, descriptor); diff --git a/src/google/protobuf/compiler/cpp/service.cc b/src/google/protobuf/compiler/cpp/service.cc index baa58b97ce..518628ac9c 100644 --- a/src/google/protobuf/compiler/cpp/service.cc +++ b/src/google/protobuf/compiler/cpp/service.cc @@ -34,7 +34,6 @@ #include "google/protobuf/compiler/cpp/service.h" -#include #include #include "absl/strings/str_cat.h" @@ -85,7 +84,7 @@ void ServiceGenerator::GenerateDeclarations(io::Printer* printer) { const ::$proto_ns$::MethodDescriptor* method) const override; }; - class $dllexport_decl $$classname$_Stub : public $classname$ { + class $dllexport_decl $$classname$_Stub final : public $classname$ { public: $classname$_Stub(::$proto_ns$::RpcChannel* channel); $classname$_Stub(::$proto_ns$::RpcChannel* channel, diff --git a/src/google/protobuf/compiler/cpp/service.h b/src/google/protobuf/compiler/cpp/service.h index 34b891423b..b38591b62b 100644 --- a/src/google/protobuf/compiler/cpp/service.h +++ b/src/google/protobuf/compiler/cpp/service.h @@ -39,6 +39,7 @@ #include #include "google/protobuf/descriptor.h" +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/io/printer.h" @@ -49,9 +50,10 @@ namespace cpp { class ServiceGenerator { public: // See generator.cc for the meaning of dllexport_decl. - ServiceGenerator(const ServiceDescriptor* descriptor, - const std::map& vars, - const Options& options) + ServiceGenerator( + const ServiceDescriptor* descriptor, + const absl::flat_hash_map& vars, + const Options& options) : descriptor_(descriptor), options_(&options), vars_(vars) { vars_["classname"] = descriptor_->name(); vars_["full_name"] = descriptor_->full_name(); @@ -98,7 +100,7 @@ class ServiceGenerator { const ServiceDescriptor* descriptor_; const Options* options_; - std::map vars_; + absl::flat_hash_map vars_; int index_in_metadata_; diff --git a/src/google/protobuf/compiler/cpp/string_field.cc b/src/google/protobuf/compiler/cpp/string_field.cc index b1aadfb56e..92d340fec1 100644 --- a/src/google/protobuf/compiler/cpp/string_field.cc +++ b/src/google/protobuf/compiler/cpp/string_field.cc @@ -34,6 +34,9 @@ #include "google/protobuf/compiler/cpp/string_field.h" +#include + +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/descriptor.pb.h" @@ -45,13 +48,12 @@ namespace cpp { namespace { -void SetStringVariables(const FieldDescriptor* descriptor, - std::map* variables, - const Options& options) { +void SetStringVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables, + const Options& options) { SetCommonFieldVariables(descriptor, variables, options); - const std::string kNS = "::" + ProtobufNamespace(options) + "::internal::"; - const std::string kArenaStringPtr = kNS + "ArenaStringPtr"; (*variables)["default"] = DefaultValue(options, descriptor); (*variables)["default_length"] = @@ -60,17 +62,21 @@ void SetStringVariables(const FieldDescriptor* descriptor, (*variables)["default_variable_field"] = MakeDefaultFieldName(descriptor); if (descriptor->default_value_string().empty()) { - (*variables)["default_string"] = kNS + "GetEmptyStringAlreadyInited()"; - (*variables)["default_value"] = "&" + (*variables)["default_string"]; + const std::string default_string = + absl::StrCat("::", ProtobufNamespace(options), + "::internal::GetEmptyStringAlreadyInited()"); + (*variables)["default_string"] = default_string; + (*variables)["default_value"] = absl::StrCat("&", default_string); (*variables)["lazy_variable_args"] = ""; } else { - (*variables)["lazy_variable"] = + const std::string lazy_variable = absl::StrCat(QualifiedClassName(descriptor->containing_type(), options), "::", MakeDefaultFieldName(descriptor)); + (*variables)["lazy_variable"] = lazy_variable; - (*variables)["default_string"] = (*variables)["lazy_variable"] + ".get()"; + (*variables)["default_string"] = absl::StrCat(lazy_variable, ".get()"); (*variables)["default_value"] = "nullptr"; - (*variables)["lazy_variable_args"] = (*variables)["lazy_variable"] + ", "; + (*variables)["lazy_variable_args"] = absl::StrCat(lazy_variable, ", "); } (*variables)["pointer_type"] = diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index bc45d740ba..158bf71074 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -33,15 +33,16 @@ #include #include #include +#include #include "google/protobuf/compiler/code_generator.h" -#include "google/protobuf/descriptor.h" -#include "google/protobuf/wire_format.h" #include "google/protobuf/compiler/csharp/csharp_helpers.h" #include "google/protobuf/compiler/csharp/names.h" +#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/printer.h" +#include "google/protobuf/wire_format.h" // Must be last. #include "google/protobuf/port_def.inc" @@ -52,7 +53,7 @@ namespace compiler { namespace csharp { void FieldGeneratorBase::SetCommonFieldVariables( - std::map* variables) { + absl::flat_hash_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. @@ -98,33 +99,46 @@ void FieldGeneratorBase::SetCommonFieldVariables( (*variables)["capitalized_type_name"] = capitalized_type_name(); (*variables)["number"] = number(); if (has_default_value() && !SupportsPresenceApi(descriptor_)) { - (*variables)["name_def_message"] = - (*variables)["name"] + "_ = " + (*variables)["default_value"]; + variables->insert({"name_def_message", + absl::StrCat((*variables)["name"], + "_ = ", (*variables)["default_value"])}); } else { - (*variables)["name_def_message"] = (*variables)["name"] + "_"; + variables->insert( + {"name_def_message", absl::StrCat((*variables)["name"], "_")}); } if (SupportsPresenceApi(descriptor_)) { - (*variables)["has_property_check"] = "Has" + (*variables)["property_name"]; - (*variables)["other_has_property_check"] = "other.Has" + (*variables)["property_name"]; - (*variables)["has_not_property_check"] = "!" + (*variables)["has_property_check"]; - (*variables)["other_has_not_property_check"] = "!" + (*variables)["other_has_property_check"]; + variables->insert({"has_property_check", + absl::StrCat("Has", (*variables)["property_name"])}); + variables->insert( + {"other_has_property_check", + absl::StrCat("other.Has", (*variables)["property_name"])}); + variables->insert({"has_not_property_check", + absl::StrCat("!", (*variables)["has_property_check"])}); + variables->insert( + {"other_has_not_property_check", + absl::StrCat("!", (*variables)["other_has_property_check"])}); if (presenceIndex_ != -1) { - std::string hasBitsNumber = absl::StrCat(presenceIndex_ / 32); - std::string hasBitsMask = absl::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; + const int hasBitsNumber = presenceIndex_ / 32; + const int hasBitsMask = 1 << (presenceIndex_ % 32); + (*variables)["has_field_check"] = absl::StrCat( + "(_hasBits", hasBitsNumber, " & ", hasBitsMask, ") != 0"); + (*variables)["set_has_field"] = + absl::StrCat("_hasBits", hasBitsNumber, " |= ", hasBitsMask); + (*variables)["clear_has_field"] = + absl::StrCat("_hasBits", hasBitsNumber, " &= ~", hasBitsMask); } } else { - (*variables)["has_property_check"] = - (*variables)["property_name"] + " != " + (*variables)["default_value"]; - (*variables)["other_has_property_check"] = "other." + - (*variables)["property_name"] + " != " + (*variables)["default_value"]; + variables->insert({"has_property_check", + absl::StrCat((*variables)["property_name"], + " != ", (*variables)["default_value"])}); + variables->insert({"other_has_property_check", + absl::StrCat("other.", (*variables)["property_name"], + " != ", (*variables)["default_value"])}); } } void FieldGeneratorBase::SetCommonOneofFieldVariables( - std::map* variables) { + absl::flat_hash_map* variables) { (*variables)["oneof_name"] = oneof_name(); if (SupportsPresenceApi(descriptor_)) { (*variables)["has_property_check"] = "Has" + property_name(); diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index 75fe19bfb3..933bbd4916 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -34,6 +34,7 @@ #include #include "google/protobuf/compiler/code_generator.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" #include "absl/strings/str_replace.h" @@ -77,7 +78,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { protected: const FieldDescriptor* descriptor_; const int presenceIndex_; - std::map variables_; + absl::flat_hash_map variables_; void AddDeprecatedFlag(io::Printer* printer); void AddNullCheck(io::Printer* printer); @@ -85,7 +86,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { void AddPublicMemberAttributes(io::Printer* printer); void SetCommonOneofFieldVariables( - std::map* variables); + absl::flat_hash_map* variables); std::string oneof_property_name(); std::string oneof_case_name(); @@ -101,7 +102,8 @@ class FieldGeneratorBase : public SourceGeneratorBase { std::string capitalized_type_name(); private: - void SetCommonFieldVariables(std::map* variables); + void SetCommonFieldVariables( + absl::flat_hash_map* variables); std::string GetStringDefaultValueInternal(const FieldDescriptor* descriptor); std::string GetBytesDefaultValueInternal(const FieldDescriptor* descriptor); }; diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index 50d8b1d828..efe87f2a6a 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -88,7 +88,7 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) { void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) { printer->Print( variables_, - "$name$_.MergeFrom(other.$name$_);\n"); + "$name$_.Add(other.$name$_);\n"); } void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index bdbd480a61..d5c803fce6 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -31,17 +31,17 @@ #include "google/protobuf/compiler/csharp/csharp_message.h" #include -#include #include #include "google/protobuf/compiler/code_generator.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/csharp/csharp_doc_comment.h" #include "google/protobuf/compiler/csharp/csharp_enum.h" #include "google/protobuf/compiler/csharp/csharp_field_base.h" #include "google/protobuf/compiler/csharp/csharp_helpers.h" -#include "google/protobuf/compiler/csharp/names.h" #include "google/protobuf/compiler/csharp/csharp_options.h" +#include "google/protobuf/compiler/csharp/names.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" @@ -114,7 +114,7 @@ void MessageGenerator::AddSerializableAttribute(io::Printer* printer) { } void MessageGenerator::Generate(io::Printer* printer) { - std::map vars; + absl::flat_hash_map vars; vars["class_name"] = class_name(); vars["access_level"] = class_access_level(); @@ -376,7 +376,7 @@ bool MessageGenerator::HasNestedGeneratedTypes() } void MessageGenerator::GenerateCloningCode(io::Printer* printer) { - std::map vars; + absl::flat_hash_map vars; WriteGeneratedCodeAttributes(printer); vars["class_name"] = class_name(); printer->Print( @@ -440,32 +440,30 @@ void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { } void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { - std::map vars; - vars["class_name"] = class_name(); + absl::flat_hash_map vars; + vars["class_name"] = class_name(); - // Equality - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public override bool Equals(object other) {\n" - " return Equals(other as $class_name$);\n" - "}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public bool Equals($class_name$ other) {\n" - " if (ReferenceEquals(other, null)) {\n" - " return false;\n" - " }\n" - " if (ReferenceEquals(other, this)) {\n" - " return true;\n" - " }\n"); - printer->Indent(); - for (int i = 0; i < descriptor_->field_count(); i++) { - std::unique_ptr generator( - CreateFieldGeneratorInternal(descriptor_->field(i))); - generator->WriteEquals(printer); - } + // Equality + WriteGeneratedCodeAttributes(printer); + printer->Print(vars, + "public override bool Equals(object other) {\n" + " return Equals(other as $class_name$);\n" + "}\n\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print(vars, + "public bool Equals($class_name$ other) {\n" + " if (ReferenceEquals(other, null)) {\n" + " return false;\n" + " }\n" + " if (ReferenceEquals(other, this)) {\n" + " return true;\n" + " }\n"); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + std::unique_ptr generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->WriteEquals(printer); + } for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n", "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); @@ -607,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; + absl::flat_hash_map vars; vars["class_name"] = class_name(); WriteGeneratedCodeAttributes(printer); @@ -687,7 +685,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { } void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_parse_context) { - std::map vars; + absl::flat_hash_map vars; vars["maybe_ref_input"] = use_parse_context ? "ref input" : "input"; printer->Print( diff --git a/src/google/protobuf/compiler/java/enum.cc b/src/google/protobuf/compiler/java/enum.cc index 788c9dd60f..f290623cac 100644 --- a/src/google/protobuf/compiler/java/enum.cc +++ b/src/google/protobuf/compiler/java/enum.cc @@ -34,10 +34,10 @@ #include "google/protobuf/compiler/java/enum.h" -#include #include #include "google/protobuf/io/printer.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -103,7 +103,7 @@ void EnumGenerator::Generate(io::Printer* printer) { } for (int i = 0; i < canonical_values_.size(); i++) { - std::map vars; + absl::flat_hash_map vars; vars["name"] = canonical_values_[i]->name(); vars["index"] = absl::StrCat(canonical_values_[i]->index()); vars["number"] = absl::StrCat(canonical_values_[i]->number()); @@ -135,7 +135,7 @@ void EnumGenerator::Generate(io::Printer* printer) { // ----------------------------------------------------------------- for (int i = 0; i < aliases_.size(); i++) { - std::map vars; + absl::flat_hash_map vars; vars["classname"] = descriptor_->name(); vars["name"] = aliases_[i].value->name(); vars["canonical_name"] = aliases_[i].canonical_value->name(); @@ -146,7 +146,7 @@ void EnumGenerator::Generate(io::Printer* printer) { } for (int i = 0; i < descriptor_->value_count(); i++) { - std::map vars; + absl::flat_hash_map vars; vars["name"] = descriptor_->value(i)->name(); vars["number"] = absl::StrCat(descriptor_->value(i)->number()); vars["{"] = ""; diff --git a/src/google/protobuf/compiler/java/enum_field.cc b/src/google/protobuf/compiler/java/enum_field.cc index b6c8dc796c..022511ff71 100644 --- a/src/google/protobuf/compiler/java/enum_field.cc +++ b/src/google/protobuf/compiler/java/enum_field.cc @@ -35,13 +35,13 @@ #include "google/protobuf/compiler/java/enum_field.h" #include -#include #include #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -58,16 +58,16 @@ namespace java { namespace { -void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetEnumVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["type"] = name_resolver->GetImmutableClassName(descriptor->enum_type()); - (*variables)["kt_type"] = EscapeKotlinKeywords((*variables)["type"]); + variables->insert({"kt_type", EscapeKotlinKeywords((*variables)["type"])}); (*variables)["mutable_type"] = name_resolver->GetMutableClassName(descriptor->enum_type()); (*variables)["default"] = @@ -82,11 +82,12 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -106,9 +107,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["set_has_field_bit_builder"] = ""; (*variables)["clear_has_field_bit_builder"] = ""; - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != " + (*variables)["default"] + - ".getNumber()"; + variables->insert({"is_field_present_message", + absl::StrCat((*variables)["name"], "_ != ", + (*variables)["default"], ".getNumber()")}); } // For repeated builders, one bit is used for whether the array is immutable. @@ -122,9 +123,10 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, GenerateSetBitToLocal(messageBitIndex); if (SupportUnknownEnumValue(descriptor->file())) { - (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED"; + variables->insert( + {"unknown", absl::StrCat((*variables)["type"], ".UNRECOGNIZED")}); } else { - (*variables)["unknown"] = (*variables)["default"]; + variables->insert({"unknown", (*variables)["default"]}); } } diff --git a/src/google/protobuf/compiler/java/enum_field.h b/src/google/protobuf/compiler/java/enum_field.h index 25ab0738da..e0fc5c1fae 100644 --- a/src/google/protobuf/compiler/java/enum_field.h +++ b/src/google/protobuf/compiler/java/enum_field.h @@ -38,6 +38,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/java/field.h" namespace google { @@ -90,7 +91,7 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; }; @@ -153,7 +154,7 @@ class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator { private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; }; diff --git a/src/google/protobuf/compiler/java/enum_field_lite.cc b/src/google/protobuf/compiler/java/enum_field_lite.cc index 470bc9d2fd..e2a1a6e149 100644 --- a/src/google/protobuf/compiler/java/enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/enum_field_lite.cc @@ -35,14 +35,15 @@ #include "google/protobuf/compiler/java/enum_field_lite.h" #include -#include #include #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_join.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/helpers.h" @@ -65,16 +66,16 @@ bool EnableExperimentalRuntimeForLite() { #endif // !PROTOBUF_EXPERIMENT } -void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetEnumVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["type"] = name_resolver->GetImmutableClassName(descriptor->enum_type()); - (*variables)["kt_type"] = EscapeKotlinKeywords((*variables)["type"]); + variables->insert({"kt_type", EscapeKotlinKeywords((*variables)["type"])}); (*variables)["mutable_type"] = name_resolver->GetMutableClassName(descriptor->enum_type()); (*variables)["default"] = @@ -89,11 +90,12 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["required"] = descriptor->is_required() ? "true" : "false"; if (HasHasbit(descriptor)) { @@ -117,9 +119,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["set_has_field_bit_message"] = ""; (*variables)["clear_has_field_bit_message"] = ""; - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != " + (*variables)["default"] + - ".getNumber()"; + variables->insert({"is_field_present_message", + absl::StrCat((*variables)["name"], "_ != ", + (*variables)["default"], ".getNumber()")}); } (*variables)["get_has_field_bit_from_local"] = @@ -128,9 +130,10 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, GenerateSetBitToLocal(messageBitIndex); if (SupportUnknownEnumValue(descriptor->file())) { - (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED"; + variables->insert( + {"unknown", absl::StrCat((*variables)["type"], ".UNRECOGNIZED")}); } else { - (*variables)["unknown"] = (*variables)["default"]; + variables->insert({"unknown", (*variables)["default"]}); } // We use `x.getClass()` as a null check because it generates less bytecode diff --git a/src/google/protobuf/compiler/java/enum_field_lite.h b/src/google/protobuf/compiler/java/enum_field_lite.h index 8d7a7d1cf4..17a95ac7f7 100644 --- a/src/google/protobuf/compiler/java/enum_field_lite.h +++ b/src/google/protobuf/compiler/java/enum_field_lite.h @@ -39,6 +39,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/java/field.h" namespace google { @@ -83,7 +84,7 @@ class ImmutableEnumFieldLiteGenerator : public ImmutableFieldLiteGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; const int messageBitIndex_; Context* context_; ClassNameResolver* name_resolver_; @@ -131,7 +132,7 @@ class RepeatedImmutableEnumFieldLiteGenerator private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; Context* context_; ClassNameResolver* name_resolver_; }; diff --git a/src/google/protobuf/compiler/java/enum_lite.cc b/src/google/protobuf/compiler/java/enum_lite.cc index 47cae62bc2..dc222541b0 100644 --- a/src/google/protobuf/compiler/java/enum_lite.cc +++ b/src/google/protobuf/compiler/java/enum_lite.cc @@ -34,10 +34,10 @@ #include "google/protobuf/compiler/java/enum_lite.h" -#include #include #include "google/protobuf/io/printer.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -86,7 +86,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { printer->Indent(); for (int i = 0; i < canonical_values_.size(); i++) { - std::map vars; + absl::flat_hash_map vars; vars["name"] = canonical_values_[i]->name(); vars["number"] = absl::StrCat(canonical_values_[i]->number()); WriteEnumValueDocComment(printer, canonical_values_[i]); @@ -109,7 +109,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { // ----------------------------------------------------------------- for (int i = 0; i < aliases_.size(); i++) { - std::map vars; + absl::flat_hash_map vars; vars["classname"] = descriptor_->name(); vars["name"] = aliases_[i].value->name(); vars["canonical_name"] = aliases_[i].canonical_value->name(); @@ -120,7 +120,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { } for (int i = 0; i < descriptor_->value_count(); i++) { - std::map vars; + absl::flat_hash_map vars; vars["name"] = descriptor_->value(i)->name(); vars["number"] = absl::StrCat(descriptor_->value(i)->number()); vars["{"] = ""; diff --git a/src/google/protobuf/compiler/java/extension.cc b/src/google/protobuf/compiler/java/extension.cc index 24a392edd8..421465b313 100644 --- a/src/google/protobuf/compiler/java/extension.cc +++ b/src/google/protobuf/compiler/java/extension.cc @@ -35,6 +35,7 @@ #include "google/protobuf/compiler/java/extension.h" #include "google/protobuf/io/printer.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -68,8 +69,9 @@ ImmutableExtensionGenerator::~ImmutableExtensionGenerator() {} void ExtensionGenerator::InitTemplateVars( const FieldDescriptor* descriptor, const std::string& scope, bool immutable, ClassNameResolver* name_resolver, - std::map* vars_pointer, Context* context) { - std::map& vars = *vars_pointer; + absl::flat_hash_map* vars_pointer, + Context* context) { + absl::flat_hash_map& vars = *vars_pointer; vars["scope"] = scope; vars["name"] = UnderscoresToCamelCaseCheckReserved(descriptor); vars["containing_type"] = @@ -116,7 +118,7 @@ void ExtensionGenerator::InitTemplateVars( } void ImmutableExtensionGenerator::Generate(io::Printer* printer) { - std::map vars; + absl::flat_hash_map vars; const bool kUseImmutableNames = true; InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_, &vars, context_); diff --git a/src/google/protobuf/compiler/java/extension.h b/src/google/protobuf/compiler/java/extension.h index b9dc99597b..15341b74dd 100644 --- a/src/google/protobuf/compiler/java/extension.h +++ b/src/google/protobuf/compiler/java/extension.h @@ -38,6 +38,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/port.h" namespace google { @@ -81,11 +82,11 @@ class ExtensionGenerator { virtual int GenerateRegistrationCode(io::Printer* printer) = 0; protected: - static void InitTemplateVars(const FieldDescriptor* descriptor, - const std::string& scope, bool immutable, - ClassNameResolver* name_resolver, - std::map* vars_pointer, - Context* context); + static void InitTemplateVars( + const FieldDescriptor* descriptor, const std::string& scope, + bool immutable, ClassNameResolver* name_resolver, + absl::flat_hash_map* vars_pointer, + Context* context); }; class ImmutableExtensionGenerator : public ExtensionGenerator { diff --git a/src/google/protobuf/compiler/java/extension_lite.cc b/src/google/protobuf/compiler/java/extension_lite.cc index e18dc6536a..111e51054b 100644 --- a/src/google/protobuf/compiler/java/extension_lite.cc +++ b/src/google/protobuf/compiler/java/extension_lite.cc @@ -30,7 +30,10 @@ #include "google/protobuf/compiler/java/extension_lite.h" +#include + #include "google/protobuf/io/printer.h" +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/helpers.h" @@ -60,7 +63,7 @@ ImmutableExtensionLiteGenerator::ImmutableExtensionLiteGenerator( ImmutableExtensionLiteGenerator::~ImmutableExtensionLiteGenerator() {} void ImmutableExtensionLiteGenerator::Generate(io::Printer* printer) { - std::map vars; + absl::flat_hash_map vars; const bool kUseImmutableNames = true; InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_, &vars, context_); diff --git a/src/google/protobuf/compiler/java/field.cc b/src/google/protobuf/compiler/java/field.cc index 831f88ab2d..449edf7fe4 100644 --- a/src/google/protobuf/compiler/java/field.cc +++ b/src/google/protobuf/compiler/java/field.cc @@ -35,10 +35,12 @@ #include "google/protobuf/compiler/java/field.h" #include +#include #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" #include "google/protobuf/io/printer.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/java/context.h" @@ -241,9 +243,9 @@ template <> FieldGeneratorMap::~FieldGeneratorMap() {} -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - const FieldGeneratorInfo* info, - std::map* variables) { +void SetCommonFieldVariables( + const FieldDescriptor* descriptor, const FieldGeneratorInfo* info, + absl::flat_hash_map* variables) { (*variables)["field_name"] = descriptor->name(); (*variables)["name"] = info->name; (*variables)["classname"] = descriptor->containing_type()->name(); @@ -273,15 +275,16 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["annotation_field_type"] = std::string(FieldTypeName(descriptor->type())) + "_LIST"; if (descriptor->is_packed()) { - (*variables)["annotation_field_type"] = - (*variables)["annotation_field_type"] + "_PACKED"; + variables->insert( + {"annotation_field_type", + absl::StrCat((*variables)["annotation_field_type"], "_PACKED")}); } } } -void SetCommonOneofVariables(const FieldDescriptor* descriptor, - const OneofGeneratorInfo* info, - std::map* variables) { +void SetCommonOneofVariables( + const FieldDescriptor* descriptor, const OneofGeneratorInfo* info, + absl::flat_hash_map* variables) { (*variables)["oneof_name"] = info->name; (*variables)["oneof_capitalized_name"] = info->capitalized_name; (*variables)["oneof_index"] = @@ -294,10 +297,10 @@ void SetCommonOneofVariables(const FieldDescriptor* descriptor, info->name + "Case_ == " + absl::StrCat(descriptor->number()); } -void PrintExtraFieldInfo(const std::map& variables, - io::Printer* printer) { - const std::map::const_iterator it = - variables.find("disambiguated_reason"); +void PrintExtraFieldInfo( + const absl::flat_hash_map& variables, + io::Printer* printer) { + auto it = variables.find("disambiguated_reason"); if (it != variables.end() && !it->second.empty()) { printer->Print( variables, diff --git a/src/google/protobuf/compiler/java/field.h b/src/google/protobuf/compiler/java/field.h index 5ac57cd4e1..7926f0821c 100644 --- a/src/google/protobuf/compiler/java/field.h +++ b/src/google/protobuf/compiler/java/field.h @@ -43,6 +43,7 @@ #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" #include "google/protobuf/descriptor.h" +#include "absl/container/flat_hash_map.h" #include "google/protobuf/port.h" namespace google { @@ -169,18 +170,19 @@ struct OneofGeneratorInfo { }; // Set some common variables used in variable FieldGenerators. -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - const FieldGeneratorInfo* info, - std::map* variables); +void SetCommonFieldVariables( + const FieldDescriptor* descriptor, const FieldGeneratorInfo* info, + absl::flat_hash_map* variables); // Set some common oneof variables used in OneofFieldGenerators. -void SetCommonOneofVariables(const FieldDescriptor* descriptor, - const OneofGeneratorInfo* info, - std::map* variables); +void SetCommonOneofVariables( + const FieldDescriptor* descriptor, const OneofGeneratorInfo* info, + absl::flat_hash_map* variables); // Print useful comments before a field's accessors. -void PrintExtraFieldInfo(const std::map& variables, - io::Printer* printer); +void PrintExtraFieldInfo( + const absl::flat_hash_map& variables, + io::Printer* printer); } // namespace java } // namespace compiler diff --git a/src/google/protobuf/compiler/java/helpers.cc b/src/google/protobuf/compiler/java/helpers.cc index d13941c6ed..fea72712b5 100644 --- a/src/google/protobuf/compiler/java/helpers.cc +++ b/src/google/protobuf/compiler/java/helpers.cc @@ -84,11 +84,10 @@ void PrintGeneratedAnnotation(io::Printer* printer, char delimiter, printer->Print(ptemplate.c_str(), "annotation_file", annotation_file); } -void PrintEnumVerifierLogic(io::Printer* printer, - const FieldDescriptor* descriptor, - const std::map& variables, - const char* var_name, - const char* terminating_string, bool enforce_lite) { +void PrintEnumVerifierLogic( + io::Printer* printer, const FieldDescriptor* descriptor, + const absl::flat_hash_map& variables, + const char* var_name, const char* terminating_string, bool enforce_lite) { std::string enum_verifier_string = enforce_lite ? absl::StrCat(var_name, ".internalGetVerifier()") : absl::StrCat( diff --git a/src/google/protobuf/compiler/java/helpers.h b/src/google/protobuf/compiler/java/helpers.h index 9273ae3c0b..a3eee1a938 100644 --- a/src/google/protobuf/compiler/java/helpers.h +++ b/src/google/protobuf/compiler/java/helpers.h @@ -74,11 +74,10 @@ void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$', // If a GeneratedMessageLite contains non-lite enums, then its verifier // must be instantiated inline, rather than retrieved from the enum class. -void PrintEnumVerifierLogic(io::Printer* printer, - const FieldDescriptor* descriptor, - const std::map& variables, - const char* var_name, - const char* terminating_string, bool enforce_lite); +void PrintEnumVerifierLogic( + io::Printer* printer, const FieldDescriptor* descriptor, + const absl::flat_hash_map& variables, + const char* var_name, const char* terminating_string, bool enforce_lite); // Converts a name to camel-case. If cap_first_letter is true, capitalize the // first letter. diff --git a/src/google/protobuf/compiler/java/map_field.cc b/src/google/protobuf/compiler/java/map_field.cc index 2b69bb6e29..4c7715c69e 100644 --- a/src/google/protobuf/compiler/java/map_field.cc +++ b/src/google/protobuf/compiler/java/map_field.cc @@ -31,6 +31,7 @@ #include "google/protobuf/compiler/java/map_field.h" #include "google/protobuf/io/printer.h" +#include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/helpers.h" @@ -88,10 +89,10 @@ std::string WireType(const FieldDescriptor* field) { std::string(FieldTypeName(field->type())); } -void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - Context* context, - std::map* variables) { +void SetMessageVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, Context* context, + absl::flat_hash_map* variables) { SetCommonFieldVariables(descriptor, info, variables); ClassNameResolver* name_resolver = context->GetNameResolver(); @@ -133,8 +134,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, if (valueJavaType == JAVATYPE_ENUM) { // We store enums as Integers internally. (*variables)["value_type"] = "int"; - (*variables)["value_type_pass_through_nullness"] = - (*variables)["value_type"]; + variables->insert( + {"value_type_pass_through_nullness", (*variables)["value_type"]}); (*variables)["boxed_value_type"] = "java.lang.Integer"; (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -143,13 +144,15 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); - (*variables)["value_enum_type_pass_through_nullness"] = - pass_through_nullness + (*variables)["value_enum_type"]; + variables->insert( + {"value_enum_type_pass_through_nullness", + absl::StrCat(pass_through_nullness, (*variables)["value_enum_type"])}); if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. - (*variables)["unrecognized_value"] = - (*variables)["value_enum_type"] + ".UNRECOGNIZED"; + variables->insert( + {"unrecognized_value", + absl::StrCat((*variables)["value_enum_type"], ".UNRECOGNIZED")}); } else { // Map unknown values to the default value if we don't have UNRECOGNIZED. (*variables)["unrecognized_value"] = @@ -158,31 +161,36 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); - (*variables)["value_type_pass_through_nullness"] = - (IsReferenceType(valueJavaType) ? pass_through_nullness : "") + - (*variables)["value_type"]; + variables->insert( + {"value_type_pass_through_nullness", + absl::StrCat( + (IsReferenceType(valueJavaType) ? pass_through_nullness : ""), + (*variables)["value_type"])}); (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = DefaultValue(value, true, name_resolver, context->options()); } - (*variables)["type_parameters"] = - (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"]; + variables->insert( + {"type_parameters", absl::StrCat((*variables)["boxed_key_type"], ", ", + (*variables)["boxed_value_type"])}); // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["on_changed"] = "onChanged();"; - (*variables)["default_entry"] = - (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry"; - (*variables)["map_field_parameter"] = (*variables)["default_entry"]; + variables->insert( + {"default_entry", absl::StrCat((*variables)["capitalized_name"], + "DefaultEntryHolder.defaultEntry")}); + variables->insert({"map_field_parameter", (*variables)["default_entry"]}); (*variables)["descriptor"] = name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" + UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, "; diff --git a/src/google/protobuf/compiler/java/map_field.h b/src/google/protobuf/compiler/java/map_field.h index 434150820b..39cdbde767 100644 --- a/src/google/protobuf/compiler/java/map_field.h +++ b/src/google/protobuf/compiler/java/map_field.h @@ -68,7 +68,7 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; Context* context_; void GenerateMapGetters(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/java/map_field_lite.cc b/src/google/protobuf/compiler/java/map_field_lite.cc index 22bc306586..94d964fa38 100644 --- a/src/google/protobuf/compiler/java/map_field_lite.cc +++ b/src/google/protobuf/compiler/java/map_field_lite.cc @@ -90,10 +90,10 @@ std::string WireType(const FieldDescriptor* field) { std::string(FieldTypeName(field->type())); } -void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - Context* context, - std::map* variables) { +void SetMessageVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, Context* context, + absl::flat_hash_map* variables) { SetCommonFieldVariables(descriptor, info, variables); ClassNameResolver* name_resolver = context->GetNameResolver(); @@ -130,8 +130,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, if (GetJavaType(value) == JAVATYPE_ENUM) { // We store enums as Integers internally. (*variables)["value_type"] = "int"; - (*variables)["value_type_pass_through_nullness"] = - (*variables)["value_type"]; + (*variables)["value_type_pass_through_nullness"] = "int"; (*variables)["boxed_value_type"] = "java.lang.Integer"; (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -140,13 +139,15 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); - (*variables)["value_enum_type_pass_through_nullness"] = - pass_through_nullness + (*variables)["value_enum_type"]; + variables->insert( + {"value_enum_type_pass_through_nullness", + absl::StrCat(pass_through_nullness, (*variables)["value_enum_type"])}); if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. - (*variables)["unrecognized_value"] = - (*variables)["value_enum_type"] + ".UNRECOGNIZED"; + variables->insert( + {"unrecognized_value", + absl::StrCat((*variables)["value_enum_type"], ".UNRECOGNIZED")}); } else { // Map unknown values to the default value if we don't have UNRECOGNIZED. (*variables)["unrecognized_value"] = @@ -155,31 +156,37 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); - (*variables)["value_type_pass_through_nullness"] = - (IsReferenceType(valueJavaType) ? pass_through_nullness : "") + - (*variables)["value_type"]; + variables->insert( + {"value_type_pass_through_nullness", + absl::StrCat( + (IsReferenceType(valueJavaType) ? pass_through_nullness : ""), + (*variables)["value_type"])}); (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = DefaultValue(value, true, name_resolver, context->options()); } - (*variables)["type_parameters"] = - (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"]; + variables->insert( + {"type_parameters", absl::StrCat((*variables)["boxed_key_type"], ", ", + (*variables)["boxed_value_type"])}); // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; - - (*variables)["default_entry"] = - (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry"; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); + + variables->insert( + {"default_entry", absl::StrCat((*variables)["capitalized_name"], + "DefaultEntryHolder.defaultEntry")}); // { and } variables are used as delimiters when emitting annotations. - (*variables)["{"] = (*variables)["}"] = ""; + (*variables)["{"] = ""; + (*variables)["}"] = ""; } } // namespace diff --git a/src/google/protobuf/compiler/java/map_field_lite.h b/src/google/protobuf/compiler/java/map_field_lite.h index 46a2d9f884..ccb2bc4c3f 100644 --- a/src/google/protobuf/compiler/java/map_field_lite.h +++ b/src/google/protobuf/compiler/java/map_field_lite.h @@ -61,7 +61,7 @@ class ImmutableMapFieldLiteGenerator : public ImmutableFieldLiteGenerator { private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; Context* context_; ClassNameResolver* name_resolver_; }; diff --git a/src/google/protobuf/compiler/java/message.cc b/src/google/protobuf/compiler/java/message.cc index eae7bb3bcc..9ff8b87aa0 100644 --- a/src/google/protobuf/compiler/java/message.cc +++ b/src/google/protobuf/compiler/java/message.cc @@ -36,7 +36,6 @@ #include #include -#include #include #include @@ -115,7 +114,7 @@ void ImmutableMessageGenerator::GenerateStaticVariables( // the outermost class in the file. This way, they will be initialized in // a deterministic order. - std::map vars; + absl::flat_hash_map vars; vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); vars["index"] = absl::StrCat(descriptor_->index()); vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_); @@ -159,7 +158,7 @@ void ImmutableMessageGenerator::GenerateStaticVariables( int ImmutableMessageGenerator::GenerateStaticVariableInitializers( io::Printer* printer) { int bytecode_estimate = 0; - std::map vars; + absl::flat_hash_map vars; vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); vars["index"] = absl::StrCat(descriptor_->index()); vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_); @@ -196,7 +195,7 @@ int ImmutableMessageGenerator::GenerateStaticVariableInitializers( void ImmutableMessageGenerator::GenerateFieldAccessorTable( io::Printer* printer, int* bytecode_estimate) { - std::map vars; + absl::flat_hash_map vars; vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) { // We can only make these package-private since the classes that use them @@ -314,7 +313,7 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { void ImmutableMessageGenerator::Generate(io::Printer* printer) { bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); - std::map variables; + absl::flat_hash_map variables; variables["static"] = is_own_file ? "" : "static "; variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); @@ -426,7 +425,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { } // oneof - std::map vars; + absl::flat_hash_map vars; for (auto oneof : oneofs_) { vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; vars["oneof_capitalized_name"] = diff --git a/src/google/protobuf/compiler/java/message_builder.cc b/src/google/protobuf/compiler/java/message_builder.cc index 150c4e6c4c..eb85dd4f76 100644 --- a/src/google/protobuf/compiler/java/message_builder.cc +++ b/src/google/protobuf/compiler/java/message_builder.cc @@ -35,13 +35,13 @@ #include "google/protobuf/compiler/java/message_builder.h" #include -#include #include #include #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" @@ -126,7 +126,7 @@ void MessageBuilderGenerator::Generate(io::Printer* printer) { } // oneof - std::map vars; + absl::flat_hash_map vars; for (auto oneof : oneofs_) { vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; vars["oneof_capitalized_name"] = diff --git a/src/google/protobuf/compiler/java/message_builder_lite.cc b/src/google/protobuf/compiler/java/message_builder_lite.cc index 1f9d13e9b6..5f047344e2 100644 --- a/src/google/protobuf/compiler/java/message_builder_lite.cc +++ b/src/google/protobuf/compiler/java/message_builder_lite.cc @@ -35,7 +35,6 @@ #include "google/protobuf/compiler/java/message_builder_lite.h" #include -#include #include #include #include @@ -43,6 +42,7 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/java/context.h" @@ -82,7 +82,7 @@ MessageBuilderLiteGenerator::~MessageBuilderLiteGenerator() {} void MessageBuilderLiteGenerator::Generate(io::Printer* printer) { WriteMessageDocComment(printer, descriptor_); - std::map vars = { + absl::flat_hash_map vars = { {"{", ""}, {"}", ""}, {"classname", name_resolver_->GetImmutableClassName(descriptor_)}, diff --git a/src/google/protobuf/compiler/java/message_field.cc b/src/google/protobuf/compiler/java/message_field.cc index 0e06ed77d8..c77d345e7c 100644 --- a/src/google/protobuf/compiler/java/message_field.cc +++ b/src/google/protobuf/compiler/java/message_field.cc @@ -34,11 +34,11 @@ #include "google/protobuf/compiler/java/message_field.h" -#include #include #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/helpers.h" @@ -55,16 +55,16 @@ namespace java { namespace { -void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetMessageVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["type"] = name_resolver->GetImmutableClassName(descriptor->message_type()); - (*variables)["kt_type"] = EscapeKotlinKeywords((*variables)["type"]); + variables->insert({"kt_type", EscapeKotlinKeywords((*variables)["type"])}); (*variables)["mutable_type"] = name_resolver->GetMutableClassName(descriptor->message_type()); (*variables)["group_or_message"] = @@ -74,11 +74,12 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["on_changed"] = "onChanged();"; (*variables)["ver"] = GeneratedCodeVersionSuffix(); (*variables)["get_parser"] = @@ -106,8 +107,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["set_has_field_bit_builder"] = ""; (*variables)["clear_has_field_bit_builder"] = ""; - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != null"; + variables->insert({"is_field_present_message", + absl::StrCat((*variables)["name"], "_ != null")}); } // For repeated builders, one bit is used for whether the array is immutable. diff --git a/src/google/protobuf/compiler/java/message_field.h b/src/google/protobuf/compiler/java/message_field.h index 4fe5ac7df4..6510a16e92 100644 --- a/src/google/protobuf/compiler/java/message_field.h +++ b/src/google/protobuf/compiler/java/message_field.h @@ -92,7 +92,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; Context* context_; @@ -165,7 +165,7 @@ class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; void PrintNestedBuilderCondition(io::Printer* printer, diff --git a/src/google/protobuf/compiler/java/message_field_lite.cc b/src/google/protobuf/compiler/java/message_field_lite.cc index d01ccc102d..0a27635d7a 100644 --- a/src/google/protobuf/compiler/java/message_field_lite.cc +++ b/src/google/protobuf/compiler/java/message_field_lite.cc @@ -35,7 +35,6 @@ #include "google/protobuf/compiler/java/message_field_lite.h" #include -#include #include #include "google/protobuf/io/printer.h" @@ -56,16 +55,16 @@ namespace java { namespace { -void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetMessageVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["type"] = name_resolver->GetImmutableClassName(descriptor->message_type()); - (*variables)["kt_type"] = EscapeKotlinKeywords((*variables)["type"]); + variables->insert({"kt_type", EscapeKotlinKeywords((*variables)["type"])}); (*variables)["mutable_type"] = name_resolver->GetMutableClassName(descriptor->message_type()); (*variables)["group_or_message"] = @@ -75,11 +74,12 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["required"] = descriptor->is_required() ? "true" : "false"; if (HasHasbit(descriptor)) { @@ -97,8 +97,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["set_has_field_bit_message"] = ""; (*variables)["clear_has_field_bit_message"] = ""; - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != null"; + variables->insert({"is_field_present_message", + absl::StrCat((*variables)["name"], "_ != null")}); } (*variables)["get_has_field_bit_from_local"] = diff --git a/src/google/protobuf/compiler/java/message_field_lite.h b/src/google/protobuf/compiler/java/message_field_lite.h index c5387a6ffe..227d2660ad 100644 --- a/src/google/protobuf/compiler/java/message_field_lite.h +++ b/src/google/protobuf/compiler/java/message_field_lite.h @@ -83,7 +83,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; const int messageBitIndex_; ClassNameResolver* name_resolver_; Context* context_; @@ -136,7 +136,7 @@ class RepeatedImmutableMessageFieldLiteGenerator protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; Context* context_; }; diff --git a/src/google/protobuf/compiler/java/message_lite.cc b/src/google/protobuf/compiler/java/message_lite.cc index 475a30b9f5..64195ecda6 100644 --- a/src/google/protobuf/compiler/java/message_lite.cc +++ b/src/google/protobuf/compiler/java/message_lite.cc @@ -36,7 +36,6 @@ #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" @@ -117,7 +117,7 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { MaybePrintGeneratedAnnotation(context_, printer, descriptor_, /* immutable = */ true, "OrBuilder"); - std::map variables = { + absl::flat_hash_map variables = { {"{", ""}, {"}", ""}, {"deprecation", @@ -173,7 +173,8 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); - std::map variables = {{"{", ""}, {"}", ""}}; + absl::flat_hash_map variables = {{"{", ""}, + {"}", ""}}; variables["static"] = is_own_file ? " " : " static "; variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); @@ -242,7 +243,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { } // oneof - std::map vars = {{"{", ""}, {"}", ""}}; + absl::flat_hash_map vars = {{"{", ""}, + {"}", ""}}; for (auto oneof : oneofs_) { vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; vars["oneof_capitalized_name"] = diff --git a/src/google/protobuf/compiler/java/name_resolver.cc b/src/google/protobuf/compiler/java/name_resolver.cc index 84e74ffddc..72078bd6b8 100644 --- a/src/google/protobuf/compiler/java/name_resolver.cc +++ b/src/google/protobuf/compiler/java/name_resolver.cc @@ -30,7 +30,6 @@ #include "google/protobuf/compiler/java/name_resolver.h" -#include #include #include "google/protobuf/compiler/code_generator.h" diff --git a/src/google/protobuf/compiler/java/primitive_field.cc b/src/google/protobuf/compiler/java/primitive_field.cc index 87dbdb6a50..36754350b3 100644 --- a/src/google/protobuf/compiler/java/primitive_field.cc +++ b/src/google/protobuf/compiler/java/primitive_field.cc @@ -35,7 +35,6 @@ #include "google/protobuf/compiler/java/primitive_field.h" #include -#include #include #include "google/protobuf/stubs/logging.h" @@ -57,54 +56,55 @@ using internal::WireFormat; namespace { -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); JavaType javaType = GetJavaType(descriptor); (*variables)["type"] = PrimitiveTypeName(javaType); (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType); (*variables)["kt_type"] = KotlinTypeName(javaType); - (*variables)["field_type"] = (*variables)["type"]; + variables->insert({"field_type", (*variables)["type"]}); + std::string name = (*variables)["name"]; if (javaType == JAVATYPE_BOOLEAN || javaType == JAVATYPE_DOUBLE || javaType == JAVATYPE_FLOAT || javaType == JAVATYPE_INT || javaType == JAVATYPE_LONG) { std::string capitalized_type = UnderscoresToCamelCase( PrimitiveTypeName(javaType), /*cap_first_letter=*/true); (*variables)["field_list_type"] = - "com.google.protobuf.Internal." + capitalized_type + "List"; - (*variables)["empty_list"] = "empty" + capitalized_type + "List()"; - (*variables)["create_list"] = "new" + capitalized_type + "List()"; + absl::StrCat("com.google.protobuf.Internal.", capitalized_type, "List"); + (*variables)["empty_list"] = + absl::StrCat("empty", capitalized_type, "List()"); + (*variables)["create_list"] = + absl::StrCat("new", capitalized_type, "List()"); (*variables)["mutable_copy_list"] = - "mutableCopy(" + (*variables)["name"] + "_)"; + absl::StrCat("mutableCopy(", name, "_)"); (*variables)["name_make_immutable"] = - (*variables)["name"] + "_.makeImmutable()"; + absl::StrCat(name, "_.makeImmutable()"); (*variables)["repeated_get"] = - (*variables)["name"] + "_.get" + capitalized_type; + absl::StrCat(name, "_.get", capitalized_type); (*variables)["repeated_add"] = - (*variables)["name"] + "_.add" + capitalized_type; + absl::StrCat(name, "_.add", capitalized_type); (*variables)["repeated_set"] = - (*variables)["name"] + "_.set" + capitalized_type; + absl::StrCat(name, "_.set", capitalized_type); } else { + std::string boxed_type = (*variables)["boxed_type"]; (*variables)["field_list_type"] = - "java.util.List<" + (*variables)["boxed_type"] + ">"; + absl::StrCat("java.util.List<", boxed_type, ">"); (*variables)["create_list"] = - "new java.util.ArrayList<" + (*variables)["boxed_type"] + ">()"; - (*variables)["mutable_copy_list"] = "new java.util.ArrayList<" + - (*variables)["boxed_type"] + ">(" + - (*variables)["name"] + "_)"; + absl::StrCat("new java.util.ArrayList<", boxed_type, ">()"); + (*variables)["mutable_copy_list"] = + absl::StrCat("new java.util.ArrayList<", boxed_type, ">(", name, "_)"); (*variables)["empty_list"] = "java.util.Collections.emptyList()"; - (*variables)["name_make_immutable"] = - (*variables)["name"] + "_ = java.util.Collections.unmodifiableList(" + - (*variables)["name"] + "_)"; - (*variables)["repeated_get"] = (*variables)["name"] + "_.get"; - (*variables)["repeated_add"] = (*variables)["name"] + "_.add"; - (*variables)["repeated_set"] = (*variables)["name"] + "_.set"; + (*variables)["name_make_immutable"] = absl::StrCat( + name, "_ = java.util.Collections.unmodifiableList(", name, "_)"); + (*variables)["repeated_get"] = absl::StrCat(name, "_.get"); + (*variables)["repeated_add"] = absl::StrCat(name, "_.add"); + (*variables)["repeated_set"] = absl::StrCat(name, "_.set"); } (*variables)["default"] = @@ -134,8 +134,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["kt_deprecation"] = descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", name, + " is deprecated\") ") : ""; int fixed_size = FixedSize(GetType(descriptor)); if (fixed_size != -1) { @@ -165,21 +165,20 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, switch (descriptor->type()) { case FieldDescriptor::TYPE_BYTES: (*variables)["is_field_present_message"] = - "!" + (*variables)["name"] + "_.isEmpty()"; + absl::StrCat("!", name, "_.isEmpty()"); break; case FieldDescriptor::TYPE_FLOAT: (*variables)["is_field_present_message"] = - "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] + - "_) != 0"; + absl::StrCat("java.lang.Float.floatToRawIntBits(", name, "_) != 0"); break; case FieldDescriptor::TYPE_DOUBLE: - (*variables)["is_field_present_message"] = - "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] + - "_) != 0"; + (*variables)["is_field_present_message"] = absl::StrCat( + "java.lang.Double.doubleToRawLongBits(", name, "_) != 0"); break; default: - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != " + (*variables)["default"]; + variables->insert( + {"is_field_present_message", + absl::StrCat(name, "_ != ", (*variables)["default"])}); break; } } diff --git a/src/google/protobuf/compiler/java/primitive_field.h b/src/google/protobuf/compiler/java/primitive_field.h index d8104ba5f6..f81e28da18 100644 --- a/src/google/protobuf/compiler/java/primitive_field.h +++ b/src/google/protobuf/compiler/java/primitive_field.h @@ -92,7 +92,7 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; }; @@ -155,7 +155,7 @@ class RepeatedImmutablePrimitiveFieldGenerator private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; }; diff --git a/src/google/protobuf/compiler/java/primitive_field_lite.cc b/src/google/protobuf/compiler/java/primitive_field_lite.cc index e370815326..31fe87dfdf 100644 --- a/src/google/protobuf/compiler/java/primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/primitive_field_lite.cc @@ -35,12 +35,10 @@ #include "google/protobuf/compiler/java/primitive_field_lite.h" #include -#include #include #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" -#include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" @@ -66,18 +64,17 @@ bool EnableExperimentalRuntimeForLite() { #endif // !PROTOBUF_EXPERIMENT } -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); JavaType javaType = GetJavaType(descriptor); (*variables)["type"] = PrimitiveTypeName(javaType); (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType); (*variables)["kt_type"] = KotlinTypeName(javaType); - (*variables)["field_type"] = (*variables)["type"]; + variables->insert({"field_type", (*variables)["type"]}); (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver, context->options()); (*variables)["capitalized_type"] = GetCapitalizedType( @@ -90,43 +87,47 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, std::string capitalized_type = UnderscoresToCamelCase( PrimitiveTypeName(javaType), true /* cap_next_letter */); + std::string name = (*variables)["name"]; switch (javaType) { case JAVATYPE_INT: case JAVATYPE_LONG: case JAVATYPE_FLOAT: case JAVATYPE_DOUBLE: case JAVATYPE_BOOLEAN: - (*variables)["field_list_type"] = - "com.google.protobuf.Internal." + capitalized_type + "List"; - (*variables)["empty_list"] = "empty" + capitalized_type + "List()"; + (*variables)["field_list_type"] = absl::StrCat( + "com.google.protobuf.Internal.", capitalized_type, "List"); + (*variables)["empty_list"] = + absl::StrCat("empty", capitalized_type, "List()"); (*variables)["make_name_unmodifiable"] = - (*variables)["name"] + "_.makeImmutable()"; + absl::StrCat(name, "_.makeImmutable()"); (*variables)["repeated_get"] = - (*variables)["name"] + "_.get" + capitalized_type; + absl::StrCat(name, "_.get", capitalized_type); (*variables)["repeated_add"] = - (*variables)["name"] + "_.add" + capitalized_type; + absl::StrCat(name, "_.add", capitalized_type); (*variables)["repeated_set"] = - (*variables)["name"] + "_.set" + capitalized_type; + absl::StrCat(name, "_.set", capitalized_type); (*variables)["visit_type"] = capitalized_type; - (*variables)["visit_type_list"] = "visit" + capitalized_type + "List"; + (*variables)["visit_type_list"] = + absl::StrCat("visit", capitalized_type, "List"); break; default: - (*variables)["field_list_type"] = - "com.google.protobuf.Internal.ProtobufList<" + - (*variables)["boxed_type"] + ">"; + variables->insert( + {"field_list_type", + absl::StrCat("com.google.protobuf.Internal.ProtobufList<", + (*variables)["boxed_type"], ">")}); (*variables)["empty_list"] = "emptyProtobufList()"; (*variables)["make_name_unmodifiable"] = - (*variables)["name"] + "_.makeImmutable()"; - (*variables)["repeated_get"] = (*variables)["name"] + "_.get"; - (*variables)["repeated_add"] = (*variables)["name"] + "_.add"; - (*variables)["repeated_set"] = (*variables)["name"] + "_.set"; + absl::StrCat(name, "_.makeImmutable()"); + (*variables)["repeated_get"] = absl::StrCat(name, "_.get"); + (*variables)["repeated_add"] = absl::StrCat(name, "_.add"); + (*variables)["repeated_set"] = absl::StrCat(name, "_.set"); (*variables)["visit_type"] = "ByteString"; (*variables)["visit_type_list"] = "visitList"; } if (javaType == JAVATYPE_BYTES) { (*variables)["bytes_default"] = - absl::AsciiStrToUpper((*variables)["name"]) + "_DEFAULT_VALUE"; + absl::AsciiStrToUpper(name) + "_DEFAULT_VALUE"; } if (IsReferenceType(javaType)) { @@ -143,8 +144,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["kt_deprecation"] = descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", name, + " is deprecated\") ") : ""; int fixed_size = FixedSize(GetType(descriptor)); if (fixed_size != -1) { @@ -169,21 +170,20 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, switch (descriptor->type()) { case FieldDescriptor::TYPE_BYTES: (*variables)["is_field_present_message"] = - "!" + (*variables)["name"] + "_.isEmpty()"; + absl::StrCat("!", name, "_.isEmpty()"); break; case FieldDescriptor::TYPE_FLOAT: (*variables)["is_field_present_message"] = - "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] + - "_) != 0"; + absl::StrCat("java.lang.Float.floatToRawIntBits(", name, "_) != 0"); break; case FieldDescriptor::TYPE_DOUBLE: - (*variables)["is_field_present_message"] = - "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] + - "_) != 0"; + (*variables)["is_field_present_message"] = absl::StrCat( + "java.lang.Double.doubleToRawLongBits(", name, "_) != 0"); break; default: - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != " + (*variables)["default"]; + variables->insert( + {"is_field_present_message", + absl::StrCat(name, "_ != " + (*variables)["default"])}); break; } } @@ -193,7 +193,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["set_has_field_bit_to_local"] = GenerateSetBitToLocal(messageBitIndex); // Annotations often use { and } variables to denote ranges. - (*variables)["{"] = (*variables)["}"] = ""; + (*variables)["{"] = ""; + (*variables)["}"] = ""; } } // namespace diff --git a/src/google/protobuf/compiler/java/primitive_field_lite.h b/src/google/protobuf/compiler/java/primitive_field_lite.h index 410b7d608f..95b42432a9 100644 --- a/src/google/protobuf/compiler/java/primitive_field_lite.h +++ b/src/google/protobuf/compiler/java/primitive_field_lite.h @@ -83,7 +83,7 @@ class ImmutablePrimitiveFieldLiteGenerator protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; const int messageBitIndex_; Context* context_; ClassNameResolver* name_resolver_; @@ -133,7 +133,7 @@ class RepeatedImmutablePrimitiveFieldLiteGenerator private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; Context* context_; ClassNameResolver* name_resolver_; }; diff --git a/src/google/protobuf/compiler/java/service.cc b/src/google/protobuf/compiler/java/service.cc index d0c525b8c4..25fbfe30bf 100644 --- a/src/google/protobuf/compiler/java/service.cc +++ b/src/google/protobuf/compiler/java/service.cc @@ -215,7 +215,7 @@ void ImmutableServiceGenerator::GenerateCallMethod(io::Printer* printer) { for (int i = 0; i < descriptor_->method_count(); i++) { const MethodDescriptor* method = descriptor_->method(i); - std::map vars; + absl::flat_hash_map vars; vars["index"] = absl::StrCat(i); vars["method"] = UnderscoresToCamelCase(method); vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); @@ -262,7 +262,7 @@ void ImmutableServiceGenerator::GenerateCallBlockingMethod( for (int i = 0; i < descriptor_->method_count(); i++) { const MethodDescriptor* method = descriptor_->method(i); - std::map vars; + absl::flat_hash_map vars; vars["index"] = absl::StrCat(i); vars["method"] = UnderscoresToCamelCase(method); vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); @@ -307,7 +307,7 @@ void ImmutableServiceGenerator::GenerateGetPrototype(RequestOrResponse which, for (int i = 0; i < descriptor_->method_count(); i++) { const MethodDescriptor* method = descriptor_->method(i); - std::map vars; + absl::flat_hash_map vars; vars["index"] = absl::StrCat(i); vars["type"] = (which == REQUEST) @@ -362,7 +362,7 @@ void ImmutableServiceGenerator::GenerateStub(io::Printer* printer) { printer->Print(" {\n"); printer->Indent(); - std::map vars; + absl::flat_hash_map vars; vars["index"] = absl::StrCat(i); vars["output"] = GetOutput(method); printer->Print(vars, @@ -426,7 +426,7 @@ void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) { printer->Print(" {\n"); printer->Indent(); - std::map vars; + absl::flat_hash_map vars; vars["index"] = absl::StrCat(i); vars["output"] = GetOutput(method); printer->Print(vars, @@ -449,7 +449,7 @@ void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) { void ImmutableServiceGenerator::GenerateMethodSignature( io::Printer* printer, const MethodDescriptor* method, IsAbstract is_abstract) { - std::map vars; + absl::flat_hash_map vars; vars["name"] = UnderscoresToCamelCase(method); vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); vars["output"] = GetOutput(method); @@ -463,7 +463,7 @@ void ImmutableServiceGenerator::GenerateMethodSignature( void ImmutableServiceGenerator::GenerateBlockingMethodSignature( io::Printer* printer, const MethodDescriptor* method) { - std::map vars; + absl::flat_hash_map vars; vars["method"] = UnderscoresToCamelCase(method); vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); vars["output"] = GetOutput(method); diff --git a/src/google/protobuf/compiler/java/string_field.cc b/src/google/protobuf/compiler/java/string_field.cc index 910ee8e0ee..4992ef2bcc 100644 --- a/src/google/protobuf/compiler/java/string_field.cc +++ b/src/google/protobuf/compiler/java/string_field.cc @@ -36,13 +36,13 @@ #include "google/protobuf/compiler/java/string_field.h" #include -#include #include #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -59,12 +59,11 @@ using internal::WireFormatLite; namespace { -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY"; @@ -96,11 +95,12 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["on_changed"] = "onChanged();"; if (HasHasbit(descriptor)) { @@ -122,8 +122,9 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["set_has_field_bit_builder"] = ""; (*variables)["clear_has_field_bit_builder"] = ""; - (*variables)["is_field_present_message"] = - "!" + (*variables)["isStringEmpty"] + "(" + (*variables)["name"] + "_)"; + variables->insert({"is_field_present_message", + absl::StrCat("!", (*variables)["isStringEmpty"], "(", + (*variables)["name"], "_)")}); } // For repeated builders, one bit is used for whether the array is immutable. diff --git a/src/google/protobuf/compiler/java/string_field.h b/src/google/protobuf/compiler/java/string_field.h index c9b6256d5d..bbe673a1c2 100644 --- a/src/google/protobuf/compiler/java/string_field.h +++ b/src/google/protobuf/compiler/java/string_field.h @@ -91,7 +91,7 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; }; @@ -152,7 +152,7 @@ class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator { private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; }; diff --git a/src/google/protobuf/compiler/java/string_field_lite.cc b/src/google/protobuf/compiler/java/string_field_lite.cc index df86df7876..9b4069a209 100644 --- a/src/google/protobuf/compiler/java/string_field_lite.cc +++ b/src/google/protobuf/compiler/java/string_field_lite.cc @@ -36,13 +36,12 @@ #include "google/protobuf/compiler/java/string_field_lite.h" #include -#include #include #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" -#include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -59,12 +58,11 @@ using internal::WireFormatLite; namespace { -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables, - Context* context) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + absl::flat_hash_map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["empty_list"] = @@ -89,11 +87,12 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["required"] = descriptor->is_required() ? "true" : "false"; if (!context->options().opensource_runtime) { (*variables)["enforce_utf8"] = CheckUtf8(descriptor) ? "true" : "false"; @@ -120,8 +119,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["set_has_field_bit_message"] = ""; (*variables)["clear_has_field_bit_message"] = ""; - (*variables)["is_field_present_message"] = - "!" + (*variables)["name"] + "_.isEmpty()"; + variables->insert({"is_field_present_message", + absl::StrCat("!", (*variables)["name"], "_.isEmpty()")}); } (*variables)["get_has_field_bit_from_local"] = @@ -129,7 +128,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["set_has_field_bit_to_local"] = GenerateSetBitToLocal(messageBitIndex); // Annotations often use { and } variables to denote text ranges. - (*variables)["{"] = (*variables)["}"] = ""; + (*variables)["{"] = ""; + (*variables)["}"] = ""; } } // namespace diff --git a/src/google/protobuf/compiler/java/string_field_lite.h b/src/google/protobuf/compiler/java/string_field_lite.h index f35da288f9..fb9a05abcb 100644 --- a/src/google/protobuf/compiler/java/string_field_lite.h +++ b/src/google/protobuf/compiler/java/string_field_lite.h @@ -84,7 +84,7 @@ class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator { protected: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; const int messageBitIndex_; ClassNameResolver* name_resolver_; Context* context_; @@ -133,7 +133,7 @@ class RepeatedImmutableStringFieldLiteGenerator private: const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; ClassNameResolver* name_resolver_; Context* context_; }; diff --git a/src/google/protobuf/compiler/objectivec/enum.cc b/src/google/protobuf/compiler/objectivec/enum.cc index c24b0654c8..650d04d31a 100644 --- a/src/google/protobuf/compiler/objectivec/enum.cc +++ b/src/google/protobuf/compiler/objectivec/enum.cc @@ -32,7 +32,6 @@ #include #include -#include #include #include diff --git a/src/google/protobuf/compiler/objectivec/enum_field.cc b/src/google/protobuf/compiler/objectivec/enum_field.cc index cf0a3df498..061033b97d 100644 --- a/src/google/protobuf/compiler/objectivec/enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/enum_field.cc @@ -30,10 +30,10 @@ #include "google/protobuf/compiler/objectivec/enum_field.h" -#include #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/io/printer.h" @@ -45,22 +45,24 @@ namespace objectivec { namespace { -void SetEnumVariables(const FieldDescriptor* descriptor, - std::map* variables) { - std::string type = EnumName(descriptor->enum_type()); +void SetEnumVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables) { + const std::string type = EnumName(descriptor->enum_type()); + const std::string enum_desc_func = absl::StrCat(type, "_EnumDescriptor"); (*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 // the forward declaration of the enums. if (!descriptor->is_repeated() && (descriptor->file() != descriptor->enum_type()->file())) { - (*variables)["property_type"] = "enum " + type; + (*variables)["property_type"] = absl::StrCat("enum ", type); } - (*variables)["enum_verifier"] = type + "_IsValidValue"; - (*variables)["enum_desc_func"] = type + "_EnumDescriptor"; + (*variables)["enum_verifier"] = absl::StrCat(type, "_IsValidValue"); + (*variables)["enum_desc_func"] = enum_desc_func; (*variables)["dataTypeSpecific_name"] = "enumDescFunc"; - (*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"]; + (*variables)["dataTypeSpecific_value"] = enum_desc_func; const Descriptor* msg_descriptor = descriptor->containing_type(); (*variables)["owning_message_class"] = ClassName(msg_descriptor); diff --git a/src/google/protobuf/compiler/objectivec/extension.cc b/src/google/protobuf/compiler/objectivec/extension.cc index 91f008ec61..d8c179b763 100644 --- a/src/google/protobuf/compiler/objectivec/extension.cc +++ b/src/google/protobuf/compiler/objectivec/extension.cc @@ -31,12 +31,12 @@ #include "google/protobuf/compiler/objectivec/extension.h" #include -#include #include #include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/names.h" @@ -64,7 +64,7 @@ ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name, } void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { - std::map vars; + absl::flat_hash_map vars; vars["method_name"] = method_name_; if (IsRetainedName(method_name_)) { vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -91,7 +91,7 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { void ExtensionGenerator::GenerateStaticVariablesInitialization( io::Printer* printer) { - std::map vars; + absl::flat_hash_map vars; vars["root_class_and_method_name"] = root_class_and_method_name_; const std::string containing_type = ClassName(descriptor_->containing_type()); vars["extended_type"] = ObjCClass(containing_type); diff --git a/src/google/protobuf/compiler/objectivec/field.cc b/src/google/protobuf/compiler/objectivec/field.cc index 6274b9d05e..63d71b3cc6 100644 --- a/src/google/protobuf/compiler/objectivec/field.cc +++ b/src/google/protobuf/compiler/objectivec/field.cc @@ -31,12 +31,12 @@ #include "google/protobuf/compiler/objectivec/field.h" #include -#include #include #include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/objectivec/enum_field.h" #include "google/protobuf/compiler/objectivec/helpers.h" @@ -53,8 +53,9 @@ namespace objectivec { namespace { -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map* variables) { +void SetCommonFieldVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables) { std::string camel_case_name = FieldName(descriptor); std::string raw_field_name; if (descriptor->type() == FieldDescriptor::TYPE_GROUP) { diff --git a/src/google/protobuf/compiler/objectivec/field.h b/src/google/protobuf/compiler/objectivec/field.h index 07643720ec..f52e7c87f7 100644 --- a/src/google/protobuf/compiler/objectivec/field.h +++ b/src/google/protobuf/compiler/objectivec/field.h @@ -31,12 +31,12 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ -#include #include #include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/match.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/io/printer.h" @@ -104,7 +104,7 @@ class FieldGenerator { bool WantsHasProperty() const; const FieldDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; }; class SingleFieldGenerator : public FieldGenerator { diff --git a/src/google/protobuf/compiler/objectivec/file.cc b/src/google/protobuf/compiler/objectivec/file.cc index fd7b644579..be711d57b5 100644 --- a/src/google/protobuf/compiler/objectivec/file.cc +++ b/src/google/protobuf/compiler/objectivec/file.cc @@ -33,13 +33,13 @@ #include #include #include -#include #include #include #include #include #include "google/protobuf/compiler/code_generator.h" +#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/objectivec/enum.h" @@ -626,7 +626,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; + absl::flat_hash_map vars; vars["root_class_name"] = root_class_name_; vars["package"] = file_->package(); vars["objc_prefix"] = FileClassPrefix(file_); diff --git a/src/google/protobuf/compiler/objectivec/import_writer.cc b/src/google/protobuf/compiler/objectivec/import_writer.cc index b276ea5634..ff154a21ec 100644 --- a/src/google/protobuf/compiler/objectivec/import_writer.cc +++ b/src/google/protobuf/compiler/objectivec/import_writer.cc @@ -31,11 +31,11 @@ #include "google/protobuf/compiler/objectivec/import_writer.h" #include -#include #include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/ascii.h" #include "absl/strings/match.h" #include "google/protobuf/compiler/objectivec/line_consumer.h" @@ -55,22 +55,22 @@ namespace { class ProtoFrameworkCollector : public LineConsumer { public: explicit ProtoFrameworkCollector( - std::map* inout_proto_file_to_framework_name) + absl::flat_hash_map* + inout_proto_file_to_framework_name) : map_(inout_proto_file_to_framework_name) {} bool ConsumeLine(absl::string_view line, std::string* out_error) override; private: - std::map* map_; + absl::flat_hash_map* map_; }; bool ProtoFrameworkCollector::ConsumeLine(absl::string_view line, std::string* out_error) { int offset = line.find(':'); if (offset == absl::string_view::npos) { - *out_error = - std::string("Framework/proto file mapping line without colon sign: '") + - std::string(line) + "'."; + *out_error = absl::StrCat( + "Framework/proto file mapping line without colon sign: '", line, "'."); return false; } absl::string_view framework_name = @@ -88,13 +88,11 @@ bool ProtoFrameworkCollector::ConsumeLine(absl::string_view line, absl::string_view proto_file = absl::StripAsciiWhitespace( proto_file_list.substr(start, offset - start)); if (!proto_file.empty()) { - std::map::iterator existing_entry = - map_->find(std::string(proto_file)); + auto existing_entry = map_->find(proto_file); if (existing_entry != map_->end()) { std::cerr << "warning: duplicate proto file reference, replacing " "framework entry for '" - << std::string(proto_file) << "' with '" - << std::string(framework_name) << "' (was '" + << proto_file << "' with '" << framework_name << "' (was '" << existing_entry->second << "')." << std::endl; std::cerr.flush(); } @@ -102,11 +100,11 @@ bool ProtoFrameworkCollector::ConsumeLine(absl::string_view line, if (absl::StrContains(proto_file, ' ')) { std::cerr << "note: framework mapping file had a proto file with a " "space in, hopefully that isn't a missing comma: '" - << std::string(proto_file) << "'" << std::endl; + << proto_file << "'" << std::endl; std::cerr.flush(); } - (*map_)[std::string(proto_file)] = std::string(framework_name); + (*map_)[proto_file] = std::string(framework_name); } start = offset + 1; @@ -147,8 +145,7 @@ void ImportWriter::AddFile(const FileDescriptor* file, ParseFrameworkMappings(); } - std::map::iterator proto_lookup = - proto_file_to_framework_name_.find(file->name()); + auto proto_lookup = proto_file_to_framework_name_.find(file->name()); if (proto_lookup != proto_file_to_framework_name_.end()) { other_framework_imports_.push_back( proto_lookup->second + "/" + FilePathBasename(file) + header_extension); diff --git a/src/google/protobuf/compiler/objectivec/import_writer.h b/src/google/protobuf/compiler/objectivec/import_writer.h index f3fb63b4b7..d36fe34cb2 100644 --- a/src/google/protobuf/compiler/objectivec/import_writer.h +++ b/src/google/protobuf/compiler/objectivec/import_writer.h @@ -35,6 +35,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" @@ -68,7 +69,7 @@ class ImportWriter { 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_; + absl::flat_hash_map proto_file_to_framework_name_; bool need_to_parse_mapping_file_; std::vector protobuf_imports_; diff --git a/src/google/protobuf/compiler/objectivec/map_field.cc b/src/google/protobuf/compiler/objectivec/map_field.cc index 4eff6f3cc4..c5ca768cfc 100644 --- a/src/google/protobuf/compiler/objectivec/map_field.cc +++ b/src/google/protobuf/compiler/objectivec/map_field.cc @@ -30,7 +30,6 @@ #include "google/protobuf/compiler/objectivec/map_field.h" -#include #include #include #include diff --git a/src/google/protobuf/compiler/objectivec/message.cc b/src/google/protobuf/compiler/objectivec/message.cc index 49375713ee..91fd9ed0f2 100644 --- a/src/google/protobuf/compiler/objectivec/message.cc +++ b/src/google/protobuf/compiler/objectivec/message.cc @@ -32,13 +32,13 @@ #include #include -#include #include #include #include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/objectivec/enum.h" @@ -517,13 +517,13 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { printer->Outdent(); } - std::map vars; + absl::flat_hash_map vars; vars["classname"] = class_name_; vars["rootclassname"] = root_classname_; vars["fields"] = has_fields ? "fields" : "NULL"; if (has_fields) { - vars["fields_count"] = - "(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))"; + vars["fields_count"] = absl::StrCat("(uint32_t)(sizeof(fields) / sizeof(", + field_description_type, "))"); } else { vars["fields_count"] = "0"; } diff --git a/src/google/protobuf/compiler/objectivec/message_field.cc b/src/google/protobuf/compiler/objectivec/message_field.cc index 1f174f6ea4..ddf1f19716 100644 --- a/src/google/protobuf/compiler/objectivec/message_field.cc +++ b/src/google/protobuf/compiler/objectivec/message_field.cc @@ -30,10 +30,10 @@ #include "google/protobuf/compiler/objectivec/message_field.h" -#include #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/names.h" @@ -44,8 +44,9 @@ namespace objectivec { namespace { -void SetMessageVariables(const FieldDescriptor* descriptor, - std::map* variables) { +void SetMessageVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables) { const std::string& message_type = ClassName(descriptor->message_type()); const std::string& containing_class = ClassName(descriptor->containing_type()); diff --git a/src/google/protobuf/compiler/objectivec/names.cc b/src/google/protobuf/compiler/objectivec/names.cc index a82f8b2818..2e1c45c4d0 100644 --- a/src/google/protobuf/compiler/objectivec/names.cc +++ b/src/google/protobuf/compiler/objectivec/names.cc @@ -34,13 +34,13 @@ #include #include #include -#include #include #include #include #include #include "google/protobuf/compiler/code_generator.h" +#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" @@ -83,16 +83,16 @@ class SimpleLineCollector : public LineConsumer { class PackageToPrefixesCollector : public LineConsumer { public: - PackageToPrefixesCollector( - const std::string& usage, - std::map* inout_package_to_prefix_map) + PackageToPrefixesCollector(const std::string& usage, + absl::flat_hash_map* + inout_package_to_prefix_map) : usage_(usage), prefix_map_(inout_package_to_prefix_map) {} bool ConsumeLine(absl::string_view line, std::string* out_error) override; private: const std::string usage_; - std::map* prefix_map_; + absl::flat_hash_map* prefix_map_; }; class PrefixModeStorage { @@ -129,7 +129,7 @@ class PrefixModeStorage { private: bool use_package_name_; - std::map package_to_prefix_map_; + absl::flat_hash_map package_to_prefix_map_; std::string package_to_prefix_mappings_path_; std::string exception_path_; std::string forced_prefix_; @@ -154,6 +154,8 @@ PrefixModeStorage::PrefixModeStorage() { } } +constexpr absl::string_view kNoPackagePrefix = "no_package:"; + std::string PrefixModeStorage::prefix_from_proto_package_mappings( const FileDescriptor* file) { if (!file) { @@ -170,9 +172,9 @@ std::string PrefixModeStorage::prefix_from_proto_package_mappings( if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector, &error_str)) { if (error_str.empty()) { - error_str = std::string("protoc:0: warning: Failed to parse") + - std::string(" prefix to proto package mappings file: ") + - package_to_prefix_mappings_path_; + error_str = absl::StrCat("protoc:0: warning: Failed to parse ", + "prefix to proto package mappings file: ", + package_to_prefix_mappings_path_); } std::cerr << error_str << std::endl; std::cerr.flush(); @@ -183,12 +185,10 @@ std::string PrefixModeStorage::prefix_from_proto_package_mappings( const std::string package = file->package(); // For files without packages, the can be registered as "no_package:PATH", // allowing the expected prefixes file. - const std::string no_package_prefix("no_package:"); const std::string lookup_key = - package.empty() ? no_package_prefix + file->name() : package; + package.empty() ? absl::StrCat(kNoPackagePrefix, file->name()) : package; - std::map::const_iterator prefix_lookup = - package_to_prefix_map_.find(lookup_key); + auto prefix_lookup = package_to_prefix_map_.find(lookup_key); if (prefix_lookup != package_to_prefix_map_.end()) { return prefix_lookup->second; @@ -1021,9 +1021,10 @@ bool PackageToPrefixesCollector::ConsumeLine(absl::string_view line, return true; } -bool LoadExpectedPackagePrefixes(const std::string& expected_prefixes_path, - std::map* prefix_map, - std::string* out_error) { +bool LoadExpectedPackagePrefixes( + const std::string& expected_prefixes_path, + absl::flat_hash_map* prefix_map, + std::string* out_error) { if (expected_prefixes_path.empty()) { return true; } @@ -1034,7 +1035,8 @@ bool LoadExpectedPackagePrefixes(const std::string& expected_prefixes_path, bool ValidateObjCClassPrefix( const FileDescriptor* file, const std::string& expected_prefixes_path, - const std::map& expected_package_prefixes, + const absl::flat_hash_map& + expected_package_prefixes, bool prefixes_must_be_registered, bool require_prefixes, std::string* out_error) { // Reminder: An explicit prefix option of "" is valid in case the default @@ -1048,17 +1050,15 @@ bool ValidateObjCClassPrefix( const std::string package = file->package(); // For files without packages, the can be registered as "no_package:PATH", // allowing the expected prefixes file. - const std::string no_package_prefix("no_package:"); const std::string lookup_key = - package.empty() ? no_package_prefix + file->name() : package; + package.empty() ? absl::StrCat(kNoPackagePrefix, file->name()) : package; // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for warnings. // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). - std::map::const_iterator package_match = - expected_package_prefixes.find(lookup_key); + auto package_match = expected_package_prefixes.find(lookup_key); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... if (has_prefix && package_match->second == prefix) { @@ -1095,14 +1095,13 @@ bool ValidateObjCClassPrefix( if (!prefix.empty() && have_expected_prefix_file) { // For a non empty prefix, look for any other package that uses the prefix. std::string other_package_for_prefix; - for (std::map::const_iterator i = - expected_package_prefixes.begin(); + for (auto i = expected_package_prefixes.begin(); i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; // Stop on the first real package listing, if it was a no_package file // specific entry, keep looking to try and find a package one. - if (!absl::StartsWith(other_package_for_prefix, no_package_prefix)) { + if (!absl::StartsWith(other_package_for_prefix, kNoPackagePrefix)) { break; } } @@ -1115,10 +1114,10 @@ bool ValidateObjCClassPrefix( *out_error = "error: Found 'option objc_class_prefix = \"" + prefix + "\";' in '" + file->name() + "'; that prefix is already used for "; - if (absl::StartsWith(other_package_for_prefix, no_package_prefix)) { + if (absl::StartsWith(other_package_for_prefix, kNoPackagePrefix)) { absl::StrAppend( out_error, "file '", - absl::StripPrefix(other_package_for_prefix, no_package_prefix), + absl::StripPrefix(other_package_for_prefix, kNoPackagePrefix), "'."); } else { absl::StrAppend(out_error, "'package ", @@ -1213,7 +1212,7 @@ bool ValidateObjCClassPrefixes(const std::vector& files, } // Load the expected package prefixes, if available, to validate against. - std::map expected_package_prefixes; + absl::flat_hash_map expected_package_prefixes; if (!LoadExpectedPackagePrefixes(validation_options.expected_prefixes_path, &expected_package_prefixes, out_error)) { return false; diff --git a/src/google/protobuf/compiler/objectivec/oneof.cc b/src/google/protobuf/compiler/objectivec/oneof.cc index 94fee5351f..4dfaf98171 100644 --- a/src/google/protobuf/compiler/objectivec/oneof.cc +++ b/src/google/protobuf/compiler/objectivec/oneof.cc @@ -30,7 +30,6 @@ #include "google/protobuf/compiler/objectivec/oneof.h" -#include #include #include "absl/strings/str_cat.h" diff --git a/src/google/protobuf/compiler/objectivec/oneof.h b/src/google/protobuf/compiler/objectivec/oneof.h index ea79251613..27a1ecbc07 100644 --- a/src/google/protobuf/compiler/objectivec/oneof.h +++ b/src/google/protobuf/compiler/objectivec/oneof.h @@ -31,11 +31,11 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ -#include #include #include #include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/io/printer.h" @@ -67,7 +67,7 @@ class OneofGenerator { private: const OneofDescriptor* descriptor_; - std::map variables_; + absl::flat_hash_map variables_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/primitive_field.cc b/src/google/protobuf/compiler/objectivec/primitive_field.cc index d116ec0462..fa89d2cfa2 100644 --- a/src/google/protobuf/compiler/objectivec/primitive_field.cc +++ b/src/google/protobuf/compiler/objectivec/primitive_field.cc @@ -30,9 +30,9 @@ #include "google/protobuf/compiler/objectivec/primitive_field.h" -#include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/io/printer.h" @@ -111,8 +111,9 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) { return nullptr; } -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - std::map* variables) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, + absl::flat_hash_map* variables) { std::string primitive_name = PrimitiveTypeName(descriptor); (*variables)["type"] = primitive_name; (*variables)["storage_type"] = primitive_name; diff --git a/src/google/protobuf/compiler/python/generator.cc b/src/google/protobuf/compiler/python/generator.cc index 0f51a7d2a3..f8a33cc6b4 100644 --- a/src/google/protobuf/compiler/python/generator.cc +++ b/src/google/protobuf/compiler/python/generator.cc @@ -46,7 +46,6 @@ #include #include -#include #include #include #include @@ -54,11 +53,13 @@ #include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/common.h" +#include "absl/container/flat_hash_map.h" #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_replace.h" +#include "absl/strings/string_view.h" #include "absl/strings/strip.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/python/helpers.h" @@ -433,7 +434,7 @@ void Generator::PrintImports() const { // Prints the single file descriptor for this file. void Generator::PrintFileDescriptor() const { - std::map m; + absl::flat_hash_map m; m["descriptor_name"] = kDescriptorKey; m["name"] = file_->name(); m["package"] = file_->package(); @@ -508,7 +509,7 @@ void Generator::PrintAllNestedEnumsInFile() const { // enum name to a Python EnumDescriptor object equivalent to // enum_descriptor. void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { - std::map m; + absl::flat_hash_map m; std::string module_level_descriptor_name = ModuleLevelDescriptorName(enum_descriptor); m["descriptor_name"] = module_level_descriptor_name; @@ -583,7 +584,7 @@ void Generator::PrintServices() const { void Generator::PrintServiceDescriptor( const ServiceDescriptor& descriptor) const { - std::map m; + absl::flat_hash_map m; m["service_name"] = ModuleLevelServiceDescriptorName(descriptor); m["name"] = descriptor.name(); m["file"] = kDescriptorKey; @@ -633,7 +634,7 @@ void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { // // Mutually recursive with PrintNestedDescriptors(). void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { - std::map m; + absl::flat_hash_map m; m["name"] = message_descriptor.name(); m["full_name"] = message_descriptor.full_name(); m["file"] = kDescriptorKey; @@ -784,7 +785,7 @@ void Generator::PrintMessage(const Descriptor& message_descriptor, to_register->push_back(qualified_name); PrintNestedMessages(message_descriptor, qualified_name, to_register); - std::map m; + absl::flat_hash_map m; m["descriptor_key"] = kDescriptorKey; m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n"); @@ -839,7 +840,7 @@ void Generator::FixForeignFieldsInDescriptor( FixContainingTypeInDescriptor(enum_descriptor, &descriptor); } for (int i = 0; i < descriptor.oneof_decl_count(); ++i) { - std::map m; + absl::flat_hash_map m; const OneofDescriptor* oneof = descriptor.oneof_decl(i); m["descriptor_name"] = ModuleLevelDescriptorName(descriptor); m["oneof_name"] = oneof->name(); @@ -858,7 +859,7 @@ void Generator::FixForeignFieldsInDescriptor( } void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { - std::map m; + absl::flat_hash_map m; m["descriptor_name"] = kDescriptorKey; m["message_name"] = descriptor.name(); m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor); @@ -870,7 +871,7 @@ void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { void Generator::AddServiceToFileDescriptor( const ServiceDescriptor& descriptor) const { - std::map m; + absl::flat_hash_map m; m["descriptor_name"] = kDescriptorKey; m["service_name"] = descriptor.name(); m["service_descriptor_name"] = ModuleLevelServiceDescriptorName(descriptor); @@ -882,7 +883,7 @@ void Generator::AddServiceToFileDescriptor( void Generator::AddEnumToFileDescriptor( const EnumDescriptor& descriptor) const { - std::map m; + absl::flat_hash_map m; m["descriptor_name"] = kDescriptorKey; m["enum_name"] = descriptor.name(); m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor); @@ -894,7 +895,7 @@ void Generator::AddEnumToFileDescriptor( void Generator::AddExtensionToFileDescriptor( const FieldDescriptor& descriptor) const { - std::map m; + absl::flat_hash_map m; m["descriptor_name"] = kDescriptorKey; m["field_name"] = descriptor.name(); m["resolved_name"] = ResolveKeyword(descriptor.name()); @@ -918,7 +919,7 @@ void Generator::FixForeignFieldsInField( const std::string& python_dict_name) const { const std::string field_referencing_expression = FieldReferencingExpression(containing_type, field, python_dict_name); - std::map m; + absl::flat_hash_map m; m["field_ref"] = field_referencing_expression; const Descriptor* foreign_message_type = field.message_type(); if (foreign_message_type) { @@ -1014,7 +1015,7 @@ void Generator::FixForeignFieldsInExtension( const FieldDescriptor& extension_field) const { GOOGLE_CHECK(extension_field.is_extension()); - std::map m; + absl::flat_hash_map m; // Confusingly, for FieldDescriptors that happen to be extensions, // containing_type() means "extended type." // On the other hand, extension_scope() will give us what we normally @@ -1046,7 +1047,7 @@ void Generator::PrintEnumValueDescriptor( // More circular references. ::sigh:: std::string options_string; descriptor.options().SerializeToString(&options_string); - std::map m; + absl::flat_hash_map m; m["name"] = descriptor.name(); m["index"] = absl::StrCat(descriptor.index()); m["number"] = absl::StrCat(descriptor.number()); @@ -1074,7 +1075,7 @@ void Generator::PrintFieldDescriptor(const FieldDescriptor& field, bool is_extension) const { std::string options_string; field.options().SerializeToString(&options_string); - std::map m; + absl::flat_hash_map m; m["name"] = field.name(); m["full_name"] = field.full_name(); m["index"] = absl::StrCat(field.index()); diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc index b09ceb2f69..bc90a6436c 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.cc +++ b/src/google/protobuf/compiler/python/pyi_generator.cc @@ -154,17 +154,19 @@ void PyiGenerator::PrintImportForDescriptor( const FileDescriptor& desc, std::set* seen_aliases) const { const std::string& filename = desc.name(); - std::string module_name = StrippedModuleName(filename); + std::string module_name_owned = StrippedModuleName(filename); + absl::string_view module_name(module_name_owned); size_t last_dot_pos = module_name.rfind('.'); std::string import_statement; if (last_dot_pos == std::string::npos) { - import_statement = "import " + module_name; + import_statement = absl::StrCat("import ", module_name); } else { - import_statement = "from " + module_name.substr(0, last_dot_pos) + - " import " + module_name.substr(last_dot_pos + 1); + import_statement = + absl::StrCat("from ", module_name.substr(0, last_dot_pos), " import ", + module_name.substr(last_dot_pos + 1)); module_name = module_name.substr(last_dot_pos + 1); } - std::string alias = "_" + module_name; + std::string alias = absl::StrCat("_", module_name); // Generate a unique alias by adding _1 suffixes until we get an unused alias. while (seen_aliases->find(alias) != seen_aliases->end()) { alias = alias + "_1"; diff --git a/src/google/protobuf/compiler/python/pyi_generator.h b/src/google/protobuf/compiler/python/pyi_generator.h index 7f1e5d839d..bd7e71f90f 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.h +++ b/src/google/protobuf/compiler/python/pyi_generator.h @@ -35,10 +35,10 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ #define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ -#include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/synchronization/mutex.h" #include "google/protobuf/compiler/code_generator.h" @@ -106,7 +106,7 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera mutable io::Printer* printer_; // Set in Generate(). Under mutex_. // import_map will be a mapping from filename to module alias, e.g. // "google3/foo/bar.py" -> "_bar" - mutable std::map import_map_; + mutable absl::flat_hash_map import_map_; }; } // namespace python diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc index acedbd46e1..289f5bfdba 100644 --- a/src/google/protobuf/io/printer.cc +++ b/src/google/protobuf/io/printer.cc @@ -469,7 +469,7 @@ void Printer::PrintImpl(absl::string_view format, LookupResult sub; absl::optional same_name_record; - if (opts.allow_digit_substitions && absl::ascii_isdigit(var[0])) { + if (opts.allow_digit_substitutions && absl::ascii_isdigit(var[0])) { PrintRaw(next_chunk); if (!Validate(var.size() == 1u, opts, "expected single-digit variable")) { diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h index 450e90ffc8..764e335f1f 100644 --- a/src/google/protobuf/io/printer.h +++ b/src/google/protobuf/io/printer.h @@ -479,6 +479,27 @@ class PROTOBUF_EXPORT Printer { } }; + // Provide a helper to use heterogeneous lookup when it's available. + template + using void_t = void; + template + struct has_heterogeneous_lookup : std::false_type {}; + template + struct has_heterogeneous_lookup().find( + std::declval()))>> + : std::true_type {}; + + template ::value, int> = 0> + static absl::string_view ToStringKey(absl::string_view x) { + return x; + } + template ::value, int> = 0> + static std::string ToStringKey(absl::string_view x) { + return std::string(x); + } + public: static constexpr char kDefaultVariableDelimiter = '$'; static constexpr absl::string_view kProtocCodegenTrace = @@ -538,7 +559,7 @@ class PROTOBUF_EXPORT Printer { template auto WithVars(const Map* vars) { var_lookups_.emplace_back([vars](absl::string_view var) -> LookupResult { - auto it = vars->find(std::string(var)); + auto it = vars->find(ToStringKey(var)); if (it == vars->end()) { return absl::nullopt; } @@ -558,7 +579,7 @@ class PROTOBUF_EXPORT Printer { auto WithVars(Map&& vars) { var_lookups_.emplace_back([vars = std::forward(vars)]( absl::string_view var) -> LookupResult { - auto it = vars.find(std::string(var)); + auto it = vars.find(ToStringKey(var)); if (it == vars.end()) { return absl::nullopt; } @@ -585,7 +606,7 @@ class PROTOBUF_EXPORT Printer { auto WithAnnotations(const Map* vars) { annotation_lookups_.emplace_back( [vars](absl::string_view var) -> absl::optional { - auto it = vars->find(std::string(var)); + auto it = vars->find(ToStringKey(var)); if (it == vars->end()) { return absl::nullopt; } @@ -605,7 +626,7 @@ class PROTOBUF_EXPORT Printer { annotation_lookups_.emplace_back( [vars = std::forward(vars)]( absl::string_view var) -> absl::optional { - auto it = vars.find(std::string(var)); + auto it = vars.find(ToStringKey(var)); if (it == vars.end()) { return absl::nullopt; } @@ -665,7 +686,7 @@ class PROTOBUF_EXPORT Printer { PrintOptions opts; opts.checks_are_debug_only = true; opts.use_substitution_map = true; - opts.allow_digit_substitions = false; + opts.allow_digit_substitutions = false; auto pop = WithVars(&vars); PrintImpl(text, {}, opts); @@ -678,10 +699,10 @@ class PROTOBUF_EXPORT Printer { // Include an extra arg, since a zero-length array is ill-formed, and // MSVC complains. absl::string_view vars[] = {args..., ""}; - absl::flat_hash_map map; + absl::flat_hash_map map; map.reserve(sizeof...(args) / 2); for (size_t i = 0; i < sizeof...(args); i += 2) { - map.emplace(std::string(vars[i]), std::string(vars[i + 1])); + map.emplace(vars[i], vars[i + 1]); } Print(map, text); @@ -737,8 +758,8 @@ class PROTOBUF_EXPORT Printer { // FormatInternal is a helper function not meant to use directly, use // compiler::cpp::Formatter instead. - void FormatInternal(absl::Span args, - const std::map& vars, + template > + void FormatInternal(absl::Span args, const Map& vars, absl::string_view format) { PrintOptions opts; opts.use_curly_brace_substitutions = true; @@ -764,7 +785,7 @@ class PROTOBUF_EXPORT Printer { bool use_curly_brace_substitutions = false; // If set, the $n$ forms will be substituted, pulling from the `args` // argument to PrintImpl(). - bool allow_digit_substitions = true; + bool allow_digit_substitutions = true; // If set, when a variable substitution with spaces in it, such as $ var$, // is encountered, the spaces are stripped, so that it is as if it was // $var$. If $var$ substitutes to a non-empty string, the removed spaces are