Clang-format all the things

pull/6539/head
Masood Malekghassemi 9 years ago
parent 1fa0faa2e2
commit ac59245624
  1. 7
      src/compiler/config.h
  2. 96
      src/compiler/cpp_generator.cc
  3. 30
      src/compiler/cpp_plugin.cc
  4. 271
      src/compiler/csharp_generator.cc
  5. 6
      src/compiler/csharp_generator_helpers.h
  6. 6
      src/compiler/csharp_plugin.cc
  7. 14
      src/compiler/generator_helpers.h
  8. 62
      src/compiler/node_generator.cc
  9. 2
      src/compiler/node_generator_helpers.h
  10. 29
      src/compiler/objective_c_generator.cc
  11. 1
      src/compiler/objective_c_generator_helpers.h
  12. 48
      src/compiler/objective_c_plugin.cc
  13. 333
      src/compiler/python_generator.cc
  14. 1
      src/compiler/python_generator.h
  15. 33
      src/compiler/ruby_generator.cc
  16. 5
      src/compiler/ruby_generator_map-inl.h

@ -60,7 +60,8 @@
#ifndef GRPC_CUSTOM_PARSEGENERATORPARAMETER #ifndef GRPC_CUSTOM_PARSEGENERATORPARAMETER
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#define GRPC_CUSTOM_PARSEGENERATORPARAMETER ::google::protobuf::compiler::ParseGeneratorParameter #define GRPC_CUSTOM_PARSEGENERATORPARAMETER \
::google::protobuf::compiler::ParseGeneratorParameter
#endif #endif
#ifndef GRPC_CUSTOM_STRING #ifndef GRPC_CUSTOM_STRING
@ -81,8 +82,8 @@ static inline int PluginMain(int argc, char* argv[],
const CodeGenerator* generator) { const CodeGenerator* generator) {
return GRPC_CUSTOM_PLUGINMAIN(argc, argv, generator); return GRPC_CUSTOM_PLUGINMAIN(argc, argv, generator);
} }
static inline void ParseGeneratorParameter(const string& parameter, static inline void ParseGeneratorParameter(
std::vector<std::pair<string, string> >* options) { const string& parameter, std::vector<std::pair<string, string> >* options) {
GRPC_CUSTOM_PARSEGENERATORPARAMETER(parameter, options); GRPC_CUSTOM_PARSEGENERATORPARAMETER(parameter, options);
} }

