src/compiler/php_generator.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2016 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 
19 #include <map>
20 
21 #include <google/protobuf/compiler/php/php_generator.h>
22 
23 #include "src/compiler/config.h"
26 
34 using std::map;
35 
36 namespace grpc_php_generator {
37 namespace {
38 
39 std::string ConvertToPhpNamespace(const std::string& name) {
40  std::vector<std::string> tokens = grpc_generator::tokenize(name, ".");
41  std::ostringstream oss;
42  for (unsigned int i = 0; i < tokens.size(); i++) {
43  oss << (i == 0 ? "" : "\\")
45  }
46  return oss.str();
47 }
48 
49 std::string PackageName(const FileDescriptor* file) {
50  if (file->options().has_php_namespace()) {
51  return file->options().php_namespace();
52  } else {
53  return ConvertToPhpNamespace(file->package());
54  }
55 }
56 
57 std::string MessageIdentifierName(const std::string& name,
58  const FileDescriptor* file) {
59  std::vector<std::string> tokens = grpc_generator::tokenize(name, ".");
60  std::ostringstream oss;
61  if (PackageName(file) != "") {
62  oss << PackageName(file) << "\\";
63  }
64  oss << grpc_generator::CapitalizeFirstLetter(tokens[tokens.size() - 1]);
65  return oss.str();
66 }
67 
68 void PrintMethod(const MethodDescriptor* method, Printer* out) {
69  const Descriptor* input_type = method->input_type();
70  const Descriptor* output_type = method->output_type();
71  map<std::string, std::string> vars;
72  vars["service_name"] = method->service()->full_name();
73  vars["name"] = method->name();
74  vars["input_type_id"] =
75  MessageIdentifierName(GeneratedClassName(input_type), input_type->file());
76  vars["output_type_id"] = MessageIdentifierName(
77  GeneratedClassName(output_type), output_type->file());
78 
79  out->Print("/**\n");
80  out->Print(GetPHPComments(method, " *").c_str());
81  if (method->client_streaming()) {
82  if (method->server_streaming()) {
83  vars["return_type_id"] = "\\Grpc\\BidiStreamingCall";
84  } else {
85  vars["return_type_id"] = "\\Grpc\\ClientStreamingCall";
86  }
87  out->Print(vars,
88  " * @param array $$metadata metadata\n"
89  " * @param array $$options call options\n"
90  " * @return $return_type_id$\n */\n"
91  "public function $name$($$metadata = [], "
92  "$$options = []) {\n");
93  out->Indent();
94  out->Indent();
95  if (method->server_streaming()) {
96  out->Print("return $$this->_bidiRequest(");
97  } else {
98  out->Print("return $$this->_clientStreamRequest(");
99  }
100  out->Print(vars,
101  "'/$service_name$/$name$',\n"
102  "['\\$output_type_id$','decode'],\n"
103  "$$metadata, $$options);\n");
104  } else {
105  if (method->server_streaming()) {
106  vars["return_type_id"] = "\\Grpc\\ServerStreamingCall";
107  } else {
108  vars["return_type_id"] = "\\Grpc\\UnaryCall";
109  }
110  out->Print(vars,
111  " * @param \\$input_type_id$ $$argument input argument\n"
112  " * @param array $$metadata metadata\n"
113  " * @param array $$options call options\n"
114  " * @return $return_type_id$\n */\n"
115  "public function $name$(\\$input_type_id$ $$argument,\n"
116  " $$metadata = [], $$options = []) {\n");
117  out->Indent();
118  out->Indent();
119  if (method->server_streaming()) {
120  out->Print("return $$this->_serverStreamRequest(");
121  } else {
122  out->Print("return $$this->_simpleRequest(");
123  }
124  out->Print(vars,
125  "'/$service_name$/$name$',\n"
126  "$$argument,\n"
127  "['\\$output_type_id$', 'decode'],\n"
128  "$$metadata, $$options);\n");
129  }
130  out->Outdent();
131  out->Outdent();
132  out->Print("}\n\n");
133 }
134 
135 void PrintServerMethod(const MethodDescriptor* method, Printer* out) {
136  map<std::string, std::string> vars;
137  const Descriptor* input_type = method->input_type();
138  const Descriptor* output_type = method->output_type();
139  vars["service_name"] = method->service()->full_name();
140  vars["method_name"] = method->name();
141  vars["input_type_id"] =
142  MessageIdentifierName(GeneratedClassName(input_type), input_type->file());
143  vars["output_type_id"] = MessageIdentifierName(
144  GeneratedClassName(output_type), output_type->file());
145 
146  out->Print("/**\n");
147  out->Print(GetPHPComments(method, " *").c_str());
148 
149  const char* method_template;
150  if (method->client_streaming() && method->server_streaming()) {
151  method_template =
152  " * @param \\Grpc\\ServerCallReader $$reader read client request data "
153  "of \\$input_type_id$\n"
154  " * @param \\Grpc\\ServerCallWriter $$writer write response data of "
155  "\\$output_type_id$\n"
156  " * @param \\Grpc\\ServerContext $$context server request context\n"
157  " * @return void\n"
158  " */\n"
159  "public function $method_name$(\n"
160  " \\Grpc\\ServerCallReader $$reader,\n"
161  " \\Grpc\\ServerCallWriter $$writer,\n"
162  " \\Grpc\\ServerContext $$context\n"
163  "): void {\n"
164  " $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
165  " $$writer->finish();\n"
166  "}\n\n";
167  } else if (method->client_streaming()) {
168  method_template =
169  " * @param \\Grpc\\ServerCallReader $$reader read client request data "
170  "of \\$input_type_id$\n"
171  " * @param \\Grpc\\ServerContext $$context server request context\n"
172  " * @return \\$output_type_id$ for response data, null if if error "
173  "occured\n"
174  " * initial metadata (if any) and status (if not ok) should be set "
175  "to $$context\n"
176  " */\n"
177  "public function $method_name$(\n"
178  " \\Grpc\\ServerCallReader $$reader,\n"
179  " \\Grpc\\ServerContext $$context\n"
180  "): ?\\$output_type_id$ {\n"
181  " $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
182  " return null;\n"
183  "}\n\n";
184  } else if (method->server_streaming()) {
185  method_template =
186  " * @param \\$input_type_id$ $$request client request\n"
187  " * @param \\Grpc\\ServerCallWriter $$writer write response data of "
188  "\\$output_type_id$\n"
189  " * @param \\Grpc\\ServerContext $$context server request context\n"
190  " * @return void\n"
191  " */\n"
192  "public function $method_name$(\n"
193  " \\$input_type_id$ $$request,\n"
194  " \\Grpc\\ServerCallWriter $$writer,\n"
195  " \\Grpc\\ServerContext $$context\n"
196  "): void {\n"
197  " $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
198  " $$writer->finish();\n"
199  "}\n\n";
200  } else {
201  method_template =
202  " * @param \\$input_type_id$ $$request client request\n"
203  " * @param \\Grpc\\ServerContext $$context server request context\n"
204  " * @return \\$output_type_id$ for response data, null if if error "
205  "occured\n"
206  " * initial metadata (if any) and status (if not ok) should be set "
207  "to $$context\n"
208  " */\n"
209  "public function $method_name$(\n"
210  " \\$input_type_id$ $$request,\n"
211  " \\Grpc\\ServerContext $$context\n"
212  "): ?\\$output_type_id$ {\n"
213  " $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
214  " return null;\n"
215  "}\n\n";
216  }
217  out->Print(vars, method_template);
218 }
219 
220 void PrintServerMethodDescriptors(const ServiceDescriptor* service,
221  Printer* out) {
222  map<std::string, std::string> vars;
223  vars["service_name"] = service->full_name();
224 
225  out->Print(
226  "/**\n"
227  " * Get the method descriptors of the service for server registration\n"
228  " *\n"
229  " * @return array of \\Grpc\\MethodDescriptor for the service methods\n"
230  " */\n"
231  "public final function getMethodDescriptors(): array\n{\n");
232  out->Indent();
233  out->Indent();
234  out->Print("return [\n");
235  out->Indent();
236  out->Indent();
237  for (int i = 0; i < service->method_count(); i++) {
238  auto method = service->method(i);
239  auto input_type = method->input_type();
240  vars["method_name"] = method->name();
241  vars["input_type_id"] = MessageIdentifierName(
242  GeneratedClassName(input_type), input_type->file());
243  if (method->client_streaming() && method->server_streaming()) {
244  vars["call_type"] = "BIDI_STREAMING_CALL";
245  } else if (method->client_streaming()) {
246  vars["call_type"] = "CLIENT_STREAMING_CALL";
247  } else if (method->server_streaming()) {
248  vars["call_type"] = "SERVER_STREAMING_CALL";
249  } else {
250  vars["call_type"] = "UNARY_CALL";
251  }
252  out->Print(
253  vars,
254  "'/$service_name$/$method_name$' => new \\Grpc\\MethodDescriptor(\n"
255  " $$this,\n"
256  " '$method_name$',\n"
257  " '\\$input_type_id$',\n"
258  " \\Grpc\\MethodDescriptor::$call_type$\n"
259  "),\n");
260  }
261  out->Outdent();
262  out->Outdent();
263  out->Print("];\n");
264  out->Outdent();
265  out->Outdent();
266  out->Print("}\n\n");
267 }
268 
269 // Prints out the service descriptor object
270 void PrintService(const ServiceDescriptor* service,
271  const std::string& class_suffix, bool is_server,
272  Printer* out) {
273  map<std::string, std::string> vars;
274  out->Print("/**\n");
275  out->Print(GetPHPComments(service, " *").c_str());
276  out->Print(" */\n");
277  vars["name"] = GetPHPServiceClassname(service, class_suffix, is_server);
278  vars["extends"] = is_server ? "" : "extends \\Grpc\\BaseStub ";
279  out->Print(vars, "class $name$ $extends${\n\n");
280  out->Indent();
281  out->Indent();
282  if (!is_server) {
283  out->Print(
284  "/**\n * @param string $$hostname hostname\n"
285  " * @param array $$opts channel options\n"
286  " * @param \\Grpc\\Channel $$channel (optional) re-use channel object\n"
287  " */\n"
288  "public function __construct($$hostname, $$opts, "
289  "$$channel = null) {\n");
290  out->Indent();
291  out->Indent();
292  out->Print("parent::__construct($$hostname, $$opts, $$channel);\n");
293  out->Outdent();
294  out->Outdent();
295  out->Print("}\n\n");
296  }
297  for (int i = 0; i < service->method_count(); i++) {
298  if (is_server) {
299  PrintServerMethod(service->method(i), out);
300  } else {
301  PrintMethod(service->method(i), out);
302  }
303  }
304  if (is_server) {
305  PrintServerMethodDescriptors(service, out);
306  }
307  out->Outdent();
308  out->Outdent();
309  out->Print("}\n");
310 }
311 } // namespace
312 
314  const ServiceDescriptor* service,
315  const std::string& class_suffix, bool is_server) {
317  {
318  StringOutputStream output_stream(&output);
319  Printer out(&output_stream, '$');
320 
321  out.Print("<?php\n");
322  out.Print("// GENERATED CODE -- DO NOT EDIT!\n\n");
323 
324  std::string leading_comments = GetPHPComments(file, "//");
325  if (!leading_comments.empty()) {
326  out.Print("// Original file comments:\n");
327  out.PrintRaw(leading_comments.c_str());
328  }
329 
330  map<std::string, std::string> vars;
331  std::string php_namespace = PackageName(file);
332  vars["package"] = php_namespace;
333  out.Print(vars, "namespace $package$;\n\n");
334 
335  PrintService(service, class_suffix, is_server, &out);
336  }
337  return output;
338 }
339 
340 } // namespace grpc_php_generator
grpc_php_generator::GetPHPServiceClassname
std::string GetPHPServiceClassname(const grpc::protobuf::ServiceDescriptor *service, const std::string &class_suffix, bool is_server)
Definition: php_generator_helpers.h:29
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
google::protobuf::compiler::php::GeneratedClassName
std::string GeneratedClassName(const Descriptor *desc)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/compiler/php/php_generator.cc:179
grpc_php_generator::GetPHPComments
std::string GetPHPComments(const DescriptorType *desc, std::string prefix)
Definition: php_generator_helpers.h:70
grpc::protobuf::FileDescriptor
GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:85
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
grpc_php_generator::GenerateFile
std::string GenerateFile(const FileDescriptor *file, const ServiceDescriptor *service, const std::string &class_suffix, bool is_server)
Definition: src/compiler/php_generator.cc:313
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
grpc::protobuf::io::Printer
GRPC_CUSTOM_PRINTER Printer
Definition: src/compiler/config.h:54
setup.name
name
Definition: setup.py:542
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
grpc_generator::tokenize
std::vector< std::string > tokenize(const std::string &input, const std::string &delimiters)
Definition: generator_helpers.h:82
Descriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:121
php_generator_helpers.h
grpc::protobuf::io::StringOutputStream
GRPC_CUSTOM_STRINGOUTPUTSTREAM StringOutputStream
Definition: src/compiler/config.h:56
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
grpc_generator::CapitalizeFirstLetter
std::string CapitalizeFirstLetter(std::string s)
Definition: generator_helpers.h:102
grpc::protobuf::MethodDescriptor
GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:87
generator_helpers.h
grpc_php_generator
Definition: src/compiler/php_generator.cc:36
service
__attribute__((deprecated("Please use GRPCProtoMethod."))) @interface ProtoMethod NSString * service
Definition: ProtoMethod.h:25
grpc::protobuf::Descriptor
GRPC_CUSTOM_DESCRIPTOR Descriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:81
method
NSString * method
Definition: ProtoMethod.h:28
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 Thu Mar 13 2025 03:00:52