diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index d1482a40d07840a5c909416f97d679c3efcab962..6898b4dda3a05524c9b7fbd05c08949e41b7616a 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -40,14 +40,15 @@ #include <sstream> -namespace grpc_objective_c_generator { -namespace { - 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 { + void PrintProtoRpcDeclarationAsPragma(Printer *printer, const MethodDescriptor *method, map<string, string> vars) { @@ -72,6 +73,7 @@ void PrintMethodSignature(Printer *printer, } // TODO(jcanizales): Put this on a new line and align colons. + // TODO(jcanizales): eventHandler for server streaming? printer->Print(" handler:(void(^)("); if (method->server_streaming()) { printer->Print("BOOL done, "); @@ -112,69 +114,67 @@ void PrintMethodDeclarations(Printer *printer, printer->Print(";\n\n\n"); } -void PrintSourceMethodSimpleBlock(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(); +void PrintSimpleImplementation(Printer *printer, + const MethodDescriptor *method, + map<string, string> vars) { + printer->Print("{\n"); + printer->Print(vars, "[[self RPCTo$method_name$With"); + if (method->client_streaming()) { + printer->Print("RequestsWriter:requestsWriter"); //TODO(jcanizales):request? + } else { + printer->Print("Request:request"); + } + printer->Print(" handler:handler] start];\n"); + printer->Print("}\n"); +} - PrintSimpleSignature(printer, method, vars); +void PrintAdvancedImplementation(Printer *printer, + const MethodDescriptor *method, + map<string, string> vars) { + printer->Print("{\n"); + printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n"); + + printer->Print(" requestsWriter:"); + if (method->client_streaming()) { + printer->Print("requestsWriter\n"); + } else { + printer->Print("[GRXWriter writerWithValue:request]\n"); + } + + printer->Print(vars, " responseClass:[$response_type$ class]\n"); + + printer->Print(" responsesWriteable:[GRXWriteable "); + if (method->server_streaming()) { + printer->Print("writeableWithStreamHandler:handler]];\n"); + } else { + printer->Print("writeableWithSingleValueHandler:handler]];\n"); + } - printer->Print(" {\n"); - 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 PrintSourceMethodAdvanced(Printer *printer, - const MethodDescriptor *method, - map<string, string> vars) { +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(); - PrintAdvancedSignature(printer, method, vars); + PrintProtoRpcDeclarationAsPragma(printer, method, vars); - printer->Print(" {\n"); - printer->Indent(); - printer->Print(vars, "return [self $method_name$WithRequest:request " - "client:[self newClient]];\n"); - printer->Outdent(); - printer->Print("}\n"); -} + // TODO(jcanizales): Print documentation from the method. + PrintSimpleSignature(printer, method, vars); + PrintSimpleImplementation(printer, method, vars); -void PrintSourceMethodHandler(Printer *printer, - const MethodDescriptor *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["method_name"] = method->name(); - (*vars)["response_type"] = PrefixedName(method->output_type()->name()); - (*vars)["caps_name"] = grpc_generator::CapitalizeFirstLetter(method->name()); - - printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:" - "(id<GRXSource>)request client:(PBgRPCClient *)client {\n"); - printer->Indent(); - printer->Print(*vars, - "return [self responseWithMethod:$@\"$caps_name\"\n"); - printer->Print(*vars, - " class:[$response_type$ class]\n"); - printer->Print(" request:request\n"); - printer->Print(" client:client];\n"); - printer->Outdent(); - printer->Print("}\n"); + printer->Print("// Returns a not-yet-started RPC object.\n"); + PrintAdvancedSignature(printer, method, vars); + PrintAdvancedImplementation(printer, method, vars); } -} +} // namespace -grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, - const string prefix) { - grpc::string output; +string GetHeader(const ServiceDescriptor *service, const string prefix) { + string output; grpc::protobuf::io::StringOutputStream output_stream(&output); Printer printer(&output_stream, '$'); @@ -192,52 +192,47 @@ grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, printer.Print("// Basic service implementation, over gRPC, that only does" " marshalling and parsing.\n"); - // use prefix - printer.Print(vars, "@interface RMT$service_name$ :" - " ProtoService<RMT$service_name$>\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"); return output; } -grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service, - const string prefix) { - grpc::string output; +string GetSource(const ServiceDescriptor *service, const string prefix) { + string output; grpc::protobuf::io::StringOutputStream output_stream(&output); Printer printer(&output_stream, '$'); map<string, string> vars = {{"service_name", service->name()}, + {"package", service->file()->package()}, {"prefix", prefix}}; - printer.Print(vars, "#import \"$service_name$Stub.pb.h\"\n"); - printer.Print("#import \"PBGeneratedMessage+GRXSource.h\"\n\n"); - vars["full_name"] = service->full_name(); + + printer.Print(vars, + "static NSString *const kPackageName = @\"$package$\";\n"); printer.Print(vars, - "static NSString *const kInterface = @\"$full_name$\";\n"); - printer.Print("@implementation $service_name$Stub\n\n"); + "static NSString *const kServiceName = @\"$service_name$\";\n\n"); + + printer.Print(vars, "@implementation $prefix$$service_name$\n\n"); + + printer.Print("// Designated initializer\n"); printer.Print("- (instancetype)initWithHost:(NSString *)host {\n"); - printer.Indent(); - printer.Print("if ((self = [super initWithHost:host " - "interface:kInterface])) {\n"); - printer.Print("}\n"); - printer.Print("return self;\n"); - printer.Outdent(); + printer.Print(" return (self = [super initWithHost:host" + " packageName:kPackageName serviceName:kServiceName]);\n"); printer.Print("}\n\n"); - printer.Print("#pragma mark Simple block handlers.\n"); - for (int i = 0; i < service->method_count(); i++) { - PrintSourceMethodSimpleBlock(&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"); + printer.Print("// Override superclass initializer to disallow different" + " package and service names.\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host\n"); + printer.Print(" packageName:(NSString *)packageName\n"); + printer.Print(" serviceName:(NSString *)serviceName {\n"); + printer.Print(" return [self initWithHost:host];\n"); + printer.Print("}\n\n\n"); + 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"); return output; } diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h index e01724a7f7d58e29c8d5e0434458510ba04ce3cf..548e96fcf1963ee960c5ed377d048b6c7f68451b 100644 --- a/src/compiler/objective_c_generator.h +++ b/src/compiler/objective_c_generator.h @@ -38,9 +38,13 @@ namespace grpc_objective_c_generator { +// Returns the content to be included in the "global_scope" insertion point of +// the generated header file. grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, const grpc::string prefix); +// Returns the content to be included in the "global_scope" insertion point of +// the generated implementation file. grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service, const grpc::string prefix); diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc index ef32dcc0562e271fa1bd2f2862d5fc153b356d55..dec8594673ab1968af15c9e8ff3a6e306534a159 100644 --- a/src/compiler/objective_c_plugin.cc +++ b/src/compiler/objective_c_plugin.cc @@ -62,20 +62,20 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { // Generate .pb.h - Insert(context, file_name + ".pb.h", "imports", + Insert(context, file_name + ".pbobjc.h", "imports", "#import <gRPC/ProtoService.h>\n"); - Insert(context, file_name + ".pb.h", "global_scope", + Insert(context, file_name + ".pbobjc.h", "global_scope", grpc_objective_c_generator::GetHeader(service, prefix)); // Generate .pb.m - Insert(context, file_name + ".pb.m", "imports", + Insert(context, file_name + ".pbobjc.m", "imports", "#import <gRPC/GRXWriteable.h>\n" "#import <gRPC/GRXWriter+Immediate.h>\n" "#import <gRPC/ProtoRPC.h>\n"); - Insert(context, file_name + ".pb.m", "global_scope", + Insert(context, file_name + ".pbobjc.m", "global_scope", grpc_objective_c_generator::GetSource(service, prefix)); } diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m index 31a3ba3a61143621189bdbf3f82dbd4017a764cc..5c2b98890b56b8915eb0f1b5ffbc97c6dfee6273 100644 --- a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m +++ b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m @@ -44,6 +44,7 @@ static NSString *const kServiceName = @"TestService"; return [self initWithHost:host]; } + #pragma mark EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty) // One empty request followed by one empty response.