@ -64,19 +64,22 @@ grpc::string FilenameIdentifier(const grpc::string &filename) {
} }
} // namespace } // namespace
template<class T, size_t N> template <class T, size_t N>
T *array_end(T (&array)[N]) { return array + N; } T *array_end(T (&array)[N]) {
return array + N;
}
void PrintIncludes(Printer *printer, const std::vector<grpc::string>& headers, const Parameters &params) { void PrintIncludes(Printer *printer, const std::vector<grpc::string> &headers,
const Parameters &params) {
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
vars["l"] = params.use_system_headers ? '<' : '"'; vars["l"] = params.use_system_headers ? '<' : '"';
vars["r"] = params.use_system_headers ? '>' : '"'; vars["r"] = params.use_system_headers ? '>' : '"';
auto& s = params.grpc_search_path; auto &s = params.grpc_search_path;
if (!s.empty()) { if (!s.empty()) {
vars["l"] += s; vars["l"] += s;
if (s[s.size()-1] != '/') { if (s[s.size() - 1] != '/') {
vars["l"] += '/'; vars["l"] += '/';
} }
} }
@ -101,7 +104,7 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n"); printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n");
printer->Print(vars, printer->Print(vars,
"// If you make any local change, they will be lost.\n"); "// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n"); printer->Print(vars, "// source: $filename$\n");
grpc::string leading_comments = file->GetLeadingComments(); grpc::string leading_comments = file->GetLeadingComments();
if (!leading_comments.empty()) { if (!leading_comments.empty()) {
@ -117,8 +120,7 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
return output; return output;
} }
grpc::string GetHeaderIncludes(File *file, grpc::string GetHeaderIncludes(File *file, const Parameters &params) {
const Parameters &params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@ -126,15 +128,14 @@ grpc::string GetHeaderIncludes(File *file,
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = { static const char *headers_strs[] = {
"grpc++/impl/codegen/async_stream.h", "grpc++/impl/codegen/async_stream.h",
"grpc++/impl/codegen/async_unary_call.h", "grpc++/impl/codegen/async_unary_call.h",
"grpc++/impl/codegen/proto_utils.h", "grpc++/impl/codegen/proto_utils.h",
"grpc++/impl/codegen/rpc_method.h", "grpc++/impl/codegen/rpc_method.h",
"grpc++/impl/codegen/service_type.h", "grpc++/impl/codegen/service_type.h",
"grpc++/impl/codegen/status.h", "grpc++/impl/codegen/status.h",
"grpc++/impl/codegen/stub_options.h", "grpc++/impl/codegen/stub_options.h",
"grpc++/impl/codegen/sync_stream.h" "grpc++/impl/codegen/sync_stream.h"};
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params); PrintIncludes(printer.get(), headers, params);
printer->Print(vars, "\n"); printer->Print(vars, "\n");
@ -309,8 +310,7 @@ void PrintHeaderClientMethodInterfaces(
} }
} }
void PrintHeaderClientMethod(Printer *printer, void PrintHeaderClientMethod(Printer *printer, const Method *method,
const Method *method,
std::map<grpc::string, grpc::string> *vars, std::map<grpc::string, grpc::string> *vars,
bool is_public) { bool is_public) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
@ -490,10 +490,8 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
printer->Print(method->GetTrailingComments().c_str()); printer->Print(method->GetTrailingComments().c_str());
} }
void PrintHeaderServerMethodAsync( void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
Printer *printer, std::map<grpc::string, grpc::string> *vars) {
const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@ -607,8 +605,7 @@ void PrintHeaderServerMethodAsync(
} }
void PrintHeaderServerMethodGeneric( void PrintHeaderServerMethodGeneric(
Printer *printer, Printer *printer, const Method *method,
const Method *method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
@ -677,8 +674,7 @@ void PrintHeaderServerMethodGeneric(
printer->Print(*vars, "};\n"); printer->Print(*vars, "};\n");
} }
void PrintHeaderService(Printer *printer, void PrintHeaderService(Printer *printer, const Service *service,
const Service *service,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name(); (*vars)["Service"] = service->name();
@ -696,14 +692,16 @@ void PrintHeaderService(Printer *printer,
printer->Print("virtual ~StubInterface() {}\n"); printer->Print("virtual ~StubInterface() {}\n");
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
printer->Print(service->method(i)->GetLeadingComments().c_str()); printer->Print(service->method(i)->GetLeadingComments().c_str());
PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, true); PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
true);
printer->Print(service->method(i)->GetTrailingComments().c_str()); printer->Print(service->method(i)->GetTrailingComments().c_str());
} }
printer->Outdent(); printer->Outdent();
printer->Print("private:\n"); printer->Print("private:\n");
printer->Indent(); printer->Indent();
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, false); PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
false);
} }
printer->Outdent(); printer->Outdent();
printer->Print("};\n"); printer->Print("};\n");
@ -711,7 +709,8 @@ void PrintHeaderService(Printer *printer,
"class Stub GRPC_FINAL : public StubInterface" "class Stub GRPC_FINAL : public StubInterface"
" {\n public:\n"); " {\n public:\n");
printer->Indent(); printer->Indent();
printer->Print("Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n"); printer->Print(
"Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethod(printer, service->method(i).get(), vars, true); PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
} }
@ -776,8 +775,7 @@ void PrintHeaderService(Printer *printer,
printer->Print(service->GetTrailingComments().c_str()); printer->Print(service->GetTrailingComments().c_str());
} }
grpc::string GetHeaderServices(File *file, grpc::string GetHeaderServices(File *file, const Parameters &params) {
const Parameters &params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@ -849,7 +847,7 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n"); printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n");
printer->Print(vars, printer->Print(vars,
"// If you make any local change, they will be lost.\n"); "// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n\n"); printer->Print(vars, "// source: $filename$\n\n");
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n"); printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
@ -860,8 +858,7 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
return output; return output;
} }
grpc::string GetSourceIncludes(File *file, grpc::string GetSourceIncludes(File *file, const Parameters &params) {
const Parameters &params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@ -869,15 +866,14 @@ grpc::string GetSourceIncludes(File *file,
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = { static const char *headers_strs[] = {
"grpc++/impl/codegen/async_stream.h", "grpc++/impl/codegen/async_stream.h",
"grpc++/impl/codegen/async_unary_call.h", "grpc++/impl/codegen/async_unary_call.h",
"grpc++/impl/codegen/channel_interface.h", "grpc++/impl/codegen/channel_interface.h",
"grpc++/impl/codegen/client_unary_call.h", "grpc++/impl/codegen/client_unary_call.h",
"grpc++/impl/codegen/method_handler_impl.h", "grpc++/impl/codegen/method_handler_impl.h",
"grpc++/impl/codegen/rpc_service_method.h", "grpc++/impl/codegen/rpc_service_method.h",
"grpc++/impl/codegen/service_type.h", "grpc++/impl/codegen/service_type.h",
"grpc++/impl/codegen/sync_stream.h" "grpc++/impl/codegen/sync_stream.h"};
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params); PrintIncludes(printer.get(), headers, params);
@ -895,8 +891,7 @@ grpc::string GetSourceIncludes(File *file,
return output; return output;
} }
void PrintSourceClientMethod(Printer *printer, void PrintSourceClientMethod(Printer *printer, const Method *method,
const Method *method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
@ -996,8 +991,7 @@ void PrintSourceClientMethod(Printer *printer,
} }
} }
void PrintSourceServerMethod(Printer *printer, void PrintSourceServerMethod(Printer *printer, const Method *method,
const Method *method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
@ -1055,8 +1049,7 @@ void PrintSourceServerMethod(Printer *printer,
} }
} }
void PrintSourceService(Printer *printer, void PrintSourceService(Printer *printer, const Service *service,
const Service *service,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name(); (*vars)["Service"] = service->name();
@ -1168,8 +1161,7 @@ void PrintSourceService(Printer *printer,
} }
} }
grpc::string GetSourceServices(File *file, grpc::string GetSourceServices(File *file, const Parameters &params) {
const Parameters &params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.

@ -48,7 +48,7 @@ using grpc_cpp_generator::GetCppComments;
class ProtoBufMethod : public grpc_cpp_generator::Method { class ProtoBufMethod : public grpc_cpp_generator::Method {
public: public:
ProtoBufMethod(const grpc::protobuf::MethodDescriptor *method) ProtoBufMethod(const grpc::protobuf::MethodDescriptor *method)
: method_(method) {} : method_(method) {}
grpc::string name() const { return method_->name(); } grpc::string name() const { return method_->name(); }
@ -90,14 +90,14 @@ class ProtoBufMethod : public grpc_cpp_generator::Method {
class ProtoBufService : public grpc_cpp_generator::Service { class ProtoBufService : public grpc_cpp_generator::Service {
public: public:
ProtoBufService(const grpc::protobuf::ServiceDescriptor *service) ProtoBufService(const grpc::protobuf::ServiceDescriptor *service)
: service_(service) {} : service_(service) {}
grpc::string name() const { return service_->name(); } grpc::string name() const { return service_->name(); }
int method_count() const { return service_->method_count(); }; int method_count() const { return service_->method_count(); };
std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const { std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const {
return std::unique_ptr<const grpc_cpp_generator::Method>( return std::unique_ptr<const grpc_cpp_generator::Method>(
new ProtoBufMethod(service_->method(i))); new ProtoBufMethod(service_->method(i)));
}; };
grpc::string GetLeadingComments() const { grpc::string GetLeadingComments() const {
@ -115,7 +115,7 @@ class ProtoBufService : public grpc_cpp_generator::Service {
class ProtoBufPrinter : public grpc_cpp_generator::Printer { class ProtoBufPrinter : public grpc_cpp_generator::Printer {
public: public:
ProtoBufPrinter(grpc::string *str) ProtoBufPrinter(grpc::string *str)
: output_stream_(str), printer_(&output_stream_, '$') {} : output_stream_(str), printer_(&output_stream_, '$') {}
void Print(const std::map<grpc::string, grpc::string> &vars, void Print(const std::map<grpc::string, grpc::string> &vars,
const char *string_template) { const char *string_template) {
@ -152,13 +152,14 @@ class ProtoBufFile : public grpc_cpp_generator::File {
int service_count() const { return file_->service_count(); }; int service_count() const { return file_->service_count(); };
std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const { std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const {
return std::unique_ptr<const grpc_cpp_generator::Service> ( return std::unique_ptr<const grpc_cpp_generator::Service>(
new ProtoBufService(file_->service(i))); new ProtoBufService(file_->service(i)));
} }
std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(grpc::string *str) const { std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(
grpc::string *str) const {
return std::unique_ptr<grpc_cpp_generator::Printer>( return std::unique_ptr<grpc_cpp_generator::Printer>(
new ProtoBufPrinter(str)); new ProtoBufPrinter(str));
} }
grpc::string GetLeadingComments() const { grpc::string GetLeadingComments() const {
@ -197,12 +198,11 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
if (!parameter.empty()) { if (!parameter.empty()) {
std::vector<grpc::string> parameters_list = std::vector<grpc::string> parameters_list =
grpc_generator::tokenize(parameter, ","); grpc_generator::tokenize(parameter, ",");
for (auto parameter_string = parameters_list.begin(); for (auto parameter_string = parameters_list.begin();
parameter_string != parameters_list.end(); parameter_string != parameters_list.end(); parameter_string++) {
parameter_string++) {
std::vector<grpc::string> param = std::vector<grpc::string> param =
grpc_generator::tokenize(*parameter_string, "="); grpc_generator::tokenize(*parameter_string, "=");
if (param[0] == "services_namespace") { if (param[0] == "services_namespace") {
generator_parameters.services_namespace = param[1]; generator_parameters.services_namespace = param[1];
} else if (param[0] == "use_system_headers") { } else if (param[0] == "use_system_headers") {
@ -232,8 +232,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters); grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output( std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
context->Open(file_name + ".grpc.pb.h")); context->Open(file_name + ".grpc.pb.h"));
grpc::protobuf::io::CodedOutputStream header_coded_out( grpc::protobuf::io::CodedOutputStream header_coded_out(header_output.get());
header_output.get());
header_coded_out.WriteRaw(header_code.data(), header_code.size()); header_coded_out.WriteRaw(header_code.data(), header_code.size());
grpc::string source_code = grpc::string source_code =
@ -243,8 +242,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters); grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output( std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
context->Open(file_name + ".grpc.pb.cc")); context->Open(file_name + ".grpc.pb.cc"));
grpc::protobuf::io::CodedOutputStream source_coded_out( grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get());
source_output.get());
source_coded_out.WriteRaw(source_code.data(), source_code.size()); source_coded_out.WriteRaw(source_code.data(), source_code.size());
return true; return true;

@ -36,11 +36,10 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include "src/compiler/csharp_generator.h"
#include "src/compiler/config.h" #include "src/compiler/config.h"
#include "src/compiler/csharp_generator_helpers.h"
#include "src/compiler/csharp_generator.h" #include "src/compiler/csharp_generator.h"
#include "src/compiler/csharp_generator.h"
#include "src/compiler/csharp_generator_helpers.h"
using google::protobuf::compiler::csharp::GetFileNamespace; using google::protobuf::compiler::csharp::GetFileNamespace;
using google::protobuf::compiler::csharp::GetClassName; using google::protobuf::compiler::csharp::GetClassName;
@ -61,7 +60,6 @@ using grpc_generator::StringReplace;
using std::map; using std::map;
using std::vector; using std::vector;
namespace grpc_csharp_generator { namespace grpc_csharp_generator {
namespace { namespace {
@ -70,34 +68,43 @@ namespace {
// Currently, we cannot easily reuse the functionality as // Currently, we cannot easily reuse the functionality as
// google/protobuf/compiler/csharp/csharp_doc_comment.h is not a public header. // google/protobuf/compiler/csharp/csharp_doc_comment.h is not a public header.
// TODO(jtattermusch): reuse the functionality from google/protobuf. // TODO(jtattermusch): reuse the functionality from google/protobuf.
void GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer* printer, grpc::protobuf::SourceLocation location) { void GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer *printer,
grpc::string comments = location.leading_comments.empty() ? grpc::protobuf::SourceLocation location) {
location.trailing_comments : location.leading_comments; grpc::string comments = location.leading_comments.empty()
? location.trailing_comments
: location.leading_comments;
if (comments.empty()) { if (comments.empty()) {
return; return;
} }
// XML escaping... no need for apostrophes etc as the whole text is going to be a child // XML escaping... no need for apostrophes etc as the whole text is going to
// be a child
// node of a summary element, not part of an attribute. // node of a summary element, not part of an attribute.
comments = grpc_generator::StringReplace(comments, "&", "&amp;", true); comments = grpc_generator::StringReplace(comments, "&", "&amp;", true);
comments = grpc_generator::StringReplace(comments, "<", "&lt;", true); comments = grpc_generator::StringReplace(comments, "<", "&lt;", true);
std::vector<grpc::string> lines; std::vector<grpc::string> lines;
grpc_generator::Split(comments, '\n', &lines); grpc_generator::Split(comments, '\n', &lines);
// TODO: We really should work out which part to put in the summary and which to put in the remarks... // TODO: We really should work out which part to put in the summary and which
// but that needs to be part of a bigger effort to understand the markdown better anyway. // to put in the remarks...
// but that needs to be part of a bigger effort to understand the markdown
// better anyway.
printer->Print("/// <summary>\n"); printer->Print("/// <summary>\n");
bool last_was_empty = false; bool last_was_empty = false;
// We squash multiple blank lines down to one, and remove any trailing blank lines. We need // We squash multiple blank lines down to one, and remove any trailing blank
// to preserve the blank lines themselves, as this is relevant in the markdown. // lines. We need
// Note that we can't remove leading or trailing whitespace as *that's* relevant in markdown too. // to preserve the blank lines themselves, as this is relevant in the
// markdown.
// Note that we can't remove leading or trailing whitespace as *that's*
// relevant in markdown too.
// (We don't skip "just whitespace" lines, either.) // (We don't skip "just whitespace" lines, either.)
for (std::vector<grpc::string>::iterator it = lines.begin(); it != lines.end(); ++it) { for (std::vector<grpc::string>::iterator it = lines.begin();
it != lines.end(); ++it) {
grpc::string line = *it; grpc::string line = *it;
if (line.empty()) { if (line.empty()) {
last_was_empty = true; last_was_empty = true;
} else { } else {
if (last_was_empty) { if (last_was_empty) {
printer->Print("///\n"); printer->Print("///\n");
} }
last_was_empty = false; last_was_empty = false;
printer->Print("/// $line$\n", "line", *it); printer->Print("/// $line$\n", "line", *it);
@ -107,23 +114,23 @@ void GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer* printer, grpc::prot
} }
template <typename DescriptorType> template <typename DescriptorType>
void GenerateDocCommentBody( void GenerateDocCommentBody(grpc::protobuf::io::Printer *printer,
grpc::protobuf::io::Printer* printer, const DescriptorType* descriptor) { const DescriptorType *descriptor) {
grpc::protobuf::SourceLocation location; grpc::protobuf::SourceLocation location;
if (descriptor->GetSourceLocation(&location)) { if (descriptor->GetSourceLocation(&location)) {
GenerateDocCommentBodyImpl(printer, location); GenerateDocCommentBodyImpl(printer, location);
} }
} }
std::string GetServiceClassName(const ServiceDescriptor* service) { std::string GetServiceClassName(const ServiceDescriptor *service) {
return service->name(); return service->name();
} }
std::string GetClientClassName(const ServiceDescriptor* service) { std::string GetClientClassName(const ServiceDescriptor *service) {
return service->name() + "Client"; return service->name() + "Client";
} }
std::string GetServerClassName(const ServiceDescriptor* service) { std::string GetServerClassName(const ServiceDescriptor *service) {
return service->name() + "Base"; return service->name() + "Base";
} }
@ -138,13 +145,11 @@ std::string GetCSharpMethodType(MethodType method_type) {
case METHODTYPE_BIDI_STREAMING: case METHODTYPE_BIDI_STREAMING:
return "MethodType.DuplexStreaming"; return "MethodType.DuplexStreaming";
} }
GOOGLE_LOG(FATAL)<< "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return ""; return "";
} }
std::string GetServiceNameFieldName() { std::string GetServiceNameFieldName() { return "__ServiceName"; }
return "__ServiceName";
}
std::string GetMarshallerFieldName(const Descriptor *message) { std::string GetMarshallerFieldName(const Descriptor *message) {
return "__Marshaller_" + message->name(); return "__Marshaller_" + message->name();
@ -155,7 +160,7 @@ std::string GetMethodFieldName(const MethodDescriptor *method) {
} }
std::string GetMethodRequestParamMaybe(const MethodDescriptor *method, std::string GetMethodRequestParamMaybe(const MethodDescriptor *method,
bool invocation_param=false) { bool invocation_param = false) {
if (method->client_streaming()) { if (method->client_streaming()) {
return ""; return "";
} }
@ -174,16 +179,16 @@ std::string GetMethodReturnTypeClient(const MethodDescriptor *method) {
case METHODTYPE_NO_STREAMING: case METHODTYPE_NO_STREAMING:
return "AsyncUnaryCall<" + GetClassName(method->output_type()) + ">"; return "AsyncUnaryCall<" + GetClassName(method->output_type()) + ">";
case METHODTYPE_CLIENT_STREAMING: case METHODTYPE_CLIENT_STREAMING:
return "AsyncClientStreamingCall<" + GetClassName(method->input_type()) return "AsyncClientStreamingCall<" + GetClassName(method->input_type()) +
+ ", " + GetClassName(method->output_type()) + ">"; ", " + GetClassName(method->output_type()) + ">";
case METHODTYPE_SERVER_STREAMING: case METHODTYPE_SERVER_STREAMING:
return "AsyncServerStreamingCall<" + GetClassName(method->output_type()) return "AsyncServerStreamingCall<" + GetClassName(method->output_type()) +
+ ">"; ">";
case METHODTYPE_BIDI_STREAMING: case METHODTYPE_BIDI_STREAMING:
return "AsyncDuplexStreamingCall<" + GetClassName(method->input_type()) return "AsyncDuplexStreamingCall<" + GetClassName(method->input_type()) +
+ ", " + GetClassName(method->output_type()) + ">"; ", " + GetClassName(method->output_type()) + ">";
} }
GOOGLE_LOG(FATAL)<< "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return ""; return "";
} }
@ -194,10 +199,10 @@ std::string GetMethodRequestParamServer(const MethodDescriptor *method) {
return GetClassName(method->input_type()) + " request"; return GetClassName(method->input_type()) + " request";
case METHODTYPE_CLIENT_STREAMING: case METHODTYPE_CLIENT_STREAMING:
case METHODTYPE_BIDI_STREAMING: case METHODTYPE_BIDI_STREAMING:
return "IAsyncStreamReader<" + GetClassName(method->input_type()) return "IAsyncStreamReader<" + GetClassName(method->input_type()) +
+ "> requestStream"; "> requestStream";
} }
GOOGLE_LOG(FATAL)<< "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return ""; return "";
} }
@ -205,12 +210,13 @@ std::string GetMethodReturnTypeServer(const MethodDescriptor *method) {
switch (GetMethodType(method)) { switch (GetMethodType(method)) {
case METHODTYPE_NO_STREAMING: case METHODTYPE_NO_STREAMING:
case METHODTYPE_CLIENT_STREAMING: case METHODTYPE_CLIENT_STREAMING:
return "global::System.Threading.Tasks.Task<" + GetClassName(method->output_type()) + ">"; return "global::System.Threading.Tasks.Task<" +
GetClassName(method->output_type()) + ">";
case METHODTYPE_SERVER_STREAMING: case METHODTYPE_SERVER_STREAMING:
case METHODTYPE_BIDI_STREAMING: case METHODTYPE_BIDI_STREAMING:
return "global::System.Threading.Tasks.Task"; return "global::System.Threading.Tasks.Task";
} }
GOOGLE_LOG(FATAL)<< "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return ""; return "";
} }
@ -221,18 +227,19 @@ std::string GetMethodResponseStreamMaybe(const MethodDescriptor *method) {
return ""; return "";
case METHODTYPE_SERVER_STREAMING: case METHODTYPE_SERVER_STREAMING:
case METHODTYPE_BIDI_STREAMING: case METHODTYPE_BIDI_STREAMING:
return ", IServerStreamWriter<" + GetClassName(method->output_type()) return ", IServerStreamWriter<" + GetClassName(method->output_type()) +
+ "> responseStream"; "> responseStream";
} }
GOOGLE_LOG(FATAL)<< "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return ""; return "";
} }
// Gets vector of all messages used as input or output types. // Gets vector of all messages used as input or output types.
std::vector<const Descriptor*> GetUsedMessages( std::vector<const Descriptor *> GetUsedMessages(
const ServiceDescriptor *service) { const ServiceDescriptor *service) {
std::set<const Descriptor*> descriptor_set; std::set<const Descriptor *> descriptor_set;
std::vector<const Descriptor*> result; // vector is to maintain stable ordering std::vector<const Descriptor *>
result; // vector is to maintain stable ordering
for (int i = 0; i < service->method_count(); i++) { for (int i = 0; i < service->method_count(); i++) {
const MethodDescriptor *method = service->method(i); const MethodDescriptor *method = service->method(i);
if (descriptor_set.find(method->input_type()) == descriptor_set.end()) { if (descriptor_set.find(method->input_type()) == descriptor_set.end()) {
@ -247,21 +254,25 @@ std::vector<const Descriptor*> GetUsedMessages(
return result; return result;
} }
void GenerateMarshallerFields(Printer* out, const ServiceDescriptor *service) { void GenerateMarshallerFields(Printer *out, const ServiceDescriptor *service) {
std::vector<const Descriptor*> used_messages = GetUsedMessages(service); std::vector<const Descriptor *> used_messages = GetUsedMessages(service);
for (size_t i = 0; i < used_messages.size(); i++) { for (size_t i = 0; i < used_messages.size(); i++) {
const Descriptor *message = used_messages[i]; const Descriptor *message = used_messages[i];
out->Print( out->Print(
"static readonly Marshaller<$type$> $fieldname$ = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), $type$.Parser.ParseFrom);\n", "static readonly Marshaller<$type$> $fieldname$ = "
"Marshallers.Create((arg) => "
"global::Google.Protobuf.MessageExtensions.ToByteArray(arg), "
"$type$.Parser.ParseFrom);\n",
"fieldname", GetMarshallerFieldName(message), "type", "fieldname", GetMarshallerFieldName(message), "type",
GetClassName(message)); GetClassName(message));
} }
out->Print("\n"); out->Print("\n");
} }
void GenerateStaticMethodField(Printer* out, const MethodDescriptor *method) { void GenerateStaticMethodField(Printer *out, const MethodDescriptor *method) {
out->Print( out->Print(
"static readonly Method<$request$, $response$> $fieldname$ = new Method<$request$, $response$>(\n", "static readonly Method<$request$, $response$> $fieldname$ = new "
"Method<$request$, $response$>(\n",
"fieldname", GetMethodFieldName(method), "request", "fieldname", GetMethodFieldName(method), "request",
GetClassName(method->input_type()), "response", GetClassName(method->input_type()), "response",
GetClassName(method->output_type())); GetClassName(method->output_type()));
@ -270,7 +281,7 @@ void GenerateStaticMethodField(Printer* out, const MethodDescriptor *method) {
out->Print("$methodtype$,\n", "methodtype", out->Print("$methodtype$,\n", "methodtype",
GetCSharpMethodType(GetMethodType(method))); GetCSharpMethodType(GetMethodType(method)));
out->Print("$servicenamefield$,\n", "servicenamefield", out->Print("$servicenamefield$,\n", "servicenamefield",
GetServiceNameFieldName()); GetServiceNameFieldName());
out->Print("\"$methodname$\",\n", "methodname", method->name()); out->Print("\"$methodname$\",\n", "methodname", method->name());
out->Print("$requestmarshaller$,\n", "requestmarshaller", out->Print("$requestmarshaller$,\n", "requestmarshaller",
GetMarshallerFieldName(method->input_type())); GetMarshallerFieldName(method->input_type()));
@ -281,11 +292,14 @@ void GenerateStaticMethodField(Printer* out, const MethodDescriptor *method) {
out->Outdent(); out->Outdent();
} }
void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *service) { void GenerateServiceDescriptorProperty(Printer *out,
const ServiceDescriptor *service) {
std::ostringstream index; std::ostringstream index;
index << service->index(); index << service->index();
out->Print("/// <summary>Service descriptor</summary>\n"); out->Print("/// <summary>Service descriptor</summary>\n");
out->Print("public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor\n"); out->Print(
"public static global::Google.Protobuf.Reflection.ServiceDescriptor "
"Descriptor\n");
out->Print("{\n"); out->Print("{\n");
out->Print(" get { return $umbrella$.Descriptor.Services[$index$]; }\n", out->Print(" get { return $umbrella$.Descriptor.Services[$index$]; }\n",
"umbrella", GetReflectionClassName(service->file()), "index", "umbrella", GetReflectionClassName(service->file()), "index",
@ -294,9 +308,11 @@ void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *se
out->Print("\n"); out->Print("\n");
} }
void GenerateServerClass(Printer* out, const ServiceDescriptor *service) { void GenerateServerClass(Printer *out, const ServiceDescriptor *service) {
out->Print("/// <summary>Base class for server-side implementations of $servicename$</summary>\n", out->Print(
"servicename", GetServiceClassName(service)); "/// <summary>Base class for server-side implementations of "
"$servicename$</summary>\n",
"servicename", GetServiceClassName(service));
out->Print("public abstract class $name$\n", "name", out->Print("public abstract class $name$\n", "name",
GetServerClassName(service)); GetServerClassName(service));
out->Print("{\n"); out->Print("{\n");
@ -305,7 +321,8 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
const MethodDescriptor *method = service->method(i); const MethodDescriptor *method = service->method(i);
GenerateDocCommentBody(out, method); GenerateDocCommentBody(out, method);
out->Print( out->Print(
"public virtual $returntype$ $methodname$($request$$response_stream_maybe$, " "public virtual $returntype$ "
"$methodname$($request$$response_stream_maybe$, "
"ServerCallContext context)\n", "ServerCallContext context)\n",
"methodname", method->name(), "returntype", "methodname", method->name(), "returntype",
GetMethodReturnTypeServer(method), "request", GetMethodReturnTypeServer(method), "request",
@ -313,8 +330,9 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
GetMethodResponseStreamMaybe(method)); GetMethodResponseStreamMaybe(method));
out->Print("{\n"); out->Print("{\n");
out->Indent(); out->Indent();
out->Print("throw new RpcException(" out->Print(
"new Status(StatusCode.Unimplemented, \"\"));\n"); "throw new RpcException("
"new Status(StatusCode.Unimplemented, \"\"));\n");
out->Outdent(); out->Outdent();
out->Print("}\n\n"); out->Print("}\n\n");
} }
@ -323,41 +341,49 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
out->Print("\n"); out->Print("\n");
} }
void GenerateClientStub(Printer* out, const ServiceDescriptor *service) { void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
out->Print("/// <summary>Client for $servicename$</summary>\n", out->Print("/// <summary>Client for $servicename$</summary>\n", "servicename",
"servicename", GetServiceClassName(service)); GetServiceClassName(service));
out->Print( out->Print("public class $name$ : ClientBase<$name$>\n", "name",
"public class $name$ : ClientBase<$name$>\n", GetClientClassName(service));
"name", GetClientClassName(service));
out->Print("{\n"); out->Print("{\n");
out->Indent(); out->Indent();
// constructors // constructors
out->Print("/// <summary>Creates a new client for $servicename$</summary>\n" out->Print(
"/// <param name=\"channel\">The channel to use to make remote calls.</param>\n", "/// <summary>Creates a new client for $servicename$</summary>\n"
"servicename", GetServiceClassName(service)); "/// <param name=\"channel\">The channel to use to make remote "
out->Print("public $name$(Channel channel) : base(channel)\n", "calls.</param>\n",
"name", GetClientClassName(service)); "servicename", GetServiceClassName(service));
out->Print("public $name$(Channel channel) : base(channel)\n", "name",
GetClientClassName(service));
out->Print("{\n"); out->Print("{\n");
out->Print("}\n"); out->Print("}\n");
out->Print("/// <summary>Creates a new client for $servicename$ that uses a custom <c>CallInvoker</c>.</summary>\n" out->Print(
"/// <param name=\"callInvoker\">The callInvoker to use to make remote calls.</param>\n", "/// <summary>Creates a new client for $servicename$ that uses a custom "
"servicename", GetServiceClassName(service)); "<c>CallInvoker</c>.</summary>\n"
"/// <param name=\"callInvoker\">The callInvoker to use to make remote "
"calls.</param>\n",
"servicename", GetServiceClassName(service));
out->Print("public $name$(CallInvoker callInvoker) : base(callInvoker)\n", out->Print("public $name$(CallInvoker callInvoker) : base(callInvoker)\n",
"name", GetClientClassName(service)); "name", GetClientClassName(service));
out->Print("{\n"); out->Print("{\n");
out->Print("}\n"); out->Print("}\n");
out->Print("/// <summary>Protected parameterless constructor to allow creation" out->Print(
" of test doubles.</summary>\n"); "/// <summary>Protected parameterless constructor to allow creation"
out->Print("protected $name$() : base()\n", " of test doubles.</summary>\n");
"name", GetClientClassName(service)); out->Print("protected $name$() : base()\n", "name",
GetClientClassName(service));
out->Print("{\n"); out->Print("{\n");
out->Print("}\n"); out->Print("}\n");
out->Print("/// <summary>Protected constructor to allow creation of configured clients.</summary>\n" out->Print(
"/// <param name=\"configuration\">The client configuration.</param>\n"); "/// <summary>Protected constructor to allow creation of configured "
out->Print("protected $name$(ClientBaseConfiguration configuration)" "clients.</summary>\n"
" : base(configuration)\n", "/// <param name=\"configuration\">The client configuration.</param>\n");
"name", GetClientClassName(service)); out->Print(
"protected $name$(ClientBaseConfiguration configuration)"
" : base(configuration)\n",
"name", GetClientClassName(service));
out->Print("{\n"); out->Print("{\n");
out->Print("}\n\n"); out->Print("}\n\n");
@ -368,27 +394,36 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
if (method_type == METHODTYPE_NO_STREAMING) { if (method_type == METHODTYPE_NO_STREAMING) {
// unary calls have an extra synchronous stub method // unary calls have an extra synchronous stub method
GenerateDocCommentBody(out, method); GenerateDocCommentBody(out, method);
out->Print("public virtual $response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n", out->Print(
"public virtual $response$ $methodname$($request$ request, Metadata "
"headers = null, DateTime? deadline = null, CancellationToken "
"cancellationToken = default(CancellationToken))\n",
"methodname", method->name(), "request", "methodname", method->name(), "request",
GetClassName(method->input_type()), "response", GetClassName(method->input_type()), "response",
GetClassName(method->output_type())); GetClassName(method->output_type()));
out->Print("{\n"); out->Print("{\n");
out->Indent(); out->Indent();
out->Print("return $methodname$(request, new CallOptions(headers, deadline, cancellationToken));\n", out->Print(
"methodname", method->name()); "return $methodname$(request, new CallOptions(headers, deadline, "
"cancellationToken));\n",
"methodname", method->name());
out->Outdent(); out->Outdent();
out->Print("}\n"); out->Print("}\n");
// overload taking CallOptions as a param // overload taking CallOptions as a param
GenerateDocCommentBody(out, method); GenerateDocCommentBody(out, method);
out->Print("public virtual $response$ $methodname$($request$ request, CallOptions options)\n", out->Print(
"public virtual $response$ $methodname$($request$ request, "
"CallOptions options)\n",
"methodname", method->name(), "request", "methodname", method->name(), "request",
GetClassName(method->input_type()), "response", GetClassName(method->input_type()), "response",
GetClassName(method->output_type())); GetClassName(method->output_type()));
out->Print("{\n"); out->Print("{\n");
out->Indent(); out->Indent();
out->Print("return CallInvoker.BlockingUnaryCall($methodfield$, null, options, request);\n", out->Print(
"methodfield", GetMethodFieldName(method)); "return CallInvoker.BlockingUnaryCall($methodfield$, null, options, "
"request);\n",
"methodfield", GetMethodFieldName(method));
out->Outdent(); out->Outdent();
out->Print("}\n"); out->Print("}\n");
} }
@ -399,23 +434,28 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
} }
GenerateDocCommentBody(out, method); GenerateDocCommentBody(out, method);
out->Print( out->Print(
"public virtual $returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n", "public virtual $returntype$ $methodname$($request_maybe$Metadata "
"methodname", method_name, "request_maybe", "headers = null, DateTime? deadline = null, CancellationToken "
GetMethodRequestParamMaybe(method), "returntype", "cancellationToken = default(CancellationToken))\n",
GetMethodReturnTypeClient(method)); "methodname", method_name, "request_maybe",
GetMethodRequestParamMaybe(method), "returntype",
GetMethodReturnTypeClient(method));
out->Print("{\n"); out->Print("{\n");
out->Indent(); out->Indent();
out->Print("return $methodname$($request_maybe$new CallOptions(headers, deadline, cancellationToken));\n", out->Print(
"methodname", method_name, "return $methodname$($request_maybe$new CallOptions(headers, deadline, "
"request_maybe", GetMethodRequestParamMaybe(method, true)); "cancellationToken));\n",
"methodname", method_name, "request_maybe",
GetMethodRequestParamMaybe(method, true));
out->Outdent(); out->Outdent();
out->Print("}\n"); out->Print("}\n");
// overload taking CallOptions as a param // overload taking CallOptions as a param
GenerateDocCommentBody(out, method); GenerateDocCommentBody(out, method);
out->Print( out->Print(
"public virtual $returntype$ $methodname$($request_maybe$CallOptions options)\n", "public virtual $returntype$ $methodname$($request_maybe$CallOptions "
"options)\n",
"methodname", method_name, "request_maybe", "methodname", method_name, "request_maybe",
GetMethodRequestParamMaybe(method), "returntype", GetMethodRequestParamMaybe(method), "returntype",
GetMethodReturnTypeClient(method)); GetMethodReturnTypeClient(method));
@ -423,36 +463,45 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
out->Indent(); out->Indent();
switch (GetMethodType(method)) { switch (GetMethodType(method)) {
case METHODTYPE_NO_STREAMING: case METHODTYPE_NO_STREAMING:
out->Print("return CallInvoker.AsyncUnaryCall($methodfield$, null, options, request);\n", out->Print(
"methodfield", GetMethodFieldName(method)); "return CallInvoker.AsyncUnaryCall($methodfield$, null, options, "
"request);\n",
"methodfield", GetMethodFieldName(method));
break; break;
case METHODTYPE_CLIENT_STREAMING: case METHODTYPE_CLIENT_STREAMING:
out->Print("return CallInvoker.AsyncClientStreamingCall($methodfield$, null, options);\n", out->Print(
"methodfield", GetMethodFieldName(method)); "return CallInvoker.AsyncClientStreamingCall($methodfield$, null, "
"options);\n",
"methodfield", GetMethodFieldName(method));
break; break;
case METHODTYPE_SERVER_STREAMING: case METHODTYPE_SERVER_STREAMING:
out->Print( out->Print(
"return CallInvoker.AsyncServerStreamingCall($methodfield$, null, options, request);\n", "return CallInvoker.AsyncServerStreamingCall($methodfield$, null, "
"options, request);\n",
"methodfield", GetMethodFieldName(method)); "methodfield", GetMethodFieldName(method));
break; break;
case METHODTYPE_BIDI_STREAMING: case METHODTYPE_BIDI_STREAMING:
out->Print("return CallInvoker.AsyncDuplexStreamingCall($methodfield$, null, options);\n", out->Print(
"methodfield", GetMethodFieldName(method)); "return CallInvoker.AsyncDuplexStreamingCall($methodfield$, null, "
"options);\n",
"methodfield", GetMethodFieldName(method));
break; break;
default: default:
GOOGLE_LOG(FATAL)<< "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
} }
out->Outdent(); out->Outdent();
out->Print("}\n"); out->Print("}\n");
} }
// override NewInstance method // override NewInstance method
out->Print("protected override $name$ NewInstance(ClientBaseConfiguration configuration)\n", out->Print(
"name", GetClientClassName(service)); "protected override $name$ NewInstance(ClientBaseConfiguration "
"configuration)\n",
"name", GetClientClassName(service));
out->Print("{\n"); out->Print("{\n");
out->Indent(); out->Indent();
out->Print("return new $name$(configuration);\n", out->Print("return new $name$(configuration);\n", "name",
"name", GetClientClassName(service)); GetClientClassName(service));
out->Outdent(); out->Outdent();
out->Print("}\n"); out->Print("}\n");
@ -461,11 +510,13 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
out->Print("\n"); out->Print("\n");
} }
void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service) { void GenerateBindServiceMethod(Printer *out, const ServiceDescriptor *service) {
out->Print( out->Print(
"/// <summary>Creates service definition that can be registered with a server</summary>\n"); "/// <summary>Creates service definition that can be registered with a "
"server</summary>\n");
out->Print( out->Print(
"public static ServerServiceDefinition BindService($implclass$ serviceImpl)\n", "public static ServerServiceDefinition BindService($implclass$ "
"serviceImpl)\n",
"implclass", GetServerClassName(service)); "implclass", GetServerClassName(service));
out->Print("{\n"); out->Print("{\n");
out->Indent(); out->Indent();
@ -491,7 +542,7 @@ void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service) {
out->Print("\n"); out->Print("\n");
} }
void GenerateService(Printer* out, const ServiceDescriptor *service, void GenerateService(Printer *out, const ServiceDescriptor *service,
bool generate_client, bool generate_server, bool generate_client, bool generate_server,
bool internal_access) { bool internal_access) {
GenerateDocCommentBody(out, service); GenerateDocCommentBody(out, service);

@ -41,14 +41,16 @@ namespace grpc_csharp_generator {
inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file, inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file,
grpc::string *file_name_or_error) { grpc::string *file_name_or_error) {
*file_name_or_error = grpc_generator::FileNameInUpperCamel(file, false) + "Grpc.cs"; *file_name_or_error =
grpc_generator::FileNameInUpperCamel(file, false) + "Grpc.cs";
return true; return true;
} }
// Get leading or trailing comments in a string. Comment lines start with "// ". // Get leading or trailing comments in a string. Comment lines start with "// ".
// Leading detached comments are put in in front of leading comments. // Leading detached comments are put in in front of leading comments.
template <typename DescriptorType> template <typename DescriptorType>
inline grpc::string GetCsharpComments(const DescriptorType *desc, bool leading) { inline grpc::string GetCsharpComments(const DescriptorType *desc,
bool leading) {
return grpc_generator::GetPrefixedComments(desc, leading, "//"); return grpc_generator::GetPrefixedComments(desc, leading, "//");
} }

@ -67,10 +67,8 @@ class CSharpGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
} }
} }
grpc::string code = grpc_csharp_generator::GetServices(file, grpc::string code = grpc_csharp_generator::GetServices(
generate_client, file, generate_client, generate_server, internal_access);
generate_server,
internal_access);
if (code.size() == 0) { if (code.size() == 0) {
return true; // don't generate a file if there are no services return true; // don't generate a file if there are no services
} }

@ -84,7 +84,7 @@ inline grpc::string StringReplace(grpc::string str, const grpc::string &from,
} }
str.replace(pos, from.length(), to); str.replace(pos, from.length(), to);
pos += to.length(); pos += to.length();
} while(replace_all); } while (replace_all);
return str; return str;
} }
@ -139,8 +139,8 @@ inline grpc::string LowerUnderscoreToUpperCamel(grpc::string str) {
return result; return result;
} }
inline grpc::string FileNameInUpperCamel(const grpc::protobuf::FileDescriptor *file, inline grpc::string FileNameInUpperCamel(
bool include_package_path) { const grpc::protobuf::FileDescriptor *file, bool include_package_path) {
std::vector<grpc::string> tokens = tokenize(StripProto(file->name()), "/"); std::vector<grpc::string> tokens = tokenize(StripProto(file->name()), "/");
grpc::string result = ""; grpc::string result = "";
if (include_package_path) { if (include_package_path) {
@ -152,7 +152,8 @@ inline grpc::string FileNameInUpperCamel(const grpc::protobuf::FileDescriptor *f
return result; return result;
} }
inline grpc::string FileNameInUpperCamel(const grpc::protobuf::FileDescriptor *file) { inline grpc::string FileNameInUpperCamel(
const grpc::protobuf::FileDescriptor *file) {
return FileNameInUpperCamel(file, true); return FileNameInUpperCamel(file, true);
} }
@ -163,7 +164,8 @@ enum MethodType {
METHODTYPE_BIDI_STREAMING METHODTYPE_BIDI_STREAMING
}; };
inline MethodType GetMethodType(const grpc::protobuf::MethodDescriptor *method) { inline MethodType GetMethodType(
const grpc::protobuf::MethodDescriptor *method) {
if (method->client_streaming()) { if (method->client_streaming()) {
if (method->server_streaming()) { if (method->server_streaming()) {
return METHODTYPE_BIDI_STREAMING; return METHODTYPE_BIDI_STREAMING;
@ -254,7 +256,7 @@ inline grpc::string GenerateCommentsWithPrefix(
const std::vector<grpc::string> &in, const grpc::string &prefix) { const std::vector<grpc::string> &in, const grpc::string &prefix) {
std::ostringstream oss; std::ostringstream oss;
for (auto it = in.begin(); it != in.end(); it++) { for (auto it = in.begin(); it != in.end(); it++) {
const grpc::string& elem = *it; const grpc::string &elem = *it;
if (elem.empty()) { if (elem.empty()) {
oss << prefix << "\n"; oss << prefix << "\n";
} else if (elem[0] == ' ') { } else if (elem[0] == ' ') {

@ -67,15 +67,15 @@ grpc::string ModuleAlias(const grpc::string filename) {
// Given a filename like foo/bar/baz.proto, returns the corresponding JavaScript // Given a filename like foo/bar/baz.proto, returns the corresponding JavaScript
// message file foo/bar/baz.js // message file foo/bar/baz.js
grpc::string GetJSMessageFilename(const grpc::string& filename) { grpc::string GetJSMessageFilename(const grpc::string &filename) {
grpc::string name = filename; grpc::string name = filename;
return grpc_generator::StripProto(name) + "_pb.js"; return grpc_generator::StripProto(name) + "_pb.js";
} }
// Given a filename like foo/bar/baz.proto, returns the root directory // Given a filename like foo/bar/baz.proto, returns the root directory
// path ../../ // path ../../
grpc::string GetRootPath(const grpc::string& from_filename, grpc::string GetRootPath(const grpc::string &from_filename,
const grpc::string& to_filename) { const grpc::string &to_filename) {
if (to_filename.find("google/protobuf") == 0) { if (to_filename.find("google/protobuf") == 0) {
// Well-known types (.proto files in the google/protobuf directory) are // Well-known types (.proto files in the google/protobuf directory) are
// assumed to come from the 'google-protobuf' npm package. We may want to // assumed to come from the 'google-protobuf' npm package. We may want to
@ -96,21 +96,24 @@ grpc::string GetRootPath(const grpc::string& from_filename,
// Return the relative path to load to_file from the directory containing // Return the relative path to load to_file from the directory containing
// from_file, assuming that both paths are relative to the same directory // from_file, assuming that both paths are relative to the same directory
grpc::string GetRelativePath(const grpc::string& from_file, grpc::string GetRelativePath(const grpc::string &from_file,
const grpc::string& to_file) { const grpc::string &to_file) {
return GetRootPath(from_file, to_file) + to_file; return GetRootPath(from_file, to_file) + to_file;
} }
/* Finds all message types used in all services in the file, and returns them /* Finds all message types used in all services in the file, and returns them
* as a map of fully qualified message type name to message descriptor */ * as a map of fully qualified message type name to message descriptor */
map<grpc::string, const Descriptor*> GetAllMessages(const FileDescriptor *file) { map<grpc::string, const Descriptor *> GetAllMessages(
map<grpc::string, const Descriptor*> message_types; const FileDescriptor *file) {
for (int service_num = 0; service_num < file->service_count(); service_num++) { map<grpc::string, const Descriptor *> message_types;
const ServiceDescriptor* service = file->service(service_num); for (int service_num = 0; service_num < file->service_count();
for (int method_num = 0; method_num < service->method_count(); method_num++) { service_num++) {
const MethodDescriptor* method = service->method(method_num); const ServiceDescriptor *service = file->service(service_num);
const Descriptor* input_type = method->input_type(); for (int method_num = 0; method_num < service->method_count();
const Descriptor* output_type = method->output_type(); method_num++) {
const MethodDescriptor *method = service->method(method_num);
const Descriptor *input_type = method->input_type();
const Descriptor *output_type = method->output_type();
message_types[input_type->name()] = input_type; message_types[input_type->name()] = input_type;
message_types[output_type->name()] = output_type; message_types[output_type->name()] = output_type;
} }
@ -118,7 +121,7 @@ map<grpc::string, const Descriptor*> GetAllMessages(const FileDescriptor *file)
return message_types; return message_types;
} }
grpc::string MessageIdentifierName(const grpc::string& name) { grpc::string MessageIdentifierName(const grpc::string &name) {
return grpc_generator::StringReplace(name, ".", "_"); return grpc_generator::StringReplace(name, ".", "_");
} }
@ -194,18 +197,18 @@ void PrintService(const ServiceDescriptor *service, Printer *out) {
out->Print(template_vars, "var $name$Service = exports.$name$Service = {\n"); out->Print(template_vars, "var $name$Service = exports.$name$Service = {\n");
out->Indent(); out->Indent();
for (int i = 0; i < service->method_count(); i++) { for (int i = 0; i < service->method_count(); i++) {
grpc::string method_name = grpc_generator::LowercaseFirstLetter( grpc::string method_name =
service->method(i)->name()); grpc_generator::LowercaseFirstLetter(service->method(i)->name());
out->Print(GetNodeComments(service->method(i), true).c_str()); out->Print(GetNodeComments(service->method(i), true).c_str());
out->Print("$method_name$: ", out->Print("$method_name$: ", "method_name", method_name);
"method_name", method_name);
PrintMethod(service->method(i), out); PrintMethod(service->method(i), out);
out->Print(",\n"); out->Print(",\n");
out->Print(GetNodeComments(service->method(i), false).c_str()); out->Print(GetNodeComments(service->method(i), false).c_str());
} }
out->Outdent(); out->Outdent();
out->Print("};\n\n"); out->Print("};\n\n");
out->Print(template_vars, "exports.$name$Client = " out->Print(template_vars,
"exports.$name$Client = "
"grpc.makeGenericClientConstructor($name$Service);\n"); "grpc.makeGenericClientConstructor($name$Service);\n");
out->Print(GetNodeComments(service, false).c_str()); out->Print(GetNodeComments(service, false).c_str());
} }
@ -213,27 +216,25 @@ void PrintService(const ServiceDescriptor *service, Printer *out) {
void PrintImports(const FileDescriptor *file, Printer *out) { void PrintImports(const FileDescriptor *file, Printer *out) {
out->Print("var grpc = require('grpc');\n"); out->Print("var grpc = require('grpc');\n");
if (file->message_type_count() > 0) { if (file->message_type_count() > 0) {
grpc::string file_path = GetRelativePath(file->name(), grpc::string file_path =
GetJSMessageFilename( GetRelativePath(file->name(), GetJSMessageFilename(file->name()));
file->name())); out->Print("var $module_alias$ = require('$file_path$');\n", "module_alias",
out->Print("var $module_alias$ = require('$file_path$');\n", ModuleAlias(file->name()), "file_path", file_path);
"module_alias", ModuleAlias(file->name()),
"file_path", file_path);
} }
for (int i = 0; i < file->dependency_count(); i++) { for (int i = 0; i < file->dependency_count(); i++) {
grpc::string file_path = GetRelativePath( grpc::string file_path = GetRelativePath(
file->name(), GetJSMessageFilename(file->dependency(i)->name())); file->name(), GetJSMessageFilename(file->dependency(i)->name()));
out->Print("var $module_alias$ = require('$file_path$');\n", out->Print("var $module_alias$ = require('$file_path$');\n", "module_alias",
"module_alias", ModuleAlias(file->dependency(i)->name()), ModuleAlias(file->dependency(i)->name()), "file_path",
"file_path", file_path); file_path);
} }
out->Print("\n"); out->Print("\n");
} }
void PrintTransformers(const FileDescriptor *file, Printer *out) { void PrintTransformers(const FileDescriptor *file, Printer *out) {
map<grpc::string, const Descriptor*> messages = GetAllMessages(file); map<grpc::string, const Descriptor *> messages = GetAllMessages(file);
for (std::map<grpc::string, const Descriptor*>::iterator it = for (std::map<grpc::string, const Descriptor *>::iterator it =
messages.begin(); messages.begin();
it != messages.end(); it++) { it != messages.end(); it++) {
PrintMessageTransformer(it->second, out); PrintMessageTransformer(it->second, out);
@ -246,7 +247,6 @@ void PrintServices(const FileDescriptor *file, Printer *out) {
PrintService(file->service(i), out); PrintService(file->service(i), out);
} }
} }
} }
grpc::string GenerateFile(const FileDescriptor *file) { grpc::string GenerateFile(const FileDescriptor *file) {

@ -48,7 +48,7 @@ inline grpc::string GetJSServiceFilename(const grpc::string& filename) {
// Get leading or trailing comments in a string. Comment lines start with "// ". // Get leading or trailing comments in a string. Comment lines start with "// ".
// Leading detached comments are put in in front of leading comments. // Leading detached comments are put in in front of leading comments.
template <typename DescriptorType> template <typename DescriptorType>
inline grpc::string GetNodeComments(const DescriptorType *desc, bool leading) { inline grpc::string GetNodeComments(const DescriptorType* desc, bool leading) {
return grpc_generator::GetPrefixedComments(desc, leading, "//"); return grpc_generator::GetPrefixedComments(desc, leading, "//");
} }

@ -49,9 +49,9 @@ using ::std::map;
namespace grpc_objective_c_generator { namespace grpc_objective_c_generator {
namespace { namespace {
void PrintProtoRpcDeclarationAsPragma(Printer *printer, void PrintProtoRpcDeclarationAsPragma(
const MethodDescriptor *method, Printer *printer, const MethodDescriptor *method,
map< ::grpc::string, ::grpc::string> vars) { map< ::grpc::string, ::grpc::string> vars) {
vars["client_stream"] = method->client_streaming() ? "stream " : ""; vars["client_stream"] = method->client_streaming() ? "stream " : "";
vars["server_stream"] = method->server_streaming() ? "stream " : ""; vars["server_stream"] = method->server_streaming() ? "stream " : "";
@ -61,7 +61,7 @@ void PrintProtoRpcDeclarationAsPragma(Printer *printer,
} }
template <typename DescriptorType> template <typename DescriptorType>
static void PrintAllComments(const DescriptorType* desc, Printer* printer) { static void PrintAllComments(const DescriptorType *desc, Printer *printer) {
std::vector<grpc::string> comments; std::vector<grpc::string> comments;
grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED, grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED,
&comments); &comments);
@ -100,7 +100,8 @@ void PrintMethodSignature(Printer *printer, const MethodDescriptor *method,
if (method->server_streaming()) { if (method->server_streaming()) {
printer->Print(vars, printer->Print(vars,
" eventHandler:(void(^)(BOOL done, " " eventHandler:(void(^)(BOOL done, "
"$response_class$ *_Nullable response, NSError *_Nullable error))eventHandler"); "$response_class$ *_Nullable response, NSError *_Nullable "
"error))eventHandler");
} else { } else {
printer->Print(vars, printer->Print(vars,
" handler:(void(^)($response_class$ *_Nullable response, " " handler:(void(^)($response_class$ *_Nullable response, "
@ -123,7 +124,8 @@ void PrintAdvancedSignature(Printer *printer, const MethodDescriptor *method,
PrintMethodSignature(printer, method, vars); PrintMethodSignature(printer, method, vars);
} }
inline map< ::grpc::string, ::grpc::string> GetMethodVars(const MethodDescriptor *method) { inline map< ::grpc::string, ::grpc::string> GetMethodVars(
const MethodDescriptor *method) {
map< ::grpc::string, ::grpc::string> res; map< ::grpc::string, ::grpc::string> res;
res["method_name"] = method->name(); res["method_name"] = method->name();
res["request_type"] = method->input_type()->name(); res["request_type"] = method->input_type()->name();
@ -210,7 +212,8 @@ void PrintMethodImplementations(Printer *printer,
grpc::protobuf::io::StringOutputStream output_stream(&output); grpc::protobuf::io::StringOutputStream output_stream(&output);
Printer printer(&output_stream, '$'); Printer printer(&output_stream, '$');
map< ::grpc::string, ::grpc::string> vars = {{"service_class", ServiceClassName(service)}}; map< ::grpc::string, ::grpc::string> vars = {
{"service_class", ServiceClassName(service)}};
printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n"); printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
@ -237,21 +240,23 @@ void PrintMethodImplementations(Printer *printer,
} }
::grpc::string GetSource(const ServiceDescriptor *service) { ::grpc::string GetSource(const ServiceDescriptor *service) {
::grpc::string output; ::grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
grpc::protobuf::io::StringOutputStream output_stream(&output); grpc::protobuf::io::StringOutputStream output_stream(&output);
Printer printer(&output_stream, '$'); Printer printer(&output_stream, '$');
map< ::grpc::string,::grpc::string> vars = {{"service_name", service->name()}, map< ::grpc::string, ::grpc::string> vars = {
{"service_class", ServiceClassName(service)}, {"service_name", service->name()},
{"package", service->file()->package()}}; {"service_class", ServiceClassName(service)},
{"package", service->file()->package()}};
printer.Print(vars, "@implementation $service_class$\n\n"); printer.Print(vars, "@implementation $service_class$\n\n");
printer.Print("// Designated initializer\n"); printer.Print("// Designated initializer\n");
printer.Print("- (instancetype)initWithHost:(NSString *)host {\n"); printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
printer.Print(vars, printer.Print(
vars,
" return (self = [super initWithHost:host" " return (self = [super initWithHost:host"
" packageName:@\"$package$\" serviceName:@\"$service_name$\"]);\n"); " packageName:@\"$package$\" serviceName:@\"$service_name$\"]);\n");
printer.Print("}\n\n"); printer.Print("}\n\n");

@ -53,6 +53,5 @@ inline string ServiceClassName(const ServiceDescriptor *service) {
string prefix = file->options().objc_class_prefix(); string prefix = file->options().objc_class_prefix();
return prefix + service->name(); return prefix + service->name();
} }
} }
#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H #endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H

@ -42,7 +42,8 @@
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName; using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
using ::google::protobuf::compiler::objectivec::IsProtobufLibraryBundledProtoFile; using ::google::protobuf::compiler::objectivec::
IsProtobufLibraryBundledProtoFile;
class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
public: public:
@ -53,7 +54,6 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
const ::grpc::string &parameter, const ::grpc::string &parameter,
grpc::protobuf::compiler::GeneratorContext *context, grpc::protobuf::compiler::GeneratorContext *context,
::grpc::string *error) const { ::grpc::string *error) const {
if (file->service_count() == 0) { if (file->service_count() == 0) {
// No services. Do nothing. // No services. Do nothing.
return true; return true;
@ -66,29 +66,32 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
// Generate .pbrpc.h // Generate .pbrpc.h
::grpc::string imports = ::grpc::string("#import \"") + file_name + ::grpc::string imports = ::grpc::string("#import \"") + file_name +
".pbobjc.h\"\n\n" ".pbobjc.h\"\n\n"
"#import <ProtoRPC/ProtoService.h>\n" "#import <ProtoRPC/ProtoService.h>\n"
"#import <RxLibrary/GRXWriteable.h>\n" "#import <RxLibrary/GRXWriteable.h>\n"
"#import <RxLibrary/GRXWriter.h>\n"; "#import <RxLibrary/GRXWriter.h>\n";
// TODO(jcanizales): Instead forward-declare the input and output types // TODO(jcanizales): Instead forward-declare the input and output types
// and import the files in the .pbrpc.m // and import the files in the .pbrpc.m
::grpc::string proto_imports; ::grpc::string proto_imports;
for (int i = 0; i < file->dependency_count(); i++) { for (int i = 0; i < file->dependency_count(); i++) {
::grpc::string header = grpc_objective_c_generator::MessageHeaderName( ::grpc::string header =
file->dependency(i)); grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
const grpc::protobuf::FileDescriptor *dependency = file->dependency(i); const grpc::protobuf::FileDescriptor *dependency = file->dependency(i);
if (IsProtobufLibraryBundledProtoFile(dependency)) { if (IsProtobufLibraryBundledProtoFile(dependency)) {
::grpc::string base_name = header; ::grpc::string base_name = header;
grpc_generator::StripPrefix(&base_name, "google/protobuf/"); grpc_generator::StripPrefix(&base_name, "google/protobuf/");
// create the import code snippet // create the import code snippet
proto_imports += proto_imports +=
"#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n" "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
" #import <" + ::grpc::string(ProtobufLibraryFrameworkName) + " #import <" +
"/" + base_name + ">\n" ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
"#else\n" ">\n"
" #import \"" + header + "\"\n" "#else\n"
"#endif\n"; " #import \"" +
header +
"\"\n"
"#endif\n";
} else { } else {
proto_imports += ::grpc::string("#import \"") + header + "\"\n"; proto_imports += ::grpc::string("#import \"") + header + "\"\n";
} }
@ -100,21 +103,22 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
declarations += grpc_objective_c_generator::GetHeader(service); declarations += grpc_objective_c_generator::GetHeader(service);
} }
static const ::grpc::string kNonNullBegin = "\nNS_ASSUME_NONNULL_BEGIN\n\n"; static const ::grpc::string kNonNullBegin =
"\nNS_ASSUME_NONNULL_BEGIN\n\n";
static const ::grpc::string kNonNullEnd = "\nNS_ASSUME_NONNULL_END\n"; static const ::grpc::string kNonNullEnd = "\nNS_ASSUME_NONNULL_END\n";
Write(context, file_name + ".pbrpc.h", Write(context, file_name + ".pbrpc.h", imports + '\n' + proto_imports +
imports + '\n' + proto_imports + '\n' + kNonNullBegin + '\n' + kNonNullBegin +
declarations + kNonNullEnd); declarations + kNonNullEnd);
} }
{ {
// Generate .pbrpc.m // Generate .pbrpc.m
::grpc::string imports = ::grpc::string("#import \"") + file_name + ::grpc::string imports = ::grpc::string("#import \"") + file_name +
".pbrpc.h\"\n\n" ".pbrpc.h\"\n\n"
"#import <ProtoRPC/ProtoRPC.h>\n" "#import <ProtoRPC/ProtoRPC.h>\n"
"#import <RxLibrary/GRXWriter+Immediate.h>\n"; "#import <RxLibrary/GRXWriter+Immediate.h>\n";
::grpc::string definitions; ::grpc::string definitions;
for (int i = 0; i < file->service_count(); i++) { for (int i = 0; i < file->service_count(); i++) {
@ -131,7 +135,7 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
private: private:
// Write the given code into the given file. // Write the given code into the given file.
void Write(grpc::protobuf::compiler::GeneratorContext *context, void Write(grpc::protobuf::compiler::GeneratorContext *context,
const ::grpc::string &filename, const ::grpc::string &code) const { const ::grpc::string &filename, const ::grpc::string &code) const {
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output( std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
context->Open(filename)); context->Open(filename));
grpc::protobuf::io::CodedOutputStream coded_out(output.get()); grpc::protobuf::io::CodedOutputStream coded_out(output.get());

@ -74,16 +74,18 @@ PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
PythonGrpcGenerator::~PythonGrpcGenerator() {} PythonGrpcGenerator::~PythonGrpcGenerator() {}
bool PythonGrpcGenerator::Generate( bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
const FileDescriptor* file, const grpc::string& parameter, const grpc::string& parameter,
GeneratorContext* context, grpc::string* error) const { GeneratorContext* context,
grpc::string* error) const {
// Get output file name. // Get output file name.
grpc::string file_name; grpc::string file_name;
static const int proto_suffix_length = strlen(".proto"); static const int proto_suffix_length = strlen(".proto");
if (file->name().size() > static_cast<size_t>(proto_suffix_length) && if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
file->name().find_last_of(".proto") == file->name().size() - 1) { file->name().find_last_of(".proto") == file->name().size() - 1) {
file_name = file->name().substr( file_name =
0, file->name().size() - proto_suffix_length) + "_pb2.py"; file->name().substr(0, file->name().size() - proto_suffix_length) +
"_pb2.py";
} else { } else {
*error = "Invalid proto file name. Proto file must end with .proto"; *error = "Invalid proto file name. Proto file must end with .proto";
return false; return false;
@ -115,7 +117,7 @@ map<grpc::string, grpc::string> ListToDict(
assert(values.size() % 2 == 0); assert(values.size() % 2 == 0);
map<grpc::string, grpc::string> value_map; map<grpc::string, grpc::string> value_map;
auto value_iter = values.begin(); auto value_iter = values.begin();
for (unsigned i = 0; i < values.size()/2; ++i) { for (unsigned i = 0; i < values.size() / 2; ++i) {
grpc::string key = *value_iter; grpc::string key = *value_iter;
++value_iter; ++value_iter;
grpc::string value = *value_iter; grpc::string value = *value_iter;
@ -138,9 +140,7 @@ class IndentScope {
printer_->Indent(); printer_->Indent();
} }
~IndentScope() { ~IndentScope() { printer_->Outdent(); }
printer_->Outdent();
}
private: private:
Printer* printer_; Printer* printer_;
@ -173,7 +173,6 @@ grpc::string ModuleAlias(const grpc::string& filename) {
return module_name; return module_name;
} }
bool GetModuleAndMessagePath(const Descriptor* type, bool GetModuleAndMessagePath(const Descriptor* type,
const ServiceDescriptor* service, const ServiceDescriptor* service,
grpc::string* out) { grpc::string* out) {
@ -182,7 +181,7 @@ bool GetModuleAndMessagePath(const Descriptor* type,
do { do {
message_path.push_back(path_elem_type); message_path.push_back(path_elem_type);
path_elem_type = path_elem_type->containing_type(); path_elem_type = path_elem_type->containing_type();
} while (path_elem_type); // implicit nullptr comparison; don't be explicit } while (path_elem_type); // implicit nullptr comparison; don't be explicit
grpc::string file_name = type->file()->name(); grpc::string file_name = type->file()->name();
static const int proto_suffix_length = strlen(".proto"); static const int proto_suffix_length = strlen(".proto");
if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) && if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
@ -190,11 +189,11 @@ bool GetModuleAndMessagePath(const Descriptor* type,
return false; return false;
} }
grpc::string service_file_name = service->file()->name(); grpc::string service_file_name = service->file()->name();
grpc::string module = service_file_name == file_name ? grpc::string module =
"" : ModuleAlias(file_name) + "."; service_file_name == file_name ? "" : ModuleAlias(file_name) + ".";
grpc::string message_type; grpc::string message_type;
for (auto path_iter = message_path.rbegin(); for (auto path_iter = message_path.rbegin(); path_iter != message_path.rend();
path_iter != message_path.rend(); ++path_iter) { ++path_iter) {
message_type += (*path_iter)->name() + "."; message_type += (*path_iter)->name() + ".";
} }
// no pop_back prior to C++11 // no pop_back prior to C++11
@ -229,8 +228,7 @@ static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
printer->Print("\"\"\"\n"); printer->Print("\"\"\"\n");
} }
bool PrintBetaServicer(const ServiceDescriptor* service, bool PrintBetaServicer(const ServiceDescriptor* service, Printer* out) {
Printer* out) {
out->Print("\n\n"); out->Print("\n\n");
out->Print("class Beta$Service$Servicer(object):\n", "Service", out->Print("class Beta$Service$Servicer(object):\n", "Service",
service->name()); service->name());
@ -239,10 +237,10 @@ bool PrintBetaServicer(const ServiceDescriptor* service,
PrintAllComments(service, out); PrintAllComments(service, out);
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
auto meth = service->method(i); auto meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ? grpc::string arg_name =
"request_iterator" : "request"; meth->client_streaming() ? "request_iterator" : "request";
out->Print("def $Method$(self, $ArgName$, context):\n", out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
"Method", meth->name(), "ArgName", arg_name); meth->name(), "ArgName", arg_name);
{ {
IndentScope raii_method_indent(out); IndentScope raii_method_indent(out);
PrintAllComments(meth, out); PrintAllComments(meth, out);
@ -253,8 +251,7 @@ bool PrintBetaServicer(const ServiceDescriptor* service,
return true; return true;
} }
bool PrintBetaStub(const ServiceDescriptor* service, bool PrintBetaStub(const ServiceDescriptor* service, Printer* out) {
Printer* out) {
out->Print("\n\n"); out->Print("\n\n");
out->Print("class Beta$Service$Stub(object):\n", "Service", service->name()); out->Print("class Beta$Service$Stub(object):\n", "Service", service->name());
{ {
@ -262,10 +259,12 @@ bool PrintBetaStub(const ServiceDescriptor* service,
PrintAllComments(service, out); PrintAllComments(service, out);
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* meth = service->method(i); const MethodDescriptor* meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ? grpc::string arg_name =
"request_iterator" : "request"; meth->client_streaming() ? "request_iterator" : "request";
auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name}); auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
out->Print(methdict, "def $Method$(self, $ArgName$, timeout, metadata=None, with_call=False, protocol_options=None):\n"); out->Print(methdict,
"def $Method$(self, $ArgName$, timeout, metadata=None, "
"with_call=False, protocol_options=None):\n");
{ {
IndentScope raii_method_indent(out); IndentScope raii_method_indent(out);
PrintAllComments(meth, out); PrintAllComments(meth, out);
@ -282,9 +281,10 @@ bool PrintBetaStub(const ServiceDescriptor* service,
bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name, bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service, Printer* out) { const ServiceDescriptor* service, Printer* out) {
out->Print("\n\n"); out->Print("\n\n");
out->Print("def beta_create_$Service$_server(servicer, pool=None, " out->Print(
"pool_size=None, default_timeout=None, maximum_timeout=None):\n", "def beta_create_$Service$_server(servicer, pool=None, "
"Service", service->name()); "pool_size=None, default_timeout=None, maximum_timeout=None):\n",
"Service", service->name());
{ {
IndentScope raii_create_server_indent(out); IndentScope raii_create_server_indent(out);
map<grpc::string, grpc::string> method_implementation_constructors; map<grpc::string, grpc::string> method_implementation_constructors;
@ -315,58 +315,62 @@ bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
} }
out->Print("request_deserializers = {\n"); out->Print("request_deserializers = {\n");
for (auto name_and_input_module_class_pair = for (auto name_and_input_module_class_pair =
input_message_modules_and_classes.begin(); input_message_modules_and_classes.begin();
name_and_input_module_class_pair != name_and_input_module_class_pair !=
input_message_modules_and_classes.end(); input_message_modules_and_classes.end();
name_and_input_module_class_pair++) { name_and_input_module_class_pair++) {
IndentScope raii_indent(out); IndentScope raii_indent(out);
out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " out->Print(
"$InputTypeModuleAndClass$.FromString,\n", "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"PackageQualifiedServiceName", package_qualified_service_name, "$InputTypeModuleAndClass$.FromString,\n",
"MethodName", name_and_input_module_class_pair->first, "PackageQualifiedServiceName", package_qualified_service_name,
"InputTypeModuleAndClass", "MethodName", name_and_input_module_class_pair->first,
name_and_input_module_class_pair->second); "InputTypeModuleAndClass", name_and_input_module_class_pair->second);
} }
out->Print("}\n"); out->Print("}\n");
out->Print("response_serializers = {\n"); out->Print("response_serializers = {\n");
for (auto name_and_output_module_class_pair = for (auto name_and_output_module_class_pair =
output_message_modules_and_classes.begin(); output_message_modules_and_classes.begin();
name_and_output_module_class_pair != name_and_output_module_class_pair !=
output_message_modules_and_classes.end(); output_message_modules_and_classes.end();
name_and_output_module_class_pair++) { name_and_output_module_class_pair++) {
IndentScope raii_indent(out); IndentScope raii_indent(out);
out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " out->Print(
"$OutputTypeModuleAndClass$.SerializeToString,\n", "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"PackageQualifiedServiceName", package_qualified_service_name, "$OutputTypeModuleAndClass$.SerializeToString,\n",
"MethodName", name_and_output_module_class_pair->first, "PackageQualifiedServiceName", package_qualified_service_name,
"OutputTypeModuleAndClass", "MethodName", name_and_output_module_class_pair->first,
name_and_output_module_class_pair->second); "OutputTypeModuleAndClass",
name_and_output_module_class_pair->second);
} }
out->Print("}\n"); out->Print("}\n");
out->Print("method_implementations = {\n"); out->Print("method_implementations = {\n");
for (auto name_and_implementation_constructor = for (auto name_and_implementation_constructor =
method_implementation_constructors.begin(); method_implementation_constructors.begin();
name_and_implementation_constructor != name_and_implementation_constructor !=
method_implementation_constructors.end(); method_implementation_constructors.end();
name_and_implementation_constructor++) { name_and_implementation_constructor++) {
IndentScope raii_descriptions_indent(out); IndentScope raii_descriptions_indent(out);
const grpc::string method_name = const grpc::string method_name =
name_and_implementation_constructor->first; name_and_implementation_constructor->first;
out->Print("(\'$PackageQualifiedServiceName$\', \'$Method$\'): " out->Print(
"face_utilities.$Constructor$(servicer.$Method$),\n", "(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
"PackageQualifiedServiceName", package_qualified_service_name, "face_utilities.$Constructor$(servicer.$Method$),\n",
"Method", name_and_implementation_constructor->first, "PackageQualifiedServiceName", package_qualified_service_name,
"Constructor", name_and_implementation_constructor->second); "Method", name_and_implementation_constructor->first, "Constructor",
name_and_implementation_constructor->second);
} }
out->Print("}\n"); out->Print("}\n");
out->Print("server_options = beta_implementations.server_options(" out->Print(
"request_deserializers=request_deserializers, " "server_options = beta_implementations.server_options("
"response_serializers=response_serializers, " "request_deserializers=request_deserializers, "
"thread_pool=pool, thread_pool_size=pool_size, " "response_serializers=response_serializers, "
"default_timeout=default_timeout, " "thread_pool=pool, thread_pool_size=pool_size, "
"maximum_timeout=maximum_timeout)\n"); "default_timeout=default_timeout, "
out->Print("return beta_implementations.server(method_implementations, " "maximum_timeout=maximum_timeout)\n");
"options=server_options)\n"); out->Print(
"return beta_implementations.server(method_implementations, "
"options=server_options)\n");
} }
return true; return true;
} }
@ -374,10 +378,11 @@ bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name, bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service, Printer* out) { const ServiceDescriptor* service, Printer* out) {
map<grpc::string, grpc::string> dict = ListToDict({ map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(), "Service", service->name(),
}); });
out->Print("\n\n"); out->Print("\n\n");
out->Print(dict, "def beta_create_$Service$_stub(channel, host=None," out->Print(dict,
"def beta_create_$Service$_stub(channel, host=None,"
" metadata_transformer=None, pool=None, pool_size=None):\n"); " metadata_transformer=None, pool=None, pool_size=None):\n");
{ {
IndentScope raii_create_server_indent(out); IndentScope raii_create_server_indent(out);
@ -387,8 +392,7 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i); const MethodDescriptor* method = service->method(i);
const grpc::string method_cardinality = const grpc::string method_cardinality =
grpc::string(method->client_streaming() ? "STREAM" : "UNARY") + grpc::string(method->client_streaming() ? "STREAM" : "UNARY") + "_" +
"_" +
grpc::string(method->server_streaming() ? "STREAM" : "UNARY"); grpc::string(method->server_streaming() ? "STREAM" : "UNARY");
grpc::string input_message_module_and_class; grpc::string input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(), service, if (!GetModuleAndMessagePath(method->input_type(), service,
@ -409,32 +413,33 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
} }
out->Print("request_serializers = {\n"); out->Print("request_serializers = {\n");
for (auto name_and_input_module_class_pair = for (auto name_and_input_module_class_pair =
input_message_modules_and_classes.begin(); input_message_modules_and_classes.begin();
name_and_input_module_class_pair != name_and_input_module_class_pair !=
input_message_modules_and_classes.end(); input_message_modules_and_classes.end();
name_and_input_module_class_pair++) { name_and_input_module_class_pair++) {
IndentScope raii_indent(out); IndentScope raii_indent(out);
out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " out->Print(
"$InputTypeModuleAndClass$.SerializeToString,\n", "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"PackageQualifiedServiceName", package_qualified_service_name, "$InputTypeModuleAndClass$.SerializeToString,\n",
"MethodName", name_and_input_module_class_pair->first, "PackageQualifiedServiceName", package_qualified_service_name,
"InputTypeModuleAndClass", "MethodName", name_and_input_module_class_pair->first,
name_and_input_module_class_pair->second); "InputTypeModuleAndClass", name_and_input_module_class_pair->second);
} }
out->Print("}\n"); out->Print("}\n");
out->Print("response_deserializers = {\n"); out->Print("response_deserializers = {\n");
for (auto name_and_output_module_class_pair = for (auto name_and_output_module_class_pair =
output_message_modules_and_classes.begin(); output_message_modules_and_classes.begin();
name_and_output_module_class_pair != name_and_output_module_class_pair !=
output_message_modules_and_classes.end(); output_message_modules_and_classes.end();
name_and_output_module_class_pair++) { name_and_output_module_class_pair++) {
IndentScope raii_indent(out); IndentScope raii_indent(out);
out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " out->Print(
"$OutputTypeModuleAndClass$.FromString,\n", "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"PackageQualifiedServiceName", package_qualified_service_name, "$OutputTypeModuleAndClass$.FromString,\n",
"MethodName", name_and_output_module_class_pair->first, "PackageQualifiedServiceName", package_qualified_service_name,
"OutputTypeModuleAndClass", "MethodName", name_and_output_module_class_pair->first,
name_and_output_module_class_pair->second); "OutputTypeModuleAndClass",
name_and_output_module_class_pair->second);
} }
out->Print("}\n"); out->Print("}\n");
out->Print("cardinalities = {\n"); out->Print("cardinalities = {\n");
@ -443,17 +448,19 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
name_and_cardinality++) { name_and_cardinality++) {
IndentScope raii_descriptions_indent(out); IndentScope raii_descriptions_indent(out);
out->Print("\'$Method$\': cardinality.Cardinality.$Cardinality$,\n", out->Print("\'$Method$\': cardinality.Cardinality.$Cardinality$,\n",
"Method", name_and_cardinality->first, "Method", name_and_cardinality->first, "Cardinality",
"Cardinality", name_and_cardinality->second); name_and_cardinality->second);
} }
out->Print("}\n"); out->Print("}\n");
out->Print("stub_options = beta_implementations.stub_options("
"host=host, metadata_transformer=metadata_transformer, "
"request_serializers=request_serializers, "
"response_deserializers=response_deserializers, "
"thread_pool=pool, thread_pool_size=pool_size)\n");
out->Print( out->Print(
"return beta_implementations.dynamic_stub(channel, \'$PackageQualifiedServiceName$\', " "stub_options = beta_implementations.stub_options("
"host=host, metadata_transformer=metadata_transformer, "
"request_serializers=request_serializers, "
"response_deserializers=response_deserializers, "
"thread_pool=pool, thread_pool_size=pool_size)\n");
out->Print(
"return beta_implementations.dynamic_stub(channel, "
"\'$PackageQualifiedServiceName$\', "
"cardinalities, options=stub_options)\n", "cardinalities, options=stub_options)\n",
"PackageQualifiedServiceName", package_qualified_service_name); "PackageQualifiedServiceName", package_qualified_service_name);
} }
@ -476,43 +483,41 @@ bool PrintStub(const grpc::string& package_qualified_service_name,
out->Print("Args:\n"); out->Print("Args:\n");
{ {
IndentScope raii_args_indent(out); IndentScope raii_args_indent(out);
out->Print("channel: A grpc.Channel.\n"); out->Print("channel: A grpc.Channel.\n");
} }
out->Print("\"\"\"\n"); out->Print("\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i); auto method = service->method(i);
auto multi_callable_constructor = auto multi_callable_constructor =
grpc::string(method->client_streaming() ? "stream" : "unary") + grpc::string(method->client_streaming() ? "stream" : "unary") +
"_" + "_" + grpc::string(method->server_streaming() ? "stream" : "unary");
grpc::string(method->server_streaming() ? "stream" : "unary"); grpc::string request_module_and_class;
grpc::string request_module_and_class; if (!GetModuleAndMessagePath(method->input_type(), service,
if (!GetModuleAndMessagePath(method->input_type(), service, &request_module_and_class)) {
&request_module_and_class)) { return false;
return false; }
} grpc::string response_module_and_class;
grpc::string response_module_and_class; if (!GetModuleAndMessagePath(method->output_type(), service,
if (!GetModuleAndMessagePath(method->output_type(), service, &response_module_and_class)) {
&response_module_and_class)) {
return false; return false;
} }
out->Print("self.$Method$ = channel.$MultiCallableConstructor$(\n", out->Print("self.$Method$ = channel.$MultiCallableConstructor$(\n",
"Method", method->name(), "Method", method->name(), "MultiCallableConstructor",
"MultiCallableConstructor", multi_callable_constructor); multi_callable_constructor);
{ {
IndentScope raii_first_attribute_indent(out); IndentScope raii_first_attribute_indent(out);
IndentScope raii_second_attribute_indent(out); IndentScope raii_second_attribute_indent(out);
out->Print( out->Print("'/$PackageQualifiedService$/$Method$',\n",
"'/$PackageQualifiedService$/$Method$',\n", "PackageQualifiedService", package_qualified_service_name,
"PackageQualifiedService", package_qualified_service_name, "Method", method->name());
"Method", method->name()); out->Print(
out->Print( "request_serializer=$RequestModuleAndClass$.SerializeToString,\n",
"request_serializer=$RequestModuleAndClass$.SerializeToString,\n", "RequestModuleAndClass", request_module_and_class);
"RequestModuleAndClass", request_module_and_class); out->Print(
out->Print(
"response_deserializer=$ResponseModuleAndClass$.FromString,\n", "response_deserializer=$ResponseModuleAndClass$.FromString,\n",
"ResponseModuleAndClass", response_module_and_class); "ResponseModuleAndClass", response_module_and_class);
out->Print(")\n"); out->Print(")\n");
} }
} }
} }
} }
@ -527,11 +532,11 @@ bool PrintServicer(const ServiceDescriptor* service, Printer* out) {
PrintAllComments(service, out); PrintAllComments(service, out);
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i); auto method = service->method(i);
grpc::string arg_name = method->client_streaming() ? grpc::string arg_name =
"request_iterator" : "request"; method->client_streaming() ? "request_iterator" : "request";
out->Print("\n"); out->Print("\n");
out->Print("def $Method$(self, $ArgName$, context):\n", out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
"Method", method->name(), "ArgName", arg_name); method->name(), "ArgName", arg_name);
{ {
IndentScope raii_method_indent(out); IndentScope raii_method_indent(out);
PrintAllComments(method, out); PrintAllComments(method, out);
@ -544,11 +549,12 @@ bool PrintServicer(const ServiceDescriptor* service, Printer* out) {
return true; return true;
} }
bool PrintAddServicerToServer(const grpc::string& package_qualified_service_name, bool PrintAddServicerToServer(
const ServiceDescriptor* service, Printer* out) { const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service, Printer* out) {
out->Print("\n\n"); out->Print("\n\n");
out->Print("def add_$Service$Servicer_to_server(servicer, server):\n", out->Print("def add_$Service$Servicer_to_server(servicer, server):\n",
"Service", service->name()); "Service", service->name());
{ {
IndentScope raii_class_indent(out); IndentScope raii_class_indent(out);
out->Print("rpc_method_handlers = {\n"); out->Print("rpc_method_handlers = {\n");
@ -557,34 +563,37 @@ bool PrintAddServicerToServer(const grpc::string& package_qualified_service_name
IndentScope raii_dict_second_indent(out); IndentScope raii_dict_second_indent(out);
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i); auto method = service->method(i);
auto method_handler_constructor = auto method_handler_constructor =
grpc::string(method->client_streaming() ? "stream" : "unary") + grpc::string(method->client_streaming() ? "stream" : "unary") +
"_" + "_" +
grpc::string(method->server_streaming() ? "stream" : "unary") + grpc::string(method->server_streaming() ? "stream" : "unary") +
"_rpc_method_handler"; "_rpc_method_handler";
grpc::string request_module_and_class; grpc::string request_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(), service, if (!GetModuleAndMessagePath(method->input_type(), service,
&request_module_and_class)) { &request_module_and_class)) {
return false;
}
grpc::string response_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(), service,
&response_module_and_class)) {
return false; return false;
} }
out->Print("'$Method$': grpc.$MethodHandlerConstructor$(\n", grpc::string response_module_and_class;
"Method", method->name(), if (!GetModuleAndMessagePath(method->output_type(), service,
"MethodHandlerConstructor", method_handler_constructor); &response_module_and_class)) {
{ return false;
}
out->Print("'$Method$': grpc.$MethodHandlerConstructor$(\n", "Method",
method->name(), "MethodHandlerConstructor",
method_handler_constructor);
{
IndentScope raii_call_first_indent(out); IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out); IndentScope raii_call_second_indent(out);
out->Print("servicer.$Method$,\n", "Method", method->name()); out->Print("servicer.$Method$,\n", "Method", method->name());
out->Print("request_deserializer=$RequestModuleAndClass$.FromString,\n", out->Print(
"RequestModuleAndClass", request_module_and_class); "request_deserializer=$RequestModuleAndClass$.FromString,\n",
out->Print("response_serializer=$ResponseModuleAndClass$.SerializeToString,\n", "RequestModuleAndClass", request_module_and_class);
"ResponseModuleAndClass", response_module_and_class); out->Print(
} "response_serializer=$ResponseModuleAndClass$.SerializeToString,"
out->Print("),\n"); "\n",
"ResponseModuleAndClass", response_module_and_class);
}
out->Print("),\n");
} }
} }
out->Print("}\n"); out->Print("}\n");
@ -593,7 +602,7 @@ bool PrintAddServicerToServer(const grpc::string& package_qualified_service_name
IndentScope raii_call_first_indent(out); IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out); IndentScope raii_call_second_indent(out);
out->Print("'$PackageQualifiedServiceName$', rpc_method_handlers)\n", out->Print("'$PackageQualifiedServiceName$', rpc_method_handlers)\n",
"PackageQualifiedServiceName", package_qualified_service_name); "PackageQualifiedServiceName", package_qualified_service_name);
} }
out->Print("server.add_generic_rpc_handlers((generic_handler,))\n"); out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
} }
@ -605,10 +614,12 @@ bool PrintPreamble(const FileDescriptor* file,
out->Print("import $Package$\n", "Package", config.grpc_package_root); out->Print("import $Package$\n", "Package", config.grpc_package_root);
out->Print("from $Package$ import implementations as beta_implementations\n", out->Print("from $Package$ import implementations as beta_implementations\n",
"Package", config.beta_package_root); "Package", config.beta_package_root);
out->Print("from $Package$ import interfaces as beta_interfaces\n", out->Print("from $Package$ import interfaces as beta_interfaces\n", "Package",
"Package", config.beta_package_root); config.beta_package_root);
out->Print("from grpc.framework.common import cardinality\n"); out->Print("from grpc.framework.common import cardinality\n");
out->Print("from grpc.framework.interfaces.face import utilities as face_utilities\n"); out->Print(
"from grpc.framework.interfaces.face import utilities as "
"face_utilities\n");
return true; return true;
} }
@ -632,12 +643,14 @@ pair<bool, grpc::string> GetServices(const FileDescriptor* file,
auto service = file->service(i); auto service = file->service(i);
auto package_qualified_service_name = package + service->name(); auto package_qualified_service_name = package + service->name();
if (!(PrintStub(package_qualified_service_name, service, &out) && if (!(PrintStub(package_qualified_service_name, service, &out) &&
PrintServicer(service, &out) && PrintServicer(service, &out) &&
PrintAddServicerToServer(package_qualified_service_name, service, &out) && PrintAddServicerToServer(package_qualified_service_name, service,
PrintBetaServicer(service, &out) && &out) &&
PrintBetaStub(service, &out) && PrintBetaServicer(service, &out) && PrintBetaStub(service, &out) &&
PrintBetaServerFactory(package_qualified_service_name, service, &out) && PrintBetaServerFactory(package_qualified_service_name, service,
PrintBetaStubFactory(package_qualified_service_name, service, &out))) { &out) &&
PrintBetaStubFactory(package_qualified_service_name, service,
&out))) {
return make_pair(false, ""); return make_pair(false, "");
} }
} }

@ -57,6 +57,7 @@ class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
const grpc::string& parameter, const grpc::string& parameter,
grpc::protobuf::compiler::GeneratorContext* context, grpc::protobuf::compiler::GeneratorContext* context,
grpc::string* error) const; grpc::string* error) const;
private: private:
GeneratorConfiguration config_; GeneratorConfiguration config_;
}; };

@ -55,17 +55,20 @@ namespace {
// Prints out the method using the ruby gRPC DSL. // Prints out the method using the ruby gRPC DSL.
void PrintMethod(const MethodDescriptor *method, const grpc::string &package, void PrintMethod(const MethodDescriptor *method, const grpc::string &package,
Printer *out) { Printer *out) {
grpc::string input_type = RubyTypeOf(method->input_type()->full_name(), package); grpc::string input_type =
RubyTypeOf(method->input_type()->full_name(), package);
if (method->client_streaming()) { if (method->client_streaming()) {
input_type = "stream(" + input_type + ")"; input_type = "stream(" + input_type + ")";
} }
grpc::string output_type = RubyTypeOf(method->output_type()->full_name(), package); grpc::string output_type =
RubyTypeOf(method->output_type()->full_name(), package);
if (method->server_streaming()) { if (method->server_streaming()) {
output_type = "stream(" + output_type + ")"; output_type = "stream(" + output_type + ")";
} }
std::map<grpc::string, grpc::string> method_vars = std::map<grpc::string, grpc::string> method_vars = ListToDict({
ListToDict({"mth.name", method->name(), "input.type", input_type, "mth.name", method->name(), "input.type", input_type, "output.type",
"output.type", output_type, }); output_type,
});
out->Print(GetRubyComments(method, true).c_str()); out->Print(GetRubyComments(method, true).c_str());
out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n"); out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n");
out->Print(GetRubyComments(method, false).c_str()); out->Print(GetRubyComments(method, false).c_str());
@ -79,8 +82,9 @@ void PrintService(const ServiceDescriptor *service, const grpc::string &package,
} }
// Begin the service module // Begin the service module
std::map<grpc::string, grpc::string> module_vars = std::map<grpc::string, grpc::string> module_vars = ListToDict({
ListToDict({"module.name", CapitalizeFirst(service->name()), }); "module.name", CapitalizeFirst(service->name()),
});
out->Print(module_vars, "module $module.name$\n"); out->Print(module_vars, "module $module.name$\n");
out->Indent(); out->Indent();
@ -130,8 +134,9 @@ grpc::string GetServices(const FileDescriptor *file) {
} }
// Write out a file header. // Write out a file header.
std::map<grpc::string, grpc::string> header_comment_vars = ListToDict( std::map<grpc::string, grpc::string> header_comment_vars = ListToDict({
{"file.name", file->name(), "file.package", file->package(), }); "file.name", file->name(), "file.package", file->package(),
});
out.Print("# Generated by the protocol buffer compiler. DO NOT EDIT!\n"); out.Print("# Generated by the protocol buffer compiler. DO NOT EDIT!\n");
out.Print(header_comment_vars, out.Print(header_comment_vars,
"# Source: $file.name$ for package '$file.package$'\n"); "# Source: $file.name$ for package '$file.package$'\n");
@ -147,16 +152,18 @@ grpc::string GetServices(const FileDescriptor *file) {
// Write out require statemment to import the separately generated file // Write out require statemment to import the separately generated file
// that defines the messages used by the service. This is generated by the // that defines the messages used by the service. This is generated by the
// main ruby plugin. // main ruby plugin.
std::map<grpc::string, grpc::string> dep_vars = std::map<grpc::string, grpc::string> dep_vars = ListToDict({
ListToDict({"dep.name", MessagesRequireName(file), }); "dep.name", MessagesRequireName(file),
});
out.Print(dep_vars, "require '$dep.name$'\n"); out.Print(dep_vars, "require '$dep.name$'\n");
// Write out services within the modules // Write out services within the modules
out.Print("\n"); out.Print("\n");
std::vector<grpc::string> modules = Split(file->package(), '.'); std::vector<grpc::string> modules = Split(file->package(), '.');
for (size_t i = 0; i < modules.size(); ++i) { for (size_t i = 0; i < modules.size(); ++i) {
std::map<grpc::string, grpc::string> module_vars = std::map<grpc::string, grpc::string> module_vars = ListToDict({
ListToDict({"module.name", CapitalizeFirst(modules[i]), }); "module.name", CapitalizeFirst(modules[i]),
});
out.Print(module_vars, "module $module.name$\n"); out.Print(module_vars, "module $module.name$\n");
out.Indent(); out.Indent();
} }

@ -36,8 +36,8 @@
#include "src/compiler/config.h" #include "src/compiler/config.h"
#include <iostream>
#include <initializer_list> #include <initializer_list>
#include <iostream>
#include <map> #include <map>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <vector> #include <vector>
@ -53,8 +53,7 @@ namespace grpc_ruby_generator {
inline std::map<grpc::string, grpc::string> ListToDict( inline std::map<grpc::string, grpc::string> ListToDict(
const initializer_list<grpc::string> &values) { const initializer_list<grpc::string> &values) {
if (values.size() % 2 != 0) { if (values.size() % 2 != 0) {
std::cerr << "Not every 'key' has a value in `values`." std::cerr << "Not every 'key' has a value in `values`." << std::endl;
<< std::endl;
} }
std::map<grpc::string, grpc::string> value_map; std::map<grpc::string, grpc::string> value_map;
auto value_iter = values.begin(); auto value_iter = values.begin();

Loading…
Cancel
Save