protoc-c: add c_package option

This option allows to override the top-level 'package' setting, or even
remove the package prefix altogether (if set to "").

Fixes #322
This commit is contained in:
Ilya Lipnitskiy 2021-03-21 19:46:21 -07:00
parent 4f39ca6e0c
commit 7df109917a
No known key found for this signature in database
GPG Key ID: 435C02AAE7CF2014
12 changed files with 81 additions and 58 deletions

View File

@ -52,6 +52,9 @@ message ProtobufCFileOptions {
// For oneof fields, set ProtobufCFieldDescriptor name field to the
// name of the containing oneof, instead of the field name
optional bool use_oneof_field_name = 5 [default = false];
// Overrides the package name, if present
optional string c_package = 6;
}
extend google.protobuf.FileOptions {

View File

@ -114,7 +114,7 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
vars["default_value_data"] = FullNameToLower(descriptor_->full_name())
vars["default_value_data"] = FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data";
printer->Print(vars, "extern uint8_t $default_value_data$[];\n");
}
@ -122,7 +122,7 @@ void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer)
void BytesFieldGenerator::GenerateDefaultValueImplementations(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
vars["default_value_data"] = FullNameToLower(descriptor_->full_name())
vars["default_value_data"] = FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data";
vars["escaped"] = CEscape(descriptor_->default_value_string());
printer->Print(vars, "uint8_t $default_value_data$[] = \"$escaped$\";\n");
@ -132,7 +132,7 @@ std::string BytesFieldGenerator::GetDefaultValue(void) const
return "{ "
+ SimpleItoa(descriptor_->default_value_string().size())
+ ", "
+ FullNameToLower(descriptor_->full_name())
+ FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data }";
}
void BytesFieldGenerator::GenerateStaticInit(io::Printer* printer) const

View File

