diff --git a/src/google/protobuf/compiler/objectivec/enum_field.cc b/src/google/protobuf/compiler/objectivec/enum_field.cc index 7e425c7bf99b..9c71479b47e2 100644 --- a/src/google/protobuf/compiler/objectivec/enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/enum_field.cc @@ -147,8 +147,10 @@ RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( void RepeatedEnumFieldGenerator::FinishInitialization() { RepeatedFieldGenerator::FinishInitialization(); - variables_["array_comment"] = "// |" + variables_["name"] + "| contains |" + - variables_["storage_type"] + "|\n"; + std::string name = variables_["name"]; + std::string storage_type = variables_["storage_type"]; + variables_["array_comment"] = + absl::StrCat("// |", name, "| contains |", storage_type, "|\n"); } // NOTE: RepeatedEnumFieldGenerator::DetermineForwardDeclarations isn't needed diff --git a/src/google/protobuf/compiler/objectivec/extension.cc b/src/google/protobuf/compiler/objectivec/extension.cc index d70b9a412305..821b322bf284 100644 --- a/src/google/protobuf/compiler/objectivec/extension.cc +++ b/src/google/protobuf/compiler/objectivec/extension.cc @@ -48,10 +48,11 @@ namespace protobuf { namespace compiler { namespace objectivec { -ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name, +ExtensionGenerator::ExtensionGenerator(absl::string_view root_class_name, const FieldDescriptor* descriptor) : method_name_(ExtensionMethodName(descriptor)), - root_class_and_method_name_(root_class_name + "_" + method_name_), + root_class_and_method_name_( + absl::StrCat(root_class_name, "_", method_name_)), descriptor_(descriptor) { if (descriptor->is_map()) { // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some @@ -120,11 +121,11 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( vars["default"] = DefaultValue(descriptor_); } std::string type = GetCapitalizedType(descriptor_); - vars["extension_type"] = std::string("GPBDataType") + type; + vars["extension_type"] = absl::StrCat("GPBDataType", type); if (objc_type == OBJECTIVECTYPE_ENUM) { vars["enum_desc_func_name"] = - EnumName(descriptor_->enum_type()) + "_EnumDescriptor"; + absl::StrCat(EnumName(descriptor_->enum_type()), "_EnumDescriptor"); } else { vars["enum_desc_func_name"] = "NULL"; } diff --git a/src/google/protobuf/compiler/objectivec/extension.h b/src/google/protobuf/compiler/objectivec/extension.h index c174e95b6c6d..42fc173014b1 100644 --- a/src/google/protobuf/compiler/objectivec/extension.h +++ b/src/google/protobuf/compiler/objectivec/extension.h @@ -44,7 +44,7 @@ namespace objectivec { class ExtensionGenerator { public: - ExtensionGenerator(const std::string& root_class_name, + ExtensionGenerator(absl::string_view root_class_name, const FieldDescriptor* descriptor); ~ExtensionGenerator() = default; diff --git a/src/google/protobuf/compiler/objectivec/field.cc b/src/google/protobuf/compiler/objectivec/field.cc index 8119be6fdf5b..ba5671ed3b57 100644 --- a/src/google/protobuf/compiler/objectivec/field.cc +++ b/src/google/protobuf/compiler/objectivec/field.cc @@ -82,7 +82,7 @@ void SetCommonFieldVariables( (*variables)["capitalized_name"] = capitalized_name; (*variables)["raw_field_name"] = raw_field_name; (*variables)["field_number_name"] = - classname + "_FieldNumber_" + capitalized_name; + absl::StrCat(classname, "_FieldNumber_", capitalized_name); (*variables)["field_number"] = absl::StrCat(descriptor->number()); (*variables)["field_type"] = GetCapitalizedType(descriptor); (*variables)["deprecated_attribute"] = @@ -120,8 +120,8 @@ void SetCommonFieldVariables( (*variables)["dataTypeSpecific_name"] = "clazz"; (*variables)["dataTypeSpecific_value"] = "Nil"; - (*variables)["storage_offset_value"] = "(uint32_t)offsetof(" + classname + - "__storage_, " + camel_case_name + ")"; + (*variables)["storage_offset_value"] = absl::StrCat( + "(uint32_t)offsetof(", classname, "__storage_, ", camel_case_name, ")"); (*variables)["storage_offset_comment"] = ""; // Clear some common things so they can be set just when needed. diff --git a/src/google/protobuf/compiler/objectivec/generator.cc b/src/google/protobuf/compiler/objectivec/generator.cc index c28a0eecc5e3..df64463a1dc9 100644 --- a/src/google/protobuf/compiler/objectivec/generator.cc +++ b/src/google/protobuf/compiler/objectivec/generator.cc @@ -145,8 +145,9 @@ bool ObjectiveCGenerator::GenerateAll( // Default is "no". if (!StringToBool(options[i].second, &validation_options.prefixes_must_be_registered)) { - *error = "error: Unknown value for prefixes_must_be_registered: " + - options[i].second; + *error = absl::StrCat( + "error: Unknown value for prefixes_must_be_registered: ", + options[i].second); return false; } } else if (options[i].first == "require_prefixes") { @@ -158,8 +159,8 @@ bool ObjectiveCGenerator::GenerateAll( // Default is "no". if (!StringToBool(options[i].second, &validation_options.require_prefixes)) { - *error = - "error: Unknown value for require_prefixes: " + options[i].second; + *error = absl::StrCat("error: Unknown value for require_prefixes: ", + options[i].second); return false; } } else if (options[i].first == "generate_for_named_framework") { @@ -229,7 +230,8 @@ bool ObjectiveCGenerator::GenerateAll( if (StringToBool(options[i].second, &value)) { SetUseProtoPackageAsDefaultPrefix(value); } else { - *error = "error: Unknown use_package_as_prefix: " + options[i].second; + *error = absl::StrCat("error: Unknown use_package_as_prefix: ", + options[i].second); return false; } } else if (options[i].first == "proto_package_prefix_exceptions_path") { @@ -251,8 +253,9 @@ bool ObjectiveCGenerator::GenerateAll( } else if (options[i].first == "headers_use_forward_declarations") { if (!StringToBool(options[i].second, &generation_options.headers_use_forward_declarations)) { - *error = "error: Unknown value for headers_use_forward_declarations: " + - options[i].second; + *error = absl::StrCat( + "error: Unknown value for headers_use_forward_declarations: ", + options[i].second); return false; } } else if (options[i].first == "experimental_multi_source_generation") { @@ -267,13 +270,14 @@ bool ObjectiveCGenerator::GenerateAll( if (!StringToBool( options[i].second, &generation_options.experimental_multi_source_generation)) { - *error = - "error: Unknown value for experimental_multi_source_generation: " + - options[i].second; + *error = absl::StrCat( + "error: Unknown value for experimental_multi_source_generation: ", + options[i].second); return false; } } else { - *error = "error: Unknown generator option: " + options[i].first; + *error = + absl::StrCat("error: Unknown generator option: ", options[i].first); return false; } } @@ -312,7 +316,8 @@ bool ObjectiveCGenerator::GenerateAll( // Generate header. { - auto output = absl::WrapUnique(context->Open(filepath + ".pbobjc.h")); + auto output = + absl::WrapUnique(context->Open(absl::StrCat(filepath, ".pbobjc.h"))); io::Printer printer(output.get()); file_generator.GenerateHeader(&printer); if (printer.failed()) { @@ -367,7 +372,8 @@ bool ObjectiveCGenerator::GenerateAll( } } } else { - auto output = absl::WrapUnique(context->Open(filepath + ".pbobjc.m")); + auto output = absl::WrapUnique( + context->Open(absl::StrCat(filepath, ".pbobjc.m"))); io::Printer printer(output.get()); file_generator.GenerateSource(&printer); if (printer.failed()) { diff --git a/src/google/protobuf/compiler/objectivec/helpers.cc b/src/google/protobuf/compiler/objectivec/helpers.cc index 8f45c1a9830f..cb13b0ed3180 100644 --- a/src/google/protobuf/compiler/objectivec/helpers.cc +++ b/src/google/protobuf/compiler/objectivec/helpers.cc @@ -39,6 +39,7 @@ #include "absl/strings/match.h" #include "absl/strings/str_replace.h" #include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/io/strtod.h" #include "google/protobuf/stubs/common.h" @@ -97,7 +98,7 @@ std::string HandleExtremeFloatingPoint(std::string val, bool add_float_suffix) { if (add_float_suffix && (absl::StrContains(val, '.') || absl::StrContains(val, 'e') || absl::StrContains(val, 'E'))) { - val += "f"; + return absl::StrCat(val, "f"); } return val; } @@ -255,15 +256,15 @@ std::string DefaultValue(const FieldDescriptor* field) { } return absl::StrCat(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: // gcc and llvm reject the decimal form of kint32min and kint64min. if (field->default_value_int64() == LLONG_MIN) { return "-0x8000000000000000LL"; } - return absl::StrCat(field->default_value_int64()) + "LL"; + return absl::StrCat(field->default_value_int64(), "LL"); case FieldDescriptor::CPPTYPE_UINT64: - return absl::StrCat(field->default_value_uint64()) + "ULL"; + return absl::StrCat(field->default_value_uint64(), "ULL"); case FieldDescriptor::CPPTYPE_DOUBLE: return HandleExtremeFloatingPoint( io::SimpleDtoa(field->default_value_double()), false); @@ -274,7 +275,7 @@ std::string DefaultValue(const FieldDescriptor* field) { return field->default_value_bool() ? "YES" : "NO"; case FieldDescriptor::CPPTYPE_STRING: { const bool has_default_value = field->has_default_value(); - const std::string& default_string = field->default_value_string(); + absl::string_view default_string = field->default_value_string(); if (!has_default_value || default_string.length() == 0) { // If the field is defined as being the empty string, // then we will just assign to nil, as the empty string is the @@ -292,10 +293,12 @@ std::string DefaultValue(const FieldDescriptor* field) { // a cstring. uint32_t length = ghtonl(default_string.length()); std::string bytes((const char*)&length, sizeof(length)); - bytes.append(default_string); - return "(NSData*)\"" + EscapeTrigraphs(absl::CEscape(bytes)) + "\""; + absl::StrAppend(&bytes, default_string); + return absl::StrCat("(NSData*)\"", + EscapeTrigraphs(absl::CEscape(bytes)), "\""); } else { - return "@\"" + EscapeTrigraphs(absl::CEscape(default_string)) + "\""; + return absl::StrCat( + "@\"", EscapeTrigraphs(absl::CEscape(default_string)), "\""); } } case FieldDescriptor::CPPTYPE_ENUM: @@ -317,7 +320,8 @@ std::string BuildFlagsString(FlagType flag_type, } else if (strings.size() == 1) { return strings[0]; } - std::string string("(" + GetEnumNameForFlagType(flag_type) + ")("); + std::string string = + absl::StrCat("(", GetEnumNameForFlagType(flag_type), ")("); for (size_t i = 0; i != strings.size(); ++i) { if (i > 0) { string.append(" | "); @@ -328,20 +332,20 @@ std::string BuildFlagsString(FlagType flag_type, return string; } -std::string ObjCClass(const std::string& class_name) { - return std::string("GPBObjCClass(") + class_name + ")"; +std::string ObjCClass(absl::string_view class_name) { + return absl::StrCat("GPBObjCClass(", class_name, ")"); } -std::string ObjCClassDeclaration(const std::string& class_name) { - return std::string("GPBObjCClassDeclaration(") + class_name + ");"; +std::string ObjCClassDeclaration(absl::string_view class_name) { + return absl::StrCat("GPBObjCClassDeclaration(", class_name, ");"); } std::string BuildCommentsString(const SourceLocation& location, bool prefer_single_line) { - const std::string& comments = location.leading_comments.empty() - ? location.trailing_comments - : location.leading_comments; - std::vector lines; + absl::string_view comments = location.leading_comments.empty() + ? location.trailing_comments + : location.leading_comments; + std::vector lines; lines = absl::StrSplit(comments, '\n', absl::AllowEmpty()); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); @@ -364,7 +368,7 @@ std::string BuildCommentsString(const SourceLocation& location, } else { prefix = "* "; suffix = "\n"; - final_comments += "/**\n"; + absl::StrAppend(&final_comments, "/**\n"); epilogue = " **/\n"; add_leading_space = true; } @@ -382,11 +386,10 @@ std::string BuildCommentsString(const SourceLocation& location, absl::StripAsciiWhitespace(&line); // If not a one line, need to add the first space before *, as // absl::StripAsciiWhitespace would have removed it. - line = (add_leading_space ? " " : "") + line; - final_comments += line + suffix; + line = absl::StrCat(add_leading_space ? " " : "", line); + absl::StrAppend(&final_comments, line, suffix); } - final_comments += epilogue; - return final_comments; + return absl::StrCat(final_comments, epilogue); } } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/helpers.h b/src/google/protobuf/compiler/objectivec/helpers.h index 667b9e44981e..28146510984b 100644 --- a/src/google/protobuf/compiler/objectivec/helpers.h +++ b/src/google/protobuf/compiler/objectivec/helpers.h @@ -105,11 +105,11 @@ std::string BuildFlagsString(FlagType type, // Returns a symbol that can be used in C code to refer to an Objective C // class without initializing the class. -std::string ObjCClass(const std::string& class_name); +std::string ObjCClass(absl::string_view class_name); // Declares an Objective C class without initializing the class so that it can // be refrerred to by ObjCClass. -std::string ObjCClassDeclaration(const std::string& class_name); +std::string ObjCClassDeclaration(absl::string_view class_name); // Builds HeaderDoc/appledoc style comments out of the comments in the .proto // file. @@ -134,20 +134,14 @@ std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, std::string message; const FileDescriptor* sourceFile = descriptor->file(); if (isFileLevelDeprecation) { - message = sourceFile->name() + " is deprecated."; + message = absl::StrCat(sourceFile->name(), " is deprecated."); } else { - message = descriptor->full_name() + " is deprecated (see " + - sourceFile->name() + ")."; + message = absl::StrCat(descriptor->full_name(), " is deprecated (see ", + sourceFile->name(), ")."); } - std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")"; - if (preSpace) { - result.insert(0, " "); - } - if (postNewline) { - result.append("\n"); - } - return result; + return absl::StrCat(preSpace ? " " : "", "GPB_DEPRECATED_MSG(\"", message, + "\")", postNewline ? "\n" : ""); } else { return ""; } diff --git a/src/google/protobuf/compiler/objectivec/import_writer.cc b/src/google/protobuf/compiler/objectivec/import_writer.cc index 3bbf62d119b4..5d41274db4aa 100644 --- a/src/google/protobuf/compiler/objectivec/import_writer.cc +++ b/src/google/protobuf/compiler/objectivec/import_writer.cc @@ -134,9 +134,8 @@ void ImportWriter::AddFile(const FileDescriptor* file, // in other cases, they get skipped because the generated code already // import GPBProtocolBuffers.h and hence proves them. if (for_bundled_proto_) { - const std::string header_name = - "GPB" + FilePathBasename(file) + header_extension; - protobuf_imports_.push_back(header_name); + protobuf_imports_.emplace_back( + absl::StrCat("GPB", FilePathBasename(file), header_extension)); } return; } @@ -148,15 +147,15 @@ void ImportWriter::AddFile(const FileDescriptor* file, 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); + other_framework_imports_.emplace_back(absl::StrCat( + proto_lookup->second, "/", FilePathBasename(file), header_extension)); return; } if (!generate_for_named_framework_.empty()) { - other_framework_imports_.push_back(generate_for_named_framework_ + "/" + - FilePathBasename(file) + - header_extension); + other_framework_imports_.push_back( + absl::StrCat(generate_for_named_framework_, "/", FilePathBasename(file), + header_extension)); return; } diff --git a/src/google/protobuf/compiler/objectivec/line_consumer.cc b/src/google/protobuf/compiler/objectivec/line_consumer.cc index a62a7b9d6688..f70c0b1fda08 100644 --- a/src/google/protobuf/compiler/objectivec/line_consumer.cc +++ b/src/google/protobuf/compiler/objectivec/line_consumer.cc @@ -161,11 +161,11 @@ bool Parser::Finish(std::string* out_error) { } // namespace -bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer, +bool ParseSimpleFile(absl::string_view path, LineConsumer* line_consumer, std::string* out_error) { int fd; do { - fd = posix::open(path.c_str(), O_RDONLY); + fd = posix::open(std::string(path).c_str(), O_RDONLY); } while (fd < 0 && errno == EINTR); if (fd < 0) { *out_error = @@ -179,7 +179,7 @@ bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer, } bool ParseSimpleStream(io::ZeroCopyInputStream& input_stream, - const std::string& stream_name, + absl::string_view stream_name, LineConsumer* line_consumer, std::string* out_error) { std::string local_error; Parser parser(line_consumer); diff --git a/src/google/protobuf/compiler/objectivec/line_consumer.h b/src/google/protobuf/compiler/objectivec/line_consumer.h index 0b63f34d7d66..2ff027476a0b 100644 --- a/src/google/protobuf/compiler/objectivec/line_consumer.h +++ b/src/google/protobuf/compiler/objectivec/line_consumer.h @@ -55,12 +55,12 @@ class PROTOC_EXPORT LineConsumer { virtual bool ConsumeLine(absl::string_view line, std::string* out_error) = 0; }; -bool PROTOC_EXPORT ParseSimpleFile(const std::string& path, +bool PROTOC_EXPORT ParseSimpleFile(absl::string_view path, LineConsumer* line_consumer, std::string* out_error); bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream, - const std::string& stream_name, + absl::string_view stream_name, LineConsumer* line_consumer, std::string* out_error); diff --git a/src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc b/src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc index d346c3fd346a..bd86f8b66937 100644 --- a/src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc +++ b/src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc @@ -55,7 +55,7 @@ class TestLineCollector : public LineConsumer { bool ConsumeLine(absl::string_view line, std::string* out_error) override { if (reject_ && *reject_ == line) { if (!skip_msg_) { - *out_error = std::string("Rejected '") + *reject_ + "'"; + *out_error = absl::StrCat("Rejected '", *reject_, "'"); } return false; } diff --git a/src/google/protobuf/compiler/objectivec/map_field.cc b/src/google/protobuf/compiler/objectivec/map_field.cc index be76323bdb56..2a90f4716e2b 100644 --- a/src/google/protobuf/compiler/objectivec/map_field.cc +++ b/src/google/protobuf/compiler/objectivec/map_field.cc @@ -99,7 +99,8 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor) // Build custom field flags. std::vector field_flags; - field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor)); + field_flags.push_back( + absl::StrCat("GPBFieldMapKey", GetCapitalizedType(key_descriptor))); // Pull over the current text format custom name values that was calculated. if (absl::StrContains(variables_["fieldflags"], "GPBFieldTextFormatNameCustom")) { @@ -129,18 +130,17 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor) value_is_object_type) { variables_["array_storage_type"] = "NSMutableDictionary"; variables_["array_property_type"] = - "NSMutableDictionaryvariable("storage_type") + "*>"; + absl::StrCat("NSMutableDictionaryvariable("storage_type"), "*>"); } else { - std::string class_name("GPB"); - class_name += MapEntryTypeName(key_descriptor, true); - class_name += MapEntryTypeName(value_descriptor, false); - class_name += "Dictionary"; + std::string class_name = + absl::StrCat("GPB", MapEntryTypeName(key_descriptor, true), + MapEntryTypeName(value_descriptor, false), "Dictionary"); variables_["array_storage_type"] = class_name; if (value_is_object_type) { variables_["array_property_type"] = - class_name + "<" + value_field_generator_->variable("storage_type") + - "*>"; + absl::StrCat(class_name, "<", + value_field_generator_->variable("storage_type"), "*>"); } } @@ -157,9 +157,10 @@ void MapFieldGenerator::FinishInitialization() { const FieldDescriptor* value_descriptor = descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) { + std::string name = variables_["name"]; variables_["array_comment"] = - "// |" + variables_["name"] + "| values are |" + - value_field_generator_->variable("storage_type") + "|\n"; + absl::StrCat("// |", name, "| values are |", + value_field_generator_->variable("storage_type"), "|\n"); } } diff --git a/src/google/protobuf/compiler/objectivec/message_field.cc b/src/google/protobuf/compiler/objectivec/message_field.cc index 8da2f82bab3a..569e8c273bf9 100644 --- a/src/google/protobuf/compiler/objectivec/message_field.cc +++ b/src/google/protobuf/compiler/objectivec/message_field.cc @@ -90,9 +90,10 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( const FieldDescriptor* descriptor) : RepeatedFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); + std::string storage_type = variables_["storage_type"]; variables_["array_storage_type"] = "NSMutableArray"; variables_["array_property_type"] = - "NSMutableArray<" + variables_["storage_type"] + "*>"; + absl::StrCat("NSMutableArray<", storage_type, "*>"); } void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( diff --git a/src/google/protobuf/compiler/objectivec/names.cc b/src/google/protobuf/compiler/objectivec/names.cc index a64144d119bc..54af967f96bd 100644 --- a/src/google/protobuf/compiler/objectivec/names.cc +++ b/src/google/protobuf/compiler/objectivec/names.cc @@ -83,7 +83,7 @@ class SimpleLineCollector : public LineConsumer { class PackageToPrefixesCollector : public LineConsumer { public: - PackageToPrefixesCollector(const std::string& usage, + PackageToPrefixesCollector(absl::string_view usage, absl::flat_hash_map* inout_package_to_prefix_map) : usage_(usage), prefix_map_(inout_package_to_prefix_map) {} @@ -99,32 +99,33 @@ class PrefixModeStorage { public: PrefixModeStorage(); - std::string package_to_prefix_mappings_path() const { + absl::string_view package_to_prefix_mappings_path() const { return package_to_prefix_mappings_path_; } - void set_package_to_prefix_mappings_path(const std::string& path) { - package_to_prefix_mappings_path_ = path; + void set_package_to_prefix_mappings_path(absl::string_view path) { + package_to_prefix_mappings_path_ = std::string(path); package_to_prefix_map_.clear(); } - std::string prefix_from_proto_package_mappings(const FileDescriptor* file); + absl::string_view prefix_from_proto_package_mappings( + const FileDescriptor* file); bool use_package_name() const { return use_package_name_; } void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; } - std::string exception_path() const { return exception_path_; } - void set_exception_path(const std::string& path) { - exception_path_ = path; + absl::string_view exception_path() const { return exception_path_; } + void set_exception_path(absl::string_view path) { + exception_path_ = std::string(path); exceptions_.clear(); } - bool is_package_exempted(const std::string& package); + bool is_package_exempted(absl::string_view package); // When using a proto package as the prefix, this should be added as the // prefix in front of it. - const std::string& forced_package_prefix() const { return forced_prefix_; } - void set_forced_package_prefix(const std::string& prefix) { - forced_prefix_ = prefix; + absl::string_view forced_package_prefix() const { return forced_prefix_; } + void set_forced_package_prefix(absl::string_view prefix) { + forced_prefix_ = std::string(prefix); } private: @@ -156,7 +157,7 @@ PrefixModeStorage::PrefixModeStorage() { constexpr absl::string_view kNoPackagePrefix = "no_package:"; -std::string PrefixModeStorage::prefix_from_proto_package_mappings( +absl::string_view PrefixModeStorage::prefix_from_proto_package_mappings( const FileDescriptor* file) { if (!file) { return ""; @@ -197,7 +198,7 @@ std::string PrefixModeStorage::prefix_from_proto_package_mappings( return ""; } -bool PrefixModeStorage::is_package_exempted(const std::string& package) { +bool PrefixModeStorage::is_package_exempted(absl::string_view package) { if (exceptions_.empty() && !exception_path_.empty()) { std::string error_str; SimpleLineCollector collector(&exceptions_); @@ -226,11 +227,11 @@ PrefixModeStorage& g_prefix_mode = *new PrefixModeStorage(); } // namespace -std::string GetPackageToPrefixMappingsPath() { +absl::string_view GetPackageToPrefixMappingsPath() { return g_prefix_mode.package_to_prefix_mappings_path(); } -void SetPackageToPrefixMappingsPath(const std::string& file_path) { +void SetPackageToPrefixMappingsPath(absl::string_view file_path) { g_prefix_mode.set_package_to_prefix_mappings_path(file_path); } @@ -242,19 +243,19 @@ void SetUseProtoPackageAsDefaultPrefix(bool on_or_off) { g_prefix_mode.set_use_package_name(on_or_off); } -std::string GetProtoPackagePrefixExceptionList() { +absl::string_view GetProtoPackagePrefixExceptionList() { return g_prefix_mode.exception_path(); } -void SetProtoPackagePrefixExceptionList(const std::string& file_path) { +void SetProtoPackagePrefixExceptionList(absl::string_view file_path) { g_prefix_mode.set_exception_path(file_path); } -std::string GetForcedPackagePrefix() { +absl::string_view GetForcedPackagePrefix() { return g_prefix_mode.forced_package_prefix(); } -void SetForcedPackagePrefix(const std::string& prefix) { +void SetForcedPackagePrefix(absl::string_view prefix) { g_prefix_mode.set_forced_package_prefix(prefix); } @@ -277,7 +278,7 @@ const absl::flat_hash_set& UpperSegments() { // Internal helper for name handing. // Do not expose this outside of helpers, stick to having functions for specific // cases (ClassName(), FieldName()), so there is always consistent suffix rules. -std::string UnderscoresToCamelCase(const std::string& input, +std::string UnderscoresToCamelCase(absl::string_view input, bool first_capitalized) { std::vector values; std::string current; @@ -552,7 +553,7 @@ const absl::flat_hash_set& NSObjectMethods() { // here but this verifies and allows for future expansion if we decide to // redefine what a reserved C identifier is (for example the GNU list // https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html ) -bool IsReservedCIdentifier(const std::string& input) { +bool IsReservedCIdentifier(absl::string_view input) { if (input.length() > 2) { if (input.at(0) == '_') { if (isupper(input.at(1)) || input.at(1) == '_') { @@ -563,9 +564,9 @@ bool IsReservedCIdentifier(const std::string& input) { return false; } -std::string SanitizeNameForObjC(const std::string& prefix, - const std::string& input, - const std::string& extension, +std::string SanitizeNameForObjC(absl::string_view prefix, + absl::string_view input, + absl::string_view extension, std::string* out_suffix_added) { std::string sanitized; // We add the prefix in the cases where the string is missing a prefix. @@ -576,17 +577,17 @@ std::string SanitizeNameForObjC(const std::string& prefix, if (absl::StartsWith(input, prefix)) { if (input.length() == prefix.length() || !absl::ascii_isupper(input[prefix.length()])) { - sanitized = prefix + input; + sanitized = absl::StrCat(prefix, input); } else { - sanitized = input; + sanitized = std::string(input); } } else { - sanitized = prefix + input; + sanitized = absl::StrCat(prefix, input); } if (IsReservedCIdentifier(sanitized) || ReservedWords().contains(sanitized) || NSObjectMethods().contains(sanitized)) { - if (out_suffix_added) *out_suffix_added = extension; - return sanitized + extension; + if (out_suffix_added) *out_suffix_added = std::string(extension); + return absl::StrCat(sanitized, extension); } if (out_suffix_added) out_suffix_added->clear(); return sanitized; @@ -600,27 +601,27 @@ std::string NameFromFieldDescriptor(const FieldDescriptor* field) { } } -void PathSplit(const std::string& path, std::string* directory, +void PathSplit(absl::string_view path, std::string* directory, std::string* basename) { - std::string::size_type last_slash = path.rfind('/'); - if (last_slash == std::string::npos) { + absl::string_view::size_type last_slash = path.rfind('/'); + if (last_slash == absl::string_view::npos) { if (directory) { *directory = ""; } if (basename) { - *basename = path; + *basename = std::string(path); } } else { if (directory) { - *directory = path.substr(0, last_slash); + *directory = std::string(path.substr(0, last_slash)); } if (basename) { - *basename = path.substr(last_slash + 1); + *basename = std::string(path.substr(last_slash + 1)); } } } -bool IsSpecialNamePrefix(const std::string& name, +bool IsSpecialNamePrefix(absl::string_view name, const std::vector& special_names) { for (const auto& special_name : special_names) { const size_t length = special_name.length(); @@ -648,7 +649,7 @@ void MaybeUnQuote(absl::string_view* input) { } // namespace -bool IsRetainedName(const std::string& name) { +bool IsRetainedName(absl::string_view name) { // List of prefixes from // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html static const std::vector* retained_names = @@ -656,13 +657,13 @@ bool IsRetainedName(const std::string& name) { return IsSpecialNamePrefix(name, *retained_names); } -bool IsInitName(const std::string& name) { +bool IsInitName(absl::string_view name) { static const std::vector* init_names = new std::vector({"init"}); return IsSpecialNamePrefix(name, *init_names); } -bool IsCreateName(const std::string& name) { +bool IsCreateName(absl::string_view name) { // List of segments from // https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029 static const std::vector* create_names = @@ -708,10 +709,10 @@ std::string FileClassPrefix(const FileDescriptor* file) { // If package prefix is specified in an prefix to proto mappings file then use // that. - std::string objc_class_prefix = + absl::string_view objc_class_prefix = g_prefix_mode.prefix_from_proto_package_mappings(file); if (!objc_class_prefix.empty()) { - return objc_class_prefix; + return std::string(objc_class_prefix); } // If package prefix isn't enabled, done. @@ -743,7 +744,7 @@ std::string FileClassPrefix(const FileDescriptor* file) { if (!result.empty()) { result.append("_"); } - return g_prefix_mode.forced_package_prefix() + result; + return absl::StrCat(g_prefix_mode.forced_package_prefix(), result); } std::string FilePath(const FileDescriptor* file) { @@ -752,15 +753,14 @@ std::string FilePath(const FileDescriptor* file) { std::string directory; PathSplit(file->name(), &directory, &basename); if (directory.length() > 0) { - output = directory + "/"; + output = absl::StrCat(directory, "/"); } basename = StripProto(basename); // CamelCase to be more ObjC friendly. basename = UnderscoresToCamelCase(basename, true); - output += basename; - return output; + return absl::StrCat(output, basename); } std::string FilePathBasename(const FileDescriptor* file) { @@ -778,8 +778,8 @@ std::string FilePathBasename(const FileDescriptor* file) { std::string FileClassName(const FileDescriptor* file) { const std::string prefix = FileClassPrefix(file); - const std::string name = - UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; + const std::string name = absl::StrCat( + UnderscoresToCamelCase(StripProto(BaseFileName(file)), true), "Root"); // There aren't really any reserved words that end in "Root", but playing // it safe and checking. return SanitizeNameForObjC(prefix, name, "_RootClass", nullptr); @@ -788,19 +788,19 @@ std::string FileClassName(const FileDescriptor* file) { std::string ClassNameWorker(const Descriptor* descriptor) { std::string name; if (descriptor->containing_type() != nullptr) { - name = ClassNameWorker(descriptor->containing_type()); - name += "_"; + return absl::StrCat(ClassNameWorker(descriptor->containing_type()), "_", + descriptor->name()); } - return name + descriptor->name(); + return absl::StrCat(name, descriptor->name()); } std::string ClassNameWorker(const EnumDescriptor* descriptor) { std::string name; if (descriptor->containing_type() != nullptr) { - name = ClassNameWorker(descriptor->containing_type()); - name += "_"; + return absl::StrCat(ClassNameWorker(descriptor->containing_type()), "_", + descriptor->name()); } - return name + descriptor->name(); + return absl::StrCat(name, descriptor->name()); } std::string ClassName(const Descriptor* descriptor) { @@ -840,7 +840,7 @@ std::string EnumValueName(const EnumValueDescriptor* descriptor) { const std::string class_name = EnumName(descriptor->type()); const std::string value_str = UnderscoresToCamelCase(descriptor->name(), true); - const std::string name = class_name + "_" + value_str; + const std::string name = absl::StrCat(class_name, "_", value_str); // There aren't really any reserved words with an underscore and a leading // capital letter, but playing it safe and checking. return SanitizeNameForObjC("", name, "_Value", nullptr); @@ -860,12 +860,12 @@ std::string EnumValueShortName(const EnumValueDescriptor* descriptor) { // and then strip off the enum name (leaving the value name and anything // done by sanitize). const std::string class_name = EnumName(descriptor->type()); - const std::string long_name_prefix = class_name + "_"; + const std::string long_name_prefix = absl::StrCat(class_name, "_"); const std::string long_name = EnumValueName(descriptor); return std::string(absl::StripPrefix(long_name, long_name_prefix)); } -std::string UnCamelCaseEnumShortName(const std::string& name) { +std::string UnCamelCaseEnumShortName(absl::string_view name) { std::string result; for (int i = 0; i < name.size(); i++) { char c = name[i]; @@ -888,11 +888,11 @@ std::string FieldName(const FieldDescriptor* field) { std::string result = UnderscoresToCamelCase(name, false); if (field->is_repeated() && !field->is_map()) { // Add "Array" before do check for reserved worlds. - result += "Array"; + absl::StrAppend(&result, "Array"); } else { // If it wasn't repeated, but ends in "Array", force on the _p suffix. if (absl::EndsWith(result, "Array")) { - result += "_p"; + absl::StrAppend(&result, "_p"); } } return SanitizeNameForObjC("", result, "_p", nullptr); @@ -910,8 +910,9 @@ std::string FieldNameCapitalized(const FieldDescriptor* field) { std::string OneofEnumName(const OneofDescriptor* descriptor) { const Descriptor* fieldDescriptor = descriptor->containing_type(); - std::string name = ClassName(fieldDescriptor); - name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase"; + std::string name = absl::StrCat( + ClassName(fieldDescriptor), "_", + UnderscoresToCamelCase(descriptor->name(), true), "_OneOfCase"); // No sanitize needed because the OS never has names that end in _OneOfCase. return name; } @@ -932,7 +933,7 @@ std::string OneofNameCapitalized(const OneofDescriptor* descriptor) { return result; } -std::string UnCamelCaseFieldName(const std::string& name, +std::string UnCamelCaseFieldName(absl::string_view name, const FieldDescriptor* field) { absl::string_view worker(name); if (absl::EndsWith(worker, "_p")) { @@ -973,7 +974,7 @@ std::string UnCamelCaseFieldName(const std::string& name, // use a different value; so it isn't as simple as a option. const char* const ProtobufLibraryFrameworkName = "Protobuf"; -std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) { +std::string ProtobufFrameworkImportSymbol(absl::string_view framework_name) { // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS return absl::StrCat("GPB_USE_", absl::AsciiStrToUpper(framework_name), "_FRAMEWORK_IMPORTS"); @@ -1021,7 +1022,7 @@ bool PackageToPrefixesCollector::ConsumeLine(absl::string_view line, } bool LoadExpectedPackagePrefixes( - const std::string& expected_prefixes_path, + absl::string_view expected_prefixes_path, absl::flat_hash_map* prefix_map, std::string* out_error) { if (expected_prefixes_path.empty()) { @@ -1033,7 +1034,7 @@ bool LoadExpectedPackagePrefixes( } bool ValidateObjCClassPrefix( - const FileDescriptor* file, const std::string& expected_prefixes_path, + const FileDescriptor* file, absl::string_view expected_prefixes_path, const absl::flat_hash_map& expected_package_prefixes, bool prefixes_must_be_registered, bool require_prefixes, @@ -1065,16 +1066,17 @@ bool ValidateObjCClassPrefix( return true; } else { // ...it didn't match! - *out_error = "error: Expected 'option objc_class_prefix = \"" + - package_match->second + "\";'"; + *out_error = + absl::StrCat("error: Expected 'option objc_class_prefix = \"", + package_match->second, "\";'"); if (!package.empty()) { - *out_error += " for package '" + package + "'"; + absl::StrAppend(out_error, " for package '", package, "'"); } - *out_error += " in '" + file->name() + "'"; + absl::StrAppend(out_error, " in '", file->name(), "'"); if (has_prefix) { - *out_error += "; but found '" + prefix + "' instead"; + absl::StrAppend(out_error, "; but found '", prefix, "' instead"); } - *out_error += "."; + absl::StrAppend(out_error, "."); return false; } } @@ -1082,9 +1084,9 @@ bool ValidateObjCClassPrefix( // If there was no prefix option, we're done at this point. if (!has_prefix) { if (require_prefixes) { - *out_error = "error: '" + file->name() + - "' does not have a required 'option" + - " objc_class_prefix'."; + *out_error = absl::StrCat("error: '", file->name(), + "' does not have a required 'option" + " objc_class_prefix'."); return false; } return true; @@ -1110,17 +1112,17 @@ bool ValidateObjCClassPrefix( // package (overlap is allowed, but it has to be listed as an expected // overlap). if (!other_package_for_prefix.empty()) { - *out_error = "error: Found 'option objc_class_prefix = \"" + prefix + - "\";' in '" + file->name() + - "'; that prefix is already used for "; + *out_error = absl::StrCat("error: Found 'option objc_class_prefix = \"", + prefix, "\";' in '", file->name(), + "'; that prefix is already used for "); if (absl::StartsWith(other_package_for_prefix, kNoPackagePrefix)) { absl::StrAppend( out_error, "file '", absl::StripPrefix(other_package_for_prefix, kNoPackagePrefix), "'."); } else { - absl::StrAppend(out_error, "'package ", - other_package_for_prefix + ";'."); + absl::StrAppend(out_error, "'package ", other_package_for_prefix, + ";'."); } absl::StrAppend(out_error, " It can only be reused by adding '", lookup_key, " = ", prefix, @@ -1153,11 +1155,11 @@ bool ValidateObjCClassPrefix( // issue a error/warning to added to the file. if (have_expected_prefix_file) { if (prefixes_must_be_registered) { - *out_error = - "error: '" + file->name() + "' has 'option objc_class_prefix = \"" + - prefix + "\";', but it is not registered. Add '" + lookup_key + - " = " + (prefix.empty() ? "\"\"" : prefix) + - "' to the expected prefixes file (" + expected_prefixes_path + ")."; + *out_error = absl::StrCat( + "error: '", file->name(), "' has 'option objc_class_prefix = \"", + prefix, "\";', but it is not registered. Add '", lookup_key, " = ", + (prefix.empty() ? "\"\"" : prefix), + "' to the expected prefixes file (", expected_prefixes_path, ")."); return false; } diff --git a/src/google/protobuf/compiler/objectivec/names.h b/src/google/protobuf/compiler/objectivec/names.h index a6f792e8e7b4..d58502ef1a7a 100644 --- a/src/google/protobuf/compiler/objectivec/names.h +++ b/src/google/protobuf/compiler/objectivec/names.h @@ -47,8 +47,8 @@ namespace compiler { namespace objectivec { // Get/Set the path to a file to load for objc class prefix lookups. -PROTOC_EXPORT std::string GetPackageToPrefixMappingsPath(); -PROTOC_EXPORT void SetPackageToPrefixMappingsPath(const std::string& file_path); +PROTOC_EXPORT absl::string_view GetPackageToPrefixMappingsPath(); +PROTOC_EXPORT void SetPackageToPrefixMappingsPath(absl::string_view file_path); // Get/Set if the proto package should be used to make the default prefix for // symbols. This will then impact most of the type naming apis below. It is done // as a global to not break any other generator reusing the methods since they @@ -58,25 +58,25 @@ PROTOC_EXPORT void SetUseProtoPackageAsDefaultPrefix(bool on_or_off); // Get/Set the path to a file to load as exceptions when // `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there // should be no exceptions. -PROTOC_EXPORT std::string GetProtoPackagePrefixExceptionList(); +PROTOC_EXPORT absl::string_view GetProtoPackagePrefixExceptionList(); PROTOC_EXPORT void SetProtoPackagePrefixExceptionList( - const std::string& file_path); + absl::string_view file_path); // Get/Set a prefix to add before the prefix generated from the package name. // This is only used when UseProtoPackageAsDefaultPrefix() is True. -PROTOC_EXPORT std::string GetForcedPackagePrefix(); -PROTOC_EXPORT void SetForcedPackagePrefix(const std::string& prefix); +PROTOC_EXPORT absl::string_view GetForcedPackagePrefix(); +PROTOC_EXPORT void SetForcedPackagePrefix(absl::string_view prefix); // Returns true if the name requires a ns_returns_not_retained attribute applied // to it. -PROTOC_EXPORT bool IsRetainedName(const std::string& name); +PROTOC_EXPORT bool IsRetainedName(absl::string_view name); // Returns true if the name starts with "init" and will need to have special // handling under ARC. -PROTOC_EXPORT bool IsInitName(const std::string& name); +PROTOC_EXPORT bool IsInitName(absl::string_view name); // Returns true if the name requires a cf_returns_not_retained attribute applied // to it. -PROTOC_EXPORT bool IsCreateName(const std::string& name); +PROTOC_EXPORT bool IsCreateName(absl::string_view name); // Gets the objc_class_prefix or the prefix made from the proto package. PROTOC_EXPORT std::string FileClassPrefix(const FileDescriptor* file); @@ -110,7 +110,7 @@ PROTOC_EXPORT std::string EnumValueShortName( const EnumValueDescriptor* descriptor); // Reverse what an enum does. -PROTOC_EXPORT std::string UnCamelCaseEnumShortName(const std::string& name); +PROTOC_EXPORT std::string UnCamelCaseEnumShortName(absl::string_view name); // Returns the name to use for the extension (used as the method off the file's // Root class). @@ -128,7 +128,7 @@ PROTOC_EXPORT std::string OneofNameCapitalized( const OneofDescriptor* descriptor); // Reverse of the above. -PROTOC_EXPORT std::string UnCamelCaseFieldName(const std::string& name, +PROTOC_EXPORT std::string UnCamelCaseFieldName(absl::string_view name, const FieldDescriptor* field); // The name the commonly used by the library when built as a framework. @@ -137,7 +137,7 @@ extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName; // Returns the CPP symbol name to use as the gate for framework style imports // for the given framework name to use. PROTOC_EXPORT std::string ProtobufFrameworkImportSymbol( - const std::string& framework_name); + absl::string_view framework_name); // --------------------------------------------------------------------------- diff --git a/src/google/protobuf/compiler/objectivec/primitive_field.cc b/src/google/protobuf/compiler/objectivec/primitive_field.cc index 24c85b34a56e..ede7493150f1 100644 --- a/src/google/protobuf/compiler/objectivec/primitive_field.cc +++ b/src/google/protobuf/compiler/objectivec/primitive_field.cc @@ -168,11 +168,12 @@ RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( std::string base_name = PrimitiveArrayTypeName(descriptor); if (base_name.length()) { - variables_["array_storage_type"] = "GPB" + base_name + "Array"; + variables_["array_storage_type"] = absl::StrCat("GPB", base_name, "Array"); } else { + std::string storage_type = variables_["storage_type"]; variables_["array_storage_type"] = "NSMutableArray"; variables_["array_property_type"] = - "NSMutableArray<" + variables_["storage_type"] + "*>"; + absl::StrCat("NSMutableArray<", storage_type, "*>"); } }