Migrate std::operator+ to Abseil helpers in C++ compiler directory.

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

PiperOrigin-RevId: 502739036
pull/11559/head
Mike Kruskal 2 years ago committed by Copybara-Service
parent 4363ef2c92
commit 85b785c32b
  1. 27
      src/google/protobuf/compiler/code_generator.cc
  2. 5
      src/google/protobuf/compiler/code_generator.h
  3. 2
      src/google/protobuf/compiler/cpp/BUILD.bazel
  4. 12
      src/google/protobuf/compiler/cpp/bootstrap_unittest.cc
  5. 14
      src/google/protobuf/compiler/cpp/extension.cc
  6. 8
      src/google/protobuf/compiler/cpp/field_generators/map_field.cc
  7. 8
      src/google/protobuf/compiler/cpp/field_generators/message_field.cc
  8. 6
      src/google/protobuf/compiler/cpp/generator.cc
  9. 76
      src/google/protobuf/compiler/cpp/helpers.cc
  10. 46
      src/google/protobuf/compiler/cpp/helpers.h
  11. 10
      src/google/protobuf/compiler/cpp/message.cc
  12. 29
      src/google/protobuf/compiler/cpp/metadata_test.cc
  13. 4
      src/google/protobuf/compiler/cpp/names.h
  14. 6
      src/google/protobuf/compiler/cpp/parse_function_generator.cc
  15. 9
      src/google/protobuf/compiler/cpp/plugin_unittest.cc
  16. 9
      src/google/protobuf/compiler/cpp/unittest.inc

@ -34,11 +34,14 @@
#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/code_generator.h"
#include <utility>
#include "google/protobuf/compiler/plugin.pb.h" #include "google/protobuf/compiler/plugin.pb.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/logging.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h" #include "absl/strings/strip.h"
namespace google { namespace google {
@ -106,26 +109,24 @@ void GeneratorContext::GetCompilerVersion(Version* version) const {
// Parses a set of comma-delimited name/value pairs. // Parses a set of comma-delimited name/value pairs.
void ParseGeneratorParameter( void ParseGeneratorParameter(
const std::string& text, absl::string_view text,
std::vector<std::pair<std::string, std::string> >* output) { std::vector<std::pair<std::string, std::string> >* output) {
std::vector<std::string> parts = absl::StrSplit(text, ",", absl::SkipEmpty()); std::vector<absl::string_view> 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('='); for (absl::string_view part : parts) {
std::pair<std::string, std::string> value; auto equals_pos = part.find_first_of('=');
if (equals_pos == std::string::npos) { if (equals_pos == absl::string_view::npos) {
value.first = parts[i]; output->emplace_back(part, "");
value.second = "";
} else { } else {
value.first = parts[i].substr(0, equals_pos); output->emplace_back(part.substr(0, equals_pos),
value.second = parts[i].substr(equals_pos + 1); part.substr(equals_pos + 1));
} }
output->push_back(value);
} }
} }
// Strips ".proto" or ".protodevel" from the end of a filename. // 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")) { if (absl::EndsWith(filename, ".protodevel")) {
return std::string(absl::StripSuffix(filename, ".protodevel")); return std::string(absl::StripSuffix(filename, ".protodevel"));
} else { } else {

@ -42,6 +42,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "absl/strings/string_view.h"
#include "google/protobuf/port.h" #include "google/protobuf/port.h"
// Must be included last. // Must be included last.
@ -192,10 +193,10 @@ typedef GeneratorContext OutputDirectory;
// parses to the pairs: // parses to the pairs:
// ("foo", "bar"), ("baz", ""), ("moo", "corge") // ("foo", "bar"), ("baz", ""), ("moo", "corge")
PROTOC_EXPORT void ParseGeneratorParameter( PROTOC_EXPORT void ParseGeneratorParameter(
const std::string&, std::vector<std::pair<std::string, std::string> >*); absl::string_view, std::vector<std::pair<std::string, std::string> >*);
// Strips ".proto" or ".protodevel" from the end of a filename. // 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 compiler
} // namespace protobuf } // namespace protobuf

@ -17,6 +17,7 @@ cc_library(
":names_internal", ":names_internal",
"//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/strings",
], ],
) )
@ -36,6 +37,7 @@ cc_library(
deps = [ deps = [
"//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/strings",
], ],
) )