@ -82,9 +82,9 @@ EnumGenerator::~EnumGenerator() {}
void EnumGenerator::GenerateDefinition(io::Printer* printer) {
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name());
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = descriptor_->name();
vars["uc_name"] = FullNameToUpper(descriptor_->full_name());
vars["uc_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
SourceLocation sourceLoc;
descriptor_->GetSourceLocation(&sourceLoc);
@ -98,7 +98,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
vars["opt_comma"] = ",";
vars["prefix"] = FullNameToUpper(descriptor_->full_name()) + "__";
vars["prefix"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__";
for (int i = 0; i < descriptor_->value_count(); i++) {
vars["name"] = descriptor_->value(i)->name();
vars["number"] = SimpleItoa(descriptor_->value(i)->number());
@ -132,8 +132,8 @@ void EnumGenerator::GenerateDescriptorDeclarations(io::Printer* printer) {
} else {
vars["dllexport"] = dllexport_decl_ + " ";
}
vars["classname"] = FullNameToC(descriptor_->full_name());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name());
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
printer->Print(vars,
"extern $dllexport$const ProtobufCEnumDescriptor $lcclassname$__descriptor;\n");
@ -154,7 +154,7 @@ void EnumGenerator::GenerateValueInitializer(io::Printer *printer, int index)
descriptor_->file()->options().optimize_for() ==
FileOptions_OptimizeMode_CODE_SIZE;
vars["enum_value_name"] = vd->name();
vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name()) + "__" + vd->name();
vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__" + vd->name();
vars["value"] = SimpleItoa(vd->number());
if (optimize_code_size)
printer->Print(vars, " { NULL, NULL, $value$ }, /* CODE_SIZE */\n");
@ -184,8 +184,8 @@ static int compare_value_indices_by_name(const void *a, const void *b)
void EnumGenerator::GenerateEnumDescriptor(io::Printer* printer) {
std::map<std::string, std::string> vars;
vars["fullname"] = descriptor_->full_name();
vars["lcclassname"] = FullNameToLower(descriptor_->full_name());
vars["cname"] = FullNameToC(descriptor_->full_name());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["cname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = descriptor_->name();
vars["packagename"] = descriptor_->file()->package();
vars["value_count"] = SimpleItoa(descriptor_->value_count());

View File

@ -78,9 +78,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) {
(*variables)["name"] = FieldName(descriptor);
(*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name());
(*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name(), descriptor->enum_type()->file());
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
(*variables)["default"] = FullNameToUpper(default_value->type()->full_name())
(*variables)["default"] = FullNameToUpper(default_value->type()->full_name(), default_value->type()->file())
+ "__" + default_value->name();
(*variables)["deprecated"] = FieldDeprecated(descriptor);
}
@ -138,7 +138,7 @@ void EnumFieldGenerator::GenerateStaticInit(io::Printer* printer) const
void EnumFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
std::string addr = "&" + FullNameToLower(descriptor_->enum_type()->full_name()) + "__descriptor";
std::string addr = "&" + FullNameToLower(descriptor_->enum_type()->full_name(), descriptor_->enum_type()->file()) + "__descriptor";
GenerateDescriptorInitializerGeneric(printer, true, "ENUM", addr);
}

View File

@ -110,7 +110,7 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
const OneofDescriptor *oneof = descriptor_->containing_oneof();
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
variables["TYPE"] = type_macro;
variables["classname"] = FullNameToC(FieldScope(descriptor_)->full_name());
variables["classname"] = FullNameToC(FieldScope(descriptor_)->full_name(), FieldScope(descriptor_)->file());
variables["name"] = FieldName(descriptor_);
if (opt.use_oneof_field_name())
variables["proto_name"] = oneof->name();
@ -131,7 +131,7 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
if (descriptor_->has_default_value()) {
variables["default_value"] = std::string("&")
+ FullNameToLower(descriptor_->full_name())
+ FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value";
} else if (FieldSyntax(descriptor_) == 3 &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {

View File

@ -177,9 +177,23 @@ std::string ToCamel(const std::string &name) {
return rv;
}
std::string FullNameToLower(const std::string &full_name) {
std::string OverrideFullName(const std::string &full_name,
const FileDescriptor *file) {
const ProtobufCFileOptions opt = file->options().GetExtension(pb_c_file);
if (!opt.has_c_package())
return full_name;
std::string new_name = opt.c_package();
if (file->package().empty())
new_name += ".";
return new_name + full_name.substr(file->package().length());
}
std::string FullNameToLower(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces;
SplitStringUsing(full_name, ".", &pieces);
SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue;
@ -188,9 +202,10 @@ std::string FullNameToLower(const std::string &full_name) {
}
return rv;
}
std::string FullNameToUpper(const std::string &full_name) {
std::string FullNameToUpper(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces;
SplitStringUsing(full_name, ".", &pieces);
SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue;
@ -199,9 +214,10 @@ std::string FullNameToUpper(const std::string &full_name) {
}
return rv;
}
std::string FullNameToC(const std::string &full_name) {
std::string FullNameToC(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces;
SplitStringUsing(full_name, ".", &pieces);
SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue;

View File

@ -121,11 +121,11 @@ std::string ToLower(const std::string &class_name);
std::string ToUpper(const std::string &class_name);
// full_name() to lowercase with underscores
std::string FullNameToLower(const std::string &full_name);
std::string FullNameToUpper(const std::string &full_name);
std::string FullNameToLower(const std::string &full_name, const FileDescriptor *file);
std::string FullNameToUpper(const std::string &full_name, const FileDescriptor *file);
// full_name() to c-typename (with underscores for packages, otherwise camel case)
std::string FullNameToC(const std::string &class_name);
std::string FullNameToC(const std::string &class_name, const FileDescriptor *file);
// Splits, indents, formats, and prints comment lines
void PrintComment (io::Printer* printer, std::string comment);

View File

@ -112,7 +112,7 @@ MessageGenerator::~MessageGenerator() {}
void MessageGenerator::
GenerateStructTypedef(io::Printer* printer) {
printer->Print("typedef struct $classname$ $classname$;\n",
"classname", FullNameToC(descriptor_->full_name()));
"classname", FullNameToC(descriptor_->full_name(), descriptor_->file()));
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateStructTypedef(printer);
@ -138,9 +138,9 @@ GenerateStructDefinition(io::Printer* printer) {
}
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name());
vars["ucclassname"] = FullNameToUpper(descriptor_->full_name());
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["ucclassname"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
vars["field_count"] = SimpleItoa(descriptor_->field_count());
if (dllexport_decl_.empty()) {
vars["dllexport"] = "";
@ -154,7 +154,7 @@ GenerateStructDefinition(io::Printer* printer) {
vars["opt_comma"] = ",";
vars["oneofname"] = CamelToUpper(oneof->name());
vars["foneofname"] = FullNameToC(oneof->full_name());
vars["foneofname"] = FullNameToC(oneof->full_name(), oneof->file());
printer->Print("typedef enum {\n");
printer->Indent();
@ -205,7 +205,7 @@ GenerateStructDefinition(io::Printer* printer) {
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["oneofname"] = CamelToLower(oneof->name());
vars["foneofname"] = FullNameToC(oneof->full_name());
vars["foneofname"] = FullNameToC(oneof->full_name(), oneof->file());
printer->Print(vars, "$foneofname$Case $oneofname$_case;\n");
@ -245,7 +245,7 @@ GenerateStructDefinition(io::Printer* printer) {
}
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["foneofname"] = FullNameToUpper(oneof->full_name());
vars["foneofname"] = FullNameToUpper(oneof->full_name(), oneof->file());
// Initialize the case enum
printer->Print(vars, ", $foneofname$__NOT_SET");
// Initialize the union
@ -278,8 +278,8 @@ GenerateHelperFunctionDeclarations(io::Printer* printer,
}
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name());
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
if (gen_init) {
printer->Print(vars,
"/* $classname$ methods */\n"
@ -312,7 +312,7 @@ GenerateHelperFunctionDeclarations(io::Printer* printer,
void MessageGenerator::
GenerateDescriptorDeclarations(io::Printer* printer) {
printer->Print("extern const ProtobufCMessageDescriptor $name$__descriptor;\n",
"name", FullNameToLower(descriptor_->full_name()));
"name", FullNameToLower(descriptor_->full_name(), descriptor_->file()));
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateDescriptorDeclarations(printer);
@ -328,7 +328,7 @@ void MessageGenerator::GenerateClosureTypedef(io::Printer* printer)
nested_generators_[i]->GenerateClosureTypedef(printer);
}
std::map<std::string, std::string> vars;
vars["name"] = FullNameToC(descriptor_->full_name());
vars["name"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
printer->Print(vars,
"typedef void (*$name$_Closure)\n"
" (const $name$ *message,\n"
@ -368,9 +368,9 @@ GenerateHelperFunctionDefinitions(io::Printer* printer,
}
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name());
vars["ucclassname"] = FullNameToUpper(descriptor_->full_name());
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["ucclassname"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
vars["base"] = opt.base_field_name();
if (gen_init) {
printer->Print(vars,
@ -430,8 +430,8 @@ void MessageGenerator::
GenerateMessageDescriptor(io::Printer* printer, bool gen_init) {
std::map<std::string, std::string> vars;
vars["fullname"] = descriptor_->full_name();
vars["classname"] = FullNameToC(descriptor_->full_name());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name());
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = ToCamel(descriptor_->name());
vars["n_fields"] = SimpleItoa(descriptor_->field_count());
vars["packagename"] = descriptor_->file()->package();
@ -517,7 +517,7 @@ GenerateMessageDescriptor(io::Printer* printer, bool gen_init) {
case FieldDescriptor::CPPTYPE_ENUM:
{
const EnumValueDescriptor *vd = fd->default_value_enum();
vars["field_dv_ctype"] = FullNameToC(vd->type()->full_name());
vars["field_dv_ctype"] = FullNameToC(vd->type()->full_name(), vd->type()->file());
break;
}
default:

View File

@ -85,7 +85,7 @@ void MessageFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
vars["name"] = FieldName(descriptor_);
vars["type"] = FullNameToC(descriptor_->message_type()->full_name());
vars["type"] = FullNameToC(descriptor_->message_type()->full_name(), descriptor_->message_type()->file());
vars["deprecated"] = FieldDeprecated(descriptor_);
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
@ -119,7 +119,7 @@ void MessageFieldGenerator::GenerateStaticInit(io::Printer* printer) const
}
void MessageFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
std::string addr = "&" + FullNameToLower(descriptor_->message_type()->full_name()) + "__descriptor";
std::string addr = "&" + FullNameToLower(descriptor_->message_type()->full_name(), descriptor_->message_type()->file()) + "__descriptor";
GenerateDescriptorInitializerGeneric(printer, false, "MESSAGE", addr);
}

View File

@ -74,9 +74,9 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
: descriptor_(descriptor) {
vars_["name"] = descriptor_->name();
vars_["fullname"] = descriptor_->full_name();
vars_["cname"] = FullNameToC(descriptor_->full_name());
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name());
vars_["ucfullname"] = FullNameToUpper(descriptor_->full_name());
vars_["cname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["ucfullname"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
vars_["lcfullpadd"] = ConvertToSpaces(vars_["lcfullname"]);
vars_["package"] = descriptor_->file()->package();
if (dllexport_decl.empty()) {
@ -107,8 +107,8 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
std::string lcname = CamelToLower(method->name());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name());
vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
printer->Print(vars_,
" void (*$method$)($cname$_Service *service,\n"
" $metpad$ const $input_typename$ *input,\n"
@ -145,11 +145,11 @@ void ServiceGenerator::GenerateCallersDeclarations(io::Printer* printer)
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name());
std::string lcfullname = FullNameToLower(descriptor_->full_name());
std::string lcfullname = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name());
vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname);
printer->Print(vars_,
"void $lcfullname$__$method$(ProtobufCService *service,\n"
@ -208,8 +208,8 @@ void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer)
for (int i = 0; i < n_methods; i++) {
const MethodDescriptor *method = descriptor_->method(i);
vars_["method"] = method->name();
vars_["input_descriptor"] = "&" + FullNameToLower(method->input_type()->full_name()) + "__descriptor";
vars_["output_descriptor"] = "&" + FullNameToLower(method->output_type()->full_name()) + "__descriptor";
vars_["input_descriptor"] = "&" + FullNameToLower(method->input_type()->full_name(), method->input_type()->file()) + "__descriptor";
vars_["output_descriptor"] = "&" + FullNameToLower(method->output_type()->full_name(), method->output_type()->file()) + "__descriptor";
if (optimize_code_size) {
printer->Print(vars_,
" { NULL, $input_descriptor$, $output_descriptor$ }, /* CODE_SIZE */\n");
@ -267,11 +267,11 @@ void ServiceGenerator::GenerateCallersImplementations(io::Printer* printer)
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name());
std::string lcfullname = FullNameToLower(descriptor_->full_name());
std::string lcfullname = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name());
vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname);
vars_["index"] = SimpleItoa(i);

View File

@ -76,7 +76,7 @@ using internal::WireFormat;
void SetStringVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) {
(*variables)["name"] = FieldName(descriptor);
(*variables)["default"] = FullNameToLower(descriptor->full_name())
(*variables)["default"] = FullNameToLower(descriptor->full_name(), descriptor->file())
+ "__default_value";
(*variables)["deprecated"] = FieldDeprecated(descriptor);
}

View File

@ -1,5 +1,9 @@
package foo;
import "protobuf-c/protobuf-c.proto";
option (pb_c_file).c_package = "foo";
message Person {
required string name = 1;
required int32 id = 2;