@ -40,195 +40,200 @@
# include <sstream>
# include <sstream>
using : : grpc : : protobuf : : io : : Printer ;
using : : grpc : : protobuf : : MethodDescriptor ;
using : : grpc : : protobuf : : ServiceDescriptor ;
using : : std : : map ;
using : : grpc : : string ;
namespace grpc_objective_c_generator {
namespace grpc_objective_c_generator {
namespace {
namespace {
void PrintSimpleBlockSignature ( grpc : : protobuf : : io : : Printer * printer ,
void PrintProtoRpcDeclarationAsPragma ( Printer * printer ,
const grpc : : protobuf : : MethodDescriptor * method ,
const MethodDescriptor * method ,
std : : map < grpc : : string , grpc : : string > * vars ) {
map < string , string > vars ) {
( * vars ) [ " method_name " ] = method - > name ( ) ;
vars [ " client_stream " ] = method - > client_streaming ( ) ? " stream " : " " ;
( * vars ) [ " request_type " ] = PrefixedName ( method - > input_type ( ) - > name ( ) ) ;
vars [ " server_stream " ] = method - > server_streaming ( ) ? " stream " : " " ;
( * vars ) [ " response_type " ] = PrefixedName ( method - > output_type ( ) - > name ( ) ) ;
if ( method - > server_streaming ( ) ) {
printer - > Print ( vars ,
printer - > Print ( " // When the response stream finishes, the handler is "
" #pragma mark $method_name$($client_stream$$request_type$) "
" called with nil for both arguments. \n \n " ) ;
" returns ($server_stream$$response_type$) \n \n " ) ;
} else {
printer - > Print ( " // The handler is only called once. \n \n " ) ;
}
printer - > Print ( * vars , " - (id<GRXLiveSource>)$method_name$WithRequest: "
" ($request_type$)request completionHandler:(void(^) "
" ($response_type$ *, NSError *))handler " ) ;
}
}
void PrintSimpleDelegateSignature ( grpc : : protobuf : : io : : Printer * printer ,
void PrintMethodSignature ( Printer * printer ,
const grpc : : protobuf : : MethodDescriptor * method ,
const MethodDescriptor * method ,
std : : map < grpc : : string , grpc : : string > * vars ) {
const map < string , string > & vars ) {
( * vars ) [ " method_name " ] = method - > name ( ) ;
// TODO(jcanizales): Print method comments.
( * vars ) [ " request_type " ] = PrefixedName ( method - > input_type ( ) - > name ( ) ) ;
printer - > Print ( * vars , " - (id<GRXLiveSource>)$method_name$WithRequest: "
printer - > Print ( vars , " - ($return_type$)$method_name$With " ) ;
" ($request_type$)request delegate:(id<GRXSink>)delegate " ) ;
if ( method - > client_streaming ( ) ) {
}
printer - > Print ( " RequestsWriter:(id<GRXWriter>)request " ) ;
} else {
printer - > Print ( vars , " Request:($prefix$$request_type$ *)request " ) ;
}
void PrintAdvancedSignature ( grpc : : protobuf : : io : : Printer * printer ,
// TODO(jcanizales): Put this on a new line and align colons.
const grpc : : protobuf : : MethodDescriptor * method ,
// TODO(jcanizales): eventHandler for server streaming?
std : : map < grpc : : string , grpc : : string > * vars ) {
printer - > Print ( " handler:(void(^)( " ) ;
( * vars ) [ " method_name " ] = method - > name ( ) ;
if ( method - > server_streaming ( ) ) {
printer - > Print ( * vars , " - (GRXSource *)$method_name$WithRequest: "
printer - > Print ( " BOOL done, " ) ;
" (id<GRXSource>)request " ) ;
}
printer - > Print ( vars ,
" $prefix$$response_type$ *response, NSError *error))handler " ) ;
}
}
void PrintSourceMethodSimpleBlock ( grpc : : protobuf : : io : : Printer * printer ,
void PrintSimpleSignature ( Printer * printer ,
const grpc : : protobuf : : MethodDescriptor * method ,
const MethodDescriptor * method ,
std : : map < grpc : : string , grpc : : string > * vars ) {
map < string , string > vars ) {
PrintSimpleBlockSignature ( printer , method , vars ) ;
vars [ " method_name " ] =
grpc_generator : : LowercaseFirstLetter ( vars [ " method_name " ] ) ;
( * vars ) [ " method_name " ] = method - > name ( ) ;
vars [ " return_type " ] = " void " ;
printer - > Print ( " { \n " ) ;
PrintMethodSignature ( printer , method , vars ) ;
printer - > Indent ( ) ;
printer - > Print ( * vars , " return [[self $method_name$WithRequest:request] "
" connectHandler:^(id value, NSError *error) { \n " ) ;
printer - > Indent ( ) ;
printer - > Print ( " handler(value, error); \n " ) ;
printer - > Outdent ( ) ;
printer - > Print ( " }]; \n " ) ;
printer - > Outdent ( ) ;
printer - > Print ( " } \n " ) ;
}
}
void PrintSourceMethodSimpleDelegate ( grpc : : protobuf : : io : : Printer * printer ,
void PrintAdvancedSignature ( Printer * printer ,
const grpc : : protobuf : : MethodDescriptor * method ,
const MethodDescriptor * method ,
std : : map < grpc : : string , grpc : : string > * vars ) {
map < string , string > vars ) {
PrintSimpleDelegateSignature ( printer , method , vars ) ;
vars [ " method_name " ] = " RPCTo " + vars [ " method_name " ] ;
vars [ " return_type " ] = " ProtoRPC * " ;
( * vars ) [ " method_name " ] = method - > name ( ) ;
PrintMethodSignature ( printer , method , vars ) ;
printer - > Print ( " { \n " ) ;
printer - > Indent ( ) ;
printer - > Print ( * vars , " return [[self $method_name$WithRequest:request] "
" connectToSink:delegate]; \n " ) ;
printer - > Outdent ( ) ;
printer - > Print ( " } \n " ) ;
}
}
void PrintSourceMethodAdvanced ( grpc : : protobuf : : io : : Printer * printer ,
void PrintMethodDeclarations ( Printer * printer ,
const grpc : : protobuf : : MethodDescriptor * method ,
const MethodDescriptor * method ,
std : : map < grpc : : string , grpc : : string > * vars ) {
map < string , string > vars ) {
vars [ " method_name " ] = method - > name ( ) ;
vars [ " request_type " ] = method - > input_type ( ) - > name ( ) ;
vars [ " response_type " ] = method - > output_type ( ) - > name ( ) ;
PrintProtoRpcDeclarationAsPragma ( printer , method , vars ) ;
PrintSimpleSignature ( printer , method , vars ) ;
printer - > Print ( " ; \n \n " ) ;
PrintAdvancedSignature ( printer , method , vars ) ;
PrintAdvancedSignature ( printer , method , vars ) ;
printer - > Print ( " ; \n \n \n " ) ;
}
( * vars ) [ " method_name " ] = method - > name ( ) ;
void PrintSimpleImplementation ( Printer * printer ,
printer - > Print ( " { \n " ) ;
const MethodDescriptor * method ,
printer - > Indent ( ) ;
map < string , string > vars ) {
printer - > Print ( * vars , " return [self $method_name$WithRequest:request "
printer - > Print ( " { \n " ) ;
" client:[self newClient]]; \n " ) ;
printer - > Print ( vars , " [[self RPCTo$method_name$With " ) ;
printer - > Outdent ( ) ;
if ( method - > client_streaming ( ) ) {
printer - > Print ( " RequestsWriter:request " ) ;
} else {
printer - > Print ( " Request:request " ) ;
}
printer - > Print ( " handler:handler] start]; \n " ) ;
printer - > Print ( " } \n " ) ;
printer - > Print ( " } \n " ) ;
}
}
void PrintSourceMethodHandler ( grpc : : protobuf : : io : : Printer * printer ,
void PrintAdvancedImplementation ( Printer * printer ,
const grpc : : protobuf : : MethodDescriptor * method ,
const MethodDescriptor * method ,
std : : map < grpc : : string , grpc : : string > * vars ) {
map < string , string > vars ) {
( * vars ) [ " method_name " ] = method - > name ( ) ;
printer - > Print ( " { \n " ) ;
( * vars ) [ " response_type " ] = PrefixedName ( method - > output_type ( ) - > name ( ) ) ;
printer - > Print ( vars , " return [self RPCToMethod:@ \" $method_name$ \" \n " ) ;
( * vars ) [ " caps_name " ] = grpc_generator : : CapitalizeFirstLetter ( method - > name ( ) ) ;
printer - > Print ( " requestsWriter: " ) ;
printer - > Print ( * vars , " - (GRXSource *)$method_name$WithRequest: "
if ( method - > client_streaming ( ) ) {
" (id<GRXSource>)request client:(PBgRPCClient *)client { \n " ) ;
printer - > Print ( " request \n " ) ;
printer - > Indent ( ) ;
} else {
printer - > Print ( * vars ,
printer - > Print ( " [GRXWriter writerWithValue:request] \n " ) ;
" return [self responseWithMethod:$@ \" $caps_name \" \n " ) ;
}
printer - > Print ( * vars ,
" class:[$response_type$ class] \n " ) ;
printer - > Print ( vars ,
printer - > Print ( " request:request \n " ) ;
" responseClass:[$prefix$$response_type$ class] \n " ) ;
printer - > Print ( " client:client]; \n " ) ;
printer - > Outdent ( ) ;
printer - > Print ( " responsesWriteable:[GRXWriteable " ) ;
if ( method - > server_streaming ( ) ) {
printer - > Print ( " writeableWithStreamHandler:handler]]; \n " ) ;
} else {
printer - > Print ( " writeableWithSingleValueHandler:handler]]; \n " ) ;
}
printer - > Print ( " } \n " ) ;
printer - > Print ( " } \n " ) ;
}
}
void PrintMethodImplementations ( Printer * printer ,
const MethodDescriptor * method ,
map < string , string > vars ) {
vars [ " method_name " ] = method - > name ( ) ;
vars [ " request_type " ] = method - > input_type ( ) - > name ( ) ;
vars [ " response_type " ] = method - > output_type ( ) - > name ( ) ;
PrintProtoRpcDeclarationAsPragma ( printer , method , vars ) ;
// TODO(jcanizales): Print documentation from the method.
PrintSimpleSignature ( printer , method , vars ) ;
PrintSimpleImplementation ( printer , method , vars ) ;
printer - > Print ( " // Returns a not-yet-started RPC object. \n " ) ;
PrintAdvancedSignature ( printer , method , vars ) ;
PrintAdvancedImplementation ( printer , method , vars ) ;
}
}
grpc : : string GetHeader ( const grpc : : protobuf : : ServiceDescriptor * service ,
} // namespace
const grpc : : string message_header ) {
grpc : : string output ;
string GetHeader ( const ServiceDescriptor * service , const string prefix ) {
string output ;
grpc : : protobuf : : io : : StringOutputStream output_stream ( & output ) ;
grpc : : protobuf : : io : : StringOutputStream output_stream ( & output ) ;
grpc : : protobuf : : io : : Printer printer ( & output_stream , ' $ ' ) ;
Printer printer ( & output_stream , ' $ ' ) ;
std : : map < grpc : : string , grpc : : string > vars ;
printer . Print ( " #import \" PBgRPCClient.h \" \n " ) ;
printer . Print ( " @protocol GRXWriteable; \n " ) ;
printer . Print ( " #import \" PBStub.h \" \n " ) ;
printer . Print ( " @protocol GRXWriter; \n \n " ) ;
vars [ " message_header " ] = message_header ;
printer . Print ( vars , " #import \" $message_header$ \" \n \n " ) ;
map < string , string > vars = { { " service_name " , service - > name ( ) } ,
printer . Print ( " @protocol GRXSource \n " ) ;
{ " prefix " , prefix } } ;
printer . Print ( " @class GRXSource \n \n " ) ;
printer . Print ( vars , " @protocol $prefix$$service_name$ <NSObject> \n \n " ) ;
vars [ " service_name " ] = service - > name ( ) ;
printer . Print ( " @protocol $service_name$Stub <NSObject> \n \n " ) ;
printer . Print ( " #pragma mark Simple block handlers \n \n " ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
PrintSimpleBlockSignature ( & printer , service - > method ( i ) , & vars ) ;
printer . Print ( " ; \n " ) ;
}
printer . Print ( " \n " ) ;
printer . Print ( " #pragma mark Simple delegate handlers. \n \n " ) ;
printer . Print ( " # TODO(jcanizales): Use high-level snippets to remove this duplication. " ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
PrintSimpleDelegateSignature ( & printer , service - > method ( i ) , & vars ) ;
printer . Print ( " ; \n " ) ;
}
printer . Print ( " \n " ) ;
printer . Print ( " #pragma mark Advanced handlers. \n \n " ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
PrintAdvancedSignature ( & printer , service - > method ( i ) , & vars ) ;
PrintMethodDeclarations ( & printer , service - > method ( i ) , vars ) ;
printer . Print ( " ; \n " ) ;
}
}
printer . Print ( " \n " ) ;
printer . Print ( " @end \n \n " ) ;
printer . Print ( " @end \n \n " ) ;
printer . Print ( " // Basic stub that only does marshalling and parsing \n " ) ;
printer . Print ( vars , " @interface $service_name$Stub : "
printer . Print ( " // Basic service implementation, over gRPC, that only does "
" PBStub<$service_name$Stub> \n " ) ;
" marshalling and parsing. \n " ) ;
printer . Print ( " - (instancetype)initWithHost:(NSString *)host; \n " ) ;
printer . Print ( vars , " @interface $prefix$$service_name$ : "
" ProtoService<$prefix$$service_name$> \n " ) ;
printer . Print ( " - (instancetype)initWithHost:(NSString *)host "
" NS_DESIGNATED_INITIALIZER; \n " ) ;
printer . Print ( " @end \n " ) ;
printer . Print ( " @end \n " ) ;
return output ;
return output ;
}
}
grpc : : string GetSource ( const grpc : : protobuf : : ServiceDescriptor * service ) {
string GetSource ( const ServiceDescriptor * service , const string prefix ) {
grpc : : string output ;
string output ;
grpc : : protobuf : : io : : StringOutputStream output_stream ( & output ) ;
grpc : : protobuf : : io : : StringOutputStream output_stream ( & output ) ;
grpc : : protobuf : : io : : Printer printer ( & output_stream , ' $ ' ) ;
Printer printer ( & output_stream , ' $ ' ) ;
std : : map < grpc : : string , grpc : : string > vars ;
vars [ " service_name " ] = service - > name ( ) ;
map < string , string > vars = { { " service_name " , service - > name ( ) } ,
printer . Print ( vars , " #import \" $service_name$Stub.pb.h \" \n " ) ;
{ " package " , service - > file ( ) - > package ( ) } ,
printer . Print ( " #import \" PBGeneratedMessage+GRXSource.h \" \n \n " ) ;
{ " prefix " , prefix } } ;
vars [ " full_name " ] = service - > full_name ( ) ;
printer . Print ( vars ,
" static NSString *const kPackageName = @ \" $package$ \" ; \n " ) ;
printer . Print ( vars ,
printer . Print ( vars ,
" static NSString *const kInterface = @ \" $full_name$ \" ; \n " ) ;
" static NSString *const kServiceName = @ \" $service_name$ \" ; \n \n " ) ;
printer . Print ( " @implementation $service_name$Stub \n \n " ) ;
printer . Print ( vars , " @implementation $prefix$$service_name$ \n \n " ) ;
printer . Print ( " // Designated initializer \n " ) ;
printer . Print ( " - (instancetype)initWithHost:(NSString *)host { \n " ) ;
printer . Print ( " - (instancetype)initWithHost:(NSString *)host { \n " ) ;
printer . Indent ( ) ;
printer . Print ( " return (self = [super initWithHost:host "
printer . Print ( " if ((self = [super initWithHost:host "
" packageName:kPackageName serviceName:kServiceName]); \n " ) ;
" interface:kInterface])) { \n " ) ;
printer . Print ( " } \n " ) ;
printer . Print ( " return self; \n " ) ;
printer . Outdent ( ) ;
printer . Print ( " } \n \n " ) ;
printer . Print ( " } \n \n " ) ;
printer . Print ( " #pragma mark Simple block handlers. \n " ) ;
printer . Print ( " // Override superclass initializer to disallow different "
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
" package and service names. \n " ) ;
PrintSourceMethodSimpleBlock ( & printer , service - > method ( i ) , & vars ) ;
printer . Print ( " - (instancetype)initWithHost:(NSString *)host \n " ) ;
}
printer . Print ( " packageName:(NSString *)packageName \n " ) ;
printer . Print ( " \n " ) ;
printer . Print ( " serviceName:(NSString *)serviceName { \n " ) ;
printer . Print ( " #pragma mark Simple delegate handlers. \n " ) ;
printer . Print ( " return [self initWithHost:host]; \n " ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
printer . Print ( " } \n \n \n " ) ;
PrintSourceMethodSimpleDelegate ( & printer , service - > method ( i ) , & vars ) ;
}
printer . Print ( " \n " ) ;
printer . Print ( " #pragma mark Advanced handlers. \n " ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
PrintSourceMethodAdvanced ( & printer , service - > method ( i ) , & vars ) ;
}
printer . Print ( " \n " ) ;
printer . Print ( " #pragma mark Handlers for subclasses "
" (stub wrappers) to override. \n " ) ;
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
for ( int i = 0 ; i < service - > method_count ( ) ; i + + ) {
PrintSourceMethodHandler ( & printer , service - > method ( i ) , & vars ) ;
PrintMethodImplementations ( & printer , service - > method ( i ) , vars ) ;
}
}
printer . Print ( " @end \n " ) ;
printer . Print ( " @end \n " ) ;
return output ;
return output ;
}
}