objective_c_generator.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
21 #include <map>
22 #include <set>
23 #include <sstream>
24 
25 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
26 
27 #include "src/compiler/config.h"
29 
37 
39 namespace {
40 
41 void PrintProtoRpcDeclarationAsPragma(Printer* printer,
42  const MethodDescriptor* method,
43  map< ::std::string, ::std::string> vars) {
44  vars["client_stream"] = method->client_streaming() ? "stream " : "";
45  vars["server_stream"] = method->server_streaming() ? "stream " : "";
46 
47  printer->Print(vars,
48  "#pragma mark $method_name$($client_stream$$request_type$)"
49  " returns ($server_stream$$response_type$)\n\n");
50 }
51 
52 template <typename DescriptorType>
53 static void PrintAllComments(const DescriptorType* desc, Printer* printer,
54  bool deprecated = false) {
55  std::vector<std::string> comments;
57  &comments);
59  &comments);
61  &comments);
62  if (comments.empty()) {
63  return;
64  }
65  printer->Print("/**\n");
66  for (auto it = comments.begin(); it != comments.end(); ++it) {
67  printer->Print(" * ");
68  size_t start_pos = it->find_first_not_of(' ');
69  if (start_pos != std::string::npos) {
70  printer->PrintRaw(it->c_str() + start_pos);
71  }
72  printer->Print("\n");
73  }
74  if (deprecated) {
75  printer->Print(" *\n");
76  printer->Print(
77  " * This method belongs to a set of APIs that have been deprecated. "
78  "Using"
79  " the v2 API is recommended.\n");
80  }
81  printer->Print(" */\n");
82 }
83 
84 void PrintMethodSignature(Printer* printer, const MethodDescriptor* method,
85  const map< ::std::string, ::std::string>& vars) {
86  // Print comment
87  PrintAllComments(method, printer, true);
88 
89  printer->Print(vars, "- ($return_type$)$method_name$With");
90  if (method->client_streaming()) {
91  printer->Print("RequestsWriter:(GRXWriter *)requestWriter");
92  } else {
93  printer->Print(vars, "Request:($request_class$ *)request");
94  }
95 
96  // TODO(jcanizales): Put this on a new line and align colons.
97  if (method->server_streaming()) {
98  printer->Print(vars,
99  " eventHandler:(void(^)(BOOL done, "
100  "$response_class$ *_Nullable response, NSError *_Nullable "
101  "error))eventHandler");
102  } else {
103  printer->Print(vars,
104  " handler:(void(^)($response_class$ *_Nullable response, "
105  "NSError *_Nullable error))handler");
106  }
107 }
108 
109 void PrintSimpleSignature(Printer* printer, const MethodDescriptor* method,
110  map< ::std::string, ::std::string> vars) {
111  vars["method_name"] =
112  grpc_generator::LowercaseFirstLetter(vars["method_name"]);
113  vars["return_type"] = "void";
114  PrintMethodSignature(printer, method, vars);
115 }
116 
117 void PrintAdvancedSignature(Printer* printer, const MethodDescriptor* method,
118  map< ::std::string, ::std::string> vars) {
119  vars["method_name"] = "RPCTo" + vars["method_name"];
120  vars["return_type"] = "GRPCProtoCall *";
121  PrintMethodSignature(printer, method, vars);
122 }
123 
124 void PrintV2Signature(Printer* printer, const MethodDescriptor* method,
125  map< ::std::string, ::std::string> vars) {
126  if (method->client_streaming()) {
127  vars["return_type"] = "GRPCStreamingProtoCall *";
128  } else {
129  vars["return_type"] = "GRPCUnaryProtoCall *";
130  }
131  vars["method_name"] =
132  grpc_generator::LowercaseFirstLetter(vars["method_name"]);
133 
134  PrintAllComments(method, printer);
135 
136  printer->Print(vars, "- ($return_type$)$method_name$With");
137  if (method->client_streaming()) {
138  printer->Print("ResponseHandler:(id<GRPCProtoResponseHandler>)handler");
139  } else {
140  printer->Print(vars,
141  "Message:($request_class$ *)message "
142  "responseHandler:(id<GRPCProtoResponseHandler>)handler");
143  }
144  printer->Print(" callOptions:(GRPCCallOptions *_Nullable)callOptions");
145 }
146 
147 inline map< ::std::string, ::std::string> GetMethodVars(
148  const MethodDescriptor* method) {
149  map< ::std::string, ::std::string> res;
150  res["method_name"] = method->name();
151  res["request_type"] = method->input_type()->name();
152  res["response_type"] = method->output_type()->name();
153  res["request_class"] = ClassName(method->input_type());
154  res["response_class"] = ClassName(method->output_type());
155  return res;
156 }
157 
158 void PrintMethodDeclarations(Printer* printer, const MethodDescriptor* method) {
159  map< ::std::string, ::std::string> vars = GetMethodVars(method);
160 
161  PrintProtoRpcDeclarationAsPragma(printer, method, vars);
162 
163  PrintSimpleSignature(printer, method, vars);
164  printer->Print(";\n\n");
165  PrintAdvancedSignature(printer, method, vars);
166  printer->Print(";\n\n\n");
167 }
168 
169 void PrintV2MethodDeclarations(Printer* printer,
170  const MethodDescriptor* method) {
171  map< ::std::string, ::std::string> vars = GetMethodVars(method);
172 
173  PrintProtoRpcDeclarationAsPragma(printer, method, vars);
174 
175  PrintV2Signature(printer, method, vars);
176  printer->Print(";\n\n");
177 }
178 
179 void PrintSimpleImplementation(Printer* printer, const MethodDescriptor* method,
180  map< ::std::string, ::std::string> vars) {
181  printer->Print("{\n");
182  printer->Print(vars, " [[self RPCTo$method_name$With");
183  if (method->client_streaming()) {
184  printer->Print("RequestsWriter:requestWriter");
185  } else {
186  printer->Print("Request:request");
187  }
188  if (method->server_streaming()) {
189  printer->Print(" eventHandler:eventHandler] start];\n");
190  } else {
191  printer->Print(" handler:handler] start];\n");
192  }
193  printer->Print("}\n");
194 }
195 
196 void PrintAdvancedImplementation(Printer* printer,
197  const MethodDescriptor* method,
198  map< ::std::string, ::std::string> vars) {
199  printer->Print("{\n");
200  printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n");
201 
202  printer->Print(" requestsWriter:");
203  if (method->client_streaming()) {
204  printer->Print("requestWriter\n");
205  } else {
206  printer->Print("[GRXWriter writerWithValue:request]\n");
207  }
208 
209  printer->Print(vars, " responseClass:[$response_class$ class]\n");
210 
211  printer->Print(" responsesWriteable:[GRXWriteable ");
212  if (method->server_streaming()) {
213  printer->Print("writeableWithEventHandler:eventHandler]];\n");
214  } else {
215  printer->Print("writeableWithSingleHandler:handler]];\n");
216  }
217 
218  printer->Print("}\n");
219 }
220 
221 void PrintV2Implementation(Printer* printer, const MethodDescriptor* method,
222  map< ::std::string, ::std::string> vars) {
223  printer->Print(" {\n");
224  if (method->client_streaming()) {
225  printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n");
226  printer->Print(" responseHandler:handler\n");
227  printer->Print(" callOptions:callOptions\n");
228  printer->Print(
229  vars, " responseClass:[$response_class$ class]];\n}\n\n");
230  } else {
231  printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n");
232  printer->Print(" message:message\n");
233  printer->Print(" responseHandler:handler\n");
234  printer->Print(" callOptions:callOptions\n");
235  printer->Print(
236  vars, " responseClass:[$response_class$ class]];\n}\n\n");
237  }
238 }
239 
240 void PrintMethodImplementations(Printer* printer,
241  const MethodDescriptor* method,
242  const Parameters& generator_params) {
243  map< ::std::string, ::std::string> vars = GetMethodVars(method);
244 
245  PrintProtoRpcDeclarationAsPragma(printer, method, vars);
246 
247  if (!generator_params.no_v1_compatibility) {
248  // TODO(jcanizales): Print documentation from the method.
249  PrintSimpleSignature(printer, method, vars);
250  PrintSimpleImplementation(printer, method, vars);
251 
252  printer->Print("// Returns a not-yet-started RPC object.\n");
253  PrintAdvancedSignature(printer, method, vars);
254  PrintAdvancedImplementation(printer, method, vars);
255  }
256 
257  PrintV2Signature(printer, method, vars);
258  PrintV2Implementation(printer, method, vars);
259 }
260 
261 } // namespace
262 
265  set< ::std::string> classes;
266  for (int i = 0; i < file->service_count(); i++) {
267  const auto service = file->service(i);
268  for (int i = 0; i < service->method_count(); i++) {
269  const auto method = service->method(i);
270  classes.insert(ClassName(method->input_type()));
271  classes.insert(ClassName(method->output_type()));
272  }
273  }
274  for (auto one_class : classes) {
275  output += "@class " + one_class + ";\n";
276  }
277 
278  return output;
279 }
280 
282  const Parameters& generator_params) {
284 
285  if (generator_params.no_v1_compatibility) return output;
286 
287  // Scope the output stream so it closes and finalizes output to the string.
289  Printer printer(&output_stream, '$');
290 
291  map< ::std::string, ::std::string> vars = {
292  {"service_class", ServiceClassName(service)}};
293 
294  printer.Print(vars,
295  "/**\n"
296  " * The methods in this protocol belong to a set of old APIs "
297  "that have been deprecated. They do not\n"
298  " * recognize call options provided in the initializer. Using "
299  "the v2 protocol is recommended.\n"
300  " */\n");
301  printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
302  for (int i = 0; i < service->method_count(); i++) {
303  PrintMethodDeclarations(&printer, service->method(i));
304  }
305  printer.Print("@end\n\n");
306 
307  return output;
308 }
309 
312 
313  // Scope the output stream so it closes and finalizes output to the string.
315  Printer printer(&output_stream, '$');
316 
317  map< ::std::string, ::std::string> vars = {
318  {"service_class", ServiceClassName(service) + "2"}};
319 
320  printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
321  for (int i = 0; i < service->method_count(); i++) {
322  PrintV2MethodDeclarations(&printer, service->method(i));
323  }
324  printer.Print("@end\n\n");
325 
326  return output;
327 }
328 
330  const Parameters& generator_params) {
332 
333  // Scope the output stream so it closes and finalizes output to the string.
335  Printer printer(&output_stream, '$');
336 
337  map< ::std::string, ::std::string> vars = {
338  {"service_class", ServiceClassName(service)}};
339 
340  printer.Print(vars,
341  "/**\n"
342  " * Basic service implementation, over gRPC, that only does\n"
343  " * marshalling and parsing.\n"
344  " */\n");
345  printer.Print(vars,
346  "@interface $service_class$ :"
347  " GRPCProtoService<$service_class$2");
348  if (!generator_params.no_v1_compatibility) {
349  printer.Print(vars, ", $service_class$");
350  }
351  printer.Print(">\n");
352  printer.Print(
353  "- (instancetype)initWithHost:(NSString *)host "
354  "callOptions:(GRPCCallOptions "
355  "*_Nullable)callOptions"
356  " NS_DESIGNATED_INITIALIZER;\n");
357  printer.Print(
358  "+ (instancetype)serviceWithHost:(NSString *)host "
359  "callOptions:(GRPCCallOptions *_Nullable)callOptions;\n");
360  if (!generator_params.no_v1_compatibility) {
361  printer.Print(
362  "// The following methods belong to a set of old APIs that have been "
363  "deprecated.\n");
364  printer.Print("- (instancetype)initWithHost:(NSString *)host;\n");
365  printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n");
366  }
367  printer.Print("@end\n");
368 
369  return output;
370 }
371 
373  const Parameters& generator_params) {
375  {
376  // Scope the output stream so it closes and finalizes output to the string.
378  Printer printer(&output_stream, '$');
379 
380  map< ::std::string, ::std::string> vars = {
381  {"service_name", service->name()},
382  {"service_class", ServiceClassName(service)},
383  {"package", service->file()->package()}};
384 
385  printer.Print(vars,
386  "@implementation $service_class$\n\n"
387  "#pragma clang diagnostic push\n"
388  "#pragma clang diagnostic ignored "
389  "\"-Wobjc-designated-initializers\"\n\n"
390  "// Designated initializer\n"
391  "- (instancetype)initWithHost:(NSString *)host "
392  "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n"
393  " return [super initWithHost:host\n"
394  " packageName:@\"$package$\"\n"
395  " serviceName:@\"$service_name$\"\n"
396  " callOptions:callOptions];\n"
397  "}\n\n");
398  if (!generator_params.no_v1_compatibility) {
399  printer.Print(vars,
400  "- (instancetype)initWithHost:(NSString *)host {\n"
401  " return [super initWithHost:host\n"
402  " packageName:@\"$package$\"\n"
403  " serviceName:@\"$service_name$\"];\n"
404  "}\n\n");
405  }
406  printer.Print("#pragma clang diagnostic pop\n\n");
407 
408  if (!generator_params.no_v1_compatibility) {
409  printer.Print(
410  "// Override superclass initializer to disallow different"
411  " package and service names.\n"
412  "- (instancetype)initWithHost:(NSString *)host\n"
413  " packageName:(NSString *)packageName\n"
414  " serviceName:(NSString *)serviceName {\n"
415  " return [self initWithHost:host];\n"
416  "}\n\n");
417  }
418  printer.Print(
419  "- (instancetype)initWithHost:(NSString *)host\n"
420  " packageName:(NSString *)packageName\n"
421  " serviceName:(NSString *)serviceName\n"
422  " callOptions:(GRPCCallOptions *)callOptions {\n"
423  " return [self initWithHost:host callOptions:callOptions];\n"
424  "}\n\n");
425 
426  printer.Print("#pragma mark - Class Methods\n\n");
427  if (!generator_params.no_v1_compatibility) {
428  printer.Print(
429  "+ (instancetype)serviceWithHost:(NSString *)host {\n"
430  " return [[self alloc] initWithHost:host];\n"
431  "}\n\n");
432  }
433  printer.Print(
434  "+ (instancetype)serviceWithHost:(NSString *)host "
435  "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n"
436  " return [[self alloc] initWithHost:host callOptions:callOptions];\n"
437  "}\n\n");
438 
439  printer.Print("#pragma mark - Method Implementations\n\n");
440 
441  for (int i = 0; i < service->method_count(); i++) {
442  PrintMethodImplementations(&printer, service->method(i),
443  generator_params);
444  }
445 
446  printer.Print("@end\n");
447  }
448  return output;
449 }
450 
451 } // namespace grpc_objective_c_generator
regen-readme.it
it
Definition: regen-readme.py:15
objective_c_generator_helpers.h
grpc_objective_c_generator
Definition: objective_c_generator.cc:38
config.h
FileDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:128
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
grpc::protobuf::io::Printer
GRPC_CUSTOM_PRINTER Printer
Definition: src/compiler/config.h:54
grpc_generator::COMMENTTYPE_TRAILING
@ COMMENTTYPE_TRAILING
Definition: generator_helpers.h:180
grpc_objective_c_generator::GetAllMessageClasses
::std::string GetAllMessageClasses(const FileDescriptor *file)
Definition: objective_c_generator.cc:263
grpc_generator::GetComment
void GetComment(const DescriptorType *desc, CommentType type, std::vector< std::string > *out)
Definition: generator_helpers.h:186
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
grpc_objective_c_generator::ServiceClassName
inline ::std::string ServiceClassName(const ServiceDescriptor *service)
Definition: objective_c_generator_helpers.h:41
grpc::protobuf::io::StringOutputStream
GRPC_CUSTOM_STRINGOUTPUTSTREAM StringOutputStream
Definition: src/compiler/config.h:56
grpc_generator::COMMENTTYPE_LEADING_DETACHED
@ COMMENTTYPE_LEADING_DETACHED
Definition: generator_helpers.h:181
grpc_objective_c_generator::GetProtocol
::std::string GetProtocol(const ServiceDescriptor *service, const Parameters &generator_params)
Definition: objective_c_generator.cc:281
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
grpc::protobuf::MethodDescriptor
GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:87
grpc_objective_c_generator::GetSource
::std::string GetSource(const ServiceDescriptor *service, const Parameters &generator_params)
Definition: objective_c_generator.cc:372
grpc_objective_c_generator::GetInterface
::std::string GetInterface(const ServiceDescriptor *service, const Parameters &generator_params)
Definition: objective_c_generator.cc:329
grpc_objective_c_generator::GetV2Protocol
::std::string GetV2Protocol(const ServiceDescriptor *service)
Definition: objective_c_generator.cc:310
grpc_generator::LowercaseFirstLetter
std::string LowercaseFirstLetter(std::string s)
Definition: generator_helpers.h:110
grpc_objective_c_generator::Parameters
Definition: objective_c_generator.h:26
classes
static const struct nv classes[]
Definition: adig.c:75
grpc_objective_c_generator::Parameters::no_v1_compatibility
bool no_v1_compatibility
Definition: objective_c_generator.h:28
cpp.gmock_class.set
set
Definition: bloaty/third_party/googletest/googlemock/scripts/generator/cpp/gmock_class.py:44
grpc_cpp_generator::ClassName
std::string ClassName(const grpc::protobuf::Descriptor *descriptor, bool qualified)
Definition: cpp_generator_helpers.h:37
desc
#define desc
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:338
grpc_generator::COMMENTTYPE_LEADING
@ COMMENTTYPE_LEADING
Definition: generator_helpers.h:179
FileDescriptor
struct FileDescriptor FileDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:56
service
__attribute__((deprecated("Please use GRPCProtoMethod."))) @interface ProtoMethod NSString * service
Definition: ProtoMethod.h:25
method
NSString * method
Definition: ProtoMethod.h:28
objective_c_generator.h
grpc::protobuf::ServiceDescriptor
GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:88
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:33