@ -97,8 +97,8 @@ class MockGeneratorContext : public GeneratorContext {
std::string expected_contents = *it->second; std::string expected_contents = *it->second;
std::string actual_contents; std::string actual_contents;
GOOGLE_ABSL_CHECK_OK( GOOGLE_ABSL_CHECK_OK(File::GetContents(
File::GetContents(TestUtil::TestSourceDir() + "/" + physical_filename, absl::StrCat(TestUtil::TestSourceDir(), "/", physical_filename),
&actual_contents, true)) &actual_contents, true))
<< physical_filename; << physical_filename;
@ -174,8 +174,10 @@ TEST(BootstrapTest, GeneratedFilesMatch) {
FindWithDefault(vpath_map, file_parameter[0], file_parameter[0]); FindWithDefault(vpath_map, file_parameter[0], file_parameter[0]);
std::string rpath = std::string rpath =
FindWithDefault(rpath_map, file_parameter[0], file_parameter[0]); FindWithDefault(rpath_map, file_parameter[0], file_parameter[0]);
context.ExpectFileMatches(vpath + ".pb.cc", rpath + ".pb.cc"); context.ExpectFileMatches(absl::StrCat(vpath, ".pb.cc"),
context.ExpectFileMatches(vpath + ".pb.h", rpath + ".pb.h"); 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( ASSERT_FALSE(generator.Generate(
pool.FindFileByName("google/protobuf/descriptor.proto"), parameter, pool.FindFileByName("google/protobuf/descriptor.proto"), parameter,
generator_context, &error)); generator_context, &error));
EXPECT_EQ(error, "Unknown generator option: " + parameter); EXPECT_EQ(error, absl::StrCat("Unknown generator option: ", parameter));
} }
} // namespace } // namespace

@ -87,8 +87,12 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
absl::StrCat(static_cast<int>(descriptor_->type())); absl::StrCat(static_cast<int>(descriptor_->type()));
variables_["packed"] = descriptor_->is_packed() ? "true" : "false"; variables_["packed"] = descriptor_->is_packed() ? "true" : "false";
std::string scope = std::string scope;
IsScoped() ? ClassName(descriptor_->extension_scope(), false) + "::" : ""; if (IsScoped()) {
scope =
absl::StrCat(ClassName(descriptor_->extension_scope(), false), "::");
}
variables_["scope"] = scope; variables_["scope"] = scope;
variables_["scoped_name"] = ExtensionName(descriptor_); variables_["scoped_name"] = ExtensionName(descriptor_);
variables_["number"] = absl::StrCat(descriptor_->number()); variables_["number"] = absl::StrCat(descriptor_->number());
@ -123,7 +127,7 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const {
if (!IsScoped()) { if (!IsScoped()) {
qualifier = "extern"; qualifier = "extern";
if (!options_.dllexport_decl.empty()) { if (!options_.dllexport_decl.empty()) {
qualifier = options_.dllexport_decl + " " + qualifier; qualifier = absl::StrCat(options_.dllexport_decl, " ", qualifier);
} }
} else { } else {
qualifier = "static"; qualifier = "static";
@ -164,8 +168,8 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
} else if (descriptor_->message_type()) { } else if (descriptor_->message_type()) {
// We have to initialize the default instance for extensions at registration // We have to initialize the default instance for extensions at registration
// time. // time.
default_str = default_str = absl::StrCat(FieldMessageTypeName(descriptor_, options_),
FieldMessageTypeName(descriptor_, options_) + "::default_instance()"; "::default_instance()");
} else { } else {
default_str = DefaultValue(options_, descriptor_); default_str = DefaultValue(options_, descriptor_);
} }

@ -65,10 +65,10 @@ void SetMessageVariables(
default: default:
(*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type()); (*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
} }
(*variables)["key_wire_type"] = (*variables)["key_wire_type"] = absl::StrCat(
"TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type())); "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type())));
(*variables)["val_wire_type"] = (*variables)["val_wire_type"] = absl::StrCat(
"TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type())); "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type())));
(*variables)["map_classname"] = ClassName(descriptor->message_type(), false); (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
(*variables)["number"] = absl::StrCat(descriptor->number()); (*variables)["number"] = absl::StrCat(descriptor->number());
(*variables)["tag"] = absl::StrCat(internal::WireFormat::MakeTag(descriptor)); (*variables)["tag"] = absl::StrCat(internal::WireFormat::MakeTag(descriptor));

@ -49,13 +49,13 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace cpp { namespace cpp {
namespace { namespace {
std::string ReinterpretCast(const std::string& type, std::string ReinterpretCast(absl::string_view type,
const std::string& expression, absl::string_view expression,
bool implicit_weak_field) { bool implicit_weak_field) {
if (implicit_weak_field) { if (implicit_weak_field) {
return "reinterpret_cast< " + type + " >(" + expression + ")"; return absl::StrCat("reinterpret_cast< ", type, " >(", expression, ")");
} else { } else {
return expression; return std::string(expression);
} }
} }

@ -187,12 +187,12 @@ bool CppGenerator::Generate(const FileDescriptor* file,
} else if (value == "always") { } else if (value == "always") {
file_options.tctable_mode = Options::kTCTableAlways; file_options.tctable_mode = Options::kTCTableAlways;
} else { } else {
*error = *error = absl::StrCat(
"Unknown value for experimental_tail_call_table_mode: " + value; "Unknown value for experimental_tail_call_table_mode: ", value);
return false; return false;
} }
} else { } else {
*error = "Unknown generator option: " + key; *error = absl::StrCat("Unknown generator option: ", key);
return false; return false;
} }
} }

