Migrate std::operator+ to Abseil helpers in Objective-c compiler directory.

This also opportunistically migrates many C-style and STL strings to string_view in touched code.

PiperOrigin-RevId: 502774859
pull/11563/head
Mike Kruskal 2 years ago committed by Copybara-Service
parent 5184022a17
commit 324f0b57d7
  1. 6
      src/google/protobuf/compiler/objectivec/enum_field.cc
  2. 9
      src/google/protobuf/compiler/objectivec/extension.cc
  3. 2
      src/google/protobuf/compiler/objectivec/extension.h
  4. 6
      src/google/protobuf/compiler/objectivec/field.cc
  5. 32
      src/google/protobuf/compiler/objectivec/generator.cc
  6. 47
      src/google/protobuf/compiler/objectivec/helpers.cc
  7. 20
      src/google/protobuf/compiler/objectivec/helpers.h
  8. 15
      src/google/protobuf/compiler/objectivec/import_writer.cc
  9. 6
      src/google/protobuf/compiler/objectivec/line_consumer.cc
  10. 4
      src/google/protobuf/compiler/objectivec/line_consumer.h
  11. 2
      src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc
  12. 23
      src/google/protobuf/compiler/objectivec/map_field.cc
  13. 3
      src/google/protobuf/compiler/objectivec/message_field.cc
  14. 170
      src/google/protobuf/compiler/objectivec/names.cc
  15. 24
      src/google/protobuf/compiler/objectivec/names.h
  16. 5
      src/google/protobuf/compiler/objectivec/primitive_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

@ -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";
}

@ -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;

@ -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.

@ -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()) {

@ -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<std::string> lines;
absl::string_view comments = location.leading_comments.empty()
? location.trailing_comments
: location.leading_comments;
std::vector<absl::string_view> 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

@ -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 "";
}

@ -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;
}

@ -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);

@ -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);

@ -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;
}

@ -99,7 +99,8 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
// Build custom field flags.
std::vector<std::string> 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"] =
"NSMutableDictionary<NSString*, " +
value_field_generator_->variable("storage_type") + "*>";
absl::StrCat("NSMutableDictionary<NSString*, ",
value_field_generator_->variable("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");
}
}

@ -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(

@ -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<std::string, std::string>*
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<absl::string_view>& 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<std::string> values;
std::string current;
@ -552,7 +553,7 @@ const absl::flat_hash_set<absl::string_view>& 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<std::string>& 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<std::string>* 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<std::string>* init_names =
new std::vector<std::string>({"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<std::string>* 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<std::string, std::string>* 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<std::string, std::string>&
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;
}

@ -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);
// ---------------------------------------------------------------------------

@ -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, "*>");
}
}

Loading…
Cancel
Save