diff --git a/protobuf-c/protobuf-c.proto b/protobuf-c/protobuf-c.proto index 1da934f..c8a2d1e 100644 --- a/protobuf-c/protobuf-c.proto +++ b/protobuf-c/protobuf-c.proto @@ -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 { diff --git a/protoc-c/c_bytes_field.cc b/protoc-c/c_bytes_field.cc index 7e35ea2..e4a69ca 100644 --- a/protoc-c/c_bytes_field.cc +++ b/protoc-c/c_bytes_field.cc @@ -114,7 +114,7 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer) const { std::map 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 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 diff --git a/protoc-c/c_enum.cc b/protoc-c/c_enum.cc index 7438422..1342af5 100644 --- a/protoc-c/c_enum.cc +++ b/protoc-c/c_enum.cc @@ -82,9 +82,9 @@ EnumGenerator::~EnumGenerator() {} void EnumGenerator::GenerateDefinition(io::Printer* printer) { std::map 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 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()); diff --git a/protoc-c/c_enum_field.cc b/protoc-c/c_enum_field.cc index f06b1ef..661c9f5 100644 --- a/protoc-c/c_enum_field.cc +++ b/protoc-c/c_enum_field.cc @@ -78,9 +78,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor, std::map* 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); } diff --git a/protoc-c/c_field.cc b/protoc-c/c_field.cc index 75afa39..0716744 100644 --- a/protoc-c/c_field.cc +++ b/protoc-c/c_field.cc @@ -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) { diff --git a/protoc-c/c_helpers.cc b/protoc-c/c_helpers.cc index 7baa265..6fd0cd3 100644 --- a/protoc-c/c_helpers.cc +++ b/protoc-c/c_helpers.cc @@ -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 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 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 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; diff --git a/protoc-c/c_helpers.h b/protoc-c/c_helpers.h index 6db45c1..7598a4e 100644 --- a/protoc-c/c_helpers.h +++ b/protoc-c/c_helpers.h @@ -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); diff --git a/protoc-c/c_message.cc b/protoc-c/c_message.cc index 0f96688..37e8bf8 100755 --- a/protoc-c/c_message.cc +++ b/protoc-c/c_message.cc @@ -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 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 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 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 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 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: diff --git a/protoc-c/c_message_field.cc b/protoc-c/c_message_field.cc index b57fcf5..16661bc 100644 --- a/protoc-c/c_message_field.cc +++ b/protoc-c/c_message_field.cc @@ -85,7 +85,7 @@ void MessageFieldGenerator::GenerateStructMembers(io::Printer* printer) const { std::map 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); } diff --git a/protoc-c/c_service.cc b/protoc-c/c_service.cc index 982cb3e..b1c24cc 100644 --- a/protoc-c/c_service.cc +++ b/protoc-c/c_service.cc @@ -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); diff --git a/protoc-c/c_string_field.cc b/protoc-c/c_string_field.cc index 4fb42f7..80899e4 100644 --- a/protoc-c/c_string_field.cc +++ b/protoc-c/c_string_field.cc @@ -76,7 +76,7 @@ using internal::WireFormat; void SetStringVariables(const FieldDescriptor* descriptor, std::map* 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); } diff --git a/t/test.proto b/t/test.proto index bda724e..884993c 100644 --- a/t/test.proto +++ b/t/test.proto @@ -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;