From 931bdceb4916f1c1942bc225be04a68fb4c81036 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org> Date: Tue, 12 Jan 2016 03:08:11 +0100 Subject: [PATCH] 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/... --- src/compiler/cpp_generator.cc | 95 ++++++++++++++++++++++------------- src/compiler/cpp_generator.h | 4 ++ src/compiler/cpp_plugin.cc | 12 +++++ 3 files changed, 76 insertions(+), 35 deletions(-) diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 3c8ca8ab45..fb52b58047 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -111,37 +111,52 @@ grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, const Parameters ¶ms) { - 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 ¶m) { + const Parameters ¶ms) { 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 = diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h index 70c2e985f6..03621c8794 100644 --- a/src/compiler/cpp_generator.h +++ b/src/compiler/cpp_generator.h @@ -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. diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc index 88c704948e..92a9ba7549 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -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; -- GitLab