@ -194,7 +194,7 @@ const absl::flat_hash_set<absl::string_view>& Keywords() {
return *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"); 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) { bool cap_next_letter) {
std::string result; std::string result;
// Note: I distrust ctype.h due to locales. // 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) { std::string ClassName(const Descriptor* descriptor) {
const Descriptor* parent = descriptor->containing_type(); const Descriptor* parent = descriptor->containing_type();
std::string res; std::string res;
if (parent) res += ClassName(parent) + "_"; if (parent) absl::StrAppend(&res, ClassName(parent), "_");
res += descriptor->name(); absl::StrAppend(&res, descriptor->name());
if (IsMapEntryMessage(descriptor)) res += "_DoNotUse"; if (IsMapEntryMessage(descriptor)) absl::StrAppend(&res, "_DoNotUse");
return ResolveKeyword(res); return ResolveKeyword(res);
} }
@ -409,8 +409,8 @@ std::string ClassName(const EnumDescriptor* enum_descriptor) {
if (enum_descriptor->containing_type() == nullptr) { if (enum_descriptor->containing_type() == nullptr) {
return ResolveKeyword(enum_descriptor->name()); return ResolveKeyword(enum_descriptor->name());
} else { } else {
return ClassName(enum_descriptor->containing_type()) + "_" + return absl::StrCat(ClassName(enum_descriptor->containing_type()), "_",
enum_descriptor->name(); enum_descriptor->name());
} }
} }
@ -447,9 +447,9 @@ std::string QualifiedExtensionName(const FieldDescriptor* d) {
return QualifiedExtensionName(d, Options()); return QualifiedExtensionName(d, Options());
} }
std::string Namespace(const std::string& package) { std::string Namespace(absl::string_view package) {
if (package.empty()) return ""; if (package.empty()) return "";
return "::" + DotsToColons(package); return absl::StrCat("::", DotsToColons(package));
} }
std::string Namespace(const FileDescriptor* d) { return Namespace(d, {}); } 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, std::string DefaultInstanceName(const Descriptor* descriptor,
const Options& /*options*/, bool split) { const Options& /*options*/, bool split) {
return "_" + ClassName(descriptor, false) + (split ? "__Impl_Split" : "") + return absl::StrCat("_", ClassName(descriptor, false),
"_default_instance_"; (split ? "__Impl_Split" : ""), "_default_instance_");
} }
std::string DefaultInstancePtr(const Descriptor* descriptor, std::string DefaultInstancePtr(const Descriptor* descriptor,
const Options& options, bool split) { 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, std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
@ -509,7 +509,8 @@ std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor, std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
const Options& options, bool split) { 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, 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, std::string SuperClassName(const Descriptor* descriptor,
const Options& options) { const Options& options) {
if (!HasDescriptorMethods(descriptor->file(), options)) { if (!HasDescriptorMethods(descriptor->file(), options)) {
return "::" + ProtobufNamespace(options) + "::MessageLite"; return absl::StrCat("::", ProtobufNamespace(options), "::MessageLite");
} }
auto simple_base = SimpleBaseClass(descriptor, options); auto simple_base = SimpleBaseClass(descriptor, options);
if (simple_base.empty()) { 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) { if (Keywords().count(name) > 0) {
return name + "_"; return absl::StrCat(name, "_");
} }
return name; return std::string(name);
} }
std::string FieldName(const FieldDescriptor* field) { std::string FieldName(const FieldDescriptor* field) {
@ -565,7 +567,7 @@ std::string FieldMemberName(const FieldDescriptor* field, bool split) {
std::string OneofCaseConstantName(const FieldDescriptor* field) { std::string OneofCaseConstantName(const FieldDescriptor* field) {
GOOGLE_ABSL_DCHECK(field->containing_oneof()); GOOGLE_ABSL_DCHECK(field->containing_oneof());
std::string field_name = UnderscoresToCamelCase(field->name(), true); std::string field_name = UnderscoresToCamelCase(field->name(), true);
return "k" + field_name; return absl::StrCat("k", field_name);
} }
std::string QualifiedOneofCaseConstantName(const FieldDescriptor* field) { std::string QualifiedOneofCaseConstantName(const FieldDescriptor* field) {
@ -609,7 +611,7 @@ int EstimateAlignmentSize(const FieldDescriptor* field) {
std::string FieldConstantName(const FieldDescriptor* field) { std::string FieldConstantName(const FieldDescriptor* field) {
std::string field_name = UnderscoresToCamelCase(field->name(), true); 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() && if (!field->is_extension() &&
field->containing_type()->FindFieldByCamelcaseName( 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 // 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, // number to the constant name. This makes the constant rather useless,
// but what can we do? // but what can we do?
result += "_" + absl::StrCat(field->number()); absl::StrAppend(&result, "_", field->number());
} }
return result; return result;
@ -630,7 +632,7 @@ std::string FieldMessageTypeName(const FieldDescriptor* field,
return QualifiedClassName(field->message_type(), options); 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 * TODO(github/georgthegreat) remove this proxy method
* once Google's internal codebase will become ready * 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: case FieldDescriptor::CPPTYPE_INT32:
return Int32ToString(field->default_value_int32()); return Int32ToString(field->default_value_int32());
case FieldDescriptor::CPPTYPE_UINT32: case FieldDescriptor::CPPTYPE_UINT32:
return absl::StrCat(field->default_value_uint32()) + "u"; return absl::StrCat(field->default_value_uint32(), "u");
case FieldDescriptor::CPPTYPE_INT64: case FieldDescriptor::CPPTYPE_INT64:
return Int64ToString(field->default_value_int64()); return Int64ToString(field->default_value_int64());
case FieldDescriptor::CPPTYPE_UINT64: 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), "static_cast< $0 >($1)", ClassName(field->enum_type(), true),
Int32ToString(field->default_value_enum()->number())); Int32ToString(field->default_value_enum()->number()));
case FieldDescriptor::CPPTYPE_STRING: case FieldDescriptor::CPPTYPE_STRING:
return "\"" + return absl::StrCat(
EscapeTrigraphs(absl::CEscape(field->default_value_string())) + "\"", EscapeTrigraphs(absl::CEscape(field->default_value_string())),
"\""; "\"");
case FieldDescriptor::CPPTYPE_MESSAGE: case FieldDescriptor::CPPTYPE_MESSAGE:
return "*" + FieldMessageTypeName(field, options) + return absl::StrCat("*", FieldMessageTypeName(field, options),
"::internal_default_instance()"; "::internal_default_instance()");
} }
// Can't actually get here; make compiler happy. (We could add a default // 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 // 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. // 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; std::string result;
for (int i = 0; i < filename.size(); i++) { for (int i = 0; i < filename.size(); i++) {
if (absl::ascii_isalnum(filename[i])) { if (absl::ascii_isalnum(filename[i])) {
@ -856,14 +858,14 @@ std::string FilenameIdentifier(const std::string& filename) {
return result; 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) { const Options& options) {
return name + "_" + FilenameIdentifier(filename); return absl::StrCat(name, "_", FilenameIdentifier(filename));
} }
// Return the qualified C++ name for a file level symbol. // Return the qualified C++ name for a file level symbol.
std::string QualifiedFileLevelSymbol(const FileDescriptor* file, std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
const std::string& name, absl::string_view name,
const Options& options) { const Options& options) {
if (file->package().empty()) { if (file->package().empty()) {
return absl::StrCat("::", name); return absl::StrCat("::", name);
@ -879,11 +881,11 @@ std::string EscapeTrigraphs(absl::string_view to_escape) {
// Escaped function name to eliminate naming conflict. // Escaped function name to eliminate naming conflict.
std::string SafeFunctionName(const Descriptor* descriptor, std::string SafeFunctionName(const Descriptor* descriptor,
const FieldDescriptor* field, const FieldDescriptor* field,
const std::string& prefix) { absl::string_view prefix) {
// Do not use FieldName() since it will escape keywords. // Do not use FieldName() since it will escape keywords.
std::string name = field->name(); std::string name = field->name();
absl::AsciiStrToLower(&name); absl::AsciiStrToLower(&name);
std::string function_name = prefix + name; std::string function_name = absl::StrCat(prefix, name);
if (descriptor->FindFieldByName(function_name)) { if (descriptor->FindFieldByName(function_name)) {
// Single underscore will also make it conflicting with the private data // Single underscore will also make it conflicting with the private data
// member. We use double underscore to escape function names. // 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) { std::string* bootstrap_basename) {
if (options.opensource_runtime) { if (options.opensource_runtime) {
return false; return false;
@ -1427,7 +1429,7 @@ bool GetBootstrapBasename(const Options& options, const std::string& basename,
}; };
auto iter = bootstrap_mapping->find(basename); auto iter = bootstrap_mapping->find(basename);
if (iter == bootstrap_mapping->end()) { if (iter == bootstrap_mapping->end()) {
*bootstrap_basename = basename; *bootstrap_basename = std::string(basename);
return false; return false;
} else { } else {
*bootstrap_basename = iter->second; *bootstrap_basename = iter->second;

@ -104,7 +104,7 @@ void SetUnknownFieldsVariable(
const Descriptor* descriptor, const Options& options, const Descriptor* descriptor, const Options& options,
absl::flat_hash_map<absl::string_view, std::string>* variables); absl::flat_hash_map<absl::string_view, std::string>* variables);
bool GetBootstrapBasename(const Options& options, const std::string& basename, bool GetBootstrapBasename(const Options& options, absl::string_view basename,
std::string* bootstrap_basename); std::string* bootstrap_basename);
bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context, bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
bool bootstrap_flag, std::string* basename); bool bootstrap_flag, std::string* basename);
@ -208,7 +208,7 @@ std::string SuperClassName(const Descriptor* descriptor,
const Options& options); const Options& options);
// Adds an underscore if necessary to prevent conflicting with a keyword. // 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. // 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 // 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); std::string DefaultValue(const FieldDescriptor* field);
// Convert a file name into a valid identifier. // 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 // For each .proto file generates a unique name. To prevent collisions of
// symbols in the global namespace // 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); 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) { const Options& options) {
return UniqueName(name, d->name(), 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) { const Options& options) {
return UniqueName(name, d->file(), 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) { const Options& options) {
return UniqueName(name, d->file(), 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 ServiceDescriptor* d,
const Options& options) { const Options& options) {
return UniqueName(name, d->file(), options); return UniqueName(name, d->file(), options);
@ -291,29 +291,27 @@ inline Options InternalRuntimeOptions() {
options.opensource_runtime = false; options.opensource_runtime = false;
return options; return options;
} }
inline std::string UniqueName(const std::string& name, inline std::string UniqueName(absl::string_view name,
const std::string& filename) { absl::string_view filename) {
return UniqueName(name, filename, InternalRuntimeOptions()); return UniqueName(name, filename, InternalRuntimeOptions());
} }
inline std::string UniqueName(const std::string& name, inline std::string UniqueName(absl::string_view name, const FileDescriptor* d) {
const FileDescriptor* d) {
return UniqueName(name, d->name(), InternalRuntimeOptions()); 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()); return UniqueName(name, d->file(), InternalRuntimeOptions());
} }
inline std::string UniqueName(const std::string& name, inline std::string UniqueName(absl::string_view name, const EnumDescriptor* d) {
const EnumDescriptor* d) {
return UniqueName(name, d->file(), InternalRuntimeOptions()); 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) { const ServiceDescriptor* d) {
return UniqueName(name, d->file(), InternalRuntimeOptions()); return UniqueName(name, d->file(), InternalRuntimeOptions());
} }
// Return the qualified C++ name for a file level symbol. // Return the qualified C++ name for a file level symbol.
std::string QualifiedFileLevelSymbol(const FileDescriptor* file, std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
const std::string& name, absl::string_view name,
const Options& options); const Options& options);
// Escape C++ trigraphs by escaping question marks to \? // 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. // Escaped function name to eliminate naming conflict.
std::string SafeFunctionName(const Descriptor* descriptor, std::string SafeFunctionName(const Descriptor* descriptor,
const FieldDescriptor* field, const FieldDescriptor* field,
const std::string& prefix); absl::string_view prefix);
// Returns true if generated messages have public unknown fields accessors // Returns true if generated messages have public unknown fields accessors
inline bool PublicUnknownFieldsAccessors(const Descriptor* message) { 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. // Returns true if the field's CPPTYPE is string or message.
bool IsStringOrMessage(const FieldDescriptor* field); bool IsStringOrMessage(const FieldDescriptor* field);
std::string UnderscoresToCamelCase(const std::string& input, std::string UnderscoresToCamelCase(absl::string_view input,
bool cap_next_letter); bool cap_next_letter);
inline bool IsProto3(const FileDescriptor* file) { 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 // have distinct include guards, because some source files include both and
// both need to be defined (the third_party copies will be in the // both need to be defined (the third_party copies will be in the
// google::protobuf_opensource namespace). // google::protobuf_opensource namespace).
return MacroPrefix(options) + "_INCLUDED_" + filename_identifier; return absl::StrCat(MacroPrefix(options), "_INCLUDED_",
filename_identifier);
} else { } else {
// Ideally this case would use distinct include guards for opensource and // Ideally this case would use distinct include guards for opensource and
// google3 protos also. (The behavior of "first #included wins" is not // 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. // the identical include guards to avoid compile errors.
// //
// We should clean this up so that this case can be removed. // 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<absl::string_view, std::string> vars_; absl::flat_hash_map<absl::string_view, std::string> vars_;
// Convenience overloads to accept different types as arguments. // 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 <typename I, typename = typename std::enable_if< template <typename I, typename = typename std::enable_if<
std::is_integral<I>::value>::type> std::is_integral<I>::value>::type>
static std::string ToString(I x) { static std::string ToString(I x) {
@ -1012,7 +1011,8 @@ struct OneOfRangeImpl {
inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; } 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, bool ShouldVerify(const Descriptor* descriptor, const Options& options,
MessageSCCAnalyzer* scc_analyzer); MessageSCCAnalyzer* scc_analyzer);

@ -288,10 +288,10 @@ void CollectMapInfo(
default: default:
vars["val_cpp"] = PrimitiveTypeName(options, val->cpp_type()); vars["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
} }
vars["key_wire_type"] = vars["key_wire_type"] = absl::StrCat(
"TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type())); "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(key->type())));
vars["val_wire_type"] = vars["val_wire_type"] = absl::StrCat(
"TYPE_" + absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type())); "TYPE_", absl::AsciiStrToUpper(DeclaredTypeMethodName(val->type())));
} }
@ -2142,7 +2142,7 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(io::Printer* p) {
format("PROTOBUF_FIELD_OFFSET($classtype$$1$, $2$)", format("PROTOBUF_FIELD_OFFSET($classtype$$1$, $2$)",
ShouldSplit(field, options_) ? "::Impl_::Split" : "", ShouldSplit(field, options_) ? "::Impl_::Split" : "",
ShouldSplit(field, options_) ShouldSplit(field, options_)
? FieldName(field) + "_" ? absl::StrCat(FieldName(field), "_")
: FieldMemberName(field, /*cold=*/false)); : FieldMemberName(field, /*cold=*/false));
} }

@ -63,11 +63,11 @@ class CppMetadataTest : public ::testing::Test {
CommandLineInterface cli; CommandLineInterface cli;
CppGenerator cpp_generator; CppGenerator cpp_generator;
cli.RegisterGenerator("--cpp_out", &cpp_generator, ""); cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
std::string cpp_out = std::string cpp_out = absl::StrCat(
"--cpp_out=annotate_headers=true," "--cpp_out=annotate_headers=true,"
"annotation_pragma_name=pragma_name," "annotation_pragma_name=pragma_name,"
"annotation_guard_name=guard_name:" + "annotation_guard_name=guard_name:",
TestTempDir(); TestTempDir());
const bool result = atu::RunProtoCompiler(filename, cpp_out, &cli, file); const bool result = atu::RunProtoCompiler(filename, cpp_out, &cli, file);
@ -75,25 +75,28 @@ class CppMetadataTest : public ::testing::Test {
return result; return result;
} }
std::string output_base = TestTempDir() + "/" + StripProto(filename); std::string output_base =
absl::StrCat(TestTempDir(), "/", StripProto(filename));
if (pb_cc != nullptr) { if (pb_cc != nullptr) {
GOOGLE_ABSL_CHECK_OK( GOOGLE_ABSL_CHECK_OK(File::GetContents(absl::StrCat(output_base, ".pb.cc"),
File::GetContents(output_base + ".pb.cc", pb_cc, true)); pb_cc, true));
} }
if (pb_h != nullptr && pb_h_info != nullptr) { if (pb_h != nullptr && pb_h_info != nullptr) {
GOOGLE_ABSL_CHECK_OK( GOOGLE_ABSL_CHECK_OK(File::GetContents(absl::StrCat(output_base, ".pb.h"), pb_h,
File::GetContents(output_base + ".pb.h", pb_h, true)); true));
if (!atu::DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) { if (!atu::DecodeMetadata(absl::StrCat(output_base, ".pb.h.meta"),
pb_h_info)) {
return false; return false;
} }
} }
if (proto_h != nullptr && proto_h_info != nullptr) { if (proto_h != nullptr && proto_h_info != nullptr) {
GOOGLE_ABSL_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h, GOOGLE_ABSL_CHECK_OK(File::GetContents(absl::StrCat(output_base, ".proto.h"),
true)); proto_h, true));
if (!atu::DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) { if (!atu::DecodeMetadata(absl::StrCat(output_base, ".proto.h.meta"),
proto_h_info)) {
return false; return false;
} }
} }
@ -102,7 +105,7 @@ class CppMetadataTest : public ::testing::Test {
} }
}; };
const char kSmallTestFile[] = constexpr absl::string_view kSmallTestFile =
"syntax = \"proto2\";\n" "syntax = \"proto2\";\n"
"package foo;\n" "package foo;\n"
"enum Enum { VALUE = 0; }\n" "enum Enum { VALUE = 0; }\n"

@ -33,6 +33,8 @@
#include <string> #include <string>
#include "absl/strings/string_view.h"
// Must be included last. // Must be included last.
#include "google/protobuf/port_def.inc" #include "google/protobuf/port_def.inc"
@ -98,7 +100,7 @@ std::string QualifiedOneofCaseConstantName(const FieldDescriptor* field);
std::string EnumValueName(const EnumValueDescriptor* enum_value); std::string EnumValueName(const EnumValueDescriptor* enum_value);
// Strips ".proto" or ".protodevel" from the end of a filename. // 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 cpp
} // namespace compiler } // namespace compiler

@ -458,12 +458,12 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) {
// All entries without a fast-path parsing function need a fallback. // All entries without a fast-path parsing function need a fallback.
std::string fallback; std::string fallback;
if (tc_table_info_->use_generated_fallback) { if (tc_table_info_->use_generated_fallback) {
fallback = ClassName(descriptor_) + "::Tct_ParseFallback"; fallback = absl::StrCat(ClassName(descriptor_), "::Tct_ParseFallback");
} else { } else {
fallback = "::_pbi::TcParser::GenericFallback"; fallback = "::_pbi::TcParser::GenericFallback";
if (GetOptimizeFor(descriptor_->file(), options_) == if (GetOptimizeFor(descriptor_->file(), options_) ==
FileOptions::LITE_RUNTIME) { FileOptions::LITE_RUNTIME) {
fallback += "Lite"; absl::StrAppend(&fallback, "Lite");
} }
} }
@ -842,7 +842,7 @@ void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) {
bool split = ShouldSplit(field, options_); bool split = ShouldSplit(field, options_);
if (split) { if (split) {
format("PROTOBUF_FIELD_OFFSET($classname$::Impl_::Split, $1$), ", format("PROTOBUF_FIELD_OFFSET($classname$::Impl_::Split, $1$), ",
FieldName(field) + "_"); absl::StrCat(FieldName(field), "_"));
} else { } else {
format("PROTOBUF_FIELD_OFFSET($classname$, $1$), ", format("PROTOBUF_FIELD_OFFSET($classname$, $1$), ",
FieldMemberName(field, /*cold=*/false)); FieldMemberName(field, /*cold=*/false));

@ -172,7 +172,8 @@ class TestGenerator : public CodeGenerator {
// not verify that they are correctly-placed; that would require actually // 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. // compiling the output which is a bit more than I care to do for this test.
TEST(CppPluginTest, PluginTest) { TEST(CppPluginTest, PluginTest) {
GOOGLE_ABSL_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto", GOOGLE_ABSL_CHECK_OK(
File::SetContents(absl::StrCat(TestTempDir(), "/test.proto"),
"syntax = \"proto2\";\n" "syntax = \"proto2\";\n"
"package foo;\n" "package foo;\n"
"\n" "\n"
@ -219,9 +220,9 @@ TEST(CppPluginTest, PluginTest) {
cli.RegisterGenerator("--cpp_out", &cpp_generator, ""); cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
cli.RegisterGenerator("--test_out", &test_generator, ""); cli.RegisterGenerator("--test_out", &test_generator, "");
std::string proto_path = "-I" + TestTempDir(); std::string proto_path = absl::StrCat("-I", TestTempDir());
std::string cpp_out = "--cpp_out=" + TestTempDir(); std::string cpp_out = absl::StrCat("--cpp_out=", TestTempDir());
std::string test_out = "--test_out=" + TestTempDir(); std::string test_out = absl::StrCat("--test_out=", TestTempDir());
const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(), const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(),
test_out.c_str(), "test.proto"}; test_out.c_str(), "test.proto"};

@ -2107,10 +2107,11 @@ TEST(HELPERS_TEST_NAME, TestSCC) {
std::string package = a.GetDescriptor()->file()->package(); std::string package = a.GetDescriptor()->file()->package();
ASSERT_EQ(names.size(), 4); ASSERT_EQ(names.size(), 4);
std::sort(names.begin(), names.end()); std::sort(names.begin(), names.end());
EXPECT_EQ(names[0], package + ".TestMutualRecursionA"); EXPECT_EQ(names[0], absl::StrCat(package, ".TestMutualRecursionA"));
EXPECT_EQ(names[1], package + ".TestMutualRecursionA.SubGroup"); EXPECT_EQ(names[1], absl::StrCat(package, ".TestMutualRecursionA.SubGroup"));
EXPECT_EQ(names[2], package + ".TestMutualRecursionA.SubMessage"); EXPECT_EQ(names[2],
EXPECT_EQ(names[3], package + ".TestMutualRecursionB"); absl::StrCat(package, ".TestMutualRecursionA.SubMessage"));
EXPECT_EQ(names[3], absl::StrCat(package, ".TestMutualRecursionB"));
MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
EXPECT_EQ(result.is_recursive, true); EXPECT_EQ(result.is_recursive, true);

Loading…
Cancel
Save