diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index c1121fda29..f7c9bdf667 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -34,11 +34,14 @@ #include "google/protobuf/compiler/code_generator.h" +#include + #include "google/protobuf/compiler/plugin.pb.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/stubs/logging.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "absl/strings/strip.h" namespace google { @@ -106,26 +109,24 @@ void GeneratorContext::GetCompilerVersion(Version* version) const { // Parses a set of comma-delimited name/value pairs. void ParseGeneratorParameter( - const std::string& text, + absl::string_view text, std::vector >* output) { - std::vector parts = absl::StrSplit(text, ",", absl::SkipEmpty()); - - for (int i = 0; i < parts.size(); i++) { - std::string::size_type equals_pos = parts[i].find_first_of('='); - std::pair value; - if (equals_pos == std::string::npos) { - value.first = parts[i]; - value.second = ""; + std::vector parts = + absl::StrSplit(text, ',', absl::SkipEmpty()); + + for (absl::string_view part : parts) { + auto equals_pos = part.find_first_of('='); + if (equals_pos == absl::string_view::npos) { + output->emplace_back(part, ""); } else { - value.first = parts[i].substr(0, equals_pos); - value.second = parts[i].substr(equals_pos + 1); + output->emplace_back(part.substr(0, equals_pos), + part.substr(equals_pos + 1)); } - output->push_back(value); } } // Strips ".proto" or ".protodevel" from the end of a filename. -std::string StripProto(const std::string& filename) { +std::string StripProto(absl::string_view filename) { if (absl::EndsWith(filename, ".protodevel")) { return std::string(absl::StripSuffix(filename, ".protodevel")); } else { diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 55b510ab69..c563f1c534 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -42,6 +42,7 @@ #include #include +#include "absl/strings/string_view.h" #include "google/protobuf/port.h" // Must be included last. @@ -192,10 +193,10 @@ typedef GeneratorContext OutputDirectory; // parses to the pairs: // ("foo", "bar"), ("baz", ""), ("moo", "corge") PROTOC_EXPORT void ParseGeneratorParameter( - const std::string&, std::vector >*); + absl::string_view, std::vector >*); // Strips ".proto" or ".protodevel" from the end of a filename. -PROTOC_EXPORT std::string StripProto(const std::string& filename); +PROTOC_EXPORT std::string StripProto(absl::string_view filename); } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/BUILD.bazel b/src/google/protobuf/compiler/cpp/BUILD.bazel index dd59dd2d54..e463346688 100644 --- a/src/google/protobuf/compiler/cpp/BUILD.bazel +++ b/src/google/protobuf/compiler/cpp/BUILD.bazel @@ -17,6 +17,7 @@ cc_library( ":names_internal", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", + "@com_google_absl//absl/strings", ], ) @@ -36,6 +37,7 @@ cc_library( deps = [ "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", + "@com_google_absl//absl/strings", ], ) diff --git a/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc index 3a876666f6..f87856ef8d 100644 --- a/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc @@ -97,9 +97,9 @@ class MockGeneratorContext : public GeneratorContext { std::string expected_contents = *it->second; std::string actual_contents; - GOOGLE_ABSL_CHECK_OK( - File::GetContents(TestUtil::TestSourceDir() + "/" + physical_filename, - &actual_contents, true)) + GOOGLE_ABSL_CHECK_OK(File::GetContents( + absl::StrCat(TestUtil::TestSourceDir(), "/", physical_filename), + &actual_contents, true)) << physical_filename; #ifdef WRITE_FILES // Define to debug mismatched files. @@ -174,8 +174,10 @@ TEST(BootstrapTest, GeneratedFilesMatch) { FindWithDefault(vpath_map, file_parameter[0], file_parameter[0]); std::string rpath = FindWithDefault(rpath_map, file_parameter[0], file_parameter[0]); - context.ExpectFileMatches(vpath + ".pb.cc", rpath + ".pb.cc"); - context.ExpectFileMatches(vpath + ".pb.h", rpath + ".pb.h"); + context.ExpectFileMatches(absl::StrCat(vpath, ".pb.cc"), + absl::StrCat(rpath, ".pb.cc")); + context.ExpectFileMatches(absl::StrCat(vpath, ".pb.h"), + absl::StrCat(rpath, ".pb.h")); } } @@ -189,7 +191,7 @@ TEST(BootstrapTest, OptionNotExist) { ASSERT_FALSE(generator.Generate( pool.FindFileByName("google/protobuf/descriptor.proto"), parameter, generator_context, &error)); - EXPECT_EQ(error, "Unknown generator option: " + parameter); + EXPECT_EQ(error, absl::StrCat("Unknown generator option: ", parameter)); } } // namespace diff --git a/src/google/protobuf/compiler/cpp/extension.cc b/src/google/protobuf/compiler/cpp/extension.cc index 3b43ccb798..a33fe91457 100644 --- a/src/google/protobuf/compiler/cpp/extension.cc +++ b/src/google/protobuf/compiler/cpp/extension.cc @@ -87,8 +87,12 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, absl::StrCat(static_cast(descriptor_->type())); variables_["packed"] = descriptor_->is_packed() ? "true" : "false"; - std::string scope = - IsScoped() ? ClassName(descriptor_->extension_scope(), false) + "::" : ""; + std::string scope; + if (IsScoped()) { + scope = + absl::StrCat(ClassName(descriptor_->extension_scope(), false), "::"); + } + variables_["scope"] = scope; variables_["scoped_name"] = ExtensionName(descriptor_); variables_["number"] = absl::StrCat(descriptor_->number()); @@ -123,7 +127,7 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const { if (!IsScoped()) { qualifier = "extern"; if (!options_.dllexport_decl.empty()) { - qualifier = options_.dllexport_decl + " " + qualifier; + qualifier = absl::StrCat(options_.dllexport_decl, " ", qualifier); } } else { qualifier = "static"; @@ -164,8 +168,8 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { } else if (descriptor_->message_type()) { // We have to initialize the default instance for extensions at registration // time. - default_str = - FieldMessageTypeName(descriptor_, options_) + "::default_instance()"; + default_str = absl::StrCat(FieldMessageTypeName(descriptor_, options_), + "::default_instance()"); } else { default_str = DefaultValue(options_, descriptor_); } diff --git a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc index b684b2dd0a..73d3709f95 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc @@ -65,10 +65,10 @@ void SetMessageVariables( default: (*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type()); } - (*variables)["key_wire_type"] = - "TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type())); - (*variables)["val_wire_type"] = - "TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type())); + (*variables)["key_wire_type"] = absl::StrCat( + "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type()))); + (*variables)["val_wire_type"] = absl::StrCat( + "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type()))); (*variables)["map_classname"] = ClassName(descriptor->message_type(), false); (*variables)["number"] = absl::StrCat(descriptor->number()); (*variables)["tag"] = absl::StrCat(internal::WireFormat::MakeTag(descriptor)); diff --git a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc index 1e6bf4c23a..afbef124c9 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -49,13 +49,13 @@ namespace protobuf { namespace compiler { namespace cpp { namespace { -std::string ReinterpretCast(const std::string& type, - const std::string& expression, +std::string ReinterpretCast(absl::string_view type, + absl::string_view expression, bool implicit_weak_field) { if (implicit_weak_field) { - return "reinterpret_cast< " + type + " >(" + expression + ")"; + return absl::StrCat("reinterpret_cast< ", type, " >(", expression, ")"); } else { - return expression; + return std::string(expression); } } diff --git a/src/google/protobuf/compiler/cpp/generator.cc b/src/google/protobuf/compiler/cpp/generator.cc index ed39c3d1be..fc2dc80266 100644 --- a/src/google/protobuf/compiler/cpp/generator.cc +++ b/src/google/protobuf/compiler/cpp/generator.cc @@ -187,12 +187,12 @@ bool CppGenerator::Generate(const FileDescriptor* file, } else if (value == "always") { file_options.tctable_mode = Options::kTCTableAlways; } else { - *error = - "Unknown value for experimental_tail_call_table_mode: " + value; + *error = absl::StrCat( + "Unknown value for experimental_tail_call_table_mode: ", value); return false; } } else { - *error = "Unknown generator option: " + key; + *error = absl::StrCat("Unknown generator option: ", key); return false; } } diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index b8a55fe7ff..fce4e80724 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -194,7 +194,7 @@ const absl::flat_hash_set& Keywords() { return *keywords; } -std::string IntTypeName(const Options& options, const std::string& type) { +std::string IntTypeName(const Options& options, absl::string_view type) { return absl::StrCat("::", type, "_t"); } @@ -288,7 +288,7 @@ void SetUnknownFieldsVariable( } } -std::string UnderscoresToCamelCase(const std::string& input, +std::string UnderscoresToCamelCase(absl::string_view input, bool cap_next_letter) { std::string result; // Note: I distrust ctype.h due to locales. @@ -399,9 +399,9 @@ bool HasTrivialSwap(const FieldDescriptor* field, const Options& options, std::string ClassName(const Descriptor* descriptor) { const Descriptor* parent = descriptor->containing_type(); std::string res; - if (parent) res += ClassName(parent) + "_"; - res += descriptor->name(); - if (IsMapEntryMessage(descriptor)) res += "_DoNotUse"; + if (parent) absl::StrAppend(&res, ClassName(parent), "_"); + absl::StrAppend(&res, descriptor->name()); + if (IsMapEntryMessage(descriptor)) absl::StrAppend(&res, "_DoNotUse"); return ResolveKeyword(res); } @@ -409,8 +409,8 @@ std::string ClassName(const EnumDescriptor* enum_descriptor) { if (enum_descriptor->containing_type() == nullptr) { return ResolveKeyword(enum_descriptor->name()); } else { - return ClassName(enum_descriptor->containing_type()) + "_" + - enum_descriptor->name(); + return absl::StrCat(ClassName(enum_descriptor->containing_type()), "_", + enum_descriptor->name()); } } @@ -447,9 +447,9 @@ std::string QualifiedExtensionName(const FieldDescriptor* d) { return QualifiedExtensionName(d, Options()); } -std::string Namespace(const std::string& package) { +std::string Namespace(absl::string_view package) { if (package.empty()) return ""; - return "::" + DotsToColons(package); + return absl::StrCat("::", DotsToColons(package)); } std::string Namespace(const FileDescriptor* d) { return Namespace(d, {}); } @@ -491,13 +491,13 @@ std::string DefaultInstanceType(const Descriptor* descriptor, std::string DefaultInstanceName(const Descriptor* descriptor, const Options& /*options*/, bool split) { - return "_" + ClassName(descriptor, false) + (split ? "__Impl_Split" : "") + - "_default_instance_"; + return absl::StrCat("_", ClassName(descriptor, false), + (split ? "__Impl_Split" : ""), "_default_instance_"); } std::string DefaultInstancePtr(const Descriptor* descriptor, const Options& options, bool split) { - return DefaultInstanceName(descriptor, options, split) + "ptr_"; + return absl::StrCat(DefaultInstanceName(descriptor, options, split), "ptr_"); } std::string QualifiedDefaultInstanceName(const Descriptor* descriptor, @@ -509,7 +509,8 @@ std::string QualifiedDefaultInstanceName(const Descriptor* descriptor, std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor, const Options& options, bool split) { - return QualifiedDefaultInstanceName(descriptor, options, split) + "ptr_"; + return absl::StrCat(QualifiedDefaultInstanceName(descriptor, options, split), + "ptr_"); } std::string DescriptorTableName(const FileDescriptor* file, @@ -524,20 +525,21 @@ std::string FileDllExport(const FileDescriptor* file, const Options& options) { std::string SuperClassName(const Descriptor* descriptor, const Options& options) { if (!HasDescriptorMethods(descriptor->file(), options)) { - return "::" + ProtobufNamespace(options) + "::MessageLite"; + return absl::StrCat("::", ProtobufNamespace(options), "::MessageLite"); } auto simple_base = SimpleBaseClass(descriptor, options); if (simple_base.empty()) { - return "::" + ProtobufNamespace(options) + "::Message"; + return absl::StrCat("::", ProtobufNamespace(options), "::Message"); } - return "::" + ProtobufNamespace(options) + "::internal::" + simple_base; + return absl::StrCat("::", ProtobufNamespace(options), + "::internal::", simple_base); } -std::string ResolveKeyword(const std::string& name) { +std::string ResolveKeyword(absl::string_view name) { if (Keywords().count(name) > 0) { - return name + "_"; + return absl::StrCat(name, "_"); } - return name; + return std::string(name); } std::string FieldName(const FieldDescriptor* field) { @@ -565,7 +567,7 @@ std::string FieldMemberName(const FieldDescriptor* field, bool split) { std::string OneofCaseConstantName(const FieldDescriptor* field) { GOOGLE_ABSL_DCHECK(field->containing_oneof()); std::string field_name = UnderscoresToCamelCase(field->name(), true); - return "k" + field_name; + return absl::StrCat("k", field_name); } std::string QualifiedOneofCaseConstantName(const FieldDescriptor* field) { @@ -609,7 +611,7 @@ int EstimateAlignmentSize(const FieldDescriptor* field) { std::string FieldConstantName(const FieldDescriptor* field) { std::string field_name = UnderscoresToCamelCase(field->name(), true); - std::string result = "k" + field_name + "FieldNumber"; + std::string result = absl::StrCat("k", field_name, "FieldNumber"); if (!field->is_extension() && field->containing_type()->FindFieldByCamelcaseName( @@ -617,7 +619,7 @@ std::string FieldConstantName(const FieldDescriptor* field) { // This field's camelcase name is not unique. As a hack, add the field // number to the constant name. This makes the constant rather useless, // but what can we do? - result += "_" + absl::StrCat(field->number()); + absl::StrAppend(&result, "_", field->number()); } return result; @@ -630,7 +632,7 @@ std::string FieldMessageTypeName(const FieldDescriptor* field, return QualifiedClassName(field->message_type(), options); } -std::string StripProto(const std::string& filename) { +std::string StripProto(absl::string_view filename) { /* * TODO(github/georgthegreat) remove this proxy method * once Google's internal codebase will become ready @@ -781,7 +783,7 @@ std::string DefaultValue(const Options& options, const FieldDescriptor* field) { case FieldDescriptor::CPPTYPE_INT32: return Int32ToString(field->default_value_int32()); case FieldDescriptor::CPPTYPE_UINT32: - return absl::StrCat(field->default_value_uint32()) + "u"; + return absl::StrCat(field->default_value_uint32(), "u"); case FieldDescriptor::CPPTYPE_INT64: return Int64ToString(field->default_value_int64()); case FieldDescriptor::CPPTYPE_UINT64: @@ -826,12 +828,12 @@ std::string DefaultValue(const Options& options, const FieldDescriptor* field) { "static_cast< $0 >($1)", ClassName(field->enum_type(), true), Int32ToString(field->default_value_enum()->number())); case FieldDescriptor::CPPTYPE_STRING: - return "\"" + - EscapeTrigraphs(absl::CEscape(field->default_value_string())) + - "\""; + return absl::StrCat( + "\"", EscapeTrigraphs(absl::CEscape(field->default_value_string())), + "\""); case FieldDescriptor::CPPTYPE_MESSAGE: - return "*" + FieldMessageTypeName(field, options) + - "::internal_default_instance()"; + return absl::StrCat("*", FieldMessageTypeName(field, options), + "::internal_default_instance()"); } // Can't actually get here; make compiler happy. (We could add a default // case above but then we wouldn't get the nice compiler warning when a @@ -841,7 +843,7 @@ std::string DefaultValue(const Options& options, const FieldDescriptor* field) { } // Convert a file name into a valid identifier. -std::string FilenameIdentifier(const std::string& filename) { +std::string FilenameIdentifier(absl::string_view filename) { std::string result; for (int i = 0; i < filename.size(); i++) { if (absl::ascii_isalnum(filename[i])) { @@ -856,14 +858,14 @@ std::string FilenameIdentifier(const std::string& filename) { return result; } -std::string UniqueName(const std::string& name, const std::string& filename, +std::string UniqueName(absl::string_view name, absl::string_view filename, const Options& options) { - return name + "_" + FilenameIdentifier(filename); + return absl::StrCat(name, "_", FilenameIdentifier(filename)); } // Return the qualified C++ name for a file level symbol. std::string QualifiedFileLevelSymbol(const FileDescriptor* file, - const std::string& name, + absl::string_view name, const Options& options) { if (file->package().empty()) { return absl::StrCat("::", name); @@ -879,11 +881,11 @@ std::string EscapeTrigraphs(absl::string_view to_escape) { // Escaped function name to eliminate naming conflict. std::string SafeFunctionName(const Descriptor* descriptor, const FieldDescriptor* field, - const std::string& prefix) { + absl::string_view prefix) { // Do not use FieldName() since it will escape keywords. std::string name = field->name(); absl::AsciiStrToLower(&name); - std::string function_name = prefix + name; + std::string function_name = absl::StrCat(prefix, name); if (descriptor->FindFieldByName(function_name)) { // Single underscore will also make it conflicting with the private data // member. We use double underscore to escape function names. @@ -1406,7 +1408,7 @@ void ListAllTypesForServices(const FileDescriptor* fd, } } -bool GetBootstrapBasename(const Options& options, const std::string& basename, +bool GetBootstrapBasename(const Options& options, absl::string_view basename, std::string* bootstrap_basename) { if (options.opensource_runtime) { return false; @@ -1427,7 +1429,7 @@ bool GetBootstrapBasename(const Options& options, const std::string& basename, }; auto iter = bootstrap_mapping->find(basename); if (iter == bootstrap_mapping->end()) { - *bootstrap_basename = basename; + *bootstrap_basename = std::string(basename); return false; } else { *bootstrap_basename = iter->second; diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index afb12eb793..78875ec52f 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -104,7 +104,7 @@ void SetUnknownFieldsVariable( const Descriptor* descriptor, const Options& options, absl::flat_hash_map* variables); -bool GetBootstrapBasename(const Options& options, const std::string& basename, +bool GetBootstrapBasename(const Options& options, absl::string_view basename, std::string* bootstrap_basename); bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context, bool bootstrap_flag, std::string* basename); @@ -208,7 +208,7 @@ std::string SuperClassName(const Descriptor* descriptor, const Options& options); // Adds an underscore if necessary to prevent conflicting with a keyword. -std::string ResolveKeyword(const std::string& name); +std::string ResolveKeyword(absl::string_view name); // Get the (unqualified) name that should be used for this field in C++ code. // The name is coerced to lower-case to emulate proto1 behavior. People @@ -260,25 +260,25 @@ std::string DefaultValue(const Options& options, const FieldDescriptor* field); std::string DefaultValue(const FieldDescriptor* field); // Convert a file name into a valid identifier. -std::string FilenameIdentifier(const std::string& filename); +std::string FilenameIdentifier(absl::string_view filename); // For each .proto file generates a unique name. To prevent collisions of // symbols in the global namespace -std::string UniqueName(const std::string& name, const std::string& filename, +std::string UniqueName(absl::string_view name, absl::string_view filename, const Options& options); -inline std::string UniqueName(const std::string& name, const FileDescriptor* d, +inline std::string UniqueName(absl::string_view name, const FileDescriptor* d, const Options& options) { return UniqueName(name, d->name(), options); } -inline std::string UniqueName(const std::string& name, const Descriptor* d, +inline std::string UniqueName(absl::string_view name, const Descriptor* d, const Options& options) { return UniqueName(name, d->file(), options); } -inline std::string UniqueName(const std::string& name, const EnumDescriptor* d, +inline std::string UniqueName(absl::string_view name, const EnumDescriptor* d, const Options& options) { return UniqueName(name, d->file(), options); } -inline std::string UniqueName(const std::string& name, +inline std::string UniqueName(absl::string_view name, const ServiceDescriptor* d, const Options& options) { return UniqueName(name, d->file(), options); @@ -291,29 +291,27 @@ inline Options InternalRuntimeOptions() { options.opensource_runtime = false; return options; } -inline std::string UniqueName(const std::string& name, - const std::string& filename) { +inline std::string UniqueName(absl::string_view name, + absl::string_view filename) { return UniqueName(name, filename, InternalRuntimeOptions()); } -inline std::string UniqueName(const std::string& name, - const FileDescriptor* d) { +inline std::string UniqueName(absl::string_view name, const FileDescriptor* d) { return UniqueName(name, d->name(), InternalRuntimeOptions()); } -inline std::string UniqueName(const std::string& name, const Descriptor* d) { +inline std::string UniqueName(absl::string_view name, const Descriptor* d) { return UniqueName(name, d->file(), InternalRuntimeOptions()); } -inline std::string UniqueName(const std::string& name, - const EnumDescriptor* d) { +inline std::string UniqueName(absl::string_view name, const EnumDescriptor* d) { return UniqueName(name, d->file(), InternalRuntimeOptions()); } -inline std::string UniqueName(const std::string& name, +inline std::string UniqueName(absl::string_view name, const ServiceDescriptor* d) { return UniqueName(name, d->file(), InternalRuntimeOptions()); } // Return the qualified C++ name for a file level symbol. std::string QualifiedFileLevelSymbol(const FileDescriptor* file, - const std::string& name, + absl::string_view name, const Options& options); // Escape C++ trigraphs by escaping question marks to \? @@ -322,7 +320,7 @@ std::string EscapeTrigraphs(absl::string_view to_escape); // Escaped function name to eliminate naming conflict. std::string SafeFunctionName(const Descriptor* descriptor, const FieldDescriptor* field, - const std::string& prefix); + absl::string_view prefix); // Returns true if generated messages have public unknown fields accessors inline bool PublicUnknownFieldsAccessors(const Descriptor* message) { @@ -468,7 +466,7 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) { // Returns true if the field's CPPTYPE is string or message. bool IsStringOrMessage(const FieldDescriptor* field); -std::string UnderscoresToCamelCase(const std::string& input, +std::string UnderscoresToCamelCase(absl::string_view input, bool cap_next_letter); inline bool IsProto3(const FileDescriptor* file) { @@ -555,7 +553,8 @@ inline std::string IncludeGuard(const FileDescriptor* file, // have distinct include guards, because some source files include both and // both need to be defined (the third_party copies will be in the // google::protobuf_opensource namespace). - return MacroPrefix(options) + "_INCLUDED_" + filename_identifier; + return absl::StrCat(MacroPrefix(options), "_INCLUDED_", + filename_identifier); } else { // Ideally this case would use distinct include guards for opensource and // google3 protos also. (The behavior of "first #included wins" is not @@ -563,7 +562,7 @@ inline std::string IncludeGuard(const FileDescriptor* file, // the identical include guards to avoid compile errors. // // We should clean this up so that this case can be removed. - return "GOOGLE_PROTOBUF_INCLUDED_" + filename_identifier; + return absl::StrCat("GOOGLE_PROTOBUF_INCLUDED_", filename_identifier); } } @@ -858,7 +857,7 @@ class PROTOC_EXPORT Formatter { absl::flat_hash_map vars_; // Convenience overloads to accept different types as arguments. - static std::string ToString(const std::string& s) { return s; } + static std::string ToString(absl::string_view s) { return std::string(s); } template ::value>::type> static std::string ToString(I x) { @@ -1012,7 +1011,8 @@ struct OneOfRangeImpl { inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; } -PROTOC_EXPORT std::string StripProto(const std::string& filename); +// Strips ".proto" or ".protodevel" from the end of a filename. +PROTOC_EXPORT std::string StripProto(absl::string_view filename); bool ShouldVerify(const Descriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 2f9c2d7585..e8d734482d 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -288,10 +288,10 @@ void CollectMapInfo( default: vars["val_cpp"] = PrimitiveTypeName(options, val->cpp_type()); } - vars["key_wire_type"] = - "TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type())); - vars["val_wire_type"] = - "TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type())); + vars["key_wire_type"] = absl::StrCat( + "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type()))); + vars["val_wire_type"] = absl::StrCat( + "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type()))); } @@ -2142,7 +2142,7 @@ std::pair MessageGenerator::GenerateOffsets(io::Printer* p) { format("PROTOBUF_FIELD_OFFSET($classtype$$1$, $2$)", ShouldSplit(field, options_) ? "::Impl_::Split" : "", ShouldSplit(field, options_) - ? FieldName(field) + "_" + ? absl::StrCat(FieldName(field), "_") : FieldMemberName(field, /*cold=*/false)); } diff --git a/src/google/protobuf/compiler/cpp/metadata_test.cc b/src/google/protobuf/compiler/cpp/metadata_test.cc index a4e4888c3a..51df3d5bfd 100644 --- a/src/google/protobuf/compiler/cpp/metadata_test.cc +++ b/src/google/protobuf/compiler/cpp/metadata_test.cc @@ -63,11 +63,11 @@ class CppMetadataTest : public ::testing::Test { CommandLineInterface cli; CppGenerator cpp_generator; cli.RegisterGenerator("--cpp_out", &cpp_generator, ""); - std::string cpp_out = + std::string cpp_out = absl::StrCat( "--cpp_out=annotate_headers=true," "annotation_pragma_name=pragma_name," - "annotation_guard_name=guard_name:" + - TestTempDir(); + "annotation_guard_name=guard_name:", + TestTempDir()); const bool result = atu::RunProtoCompiler(filename, cpp_out, &cli, file); @@ -75,25 +75,28 @@ class CppMetadataTest : public ::testing::Test { return result; } - std::string output_base = TestTempDir() + "/" + StripProto(filename); + std::string output_base = + absl::StrCat(TestTempDir(), "/", StripProto(filename)); if (pb_cc != nullptr) { - GOOGLE_ABSL_CHECK_OK( - File::GetContents(output_base + ".pb.cc", pb_cc, true)); + GOOGLE_ABSL_CHECK_OK(File::GetContents(absl::StrCat(output_base, ".pb.cc"), + pb_cc, true)); } if (pb_h != nullptr && pb_h_info != nullptr) { - GOOGLE_ABSL_CHECK_OK( - File::GetContents(output_base + ".pb.h", pb_h, true)); - if (!atu::DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) { + GOOGLE_ABSL_CHECK_OK(File::GetContents(absl::StrCat(output_base, ".pb.h"), pb_h, + true)); + if (!atu::DecodeMetadata(absl::StrCat(output_base, ".pb.h.meta"), + pb_h_info)) { return false; } } if (proto_h != nullptr && proto_h_info != nullptr) { - GOOGLE_ABSL_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h, - true)); - if (!atu::DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) { + GOOGLE_ABSL_CHECK_OK(File::GetContents(absl::StrCat(output_base, ".proto.h"), + proto_h, true)); + if (!atu::DecodeMetadata(absl::StrCat(output_base, ".proto.h.meta"), + proto_h_info)) { return false; } } @@ -102,7 +105,7 @@ class CppMetadataTest : public ::testing::Test { } }; -const char kSmallTestFile[] = +constexpr absl::string_view kSmallTestFile = "syntax = \"proto2\";\n" "package foo;\n" "enum Enum { VALUE = 0; }\n" diff --git a/src/google/protobuf/compiler/cpp/names.h b/src/google/protobuf/compiler/cpp/names.h index f4dac4c644..150649377b 100644 --- a/src/google/protobuf/compiler/cpp/names.h +++ b/src/google/protobuf/compiler/cpp/names.h @@ -33,6 +33,8 @@ #include +#include "absl/strings/string_view.h" + // Must be included last. #include "google/protobuf/port_def.inc" @@ -98,7 +100,7 @@ std::string QualifiedOneofCaseConstantName(const FieldDescriptor* field); std::string EnumValueName(const EnumValueDescriptor* enum_value); // Strips ".proto" or ".protodevel" from the end of a filename. -PROTOC_EXPORT std::string StripProto(const std::string& filename); +PROTOC_EXPORT std::string StripProto(absl::string_view filename); } // namespace cpp } // namespace compiler diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index e17ac84c70..cf144aba4c 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -458,12 +458,12 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { // All entries without a fast-path parsing function need a fallback. std::string fallback; if (tc_table_info_->use_generated_fallback) { - fallback = ClassName(descriptor_) + "::Tct_ParseFallback"; + fallback = absl::StrCat(ClassName(descriptor_), "::Tct_ParseFallback"); } else { fallback = "::_pbi::TcParser::GenericFallback"; if (GetOptimizeFor(descriptor_->file(), options_) == FileOptions::LITE_RUNTIME) { - fallback += "Lite"; + absl::StrAppend(&fallback, "Lite"); } } @@ -842,7 +842,7 @@ void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) { bool split = ShouldSplit(field, options_); if (split) { format("PROTOBUF_FIELD_OFFSET($classname$::Impl_::Split, $1$), ", - FieldName(field) + "_"); + absl::StrCat(FieldName(field), "_")); } else { format("PROTOBUF_FIELD_OFFSET($classname$, $1$), ", FieldMemberName(field, /*cold=*/false)); diff --git a/src/google/protobuf/compiler/cpp/plugin_unittest.cc b/src/google/protobuf/compiler/cpp/plugin_unittest.cc index ee3dfb77fb..3606505249 100644 --- a/src/google/protobuf/compiler/cpp/plugin_unittest.cc +++ b/src/google/protobuf/compiler/cpp/plugin_unittest.cc @@ -172,44 +172,45 @@ class TestGenerator : public CodeGenerator { // not verify that they are correctly-placed; that would require actually // compiling the output which is a bit more than I care to do for this test. TEST(CppPluginTest, PluginTest) { - GOOGLE_ABSL_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto", - "syntax = \"proto2\";\n" - "package foo;\n" - "\n" - "enum Thud { VALUE = 0; }\n" - "\n" - "message Bar {\n" - " message Baz {}\n" - " optional int32 optInt = 1;\n" - " repeated int32 repeatedInt = 2;\n" - "\n" - " required string requiredString = 3;\n" - " repeated string repeatedString = 4;\n" - "\n" - " optional Baz optMessage = 6;\n" - " repeated Baz repeatedMessage = 7;\n" - "\n" - " optional Thud optEnum = 8;\n" - " repeated Thud repeatedEnum = 9;\n" - "\n" - " required string requiredCord = 10 [\n" - " ctype = CORD\n" - " ];\n" - " repeated string repeatedCord = 11 [\n" - " ctype = CORD\n" - " ];\n" - "\n" - " oneof Moo {\n" - " int64 oneOfInt = 20;\n" - " string oneOfString = 21;\n" - " Baz oneOfMessage = 22;\n" - " Thud oneOfEnum = 23;" - " string oneOfCord = 24 [\n" - " ctype = CORD\n" - " ];\n" - " }\n" - "}\n", - true)); + GOOGLE_ABSL_CHECK_OK( + File::SetContents(absl::StrCat(TestTempDir(), "/test.proto"), + "syntax = \"proto2\";\n" + "package foo;\n" + "\n" + "enum Thud { VALUE = 0; }\n" + "\n" + "message Bar {\n" + " message Baz {}\n" + " optional int32 optInt = 1;\n" + " repeated int32 repeatedInt = 2;\n" + "\n" + " required string requiredString = 3;\n" + " repeated string repeatedString = 4;\n" + "\n" + " optional Baz optMessage = 6;\n" + " repeated Baz repeatedMessage = 7;\n" + "\n" + " optional Thud optEnum = 8;\n" + " repeated Thud repeatedEnum = 9;\n" + "\n" + " required string requiredCord = 10 [\n" + " ctype = CORD\n" + " ];\n" + " repeated string repeatedCord = 11 [\n" + " ctype = CORD\n" + " ];\n" + "\n" + " oneof Moo {\n" + " int64 oneOfInt = 20;\n" + " string oneOfString = 21;\n" + " Baz oneOfMessage = 22;\n" + " Thud oneOfEnum = 23;" + " string oneOfCord = 24 [\n" + " ctype = CORD\n" + " ];\n" + " }\n" + "}\n", + true)); CommandLineInterface cli; cli.SetInputsAreProtoPathRelative(true); @@ -219,9 +220,9 @@ TEST(CppPluginTest, PluginTest) { cli.RegisterGenerator("--cpp_out", &cpp_generator, ""); cli.RegisterGenerator("--test_out", &test_generator, ""); - std::string proto_path = "-I" + TestTempDir(); - std::string cpp_out = "--cpp_out=" + TestTempDir(); - std::string test_out = "--test_out=" + TestTempDir(); + std::string proto_path = absl::StrCat("-I", TestTempDir()); + std::string cpp_out = absl::StrCat("--cpp_out=", TestTempDir()); + std::string test_out = absl::StrCat("--test_out=", TestTempDir()); const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(), test_out.c_str(), "test.proto"}; diff --git a/src/google/protobuf/compiler/cpp/unittest.inc b/src/google/protobuf/compiler/cpp/unittest.inc index aaf149eff8..94b3f557df 100644 --- a/src/google/protobuf/compiler/cpp/unittest.inc +++ b/src/google/protobuf/compiler/cpp/unittest.inc @@ -2107,10 +2107,11 @@ TEST(HELPERS_TEST_NAME, TestSCC) { std::string package = a.GetDescriptor()->file()->package(); ASSERT_EQ(names.size(), 4); std::sort(names.begin(), names.end()); - EXPECT_EQ(names[0], package + ".TestMutualRecursionA"); - EXPECT_EQ(names[1], package + ".TestMutualRecursionA.SubGroup"); - EXPECT_EQ(names[2], package + ".TestMutualRecursionA.SubMessage"); - EXPECT_EQ(names[3], package + ".TestMutualRecursionB"); + EXPECT_EQ(names[0], absl::StrCat(package, ".TestMutualRecursionA")); + EXPECT_EQ(names[1], absl::StrCat(package, ".TestMutualRecursionA.SubGroup")); + EXPECT_EQ(names[2], + absl::StrCat(package, ".TestMutualRecursionA.SubMessage")); + EXPECT_EQ(names[3], absl::StrCat(package, ".TestMutualRecursionB")); MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); EXPECT_EQ(result.is_recursive, true);