Letting the user override the code generation a bit.

Example of use:

protoc --grpc_out=use_system_headers=false,grpc_search_path=a/b/c/d:path/to/output/...
This commit is contained in:
Nicolas "Pixel" Noble 2016-01-12 03:08:11 +01:00
parent 09d8cf61b2
commit 931bdceb49
3 changed files with 76 additions and 35 deletions

View File

@ -111,37 +111,52 @@ grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string temp =
"#include <grpc++/support/async_stream.h>\n"
"#include <grpc++/impl/rpc_method.h>\n"
"#include <grpc++/impl/proto_utils.h>\n"
"#include <grpc++/impl/service_type.h>\n"
"#include <grpc++/support/async_unary_call.h>\n"
"#include <grpc++/support/status.h>\n"
"#include <grpc++/support/stub_options.h>\n"
"#include <grpc++/support/sync_stream.h>\n"
"\n"
"namespace grpc {\n"
"class CompletionQueue;\n"
"class Channel;\n"
"class RpcService;\n"
"class ServerCompletionQueue;\n"
"class ServerContext;\n"
"} // namespace grpc\n\n";
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
if (!file->package().empty()) {
std::vector<grpc::string> parts =
grpc_generator::tokenize(file->package(), ".");
vars["l"] = params.use_system_headers ? '<' : '"';
vars["r"] = params.use_system_headers ? '>' : '"';
for (auto part = parts.begin(); part != parts.end(); part++) {
temp.append("namespace ");
temp.append(*part);
temp.append(" {\n");
if (!params.grpc_search_path.empty()) {
vars["l"] += params.grpc_search_path;
if (params.grpc_search_path.back() != '/') {
vars["l"] += '/';
}
}
temp.append("\n");
}
return temp;
printer.Print(vars, "#include $l$grpc++/support/async_stream.h$r$\n");
printer.Print(vars, "#include $l$grpc++/impl/rpc_method.h$r$\n");
printer.Print(vars, "#include $l$grpc++/impl/proto_utils.h$r$\n");
printer.Print(vars, "#include $l$grpc++/impl/service_type.h$r$\n");
printer.Print(vars, "#include $l$grpc++/support/async_unary_call.h$r$\n");
printer.Print(vars, "#include $l$grpc++/support/status.h$r$\n");
printer.Print(vars, "#include $l$grpc++/support/stub_options.h$r$\n");
printer.Print(vars, "#include $l$grpc++/support/sync_stream.h$r$\n");
printer.Print(vars, "\n");
printer.Print(vars, "namespace grpc {\n");
printer.Print(vars, "class CompletionQueue;\n");
printer.Print(vars, "class Channel;\n");
printer.Print(vars, "class RpcService;\n");
printer.Print(vars, "class ServerCompletionQueue;\n");
printer.Print(vars, "class ServerContext;\n");
printer.Print(vars, "} // namespace grpc\n\n");
if (!file->package().empty()) {
std::vector<grpc::string> parts =
grpc_generator::tokenize(file->package(), ".");
for (auto part = parts.begin(); part != parts.end(); part++) {
vars["part"] = *part;
printer.Print(vars, "namespace $part$ {\n");
}
printer.Print(vars, "\n");
}
}
return output;
}
void PrintHeaderClientMethodInterfaces(
@ -694,7 +709,7 @@ grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
}
grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &param) {
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -702,13 +717,23 @@ grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
printer.Print(vars, "#include <grpc++/channel.h>\n");
printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
printer.Print(vars, "#include <grpc++/support/async_unary_call.h>\n");
printer.Print(vars, "#include <grpc++/support/async_stream.h>\n");
printer.Print(vars, "#include <grpc++/support/sync_stream.h>\n");
vars["l"] = params.use_system_headers ? '<' : '"';
vars["r"] = params.use_system_headers ? '>' : '"';
if (!params.grpc_search_path.empty()) {
vars["l"] += params.grpc_search_path;
if (params.grpc_search_path.back() != '/') {
vars["l"] += '/';
}
}
printer.Print(vars, "#include $l$grpc++/channel.h$r$\n");
printer.Print(vars, "#include $l$grpc++/impl/client_unary_call.h$r$\n");
printer.Print(vars, "#include $l$grpc++/impl/rpc_service_method.h$r$\n");
printer.Print(vars, "#include $l$grpc++/impl/service_type.h$r$\n");
printer.Print(vars, "#include $l$grpc++/support/async_unary_call.h$r$\n");
printer.Print(vars, "#include $l$grpc++/support/async_stream.h$r$\n");
printer.Print(vars, "#include $l$grpc++/support/sync_stream.h$r$\n");
if (!file->package().empty()) {
std::vector<grpc::string> parts =

View File

@ -42,6 +42,10 @@ namespace grpc_cpp_generator {
struct Parameters {
// Puts the service into a namespace
grpc::string services_namespace;
// Use system includes (<>) or local includes ("")
bool use_system_headers;
// Prefix to any grpc include
grpc::string grpc_search_path;
};
// Return the prologue of the generated header file.

View File

@ -59,6 +59,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
}
grpc_cpp_generator::Parameters generator_parameters;
generator_parameters.use_system_headers = true;
if (!parameter.empty()) {
std::vector<grpc::string> parameters_list =
@ -70,6 +71,17 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc_generator::tokenize(*parameter_string, "=");
if (param[0] == "services_namespace") {
generator_parameters.services_namespace = param[1];
} else if (param[0] == "use_system_headers") {
if (param[1] == "true") {
generator_parameters.use_system_headers = true;
} else if (param[1] == "false") {
generator_parameters.use_system_headers = false;
} else {
*error = grpc::string("Invalid parameter: ") + *parameter_string;
return false;
}
} else if (param[0] == "grpc_search_path") {
generator_parameters.grpc_search_path = param[1];
} else {
*error = grpc::string("Unknown parameter: ") + *parameter_string;
return false;