@ -35,6 +35,8 @@
# include <cassert>
# include <cctype>
# include <cstring>
# include <fstream>
# include <iostream>
# include <map>
# include <memory>
# include <ostream>
@ -66,66 +68,7 @@ using std::vector;
namespace grpc_python_generator {
GeneratorConfiguration : : GeneratorConfiguration ( )
: grpc_package_root ( " grpc " ) , beta_package_root ( " grpc.beta " ) { }
PythonGrpcGenerator : : PythonGrpcGenerator ( const GeneratorConfiguration & config )
: config_ ( config ) { }
PythonGrpcGenerator : : ~ PythonGrpcGenerator ( ) { }
bool PythonGrpcGenerator : : Generate ( const FileDescriptor * file ,
const grpc : : string & parameter ,
GeneratorContext * context ,
grpc : : string * error ) const {
// Get output file name.
grpc : : string 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 ) {
file_name =
file - > name ( ) . substr ( 0 , file - > name ( ) . size ( ) - proto_suffix_length ) +
" _pb2.py " ;
} else {
* error = " Invalid proto file name. Proto file must end with .proto " ;
return false ;
}
std : : unique_ptr < ZeroCopyOutputStream > output (
context - > OpenForInsert ( file_name , " module_scope " ) ) ;
CodedOutputStream coded_out ( output . get ( ) ) ;
bool success = false ;
grpc : : string code = " " ;
tie ( success , code ) = grpc_python_generator : : GetServices ( file , config_ ) ;
if ( success ) {
coded_out . WriteRaw ( code . data ( ) , code . size ( ) ) ;
return true ;
} else {
return false ;
}
}
namespace {
//////////////////////////////////
// BEGIN FORMATTING BOILERPLATE //
//////////////////////////////////
// Converts an initializer list of the form { key0, value0, key1, value1, ... }
// into a map of key* to value*. Is merely a readability helper for later code.
map < grpc : : string , grpc : : string > ListToDict (
const initializer_list < grpc : : string > & values ) {
assert ( values . size ( ) % 2 = = 0 ) ;
map < grpc : : string , grpc : : string > value_map ;
auto value_iter = values . begin ( ) ;
for ( unsigned i = 0 ; i < values . size ( ) / 2 ; + + i ) {
grpc : : string key = * value_iter ;
+ + value_iter ;
grpc : : string value = * value_iter ;
value_map [ key ] = value ;
+ + value_iter ;
}
return value_map ;
}
// Provides RAII indentation handling. Use as:
// {
@ -146,10 +89,6 @@ class IndentScope {
Printer * printer_ ;
} ;
////////////////////////////////
// END FORMATTING BOILERPLATE //
////////////////////////////////
// TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
@ -173,8 +112,60 @@ grpc::string ModuleAlias(const grpc::string& filename) {
return module_name ;
}
bool GetModuleAndMessagePath ( const Descriptor * type ,
const ServiceDescriptor * service ,
// 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 ) ;
} ;
PrivateGenerator : : PrivateGenerator ( const GeneratorConfiguration & config ,
const FileDescriptor * file )
: config ( config ) , file ( file ) { }
bool PrivateGenerator : : GetModuleAndMessagePath ( const Descriptor * type ,
grpc : : string * out ) {
const Descriptor * path_elem_type = type ;
vector < const Descriptor * > message_path ;
@ -188,9 +179,13 @@ bool GetModuleAndMessagePath(const Descriptor* type,
file_name . find_last_of ( " .proto " ) = = file_name . size ( ) - 1 ) ) {
return false ;
}
grpc : : string service_file_name = service - > file ( ) - > name ( ) ;
grpc : : string module =
service_file_name = = file_name ? " " : ModuleAlias ( file_name ) + " . " ;
grpc : : string generator_file_name = file - > name ( ) ;
grpc : : string module ;
if ( generator_file_name ! = file_name | | generate_in_pb2_grpc ) {
module = ModuleAlias ( file_name ) + " . " ;
} else {
module = " " ;
}
grpc : : string message_type ;
for ( auto path_iter = message_path . rbegin ( ) ; path_iter ! = message_path . rend ( ) ;
+ + path_iter ) {
@ -202,33 +197,30 @@ bool GetModuleAndMessagePath(const Descriptor* type,
return true ;
}
// 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 >
static void PrintAllComments ( const DescriptorType * desc , Printer * printe r) {
std : : vector < grpc : : string > comments ;
grpc_generator : : GetComment ( desc , grpc_generator : : COMMENTTYPE_LEADING_DETACHED ,
void PrivateGenerator : : PrintAllComments ( const DescriptorType * descriptor ) {
vector < grpc : : string > comments ;
grpc_generator : : GetComment ( descriptor , grpc_generator : : COMMENTTYPE_LEADING_DETACHED ,
& comments ) ;
grpc_generator : : GetComment ( desc , grpc_generator : : COMMENTTYPE_LEADING ,
grpc_generator : : GetComment ( descriptor , grpc_generator : : COMMENTTYPE_LEADING ,
& comments ) ;
grpc_generator : : GetComment ( desc , grpc_generator : : COMMENTTYPE_TRAILING ,
grpc_generator : : GetComment ( descriptor , grpc_generator : : COMMENTTYPE_TRAILING ,
& comments ) ;
if ( comments . empty ( ) ) {
return ;
}
printer - > Print ( " \" \" \" " ) ;
out - > Print ( " \" \" \" " ) ;
for ( auto it = comments . begin ( ) ; it ! = comments . end ( ) ; + + it ) {
size_t start_pos = it - > find_first_not_of ( ' ' ) ;
if ( start_pos ! = grpc : : string : : npos ) {
printer - > Print ( it - > c_str ( ) + start_pos ) ;
out - > Print ( it - > c_str ( ) + start_pos ) ;
}
printer - > Print ( " \n " ) ;
out - > Print ( " \n " ) ;
}
printer - > Print ( " \" \" \" \n " ) ;
out - > Print ( " \" \" \" \n " ) ;
}
bool PrintBetaServicer ( const ServiceDescriptor * service , Printer * out ) {
bool PrivateGenerator : : PrintBetaServicer ( const ServiceDescriptor * service ) {
out - > Print ( " \n \n " ) ;
out - > Print ( " class Beta$Service$Servicer(object): \n " , " Service " ,
service - > name ( ) ) ;
@ -241,7 +233,7 @@ bool PrintBetaServicer(const ServiceDescriptor* service, Printer* out) {
" generated \n "
" only to ease transition from grpcio<0.15.0 to "
" grpcio>=0.15.0. \" \" \" \n " ) ;
PrintAllComments ( service , out ) ;
PrintAllComments ( service ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; + + i ) {
auto meth = service - > method ( i ) ;
grpc : : string arg_name =
@ -250,7 +242,7 @@ bool PrintBetaServicer(const ServiceDescriptor* service, Printer* out) {
meth - > name ( ) , " ArgName " , arg_name ) ;
{
IndentScope raii_method_indent ( out ) ;
PrintAllComments ( meth , out ) ;
PrintAllComments ( meth ) ;
out - > Print ( " context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) \n " ) ;
}
}
@ -258,7 +250,7 @@ bool PrintBetaServicer(const ServiceDescriptor* service, Printer* out) {
return true ;
}
bool PrintBetaStub ( const ServiceDescriptor * service , Printer * out ) {
bool PrivateGenerator : : PrintBetaStub ( const ServiceDescriptor * service ) {
out - > Print ( " \n \n " ) ;
out - > Print ( " class Beta$Service$Stub(object): \n " , " Service " , service - > name ( ) ) ;
{
@ -270,18 +262,20 @@ bool PrintBetaStub(const ServiceDescriptor* service, Printer* out) {
" generated \n "
" only to ease transition from grpcio<0.15.0 to "
" grpcio>=0.15.0. \" \" \" \n " ) ;
PrintAllComments ( service , out ) ;
PrintAllComments ( service ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; + + i ) {
const MethodDescriptor * meth = service - > method ( i ) ;
grpc : : string arg_name =
meth - > client_streaming ( ) ? " request_iterator " : " request " ;
auto methdict = ListToDict ( { " Method " , meth - > name ( ) , " ArgName " , arg_name } ) ;
auto methdict ;
methdict [ " Method " ] = meth - > name ( ) ;
methdict [ " ArgName " ] = arg_name ;
out - > Print ( methdict ,
" def $Method$(self, $ArgName$, timeout, metadata=None, "
" with_call=False, protocol_options=None): \n " ) ;
{
IndentScope raii_method_indent ( out ) ;
PrintAllComments ( meth , out ) ;
PrintAllComments ( meth ) ;
out - > Print ( " raise NotImplementedError() \n " ) ;
}
if ( ! meth - > server_streaming ( ) ) {
@ -292,8 +286,9 @@ bool PrintBetaStub(const ServiceDescriptor* service, Printer* out) {
return true ;
}
bool PrintBetaServerFactory ( const grpc : : string & package_qualified_service_name ,
const ServiceDescriptor * service , Printer * out ) {
bool PrivateGenerator : : PrintBetaServerFactory (
const grpc : : string & package_qualified_service_name ,
const ServiceDescriptor * service ) {
out - > Print ( " \n \n " ) ;
out - > Print (
" def beta_create_$Service$_server(servicer, pool=None, "
@ -317,12 +312,12 @@ bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
grpc : : string ( method - > server_streaming ( ) ? " stream_ " : " unary_ " ) +
" inline " ;
grpc : : string input_message_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) ,
& input_message_module_and_class ) ) {
return false ;
}
grpc : : string output_message_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) ,
& output_message_module_and_class ) ) {
return false ;
}
@ -395,11 +390,11 @@ bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
return true ;
}
bool PrintBetaStubFactory ( const grpc : : string & package_qualified_service_name ,
const ServiceDescriptor * service , Printer * out ) {
map < grpc : : string , grpc : : string > dict = ListToDict ( {
" Service " , service - > name ( ) ,
} ) ;
bool PrivateGenerator : : PrintBetaStubFactory (
const grpc : : string & package_qualified_service_name ,
const ServiceDescriptor * service ) {
map < grpc : : string , grpc : : string > dict ;
dict [ " Service " ] = service - > name ( ) ;
out - > Print ( " \n \n " ) ;
out - > Print ( dict ,
" def beta_create_$Service$_stub(channel, host=None, "
@ -421,12 +416,12 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
grpc : : string ( method - > client_streaming ( ) ? " STREAM " : " UNARY " ) + " _ " +
grpc : : string ( method - > server_streaming ( ) ? " STREAM " : " UNARY " ) ;
grpc : : string input_message_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) ,
& input_message_module_and_class ) ) {
return false ;
}
grpc : : string output_message_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) ,
& output_message_module_and_class ) ) {
return false ;
}
@ -493,13 +488,13 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
return true ;
}
bool PrintStub ( const grpc : : string & package_qualified_service_name ,
const ServiceDescriptor * service , Printer * out ) {
bool PrivateGenerator : : Pri ntStub ( const grpc : : string & package_qualified_service_name ,
const ServiceDescriptor * service ) {
out - > Print ( " \n \n " ) ;
out - > Print ( " class $Service$Stub(object): \n " , " Service " , service - > name ( ) ) ;
{
IndentScope raii_class_indent ( out ) ;
PrintAllComments ( service , out ) ;
PrintAllComments ( service ) ;
out - > Print ( " \n " ) ;
out - > Print ( " def __init__(self, channel): \n " ) ;
{
@ -518,12 +513,12 @@ bool PrintStub(const grpc::string& package_qualified_service_name,
grpc : : string ( method - > client_streaming ( ) ? " stream " : " unary " ) +
" _ " + grpc : : string ( method - > server_streaming ( ) ? " stream " : " unary " ) ;
grpc : : string request_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) ,
& request_module_and_class ) ) {
return false ;
}
grpc : : string response_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) ,
& response_module_and_class ) ) {
return false ;
}
@ -550,12 +545,12 @@ bool PrintStub(const grpc::string& package_qualified_service_name,
return true ;
}
bool PrintServicer ( const ServiceDescriptor * service , Printer * out ) {
bool PrivateGenerator : : PrintServicer ( const ServiceDescriptor * service ) {
out - > Print ( " \n \n " ) ;
out - > Print ( " class $Service$Servicer(object): \n " , " Service " , service - > name ( ) ) ;
{
IndentScope raii_class_indent ( out ) ;
PrintAllComments ( service , out ) ;
PrintAllComments ( service ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; + + i ) {
auto method = service - > method ( i ) ;
grpc : : string arg_name =
@ -565,7 +560,7 @@ bool PrintServicer(const ServiceDescriptor* service, Printer* out) {
method - > name ( ) , " ArgName " , arg_name ) ;
{
IndentScope raii_method_indent ( out ) ;
PrintAllComments ( method , out ) ;
PrintAllComments ( method ) ;
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 " ) ;
@ -575,9 +570,9 @@ bool PrintServicer(const ServiceDescriptor* service, Printer* out) {
return true ;
}
bool PrintAddServicerToServer (
bool PrivateGenerator : : Pri ntAddServicerToServer (
const grpc : : string & package_qualified_service_name ,
const ServiceDescriptor * service , Printer * out ) {
const ServiceDescriptor * service ) {
out - > Print ( " \n \n " ) ;
out - > Print ( " def add_$Service$Servicer_to_server(servicer, server): \n " ,
" Service " , service - > name ( ) ) ;
@ -595,12 +590,12 @@ bool PrintAddServicerToServer(
grpc : : string ( method - > server_streaming ( ) ? " stream " : " unary " ) +
" _rpc_method_handler " ;
grpc : : string request_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > input_type ( ) ,
& request_module_and_class ) ) {
return false ;
}
grpc : : string response_module_and_class ;
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) , service ,
if ( ! GetModuleAndMessagePath ( method - > output_type ( ) ,
& response_module_and_class ) ) {
return false ;
}
@ -635,53 +630,170 @@ bool PrintAddServicerToServer(
return true ;
}
bool PrintPreamble ( const FileDescriptor * file ,
const GeneratorConfiguration & config , Printer * out ) {
out - > Print ( " import $Package$ \n " , " Package " , config . grpc_package_root ) ;
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 ) ;
return true ;
}
bool PrivateGenerator : : PrintPreamble ( ) {
out - > Print ( " import $Package$ \n " , " Package " , config . grpc_package_root ) ;
out - > Print ( " from grpc.framework.common import cardinality \n " ) ;
out - > Print (
" from grpc.framework.interfaces.face import utilities as "
" face_utilities \n " ) ;
if ( generate_in_pb2_grpc ) {
out - > Print ( " \n " ) ;
for ( int i = 0 ; i < file - > service_count ( ) ; + + i ) {
const ServiceDescriptor * service = file - > service ( i ) ;
for ( int j = 0 ; j < service - > method_count ( ) ; + + j ) {
auto 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 ) ;
grpc : : string module_alias = ModuleAlias ( type_file_name ) ;
out - > Print ( " import $ModuleName$ as $ModuleAlias$ \n " , " ModuleName " , module_name , " ModuleAlias " , module_alias ) ;
}
}
}
}
return true ;
}
} // namespace
bool PrivateGenerator : : PrintGAServices ( ) {
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 ) ;
grpc : : string package_qualified_service_name = package + service - > name ( ) ;
if ( ! ( PrintStub ( package_qualified_service_name , service ) & &
PrintServicer ( service ) & &
PrintAddServicerToServer ( package_qualified_service_name , service ) ) ) {
return false ;
}
}
return true ;
}
bool PrivateGenerator : : PrintBetaServices ( ) {
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 ) ;
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 ) ) ) {
return false ;
}
}
return true ;
}
pair < bool , grpc : : string > GetServices ( const FileDescriptor * file ,
const GeneratorConfiguration & config ) {
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 ( & output_stream , ' $ ' ) ;
if ( ! PrintPreamble ( file , config , & out ) ) {
Printer out_printer ( & output_stream , ' $ ' ) ;
out = & out_printer ;
if ( generate_in_pb2_grpc ) {
if ( ! PrintPreamble ( ) ) {
return make_pair ( false , " " ) ;
}
auto package = file - > package ( ) ;
if ( ! package . empty ( ) ) {
package = package . append ( " . " ) ;
if ( ! PrintGAServices ( ) ) {
return make_pair ( false , " " ) ;
}
for ( int i = 0 ; i < file - > service_count ( ) ; + + i ) {
auto service = file - > service ( i ) ;
auto package_qualified_service_name = package + service - > name ( ) ;
if ( ! ( PrintStub ( package_qualified_service_name , service , & out ) & &
PrintServicer ( service , & out ) & &
PrintAddServicerToServer ( package_qualified_service_name , service ,
& out ) & &
PrintBetaServicer ( service , & out ) & & PrintBetaStub ( service , & out ) & &
PrintBetaServerFactory ( package_qualified_service_name , service ,
& out ) & &
PrintBetaStubFactory ( package_qualified_service_name , service ,
& out ) ) ) {
} else {
out - > Print ( " try: \n " ) ;
{
IndentScope raii_dict_try_indent ( out ) ;
out - > Print ( " # THESE ELEMENTS WILL BE DEPRECATED. \n "
" # Please use the generated *_pb2_grpc.py files instead. \n " ) ;
if ( ! PrintPreamble ( ) ) {
return make_pair ( false , " " ) ;
}
if ( ! PrintBetaPreamble ( ) ) {
return make_pair ( false , " " ) ;
}
if ( ! PrintGAServices ( ) ) {
return make_pair ( false , " " ) ;
}
if ( ! PrintBetaServices ( ) ) {
return make_pair ( false , " " ) ;
}
}
out - > Print ( " except ImportError: \n " ) ;
{
IndentScope raii_dict_except_indent ( out ) ;
out - > Print ( " pass " ) ;
}
}
}
return make_pair ( true , std : : move ( output ) ) ;
}
} // namespace
GeneratorConfiguration : : GeneratorConfiguration ( )
: grpc_package_root ( " grpc " ) , beta_package_root ( " grpc.beta " ) { }
PythonGrpcGenerator : : PythonGrpcGenerator ( const GeneratorConfiguration & config )
: config_ ( config ) { }
PythonGrpcGenerator : : ~ PythonGrpcGenerator ( ) { }
bool PythonGrpcGenerator : : Generate ( const FileDescriptor * file ,
const grpc : : string & parameter ,
GeneratorContext * context ,
grpc : : string * error ) const {
// Get output file name.
grpc : : string pb2_file_name ;
grpc : : string pb2_grpc_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 ) {
grpc : : string base = file - > name ( ) . substr (
0 , file - > name ( ) . size ( ) - proto_suffix_length ) ;
pb2_file_name = base + " _pb2.py " ;
pb2_grpc_file_name = base + " _pb2_grpc.py " ;
} else {
* error = " Invalid proto file name. Proto file must end with .proto " ;
return false ;
}
PrivateGenerator generator ( config_ , file ) ;
std : : unique_ptr < ZeroCopyOutputStream > pb2_output (
context - > OpenForAppend ( pb2_file_name ) ) ;
std : : unique_ptr < ZeroCopyOutputStream > grpc_output (
context - > Open ( pb2_grpc_file_name ) ) ;
CodedOutputStream pb2_coded_out ( pb2_output . get ( ) ) ;
CodedOutputStream grpc_coded_out ( grpc_output . get ( ) ) ;
bool success = false ;
grpc : : string pb2_code ;
grpc : : string grpc_code ;
generator . generate_in_pb2_grpc = false ;
tie ( success , pb2_code ) = generator . GetGrpcServices ( ) ;
if ( success ) {
generator . generate_in_pb2_grpc = true ;
tie ( success , grpc_code ) = generator . GetGrpcServices ( ) ;
if ( success ) {
pb2_coded_out . WriteRaw ( pb2_code . data ( ) , pb2_code . size ( ) ) ;
grpc_coded_out . WriteRaw ( grpc_code . data ( ) , grpc_code . size ( ) ) ;
return true ;
}
}
return false ;
}
} // namespace grpc_python_generator