@ -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_s treaming( ) ? " request_iterator " : " request " ;
method - > ClientS treaming( ) ? " 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_s treaming( ) ) {
if ( ! method - > ServerS treaming( ) ) {
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_s treaming( ) ? " stream_ " : " unary_ " ) +
grpc : : string ( method - > server_s treaming( ) ? " stream_ " : " unary_ " ) +
grpc : : string ( method - > ClientS treaming( ) ? " stream_ " : " unary_ " ) +
grpc : : string ( method - > ServerS treaming( ) ? " 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_s treaming( ) ? " STREAM " : " UNARY " ) + " _ " +
grpc : : string ( method - > server_s treaming( ) ? " STREAM " : " UNARY " ) ;
grpc : : string ( method - > ClientS treaming( ) ? " STREAM " : " UNARY " ) + " _ " +
grpc : : string ( method - > ServerS treaming( ) ? " 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_s treaming( ) ? " stream " : " unary " ) +
" _ " + grpc : : string ( method - > server_s treaming( ) ? " stream " : " unary " ) ;
grpc : : string ( method - > ClientS treaming( ) ? " stream " : " unary " ) + " _ " +
grpc : : string ( method - > ServerS treaming( ) ? " 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 = = " " ) {