Merge github.com:grpc/grpc into minimal_test

pull/10465/head
Craig Tiller 8 years ago
commit f6221516f4
  1. 4
      BUILD
  2. 4
      build.yaml
  3. 150
      src/compiler/cpp_generator.cc
  4. 87
      src/compiler/cpp_generator.h
  5. 1
      src/compiler/cpp_generator_helpers.h
  6. 133
      src/compiler/cpp_plugin.cc
  7. 210
      src/compiler/protobuf_plugin.h
  8. 532
      src/compiler/python_generator.cc
  9. 1
      src/compiler/python_generator.h
  10. 142
      src/compiler/python_generator_helpers.h
  11. 1
      src/compiler/python_plugin.cc
  12. 99
      src/compiler/python_private_generator.h
  13. 126
      src/compiler/schema_interface.h
  14. 12
      tools/run_tests/generated/sources_and_headers.json
  15. 4
      vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
  16. 12
      vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters

@ -182,6 +182,8 @@ grpc_cc_library(
],
hdrs = [
"src/compiler/config.h",
"src/compiler/schema_interface.h",
"src/compiler/protobuf_plugin.h",
"src/compiler/cpp_generator.h",
"src/compiler/cpp_generator_helpers.h",
"src/compiler/csharp_generator.h",
@ -194,6 +196,8 @@ grpc_cc_library(
"src/compiler/php_generator.h",
"src/compiler/php_generator_helpers.h",
"src/compiler/python_generator.h",
"src/compiler/python_generator_helpers.h",
"src/compiler/python_private_generator.h",
"src/compiler/ruby_generator.h",
"src/compiler/ruby_generator_helpers-inl.h",
"src/compiler/ruby_generator_map-inl.h",

@ -1333,11 +1333,15 @@ libs:
- src/compiler/objective_c_generator_helpers.h
- src/compiler/php_generator.h
- src/compiler/php_generator_helpers.h
- src/compiler/protobuf_plugin.h
- src/compiler/python_generator.h
- src/compiler/python_generator_helpers.h
- src/compiler/python_private_generator.h
- src/compiler/ruby_generator.h
- src/compiler/ruby_generator_helpers-inl.h
- src/compiler/ruby_generator_map-inl.h
- src/compiler/ruby_generator_string-inl.h
- src/compiler/schema_interface.h
src:
- src/compiler/cpp_generator.cc
- src/compiler/csharp_generator.cc

@ -40,6 +40,9 @@
namespace grpc_cpp_generator {
namespace {
grpc::string message_header_ext() { return ".pb.h"; }
grpc::string service_header_ext() { return ".grpc.pb.h"; }
template <class T>
grpc::string as_string(T x) {
std::ostringstream out;
@ -47,6 +50,14 @@ grpc::string as_string(T x) {
return out.str();
}
inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
return method->ClientStreaming() && !method->ServerStreaming();
}
inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
return !method->ClientStreaming() && method->ServerStreaming();
}
grpc::string FilenameIdentifier(const grpc::string &filename) {
grpc::string result;
for (unsigned i = 0; i < filename.size(); i++) {
@ -69,7 +80,8 @@ T *array_end(T (&array)[N]) {
return array + N;
}
void PrintIncludes(Printer *printer, const std::vector<grpc::string> &headers,
void PrintIncludes(grpc_generator::Printer *printer,
const std::vector<grpc::string> &headers,
const Parameters &params) {
std::map<grpc::string, grpc::string> vars;
@ -90,7 +102,8 @@ void PrintIncludes(Printer *printer, const std::vector<grpc::string> &headers,
}
}
grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
grpc::string GetHeaderPrologue(grpc_generator::File *file,
const Parameters & /*params*/) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -100,13 +113,13 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
vars["filename"] = file->filename();
vars["filename_identifier"] = FilenameIdentifier(file->filename());
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = file->message_header_ext();
vars["message_header_ext"] = message_header_ext();
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
printer->Print(vars,
"// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n");
grpc::string leading_comments = file->GetLeadingComments();
grpc::string leading_comments = file->GetLeadingComments("//");
if (!leading_comments.empty()) {
printer->Print(vars, "// Original file comments:\n");
printer->Print(leading_comments.c_str());
@ -120,7 +133,8 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
return output;
}
grpc::string GetHeaderIncludes(File *file, const Parameters &params) {
grpc::string GetHeaderIncludes(grpc_generator::File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -162,7 +176,7 @@ grpc::string GetHeaderIncludes(File *file, const Parameters &params) {
}
void PrintHeaderClientMethodInterfaces(
Printer *printer, const Method *method,
grpc_generator::Printer *printer, const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars, bool is_public) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
@ -187,7 +201,7 @@ void PrintHeaderClientMethodInterfaces(
"Async$Method$Raw(context, request, cq));\n");
printer->Outdent();
printer->Print("}\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
@ -213,7 +227,7 @@ void PrintHeaderClientMethodInterfaces(
"Async$Method$Raw(context, response, cq, tag));\n");
printer->Outdent();
printer->Print("}\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
@ -275,7 +289,7 @@ void PrintHeaderClientMethodInterfaces(
"Async$Method$Raw(::grpc::ClientContext* context, "
"const $Request$& request, "
"::grpc::CompletionQueue* cq) = 0;\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"virtual ::grpc::ClientWriterInterface< $Request$>*"
@ -286,7 +300,7 @@ void PrintHeaderClientMethodInterfaces(
" Async$Method$Raw(::grpc::ClientContext* context, "
"$Response$* response, "
"::grpc::CompletionQueue* cq, void* tag) = 0;\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
@ -311,7 +325,8 @@ void PrintHeaderClientMethodInterfaces(
}
}
void PrintHeaderClientMethod(Printer *printer, const Method *method,
void PrintHeaderClientMethod(grpc_generator::Printer *printer,
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars,
bool is_public) {
(*vars)["Method"] = method->name();
@ -336,7 +351,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
"Async$Method$Raw(context, request, cq));\n");
printer->Outdent();
printer->Print("}\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
@ -360,7 +375,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
"Async$Method$Raw(context, response, cq, tag));\n");
printer->Outdent();
printer->Print("}\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientReader< $Response$>>"
@ -418,7 +433,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
"Async$Method$Raw(::grpc::ClientContext* context, "
"const $Request$& request, "
"::grpc::CompletionQueue* cq) override;\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::ClientWriter< $Request$>* $Method$Raw("
"::grpc::ClientContext* context, $Response$* response) "
@ -427,7 +442,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
"::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
"::grpc::ClientContext* context, $Response$* response, "
"::grpc::CompletionQueue* cq, void* tag) override;\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::ClientReader< $Response$>* $Method$Raw("
"::grpc::ClientContext* context, const $Request$& request)"
@ -449,30 +464,32 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
}
}
void PrintHeaderClientMethodData(Printer *printer, const Method *method,
void PrintHeaderClientMethodData(grpc_generator::Printer *printer,
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
}
void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name();
printer->Print(method->GetLeadingComments().c_str());
printer->Print(method->GetLeadingComments("//").c_str());
if (method->NoStreaming()) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerContext* context, const $Request$* request, "
"$Response$* response);\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerReader< $Request$>* reader, "
"$Response$* response);\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerContext* context, const $Request$* request, "
@ -485,10 +502,11 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
"::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
"\n");
}
printer->Print(method->GetTrailingComments().c_str());
printer->Print(method->GetTrailingComments("//").c_str());
}
void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer,
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
@ -530,7 +548,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
" ::grpc::Service::RequestAsyncUnary($Idx$, context, "
"request, response, new_call_cq, notification_cq, tag);\n");
printer->Print("}\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@ -552,7 +570,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
" ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
"context, reader, new_call_cq, notification_cq, tag);\n");
printer->Print("}\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@ -603,7 +621,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
}
void PrintHeaderServerMethodStreamedUnary(
Printer *printer, const Method *method,
grpc_generator::Printer *printer, const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
@ -654,12 +672,12 @@ void PrintHeaderServerMethodStreamedUnary(
}
void PrintHeaderServerMethodSplitStreaming(
Printer *printer, const Method *method,
grpc_generator::Printer *printer, const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name();
if (method->ServerOnlyStreaming()) {
if (ServerOnlyStreaming(method)) {
printer->Print(*vars, "template <class BaseClass>\n");
printer->Print(*vars,
"class WithSplitStreamingMethod_$Method$ : "
@ -706,7 +724,7 @@ void PrintHeaderServerMethodSplitStreaming(
}
void PrintHeaderServerMethodGeneric(
Printer *printer, const Method *method,
grpc_generator::Printer *printer, const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
@ -737,7 +755,7 @@ void PrintHeaderServerMethodGeneric(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@ -748,7 +766,7 @@ void PrintHeaderServerMethodGeneric(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@ -775,11 +793,12 @@ void PrintHeaderServerMethodGeneric(
printer->Print(*vars, "};\n");
}
void PrintHeaderService(Printer *printer, const Service *service,
void PrintHeaderService(grpc_generator::Printer *printer,
const grpc_generator::Service *service,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name();
printer->Print(service->GetLeadingComments().c_str());
printer->Print(service->GetLeadingComments("//").c_str());
printer->Print(*vars,
"class $Service$ final {\n"
" public:\n");
@ -792,10 +811,10 @@ void PrintHeaderService(Printer *printer, const Service *service,
printer->Indent();
printer->Print("virtual ~StubInterface() {}\n");
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);
printer->Print(service->method(i)->GetTrailingComments().c_str());
printer->Print(service->method(i)->GetTrailingComments("//").c_str());
}
printer->Outdent();
printer->Print("private:\n");
@ -903,13 +922,15 @@ void PrintHeaderService(Printer *printer, const Service *service,
printer->Print("typedef ");
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["method_name"] = service->method(i).get()->name();
if (service->method(i)->ServerOnlyStreaming()) {
auto method = service->method(i);
if (ServerOnlyStreaming(method.get())) {
printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
}
}
printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) {
if (service->method(i)->ServerOnlyStreaming()) {
auto method = service->method(i);
if (ServerOnlyStreaming(method.get())) {
printer->Print(" >");
}
}
@ -919,7 +940,8 @@ void PrintHeaderService(Printer *printer, const Service *service,
printer->Print("typedef ");
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["method_name"] = service->method(i).get()->name();
if (service->method(i)->ServerOnlyStreaming()) {
auto method = service->method(i);
if (ServerOnlyStreaming(method.get())) {
printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
}
if (service->method(i)->NoStreaming()) {
@ -928,8 +950,9 @@ void PrintHeaderService(Printer *printer, const Service *service,
}
printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
if (service->method(i)->NoStreaming() ||
service->method(i)->ServerOnlyStreaming()) {
ServerOnlyStreaming(method.get())) {
printer->Print(" >");
}
}
@ -937,10 +960,11 @@ void PrintHeaderService(Printer *printer, const Service *service,
printer->Outdent();
printer->Print("};\n");
printer->Print(service->GetTrailingComments().c_str());
printer->Print(service->GetTrailingComments("//").c_str());
}
grpc::string GetHeaderServices(File *file, const Parameters &params) {
grpc::string GetHeaderServices(grpc_generator::File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -970,7 +994,8 @@ grpc::string GetHeaderServices(File *file, const Parameters &params) {
return output;
}
grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
grpc::string GetHeaderEpilogue(grpc_generator::File *file,
const Parameters & /*params*/) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -993,12 +1018,13 @@ grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
printer->Print(vars, "\n");
printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
printer->Print(file->GetTrailingComments().c_str());
printer->Print(file->GetTrailingComments("//").c_str());
}
return output;
}
grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
grpc::string GetSourcePrologue(grpc_generator::File *file,
const Parameters & /*params*/) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -1007,8 +1033,8 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
vars["filename"] = file->filename();
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = file->message_header_ext();
vars["service_header_ext"] = file->service_header_ext();
vars["message_header_ext"] = message_header_ext();
vars["service_header_ext"] = service_header_ext();
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
printer->Print(vars,
@ -1023,7 +1049,8 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
return output;
}
grpc::string GetSourceIncludes(File *file, const Parameters &params) {
grpc::string GetSourceIncludes(grpc_generator::File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -1056,7 +1083,8 @@ grpc::string GetSourceIncludes(File *file, const Parameters &params) {
return output;
}
void PrintSourceClientMethod(Printer *printer, const Method *method,
void PrintSourceClientMethod(grpc_generator::Printer *printer,
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
@ -1084,7 +1112,7 @@ void PrintSourceClientMethod(Printer *printer, const Method *method,
"rpcmethod_$Method$_, "
"context, request);\n"
"}\n\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::ClientWriter< $Request$>* "
"$ns$$Service$::Stub::$Method$Raw("
@ -1106,7 +1134,7 @@ void PrintSourceClientMethod(Printer *printer, const Method *method,
"rpcmethod_$Method$_, "
"context, response, tag);\n"
"}\n\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"::grpc::ClientReader< $Response$>* "
@ -1156,7 +1184,8 @@ void PrintSourceClientMethod(Printer *printer, const Method *method,
}
}
void PrintSourceServerMethod(Printer *printer, const Method *method,
void PrintSourceServerMethod(grpc_generator::Printer *printer,
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
@ -1173,7 +1202,7 @@ void PrintSourceServerMethod(Printer *printer, const Method *method,
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
printer->Print("}\n\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
@ -1186,7 +1215,7 @@ void PrintSourceServerMethod(Printer *printer, const Method *method,
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
printer->Print("}\n\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
@ -1214,7 +1243,8 @@ void PrintSourceServerMethod(Printer *printer, const Method *method,
}
}
void PrintSourceService(Printer *printer, const Service *service,
void PrintSourceService(grpc_generator::Printer *printer,
const grpc_generator::Service *service,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name();
@ -1250,9 +1280,9 @@ void PrintSourceService(Printer *printer, const Service *service,
// NOTE: There is no reason to consider streamed-unary as a separate
// category here since this part is setting up the client-side stub
// and this appears as a NORMAL_RPC from the client-side.
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method.get())) {
(*vars)["StreamingType"] = "CLIENT_STREAMING";
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method.get())) {
(*vars)["StreamingType"] = "SERVER_STREAMING";
} else {
(*vars)["StreamingType"] = "BIDI_STREAMING";
@ -1290,7 +1320,7 @@ void PrintSourceService(Printer *printer, const Service *service,
"$Request$, "
"$Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
} else if (method->ClientOnlyStreaming()) {
} else if (ClientOnlyStreaming(method.get())) {
printer->Print(
*vars,
"AddMethod(new ::grpc::RpcServiceMethod(\n"
@ -1299,7 +1329,7 @@ void PrintSourceService(Printer *printer, const Service *service,
" new ::grpc::ClientStreamingHandler< "
"$ns$$Service$::Service, $Request$, $Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
} else if (method->ServerOnlyStreaming()) {
} else if (ServerOnlyStreaming(method.get())) {
printer->Print(
*vars,
"AddMethod(new ::grpc::RpcServiceMethod(\n"
@ -1330,7 +1360,8 @@ void PrintSourceService(Printer *printer, const Service *service,
}
}
grpc::string GetSourceServices(File *file, const Parameters &params) {
grpc::string GetSourceServices(grpc_generator::File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -1358,7 +1389,8 @@ grpc::string GetSourceServices(File *file, const Parameters &params) {
return output;
}
grpc::string GetSourceEpilogue(File *file, const Parameters & /*params*/) {
grpc::string GetSourceEpilogue(grpc_generator::File *file,
const Parameters & /*params*/) {
grpc::string temp;
if (!file->package().empty()) {

@ -42,6 +42,7 @@
#include <vector>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING
#include <string>
@ -66,91 +67,37 @@ struct Parameters {
grpc::string grpc_search_path;
};
// A common interface for objects having comments in the source.
// Return formatted comments to be inserted in generated code.
struct CommentHolder {
virtual ~CommentHolder() {}
virtual grpc::string GetLeadingComments() const = 0;
virtual grpc::string GetTrailingComments() const = 0;
};
// An abstract interface representing a method.
struct Method : public CommentHolder {
virtual ~Method() {}
virtual grpc::string name() const = 0;
virtual grpc::string input_type_name() const = 0;
virtual grpc::string output_type_name() const = 0;
virtual bool NoStreaming() const = 0;
virtual bool ClientOnlyStreaming() const = 0;
virtual bool ServerOnlyStreaming() const = 0;
virtual bool BidiStreaming() const = 0;
};
// An abstract interface representing a service.
struct Service : public CommentHolder {
virtual ~Service() {}
virtual grpc::string name() const = 0;
virtual int method_count() const = 0;
virtual std::unique_ptr<const Method> method(int i) const = 0;
};
struct Printer {
virtual ~Printer() {}
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
const char *template_string) = 0;
virtual void Print(const char *string) = 0;
virtual void Indent() = 0;
virtual void Outdent() = 0;
};
// An interface that allows the source generated to be output using various
// libraries/idls/serializers.
struct File : public CommentHolder {
virtual ~File() {}
virtual grpc::string filename() const = 0;
virtual grpc::string filename_without_ext() const = 0;
virtual grpc::string message_header_ext() const = 0;
virtual grpc::string service_header_ext() const = 0;
virtual grpc::string package() const = 0;
virtual std::vector<grpc::string> package_parts() const = 0;
virtual grpc::string additional_headers() const = 0;
virtual int service_count() const = 0;
virtual std::unique_ptr<const Service> service(int i) const = 0;
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
};
// Return the prologue of the generated header file.
grpc::string GetHeaderPrologue(File *file, const Parameters &params);
grpc::string GetHeaderPrologue(grpc_generator::File *file,
const Parameters &params);
// Return the includes needed for generated header file.
grpc::string GetHeaderIncludes(File *file, const Parameters &params);
grpc::string GetHeaderIncludes(grpc_generator::File *file,
const Parameters &params);
// Return the includes needed for generated source file.
grpc::string GetSourceIncludes(File *file, const Parameters &params);
grpc::string GetSourceIncludes(grpc_generator::File *file,
const Parameters &params);
// Return the epilogue of the generated header file.
grpc::string GetHeaderEpilogue(File *file, const Parameters &params);
grpc::string GetHeaderEpilogue(grpc_generator::File *file,
const Parameters &params);
// Return the prologue of the generated source file.
grpc::string GetSourcePrologue(File *file, const Parameters &params);
grpc::string GetSourcePrologue(grpc_generator::File *file,
const Parameters &params);
// Return the services for generated header file.
grpc::string GetHeaderServices(File *file, const Parameters &params);
grpc::string GetHeaderServices(grpc_generator::File *file,
const Parameters &params);
// Return the services for generated source file.
grpc::string GetSourceServices(File *file, const Parameters &params);
grpc::string GetSourceServices(grpc_generator::File *file,
const Parameters &params);
// Return the epilogue of the generated source file.
grpc::string GetSourceEpilogue(File *file, const Parameters &params);
grpc::string GetSourceEpilogue(grpc_generator::File *file,
const Parameters &params);
} // namespace grpc_cpp_generator

@ -35,6 +35,7 @@
#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_HELPERS_H
#include <map>
#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"

@ -40,139 +40,8 @@
#include "src/compiler/config.h"
#include "src/compiler/cpp_generator.h"
#include "src/compiler/cpp_generator_helpers.h"
#include "src/compiler/generator_helpers.h"
using grpc_cpp_generator::GetCppComments;
class ProtoBufMethod : public grpc_cpp_generator::Method {
public:
ProtoBufMethod(const grpc::protobuf::MethodDescriptor *method)
: method_(method) {}
grpc::string name() const { return method_->name(); }
grpc::string input_type_name() const {
return grpc_cpp_generator::ClassName(method_->input_type(), true);
}
grpc::string output_type_name() const {
return grpc_cpp_generator::ClassName(method_->output_type(), true);
}
bool NoStreaming() const {
return !method_->client_streaming() && !method_->server_streaming();
}
bool ClientOnlyStreaming() const {
return method_->client_streaming() && !method_->server_streaming();
}
bool ServerOnlyStreaming() const {
return !method_->client_streaming() && method_->server_streaming();
}
bool BidiStreaming() const {
return method_->client_streaming() && method_->server_streaming();
}
grpc::string GetLeadingComments() const {
return GetCppComments(method_, true);
}
grpc::string GetTrailingComments() const {
return GetCppComments(method_, false);
}
private:
const grpc::protobuf::MethodDescriptor *method_;
};
class ProtoBufService : public grpc_cpp_generator::Service {
public:
ProtoBufService(const grpc::protobuf::ServiceDescriptor *service)
: service_(service) {}
grpc::string name() const { return service_->name(); }
int method_count() const { return service_->method_count(); };
std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const {
return std::unique_ptr<const grpc_cpp_generator::Method>(
new ProtoBufMethod(service_->method(i)));
};
grpc::string GetLeadingComments() const {
return GetCppComments(service_, true);
}
grpc::string GetTrailingComments() const {
return GetCppComments(service_, false);
}
private:
const grpc::protobuf::ServiceDescriptor *service_;
};
class ProtoBufPrinter : public grpc_cpp_generator::Printer {
public:
ProtoBufPrinter(grpc::string *str)
: output_stream_(str), printer_(&output_stream_, '$') {}
void Print(const std::map<grpc::string, grpc::string> &vars,
const char *string_template) {
printer_.Print(vars, string_template);
}
void Print(const char *string) { printer_.Print(string); }
void Indent() { printer_.Indent(); }
void Outdent() { printer_.Outdent(); }
private:
grpc::protobuf::io::StringOutputStream output_stream_;
grpc::protobuf::io::Printer printer_;
};
class ProtoBufFile : public grpc_cpp_generator::File {
public:
ProtoBufFile(const grpc::protobuf::FileDescriptor *file) : file_(file) {}
grpc::string filename() const { return file_->name(); }
grpc::string filename_without_ext() const {
return grpc_generator::StripProto(filename());
}
grpc::string message_header_ext() const { return ".pb.h"; }
grpc::string service_header_ext() const { return ".grpc.pb.h"; }
grpc::string package() const { return file_->package(); }
std::vector<grpc::string> package_parts() const {
return grpc_generator::tokenize(package(), ".");
}
grpc::string additional_headers() const { return ""; }
int service_count() const { return file_->service_count(); };
std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const {
return std::unique_ptr<const grpc_cpp_generator::Service>(
new ProtoBufService(file_->service(i)));
}
std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(
grpc::string *str) const {
return std::unique_ptr<grpc_cpp_generator::Printer>(
new ProtoBufPrinter(str));
}
grpc::string GetLeadingComments() const {
return GetCppComments(file_, true);
}
grpc::string GetTrailingComments() const {
return GetCppComments(file_, false);
}
private:
const grpc::protobuf::FileDescriptor *file_;
};
#include "src/compiler/protobuf_plugin.h"
class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
public:

@ -0,0 +1,210 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PROTOBUF_PLUGIN_H
#define GRPC_INTERNAL_COMPILER_PROTOBUF_PLUGIN_H
#include "src/compiler/config.h"
#include "src/compiler/cpp_generator_helpers.h"
#include "src/compiler/python_generator_helpers.h"
#include "src/compiler/python_private_generator.h"
#include "src/compiler/schema_interface.h"
#include <vector>
// Get leading or trailing comments in a string.
template <typename DescriptorType>
inline grpc::string GetCommentsHelper(const DescriptorType *desc, bool leading,
const grpc::string &prefix) {
return grpc_generator::GetPrefixedComments(desc, leading, prefix);
}
class ProtoBufMethod : public grpc_generator::Method {
public:
ProtoBufMethod(const grpc::protobuf::MethodDescriptor *method)
: method_(method) {}
grpc::string name() const { return method_->name(); }
grpc::string input_type_name() const {
return grpc_cpp_generator::ClassName(method_->input_type(), true);
}
grpc::string output_type_name() const {
return grpc_cpp_generator::ClassName(method_->output_type(), true);
}
grpc::string get_input_type_name() const {
return method_->input_type()->file()->name();
}
grpc::string get_output_type_name() const {
return method_->output_type()->file()->name();
}
bool get_module_and_message_path_input(grpc::string *str,
grpc::string generator_file_name,
bool generate_in_pb2_grpc,
grpc::string import_prefix) const {
return grpc_python_generator::GetModuleAndMessagePath(
method_->input_type(), str, generator_file_name, generate_in_pb2_grpc,
import_prefix);
}
bool get_module_and_message_path_output(grpc::string *str,
grpc::string generator_file_name,
bool generate_in_pb2_grpc,
grpc::string import_prefix) const {
return grpc_python_generator::GetModuleAndMessagePath(
method_->output_type(), str, generator_file_name, generate_in_pb2_grpc,
import_prefix);
}
bool NoStreaming() const {
return !method_->client_streaming() && !method_->server_streaming();
}
bool ClientStreaming() const { return method_->client_streaming(); }
bool ServerStreaming() const { return method_->server_streaming(); }
bool BidiStreaming() const {
return method_->client_streaming() && method_->server_streaming();
}
grpc::string GetLeadingComments(const grpc::string prefix) const {
return GetCommentsHelper(method_, true, prefix);
}
grpc::string GetTrailingComments(const grpc::string prefix) const {
return GetCommentsHelper(method_, false, prefix);
}
vector<grpc::string> GetAllComments() const {
return grpc_python_generator::get_all_comments(method_);
}
private:
const grpc::protobuf::MethodDescriptor *method_;
};
class ProtoBufService : public grpc_generator::Service {
public:
ProtoBufService(const grpc::protobuf::ServiceDescriptor *service)
: service_(service) {}
grpc::string name() const { return service_->name(); }
int method_count() const { return service_->method_count(); };
std::unique_ptr<const grpc_generator::Method> method(int i) const {
return std::unique_ptr<const grpc_generator::Method>(
new ProtoBufMethod(service_->method(i)));
};
grpc::string GetLeadingComments(const grpc::string prefix) const {
return GetCommentsHelper(service_, true, prefix);
}
grpc::string GetTrailingComments(const grpc::string prefix) const {
return GetCommentsHelper(service_, false, prefix);
}
vector<grpc::string> GetAllComments() const {
return grpc_python_generator::get_all_comments(service_);
}
private:
const grpc::protobuf::ServiceDescriptor *service_;
};
class ProtoBufPrinter : public grpc_generator::Printer {
public:
ProtoBufPrinter(grpc::string *str)
: output_stream_(str), printer_(&output_stream_, '$') {}
void Print(const std::map<grpc::string, grpc::string> &vars,
const char *string_template) {
printer_.Print(vars, string_template);
}
void Print(const char *string) { printer_.Print(string); }
void Indent() { printer_.Indent(); }
void Outdent() { printer_.Outdent(); }
private:
grpc::protobuf::io::StringOutputStream output_stream_;
grpc::protobuf::io::Printer printer_;
};
class ProtoBufFile : public grpc_generator::File {
public:
ProtoBufFile(const grpc::protobuf::FileDescriptor *file) : file_(file) {}
grpc::string filename() const { return file_->name(); }
grpc::string filename_without_ext() const {
return grpc_generator::StripProto(filename());
}
grpc::string package() const { return file_->package(); }
std::vector<grpc::string> package_parts() const {
return grpc_generator::tokenize(package(), ".");
}
grpc::string additional_headers() const { return ""; }
int service_count() const { return file_->service_count(); };
std::unique_ptr<const grpc_generator::Service> service(int i) const {
return std::unique_ptr<const grpc_generator::Service>(
new ProtoBufService(file_->service(i)));
}
std::unique_ptr<grpc_generator::Printer> CreatePrinter(
grpc::string *str) const {
return std::unique_ptr<grpc_generator::Printer>(new ProtoBufPrinter(str));
}
grpc::string GetLeadingComments(const grpc::string prefix) const {
return GetCommentsHelper(file_, true, prefix);
}
grpc::string GetTrailingComments(const grpc::string prefix) const {
return GetCommentsHelper(file_, false, prefix);
}
vector<grpc::string> GetAllComments() const {
return grpc_python_generator::get_all_comments(file_);
}
private:
const grpc::protobuf::FileDescriptor *file_;
};
#endif // GRPC_INTERNAL_COMPILER_PROTOBUF_PLUGIN_H

@ -47,20 +47,15 @@
#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"
#include "src/compiler/protobuf_plugin.h"
#include "src/compiler/python_generator.h"
#include "src/compiler/python_generator_helpers.h"
#include "src/compiler/python_private_generator.h"
using grpc_generator::StringReplace;
using grpc_generator::StripProto;
using grpc::protobuf::Descriptor;
using grpc::protobuf::FileDescriptor;
using grpc::protobuf::MethodDescriptor;
using grpc::protobuf::ServiceDescriptor;
using grpc::protobuf::compiler::GeneratorContext;
using grpc::protobuf::io::CodedOutputStream;
using grpc::protobuf::io::Printer;
using grpc::protobuf::io::StringOutputStream;
using grpc::protobuf::io::ZeroCopyOutputStream;
using std::initializer_list;
using std::make_pair;
using std::map;
using std::pair;
@ -71,9 +66,10 @@ using std::set;
namespace grpc_python_generator {
grpc::string generator_file_name;
namespace {
typedef vector<const Descriptor*> DescriptorVector;
typedef map<grpc::string, grpc::string> StringMap;
typedef vector<grpc::string> StringVector;
typedef tuple<grpc::string, grpc::string> StringPair;
@ -88,133 +84,22 @@ typedef set<StringPair> StringPairSet;
// }
class IndentScope {
public:
explicit IndentScope(Printer* printer) : printer_(printer) {
explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
printer_->Indent();
}
~IndentScope() { printer_->Outdent(); }
private:
Printer* printer_;
};
// TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleName(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string basename = StripProto(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return import_prefix + basename + "_pb2";
}
// TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleAlias` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleAlias(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string module_name = ModuleName(filename, import_prefix);
// We can't have dots in the module name, so we replace each with _dot_.
// But that could lead to a collision between a.b and a_dot_b, so we also
// duplicate each underscore.
module_name = StringReplace(module_name, "_", "__");
module_name = StringReplace(module_name, ".", "_dot_");
return module_name;
}
// Tucks all generator state in an anonymous namespace away from
// PythonGrpcGenerator and the header file, mostly to encourage future changes
// to not require updates to the grpcio-tools C++ code part. Assumes that it is
// only ever used from a single thread.
struct PrivateGenerator {
const GeneratorConfiguration& config;
const FileDescriptor* file;
bool generate_in_pb2_grpc;
Printer* out;
PrivateGenerator(const GeneratorConfiguration& config,
const FileDescriptor* file);
std::pair<bool, grpc::string> GetGrpcServices();
private:
bool PrintPreamble();
bool PrintBetaPreamble();
bool PrintGAServices();
bool PrintBetaServices();
bool PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service);
bool PrintServicer(const ServiceDescriptor* service);
bool PrintStub(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service);
bool PrintBetaServicer(const ServiceDescriptor* service);
bool PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service);
bool PrintBetaStub(const ServiceDescriptor* service);
bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service);
// Get all comments (leading, leading_detached, trailing) and print them as a
// docstring. Any leading space of a line will be removed, but the line
// wrapping will not be changed.
template <typename DescriptorType>
void PrintAllComments(const DescriptorType* descriptor);
bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out);
grpc_generator::Printer* printer_;
};
PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config,
const FileDescriptor* file)
const grpc_generator::File* file)
: config(config), file(file) {}
bool PrivateGenerator::GetModuleAndMessagePath(const Descriptor* type,
grpc::string* out) {
const Descriptor* path_elem_type = type;
DescriptorVector message_path;
do {
message_path.push_back(path_elem_type);
path_elem_type = path_elem_type->containing_type();
} while (path_elem_type); // implicit nullptr comparison; don't be explicit
grpc::string file_name = type->file()->name();
static const int proto_suffix_length = strlen(".proto");
if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
file_name.find_last_of(".proto") == file_name.size() - 1)) {
return false;
}
grpc::string generator_file_name = file->name();
grpc::string module;
if (generator_file_name != file_name || generate_in_pb2_grpc) {
module = ModuleAlias(file_name, config.import_prefix) + ".";
} else {
module = "";
}
grpc::string message_type;
for (DescriptorVector::reverse_iterator path_iter = message_path.rbegin();
path_iter != message_path.rend(); ++path_iter) {
message_type += (*path_iter)->name() + ".";
}
// no pop_back prior to C++11
message_type.resize(message_type.size() - 1);
*out = module + message_type;
return true;
}
template <typename DescriptorType>
void PrivateGenerator::PrintAllComments(const DescriptorType* descriptor) {
StringVector comments;
grpc_generator::GetComment(
descriptor, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &comments);
grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_LEADING,
&comments);
grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_TRAILING,
&comments);
void PrivateGenerator::PrintAllComments(StringVector comments,
grpc_generator::Printer* out) {
if (comments.empty()) {
return;
}
@ -230,10 +115,12 @@ void PrivateGenerator::PrintAllComments(const DescriptorType* descriptor) {
out->Print("\"\"\"\n");
}
bool PrivateGenerator::PrintBetaServicer(const ServiceDescriptor* service) {
bool PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print("class Beta$Service$Servicer(object):\n", "Service",
service->name());
out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
@ -243,16 +130,20 @@ bool PrivateGenerator::PrintBetaServicer(const ServiceDescriptor* service) {
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
PrintAllComments(service);
StringVector service_comments = service->GetAllComments();
PrintAllComments(service_comments, out);
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
auto method = service->method(i);
grpc::string arg_name =
method->client_streaming() ? "request_iterator" : "request";
out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
method->name(), "ArgName", arg_name);
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
PrintAllComments(method);
StringVector method_comments = method->GetAllComments();
PrintAllComments(method_comments, out);
out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
}
}
@ -260,9 +151,12 @@ bool PrivateGenerator::PrintBetaServicer(const ServiceDescriptor* service) {
return true;
}
bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
bool PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print("class Beta$Service$Stub(object):\n", "Service", service->name());
out->Print(service_dict, "class Beta$Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
@ -272,11 +166,12 @@ bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
PrintAllComments(service);
StringVector service_comments = service->GetAllComments();
PrintAllComments(service_comments, out);
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
auto method = service->method(i);
grpc::string arg_name =
method->client_streaming() ? "request_iterator" : "request";
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
@ -285,10 +180,11 @@ bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
"with_call=False, protocol_options=None):\n");
{
IndentScope raii_method_indent(out);
PrintAllComments(method);
StringVector method_comments = method->GetAllComments();
PrintAllComments(method_comments, out);
out->Print("raise NotImplementedError()\n");
}
if (!method->server_streaming()) {
if (!method->ServerStreaming()) {
out->Print(method_dict, "$Method$.future = None\n");
}
}
@ -298,12 +194,13 @@ bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
bool PrivateGenerator::PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service) {
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(
"def beta_create_$Service$_server(servicer, pool=None, "
"pool_size=None, default_timeout=None, maximum_timeout=None):\n",
"Service", service->name());
out->Print(service_dict,
"def beta_create_$Service$_server(servicer, pool=None, "
"pool_size=None, default_timeout=None, maximum_timeout=None):\n");
{
IndentScope raii_create_server_indent(out);
out->Print(
@ -316,19 +213,21 @@ bool PrivateGenerator::PrintBetaServerFactory(
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
auto method = service->method(i);
const grpc::string method_implementation_constructor =
grpc::string(method->client_streaming() ? "stream_" : "unary_") +
grpc::string(method->server_streaming() ? "stream_" : "unary_") +
grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
"inline";
grpc::string input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
if (!method->get_module_and_message_path_input(
&input_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
grpc::string output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
if (!method->get_module_and_message_path_output(
&output_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
method_implementation_constructors.insert(
@ -338,19 +237,21 @@ bool PrivateGenerator::PrintBetaServerFactory(
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
out->Print("request_deserializers = {\n");
for (StringMap::iterator name_and_input_module_class_pair =
input_message_modules_and_classes.begin();
name_and_input_module_class_pair !=
input_message_modules_and_classes.end();
name_and_input_module_class_pair++) {
method_dict["MethodName"] = name_and_input_module_class_pair->first;
method_dict["InputTypeModuleAndClass"] =
name_and_input_module_class_pair->second;
IndentScope raii_indent(out);
out->Print(
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$InputTypeModuleAndClass$.FromString,\n",
"PackageQualifiedServiceName", package_qualified_service_name,
"MethodName", name_and_input_module_class_pair->first,
"InputTypeModuleAndClass", name_and_input_module_class_pair->second);
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$InputTypeModuleAndClass$.FromString,\n");
}
out->Print("}\n");
out->Print("response_serializers = {\n");
@ -359,14 +260,13 @@ bool PrivateGenerator::PrintBetaServerFactory(
name_and_output_module_class_pair !=
output_message_modules_and_classes.end();
name_and_output_module_class_pair++) {
method_dict["MethodName"] = name_and_output_module_class_pair->first;
method_dict["OutputTypeModuleAndClass"] =
name_and_output_module_class_pair->second;
IndentScope raii_indent(out);
out->Print(
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$OutputTypeModuleAndClass$.SerializeToString,\n",
"PackageQualifiedServiceName", package_qualified_service_name,
"MethodName", name_and_output_module_class_pair->first,
"OutputTypeModuleAndClass",
name_and_output_module_class_pair->second);
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$OutputTypeModuleAndClass$.SerializeToString,\n");
}
out->Print("}\n");
out->Print("method_implementations = {\n");
@ -375,15 +275,14 @@ bool PrivateGenerator::PrintBetaServerFactory(
name_and_implementation_constructor !=
method_implementation_constructors.end();
name_and_implementation_constructor++) {
method_dict["Method"] = name_and_implementation_constructor->first;
method_dict["Constructor"] = name_and_implementation_constructor->second;
IndentScope raii_descriptions_indent(out);
const grpc::string method_name =
name_and_implementation_constructor->first;
out->Print(
"(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
"face_utilities.$Constructor$(servicer.$Method$),\n",
"PackageQualifiedServiceName", package_qualified_service_name,
"Method", name_and_implementation_constructor->first, "Constructor",
name_and_implementation_constructor->second);
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
"face_utilities.$Constructor$(servicer.$Method$),\n");
}
out->Print("}\n");
out->Print(
@ -402,7 +301,7 @@ bool PrivateGenerator::PrintBetaServerFactory(
bool PrivateGenerator::PrintBetaStubFactory(
const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service) {
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
@ -421,18 +320,20 @@ bool PrivateGenerator::PrintBetaStubFactory(
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
auto method = service->method(i);
const grpc::string method_cardinality =
grpc::string(method->client_streaming() ? "STREAM" : "UNARY") + "_" +
grpc::string(method->server_streaming() ? "STREAM" : "UNARY");
grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") + "_" +
grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
grpc::string input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
if (!method->get_module_and_message_path_input(
&input_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
grpc::string output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
if (!method->get_module_and_message_path_output(
&output_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
method_cardinalities.insert(
@ -442,19 +343,21 @@ bool PrivateGenerator::PrintBetaStubFactory(
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
out->Print("request_serializers = {\n");
for (StringMap::iterator name_and_input_module_class_pair =
input_message_modules_and_classes.begin();
name_and_input_module_class_pair !=
input_message_modules_and_classes.end();
name_and_input_module_class_pair++) {
method_dict["MethodName"] = name_and_input_module_class_pair->first;
method_dict["InputTypeModuleAndClass"] =
name_and_input_module_class_pair->second;
IndentScope raii_indent(out);
out->Print(
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$InputTypeModuleAndClass$.SerializeToString,\n",
"PackageQualifiedServiceName", package_qualified_service_name,
"MethodName", name_and_input_module_class_pair->first,
"InputTypeModuleAndClass", name_and_input_module_class_pair->second);
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$InputTypeModuleAndClass$.SerializeToString,\n");
}
out->Print("}\n");
out->Print("response_deserializers = {\n");
@ -463,14 +366,13 @@ bool PrivateGenerator::PrintBetaStubFactory(
name_and_output_module_class_pair !=
output_message_modules_and_classes.end();
name_and_output_module_class_pair++) {
method_dict["MethodName"] = name_and_output_module_class_pair->first;
method_dict["OutputTypeModuleAndClass"] =
name_and_output_module_class_pair->second;
IndentScope raii_indent(out);
out->Print(
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$OutputTypeModuleAndClass$.FromString,\n",
"PackageQualifiedServiceName", package_qualified_service_name,
"MethodName", name_and_output_module_class_pair->first,
"OutputTypeModuleAndClass",
name_and_output_module_class_pair->second);
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
"$OutputTypeModuleAndClass$.FromString,\n");
}
out->Print("}\n");
out->Print("cardinalities = {\n");
@ -478,10 +380,11 @@ bool PrivateGenerator::PrintBetaStubFactory(
method_cardinalities.begin();
name_and_cardinality != method_cardinalities.end();
name_and_cardinality++) {
method_dict["Method"] = name_and_cardinality->first;
method_dict["Cardinality"] = name_and_cardinality->second;
IndentScope raii_descriptions_indent(out);
out->Print("\'$Method$\': cardinality.Cardinality.$Cardinality$,\n",
"Method", name_and_cardinality->first, "Cardinality",
name_and_cardinality->second);
out->Print(method_dict,
"\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
}
out->Print("}\n");
out->Print(
@ -490,23 +393,25 @@ bool PrivateGenerator::PrintBetaStubFactory(
"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",
"PackageQualifiedServiceName", package_qualified_service_name);
out->Print(method_dict,
"return beta_implementations.dynamic_stub(channel, "
"\'$PackageQualifiedServiceName$\', "
"cardinalities, options=stub_options)\n");
}
return true;
}
bool PrivateGenerator::PrintStub(
const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service) {
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
out->Print("class $Service$Stub(object):\n", "Service", service->name());
out->Print(dict, "class $Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
PrintAllComments(service);
StringVector service_comments = service->GetAllComments();
PrintAllComments(service_comments, out);
out->Print("\n");
out->Print("def __init__(self, channel):\n");
{
@ -520,35 +425,41 @@ bool PrivateGenerator::PrintStub(
}
out->Print("\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
auto method = service->method(i);
grpc::string multi_callable_constructor =
grpc::string(method->client_streaming() ? "stream" : "unary") +
"_" + grpc::string(method->server_streaming() ? "stream" : "unary");
grpc::string(method->ClientStreaming() ? "stream" : "unary") + "_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary");
grpc::string request_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&request_module_and_class)) {
if (!method->get_module_and_message_path_input(
&request_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
grpc::string response_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&response_module_and_class)) {
if (!method->get_module_and_message_path_output(
&response_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
out->Print("self.$Method$ = channel.$MultiCallableConstructor$(\n",
"Method", method->name(), "MultiCallableConstructor",
multi_callable_constructor);
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MultiCallableConstructor"] = multi_callable_constructor;
out->Print(method_dict,
"self.$Method$ = channel.$MultiCallableConstructor$(\n");
{
method_dict["PackageQualifiedService"] =
package_qualified_service_name;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
IndentScope raii_first_attribute_indent(out);
IndentScope raii_second_attribute_indent(out);
out->Print("'/$PackageQualifiedService$/$Method$',\n",
"PackageQualifiedService", package_qualified_service_name,
"Method", method->name());
out->Print(
"request_serializer=$RequestModuleAndClass$.SerializeToString,\n",
"RequestModuleAndClass", request_module_and_class);
out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
out->Print(method_dict,
"request_serializer=$RequestModuleAndClass$."
"SerializeToString,\n");
out->Print(
"response_deserializer=$ResponseModuleAndClass$.FromString,\n",
"ResponseModuleAndClass", response_module_and_class);
method_dict,
"response_deserializer=$ResponseModuleAndClass$.FromString,\n");
out->Print(")\n");
}
}
@ -557,22 +468,29 @@ bool PrivateGenerator::PrintStub(
return true;
}
bool PrivateGenerator::PrintServicer(const ServiceDescriptor* service) {
bool PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print("class $Service$Servicer(object):\n", "Service", service->name());
out->Print(service_dict, "class $Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
PrintAllComments(service);
StringVector service_comments = service->GetAllComments();
PrintAllComments(service_comments, out);
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
auto method = service->method(i);
grpc::string arg_name =
method->client_streaming() ? "request_iterator" : "request";
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print("\n");
out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
method->name(), "ArgName", arg_name);
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
PrintAllComments(method);
StringVector method_comments = method->GetAllComments();
PrintAllComments(method_comments, out);
out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
out->Print("context.set_details('Method not implemented!')\n");
out->Print("raise NotImplementedError('Method not implemented!')\n");
@ -584,10 +502,12 @@ bool PrivateGenerator::PrintServicer(const ServiceDescriptor* service) {
bool PrivateGenerator::PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service) {
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print("def add_$Service$Servicer_to_server(servicer, server):\n",
"Service", service->name());
out->Print(service_dict,
"def add_$Service$Servicer_to_server(servicer, server):\n");
{
IndentScope raii_class_indent(out);
out->Print("rpc_method_handlers = {\n");
@ -595,58 +515,66 @@ bool PrivateGenerator::PrintAddServicerToServer(
IndentScope raii_dict_first_indent(out);
IndentScope raii_dict_second_indent(out);
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
auto method = service->method(i);
grpc::string method_handler_constructor =
grpc::string(method->client_streaming() ? "stream" : "unary") +
"_" +
grpc::string(method->server_streaming() ? "stream" : "unary") +
grpc::string(method->ClientStreaming() ? "stream" : "unary") + "_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary") +
"_rpc_method_handler";
grpc::string request_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&request_module_and_class)) {
if (!method->get_module_and_message_path_input(
&request_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
grpc::string response_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&response_module_and_class)) {
if (!method->get_module_and_message_path_output(
&response_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
return false;
}
out->Print("'$Method$': grpc.$MethodHandlerConstructor$(\n", "Method",
method->name(), "MethodHandlerConstructor",
method_handler_constructor);
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MethodHandlerConstructor"] = method_handler_constructor;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
out->Print(method_dict,
"'$Method$': grpc.$MethodHandlerConstructor$(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print("servicer.$Method$,\n", "Method", method->name());
out->Print(method_dict, "servicer.$Method$,\n");
out->Print(
"request_deserializer=$RequestModuleAndClass$.FromString,\n",
"RequestModuleAndClass", request_module_and_class);
method_dict,
"request_deserializer=$RequestModuleAndClass$.FromString,\n");
out->Print(
method_dict,
"response_serializer=$ResponseModuleAndClass$.SerializeToString,"
"\n",
"ResponseModuleAndClass", response_module_and_class);
"\n");
}
out->Print("),\n");
}
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
out->Print("}\n");
out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print("'$PackageQualifiedServiceName$', rpc_method_handlers)\n",
"PackageQualifiedServiceName", package_qualified_service_name);
out->Print(method_dict,
"'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
}
out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
}
return true;
}
bool PrivateGenerator::PrintBetaPreamble() {
out->Print("from $Package$ import implementations as beta_implementations\n",
"Package", config.beta_package_root);
out->Print("from $Package$ import interfaces as beta_interfaces\n", "Package",
config.beta_package_root);
bool PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.beta_package_root;
out->Print(var,
"from $Package$ import implementations as beta_implementations\n");
out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
out->Print("from grpc.framework.common import cardinality\n");
out->Print(
"from grpc.framework.interfaces.face import utilities as "
@ -654,65 +582,78 @@ bool PrivateGenerator::PrintBetaPreamble() {
return true;
}
bool PrivateGenerator::PrintPreamble() {
out->Print("import $Package$\n", "Package", config.grpc_package_root);
bool PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.grpc_package_root;
out->Print(var, "import $Package$\n");
if (generate_in_pb2_grpc) {
out->Print("\n");
StringPairSet imports_set;
for (int i = 0; i < file->service_count(); ++i) {
const ServiceDescriptor* service = file->service(i);
auto service = file->service(i);
for (int j = 0; j < service->method_count(); ++j) {
const MethodDescriptor* method = service->method(j);
const Descriptor* types[2] = {method->input_type(),
method->output_type()};
for (int k = 0; k < 2; ++k) {
const Descriptor* type = types[k];
grpc::string type_file_name = type->file()->name();
grpc::string module_name =
ModuleName(type_file_name, config.import_prefix);
grpc::string module_alias =
ModuleAlias(type_file_name, config.import_prefix);
imports_set.insert(std::make_tuple(module_name, module_alias));
}
auto method = service.get()->method(j);
grpc::string input_type_file_name = method->get_input_type_name();
grpc::string input_module_name =
ModuleName(input_type_file_name, config.import_prefix);
grpc::string input_module_alias =
ModuleAlias(input_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(input_module_name, input_module_alias));
grpc::string output_type_file_name = method->get_output_type_name();
grpc::string output_module_name =
ModuleName(output_type_file_name, config.import_prefix);
grpc::string output_module_alias =
ModuleAlias(output_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(output_module_name, output_module_alias));
}
}
for (StringPairSet::iterator it = imports_set.begin();
it != imports_set.end(); ++it) {
out->Print("import $ModuleName$ as $ModuleAlias$\n", "ModuleName",
std::get<0>(*it), "ModuleAlias", std::get<1>(*it));
var["ModuleName"] = std::get<0>(*it);
var["ModuleAlias"] = std::get<1>(*it);
out->Print(var, "import $ModuleName$ as $ModuleAlias$\n");
}
}
return true;
}
bool PrivateGenerator::PrintGAServices() {
bool PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
for (int i = 0; i < file->service_count(); ++i) {
const ServiceDescriptor* service = file->service(i);
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
if (!(PrintStub(package_qualified_service_name, service) &&
PrintServicer(service) &&
PrintAddServicerToServer(package_qualified_service_name, service))) {
if (!(PrintStub(package_qualified_service_name, service.get(), out) &&
PrintServicer(service.get(), out) &&
PrintAddServicerToServer(package_qualified_service_name,
service.get(), out))) {
return false;
}
}
return true;
}
bool PrivateGenerator::PrintBetaServices() {
bool PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
for (int i = 0; i < file->service_count(); ++i) {
const ServiceDescriptor* service = file->service(i);
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
if (!(PrintBetaServicer(service) && PrintBetaStub(service) &&
PrintBetaServerFactory(package_qualified_service_name, service) &&
PrintBetaStubFactory(package_qualified_service_name, service))) {
if (!(PrintBetaServicer(service.get(), out) &&
PrintBetaStub(service.get(), out) &&
PrintBetaServerFactory(package_qualified_service_name, service.get(),
out) &&
PrintBetaStubFactory(package_qualified_service_name, service.get(),
out))) {
return false;
}
}
@ -723,43 +664,40 @@ pair<bool, grpc::string> PrivateGenerator::GetGrpcServices() {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
StringOutputStream output_stream(&output);
Printer out_printer(&output_stream, '$');
out = &out_printer;
auto out = file->CreatePrinter(&output);
if (generate_in_pb2_grpc) {
out->Print(
"# Generated by the gRPC Python protocol compiler plugin. "
"DO NOT EDIT!\n");
if (!PrintPreamble()) {
if (!PrintPreamble(out.get())) {
return make_pair(false, "");
}
if (!PrintGAServices()) {
if (!PrintGAServices(out.get())) {
return make_pair(false, "");
}
} else {
out->Print("try:\n");
{
IndentScope raii_dict_try_indent(out);
IndentScope raii_dict_try_indent(out.get());
out->Print(
"# THESE ELEMENTS WILL BE DEPRECATED.\n"
"# Please use the generated *_pb2_grpc.py files instead.\n");
if (!PrintPreamble()) {
if (!PrintPreamble(out.get())) {
return make_pair(false, "");
}
if (!PrintBetaPreamble()) {
if (!PrintBetaPreamble(out.get())) {
return make_pair(false, "");
}
if (!PrintGAServices()) {
if (!PrintGAServices(out.get())) {
return make_pair(false, "");
}
if (!PrintBetaServices()) {
if (!PrintBetaServices(out.get())) {
return make_pair(false, "");
}
}
out->Print("except ImportError:\n");
{
IndentScope raii_dict_except_indent(out);
IndentScope raii_dict_except_indent(out.get());
out->Print("pass");
}
}
@ -823,8 +761,10 @@ bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
*error = "Invalid proto file name. Proto file must end with .proto";
return false;
}
generator_file_name = file->name();
PrivateGenerator generator(config_, file);
ProtoBufFile pbfile(file);
PrivateGenerator generator(config_, &pbfile);
if (parameter == "grpc_2_0") {
return GenerateGrpc(context, generator, pb2_grpc_file_name, true);
} else if (parameter == "") {

@ -37,6 +37,7 @@
#include <utility>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {

@ -0,0 +1,142 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H
#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H
#include <cstring>
#include <fstream>
#include <iostream>
#include <vector>
#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"
#include "src/compiler/python_generator.h"
#include "src/compiler/python_private_generator.h"
using std::vector;
using grpc_generator::StringReplace;
using grpc_generator::StripProto;
using grpc::protobuf::Descriptor;
using grpc::protobuf::FileDescriptor;
using grpc::protobuf::MethodDescriptor;
using grpc::protobuf::ServiceDescriptor;
using grpc::protobuf::compiler::GeneratorContext;
using grpc::protobuf::io::CodedOutputStream;
using grpc::protobuf::io::Printer;
using grpc::protobuf::io::StringOutputStream;
using grpc::protobuf::io::ZeroCopyOutputStream;
namespace grpc_python_generator {
namespace {
typedef vector<const Descriptor*> DescriptorVector;
typedef vector<grpc::string> StringVector;
// TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleName(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string basename = StripProto(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return import_prefix + basename + "_pb2";
}
// TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleAlias` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleAlias(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string module_name = ModuleName(filename, import_prefix);
// We can't have dots in the module name, so we replace each with _dot_.
// But that could lead to a collision between a.b and a_dot_b, so we also
// duplicate each underscore.
module_name = StringReplace(module_name, "_", "__");
module_name = StringReplace(module_name, ".", "_dot_");
return module_name;
}
bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out,
grpc::string generator_file_name,
bool generate_in_pb2_grpc,
grpc::string& import_prefix) {
const Descriptor* path_elem_type = type;
DescriptorVector message_path;
do {
message_path.push_back(path_elem_type);
path_elem_type = path_elem_type->containing_type();
} while (path_elem_type); // implicit nullptr comparison; don't be explicit
grpc::string file_name = type->file()->name();
static const int proto_suffix_length = strlen(".proto");
if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
file_name.find_last_of(".proto") == file_name.size() - 1)) {
return false;
}
grpc::string module;
if (generator_file_name != file_name || generate_in_pb2_grpc) {
module = ModuleAlias(file_name, import_prefix) + ".";
} else {
module = "";
}
grpc::string message_type;
for (DescriptorVector::reverse_iterator path_iter = message_path.rbegin();
path_iter != message_path.rend(); ++path_iter) {
message_type += (*path_iter)->name() + ".";
}
// no pop_back prior to C++11
message_type.resize(message_type.size() - 1);
*out = module + message_type;
return true;
}
template <typename DescriptorType>
StringVector get_all_comments(const DescriptorType* descriptor) {
StringVector comments;
grpc_generator::GetComment(
descriptor, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &comments);
grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_LEADING,
&comments);
grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_TRAILING,
&comments);
return comments;
}
} // namespace
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H

@ -34,6 +34,7 @@
// Generates a Python gRPC service interface out of Protobuf IDL.
#include "src/compiler/config.h"
#include "src/compiler/protobuf_plugin.h"
#include "src/compiler/python_generator.h"
int main(int argc, char* argv[]) {

@ -0,0 +1,99 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#include <iostream>
#include <vector>
#include "src/compiler/python_generator.h"
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {
namespace {
// Tucks all generator state in an anonymous namespace away from
// PythonGrpcGenerator and the header file, mostly to encourage future changes
// to not require updates to the grpcio-tools C++ code part. Assumes that it is
// only ever used from a single thread.
struct PrivateGenerator {
const GeneratorConfiguration& config;
const grpc_generator::File* file;
bool generate_in_pb2_grpc;
PrivateGenerator(const GeneratorConfiguration& config,
const grpc_generator::File* file);
std::pair<bool, grpc::string> GetGrpcServices();
private:
bool PrintPreamble(grpc_generator::Printer* out);
bool PrintBetaPreamble(grpc_generator::Printer* out);
bool PrintGAServices(grpc_generator::Printer* out);
bool PrintBetaServices(grpc_generator::Printer* out);
bool PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
bool PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
bool PrintStub(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
bool PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
bool PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
bool PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out);
bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
// Get all comments (leading, leading_detached, trailing) and print them as a
// docstring. Any leading space of a line will be removed, but the line
// wrapping will not be changed.
void PrintAllComments(std::vector<grpc::string> comments,
grpc_generator::Printer* out);
};
} // namespace
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H

@ -0,0 +1,126 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#include "src/compiler/config.h"
#include <memory>
#include <vector>
#ifndef GRPC_CUSTOM_STRING
#include <string>
#define GRPC_CUSTOM_STRING std::string
#endif
namespace grpc {
typedef GRPC_CUSTOM_STRING string;
} // namespace grpc
namespace grpc_generator {
// A common interface for objects having comments in the source.
// Return formatted comments to be inserted in generated code.
struct CommentHolder {
virtual ~CommentHolder() {}
virtual grpc::string GetLeadingComments(const grpc::string prefix) const = 0;
virtual grpc::string GetTrailingComments(const grpc::string prefix) const = 0;
virtual std::vector<grpc::string> GetAllComments() const = 0;
};
// An abstract interface representing a method.
struct Method : public CommentHolder {
virtual ~Method() {}
virtual grpc::string name() const = 0;
virtual grpc::string input_type_name() const = 0;
virtual grpc::string output_type_name() const = 0;
virtual bool get_module_and_message_path_input(
grpc::string *str, grpc::string generator_file_name,
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
virtual bool get_module_and_message_path_output(
grpc::string *str, grpc::string generator_file_name,
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
virtual grpc::string get_input_type_name() const = 0;
virtual grpc::string get_output_type_name() const = 0;
virtual bool NoStreaming() const = 0;
virtual bool ClientStreaming() const = 0;
virtual bool ServerStreaming() const = 0;
virtual bool BidiStreaming() const = 0;
};
// An abstract interface representing a service.
struct Service : public CommentHolder {
virtual ~Service() {}
virtual grpc::string name() const = 0;
virtual int method_count() const = 0;
virtual std::unique_ptr<const Method> method(int i) const = 0;
};
struct Printer {
virtual ~Printer() {}
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
const char *template_string) = 0;
virtual void Print(const char *string) = 0;
virtual void Indent() = 0;
virtual void Outdent() = 0;
};
// An interface that allows the source generated to be output using various
// libraries/idls/serializers.
struct File : public CommentHolder {
virtual ~File() {}
virtual grpc::string filename() const = 0;
virtual grpc::string filename_without_ext() const = 0;
virtual grpc::string package() const = 0;
virtual std::vector<grpc::string> package_parts() const = 0;
virtual grpc::string additional_headers() const = 0;
virtual int service_count() const = 0;
virtual std::unique_ptr<const Service> service(int i) const = 0;
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
};
} // namespace grpc_generator
#endif // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H

@ -6014,11 +6014,15 @@
"src/compiler/objective_c_generator_helpers.h",
"src/compiler/php_generator.h",
"src/compiler/php_generator_helpers.h",
"src/compiler/protobuf_plugin.h",
"src/compiler/python_generator.h",
"src/compiler/python_generator_helpers.h",
"src/compiler/python_private_generator.h",
"src/compiler/ruby_generator.h",
"src/compiler/ruby_generator_helpers-inl.h",
"src/compiler/ruby_generator_map-inl.h",
"src/compiler/ruby_generator_string-inl.h"
"src/compiler/ruby_generator_string-inl.h",
"src/compiler/schema_interface.h"
],
"is_filegroup": false,
"language": "c++",
@ -6041,13 +6045,17 @@
"src/compiler/php_generator.cc",
"src/compiler/php_generator.h",
"src/compiler/php_generator_helpers.h",
"src/compiler/protobuf_plugin.h",
"src/compiler/python_generator.cc",
"src/compiler/python_generator.h",
"src/compiler/python_generator_helpers.h",
"src/compiler/python_private_generator.h",
"src/compiler/ruby_generator.cc",
"src/compiler/ruby_generator.h",
"src/compiler/ruby_generator_helpers-inl.h",
"src/compiler/ruby_generator_map-inl.h",
"src/compiler/ruby_generator_string-inl.h"
"src/compiler/ruby_generator_string-inl.h",
"src/compiler/schema_interface.h"
],
"third_party": false,
"type": "lib"

@ -163,11 +163,15 @@
<ClInclude Include="$(SolutionDir)\..\src\compiler\objective_c_generator_helpers.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\php_generator.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\php_generator_helpers.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\protobuf_plugin.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator_helpers.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\python_private_generator.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_helpers-inl.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_map-inl.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_string-inl.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\schema_interface.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\src\compiler\cpp_generator.cc">

@ -65,9 +65,18 @@
<ClInclude Include="$(SolutionDir)\..\src\compiler\php_generator_helpers.h">
<Filter>src\compiler</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\compiler\protobuf_plugin.h">
<Filter>src\compiler</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator.h">
<Filter>src\compiler</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator_helpers.h">
<Filter>src\compiler</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\compiler\python_private_generator.h">
<Filter>src\compiler</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator.h">
<Filter>src\compiler</Filter>
</ClInclude>
@ -80,6 +89,9 @@
<ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_string-inl.h">
<Filter>src\compiler</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\compiler\schema_interface.h">
<Filter>src\compiler</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

Loading…
Cancel
Save