Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2014 Google Inc. All rights reserved. |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | // independent from idl_parser, since this code is not needed for most clients |
| 18 | |
| 19 | #include "flatbuffers/code_generators.h" |
| 20 | #include "flatbuffers/flatbuffers.h" |
| 21 | #include "flatbuffers/idl.h" |
| 22 | #include "flatbuffers/util.h" |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 23 | #include "src/compiler/cpp_generator.h" |
| 24 | #include "src/compiler/go_generator.h" |
| 25 | #include "src/compiler/java_generator.h" |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 26 | #include "src/compiler/python_generator.h" |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 27 | #include "src/compiler/swift_generator.h" |
| 28 | #include "src/compiler/ts_generator.h" |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 29 | |
| 30 | #if defined(_MSC_VER) |
| 31 | # pragma warning(push) |
| 32 | # pragma warning(disable : 4512) // C4512: 'class' : assignment operator could |
| 33 | // not be generated |
| 34 | #endif |
| 35 | |
| 36 | namespace flatbuffers { |
| 37 | |
| 38 | class FlatBufMethod : public grpc_generator::Method { |
| 39 | public: |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 40 | enum Streaming { kNone, kClient, kServer, kBiDi }; |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 41 | |
| 42 | FlatBufMethod(const RPCCall *method) : method_(method) { |
| 43 | streaming_ = kNone; |
| 44 | auto val = method_->attributes.Lookup("streaming"); |
| 45 | if (val) { |
| 46 | if (val->constant == "client") streaming_ = kClient; |
| 47 | if (val->constant == "server") streaming_ = kServer; |
| 48 | if (val->constant == "bidi") streaming_ = kBiDi; |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | grpc::string GetLeadingComments(const grpc::string) const { return ""; } |
| 53 | |
| 54 | grpc::string GetTrailingComments(const grpc::string) const { return ""; } |
| 55 | |
| 56 | std::vector<grpc::string> GetAllComments() const { |
| 57 | return method_->doc_comment; |
| 58 | } |
| 59 | |
| 60 | std::string name() const { return method_->name; } |
| 61 | |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 62 | // TODO: This method need to incorporate namespace for C++ side. Other |
| 63 | // language bindings simply don't use this method. |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 64 | std::string GRPCType(const StructDef &sd) const { |
| 65 | return "flatbuffers::grpc::Message<" + sd.name + ">"; |
| 66 | } |
| 67 | |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 68 | std::vector<std::string> get_input_namespace_parts() const { |
| 69 | return (*method_->request).defined_namespace->components; |
| 70 | } |
| 71 | |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 72 | std::string get_input_type_name() const { return (*method_->request).name; } |
| 73 | |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 74 | std::vector<std::string> get_output_namespace_parts() const { |
| 75 | return (*method_->response).defined_namespace->components; |
| 76 | } |
| 77 | |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 78 | std::string get_output_type_name() const { return (*method_->response).name; } |
| 79 | |
| 80 | bool get_module_and_message_path_input(grpc::string * /*str*/, |
| 81 | grpc::string /*generator_file_name*/, |
| 82 | bool /*generate_in_pb2_grpc*/, |
| 83 | grpc::string /*import_prefix*/) const { |
| 84 | return true; |
| 85 | } |
| 86 | |
| 87 | bool get_module_and_message_path_output( |
| 88 | grpc::string * /*str*/, grpc::string /*generator_file_name*/, |
| 89 | bool /*generate_in_pb2_grpc*/, grpc::string /*import_prefix*/) const { |
| 90 | return true; |
| 91 | } |
| 92 | |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 93 | std::string get_fb_builder() const { return "builder"; } |
| 94 | |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 95 | std::string input_type_name() const { return GRPCType(*method_->request); } |
| 96 | |
| 97 | std::string output_type_name() const { return GRPCType(*method_->response); } |
| 98 | |
| 99 | bool NoStreaming() const { return streaming_ == kNone; } |
| 100 | |
| 101 | bool ClientStreaming() const { return streaming_ == kClient; } |
| 102 | |
| 103 | bool ServerStreaming() const { return streaming_ == kServer; } |
| 104 | |
| 105 | bool BidiStreaming() const { return streaming_ == kBiDi; } |
| 106 | |
| 107 | private: |
| 108 | const RPCCall *method_; |
| 109 | Streaming streaming_; |
| 110 | }; |
| 111 | |
| 112 | class FlatBufService : public grpc_generator::Service { |
| 113 | public: |
| 114 | FlatBufService(const ServiceDef *service) : service_(service) {} |
| 115 | |
| 116 | grpc::string GetLeadingComments(const grpc::string) const { return ""; } |
| 117 | |
| 118 | grpc::string GetTrailingComments(const grpc::string) const { return ""; } |
| 119 | |
| 120 | std::vector<grpc::string> GetAllComments() const { |
| 121 | return service_->doc_comment; |
| 122 | } |
| 123 | |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 124 | std::vector<grpc::string> namespace_parts() const { |
| 125 | return service_->defined_namespace->components; |
| 126 | } |
| 127 | |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 128 | std::string name() const { return service_->name; } |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 129 | bool is_internal() const { |
| 130 | return service_->Definition::attributes.Lookup("private") ? true : false; |
| 131 | } |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 132 | |
| 133 | int method_count() const { |
| 134 | return static_cast<int>(service_->calls.vec.size()); |
| 135 | } |
| 136 | |
| 137 | std::unique_ptr<const grpc_generator::Method> method(int i) const { |
| 138 | return std::unique_ptr<const grpc_generator::Method>( |
| 139 | new FlatBufMethod(service_->calls.vec[i])); |
| 140 | } |
| 141 | |
| 142 | private: |
| 143 | const ServiceDef *service_; |
| 144 | }; |
| 145 | |
| 146 | class FlatBufPrinter : public grpc_generator::Printer { |
| 147 | public: |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 148 | FlatBufPrinter(std::string *str, const char indentation_type) |
| 149 | : str_(str), |
| 150 | escape_char_('$'), |
| 151 | indent_(0), |
| 152 | indentation_size_(2), |
| 153 | indentation_type_(indentation_type) {} |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 154 | |
| 155 | void Print(const std::map<std::string, std::string> &vars, |
| 156 | const char *string_template) { |
| 157 | std::string s = string_template; |
| 158 | // Replace any occurrences of strings in "vars" that are surrounded |
| 159 | // by the escape character by what they're mapped to. |
| 160 | size_t pos; |
| 161 | while ((pos = s.find(escape_char_)) != std::string::npos) { |
| 162 | // Found an escape char, must also find the closing one. |
| 163 | size_t pos2 = s.find(escape_char_, pos + 1); |
| 164 | // If placeholder not closed, ignore. |
| 165 | if (pos2 == std::string::npos) break; |
| 166 | auto it = vars.find(s.substr(pos + 1, pos2 - pos - 1)); |
| 167 | // If unknown placeholder, ignore. |
| 168 | if (it == vars.end()) break; |
| 169 | // Subtitute placeholder. |
| 170 | s.replace(pos, pos2 - pos + 1, it->second); |
| 171 | } |
| 172 | Print(s.c_str()); |
| 173 | } |
| 174 | |
| 175 | void Print(const char *s) { |
| 176 | if (s == nullptr || *s == '\0') { return; } |
| 177 | // Add this string, but for each part separated by \n, add indentation. |
| 178 | for (;;) { |
| 179 | // Current indentation. |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 180 | str_->insert(str_->end(), indent_ * indentation_size_, indentation_type_); |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 181 | // See if this contains more than one line. |
| 182 | const char *lf = strchr(s, '\n'); |
| 183 | if (lf) { |
| 184 | (*str_) += std::string(s, lf + 1); |
| 185 | s = lf + 1; |
| 186 | if (!*s) break; // Only continue if there's more lines. |
| 187 | } else { |
| 188 | (*str_) += s; |
| 189 | break; |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 194 | void SetIndentationSize(const size_t size) { |
| 195 | FLATBUFFERS_ASSERT(str_->empty()); |
| 196 | indentation_size_ = size; |
| 197 | } |
| 198 | |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 199 | void Indent() { indent_++; } |
| 200 | |
| 201 | void Outdent() { |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 202 | FLATBUFFERS_ASSERT(indent_ > 0); |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 203 | indent_--; |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 204 | } |
| 205 | |
| 206 | private: |
| 207 | std::string *str_; |
| 208 | char escape_char_; |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 209 | size_t indent_; |
| 210 | size_t indentation_size_; |
| 211 | char indentation_type_; |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 212 | }; |
| 213 | |
| 214 | class FlatBufFile : public grpc_generator::File { |
| 215 | public: |
| 216 | enum Language { |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 217 | kLanguageGo, |
| 218 | kLanguageCpp, |
| 219 | kLanguageJava, |
| 220 | kLanguagePython, |
| 221 | kLanguageSwift, |
| 222 | kLanguageTS |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 223 | }; |
| 224 | |
| 225 | FlatBufFile(const Parser &parser, const std::string &file_name, |
| 226 | Language language) |
| 227 | : parser_(parser), file_name_(file_name), language_(language) {} |
| 228 | |
| 229 | FlatBufFile &operator=(const FlatBufFile &); |
| 230 | |
| 231 | grpc::string GetLeadingComments(const grpc::string) const { return ""; } |
| 232 | |
| 233 | grpc::string GetTrailingComments(const grpc::string) const { return ""; } |
| 234 | |
| 235 | std::vector<grpc::string> GetAllComments() const { |
| 236 | return std::vector<grpc::string>(); |
| 237 | } |
| 238 | |
| 239 | std::string filename() const { return file_name_; } |
| 240 | |
| 241 | std::string filename_without_ext() const { |
| 242 | return StripExtension(file_name_); |
| 243 | } |
| 244 | |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 245 | std::string message_header_ext() const { |
| 246 | return parser_.opts.filename_suffix + ".h"; |
| 247 | } |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 248 | |
| 249 | std::string service_header_ext() const { return ".grpc.fb.h"; } |
| 250 | |
| 251 | std::string package() const { |
| 252 | return parser_.current_namespace_->GetFullyQualifiedName(""); |
| 253 | } |
| 254 | |
| 255 | std::vector<std::string> package_parts() const { |
| 256 | return parser_.current_namespace_->components; |
| 257 | } |
| 258 | |
| 259 | std::string additional_headers() const { |
| 260 | switch (language_) { |
| 261 | case kLanguageCpp: { |
| 262 | return "#include \"flatbuffers/grpc.h\"\n"; |
| 263 | } |
| 264 | case kLanguageGo: { |
| 265 | return "import \"github.com/google/flatbuffers/go\""; |
| 266 | } |
| 267 | case kLanguageJava: { |
| 268 | return "import com.google.flatbuffers.grpc.FlatbuffersUtils;"; |
| 269 | } |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 270 | case kLanguagePython: { |
| 271 | return ""; |
| 272 | } |
| 273 | case kLanguageSwift: { |
| 274 | return ""; |
| 275 | } |
| 276 | case kLanguageTS: { |
| 277 | return ""; |
| 278 | } |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 279 | } |
| 280 | return ""; |
| 281 | } |
| 282 | |
| 283 | int service_count() const { |
| 284 | return static_cast<int>(parser_.services_.vec.size()); |
| 285 | } |
| 286 | |
| 287 | std::unique_ptr<const grpc_generator::Service> service(int i) const { |
| 288 | return std::unique_ptr<const grpc_generator::Service>( |
| 289 | new FlatBufService(parser_.services_.vec[i])); |
| 290 | } |
| 291 | |
| 292 | std::unique_ptr<grpc_generator::Printer> CreatePrinter( |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 293 | std::string *str, const char indentation_type = ' ') const { |
| 294 | return std::unique_ptr<grpc_generator::Printer>( |
| 295 | new FlatBufPrinter(str, indentation_type)); |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | private: |
| 299 | const Parser &parser_; |
| 300 | const std::string &file_name_; |
| 301 | const Language language_; |
| 302 | }; |
| 303 | |
| 304 | class GoGRPCGenerator : public flatbuffers::BaseGenerator { |
| 305 | public: |
| 306 | GoGRPCGenerator(const Parser &parser, const std::string &path, |
| 307 | const std::string &file_name) |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 308 | : BaseGenerator(parser, path, file_name, "", "" /*Unused*/, "go"), |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 309 | parser_(parser), |
| 310 | path_(path), |
| 311 | file_name_(file_name) {} |
| 312 | |
| 313 | bool generate() { |
| 314 | FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageGo); |
| 315 | grpc_go_generator::Parameters p; |
| 316 | p.custom_method_io_type = "flatbuffers.Builder"; |
| 317 | for (int i = 0; i < file.service_count(); i++) { |
| 318 | auto service = file.service(i); |
| 319 | const Definition *def = parser_.services_.vec[i]; |
| 320 | p.package_name = LastNamespacePart(*(def->defined_namespace)); |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 321 | p.service_prefix = |
| 322 | def->defined_namespace->GetFullyQualifiedName(""); // file.package(); |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 323 | std::string output = |
| 324 | grpc_go_generator::GenerateServiceSource(&file, service.get(), &p); |
| 325 | std::string filename = |
| 326 | NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go"; |
| 327 | if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false; |
| 328 | } |
| 329 | return true; |
| 330 | } |
| 331 | |
| 332 | protected: |
| 333 | const Parser &parser_; |
| 334 | const std::string &path_, &file_name_; |
| 335 | }; |
| 336 | |
| 337 | bool GenerateGoGRPC(const Parser &parser, const std::string &path, |
| 338 | const std::string &file_name) { |
| 339 | int nservices = 0; |
| 340 | for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); |
| 341 | ++it) { |
| 342 | if (!(*it)->generated) nservices++; |
| 343 | } |
| 344 | if (!nservices) return true; |
| 345 | return GoGRPCGenerator(parser, path, file_name).generate(); |
| 346 | } |
| 347 | |
| 348 | bool GenerateCppGRPC(const Parser &parser, const std::string &path, |
| 349 | const std::string &file_name) { |
| 350 | int nservices = 0; |
| 351 | for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); |
| 352 | ++it) { |
| 353 | if (!(*it)->generated) nservices++; |
| 354 | } |
| 355 | if (!nservices) return true; |
| 356 | |
| 357 | grpc_cpp_generator::Parameters generator_parameters; |
| 358 | // TODO(wvo): make the other parameters in this struct configurable. |
| 359 | generator_parameters.use_system_headers = true; |
| 360 | |
| 361 | FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguageCpp); |
| 362 | |
| 363 | std::string header_code = |
| 364 | grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) + |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 365 | grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) + |
| 366 | grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) + |
| 367 | grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters); |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 368 | |
| 369 | std::string source_code = |
| 370 | grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) + |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 371 | grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) + |
| 372 | grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) + |
| 373 | grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters); |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 374 | |
| 375 | return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(), |
| 376 | header_code, false) && |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 377 | flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(), |
| 378 | source_code, false); |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 379 | } |
| 380 | |
| 381 | class JavaGRPCGenerator : public flatbuffers::BaseGenerator { |
| 382 | public: |
| 383 | JavaGRPCGenerator(const Parser &parser, const std::string &path, |
| 384 | const std::string &file_name) |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 385 | : BaseGenerator(parser, path, file_name, "", "." /*separator*/, "java") {} |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 386 | |
| 387 | bool generate() { |
| 388 | FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava); |
| 389 | grpc_java_generator::Parameters p; |
| 390 | for (int i = 0; i < file.service_count(); i++) { |
| 391 | auto service = file.service(i); |
| 392 | const Definition *def = parser_.services_.vec[i]; |
| 393 | p.package_name = |
| 394 | def->defined_namespace->GetFullyQualifiedName(""); // file.package(); |
| 395 | std::string output = |
| 396 | grpc_java_generator::GenerateServiceSource(&file, service.get(), &p); |
| 397 | std::string filename = |
| 398 | NamespaceDir(*def->defined_namespace) + def->name + "Grpc.java"; |
| 399 | if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false; |
| 400 | } |
| 401 | return true; |
| 402 | } |
| 403 | }; |
| 404 | |
| 405 | bool GenerateJavaGRPC(const Parser &parser, const std::string &path, |
| 406 | const std::string &file_name) { |
| 407 | int nservices = 0; |
| 408 | for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); |
| 409 | ++it) { |
| 410 | if (!(*it)->generated) nservices++; |
| 411 | } |
| 412 | if (!nservices) return true; |
| 413 | return JavaGRPCGenerator(parser, path, file_name).generate(); |
| 414 | } |
| 415 | |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 416 | class PythonGRPCGenerator : public flatbuffers::BaseGenerator { |
| 417 | private: |
| 418 | CodeWriter code_; |
| 419 | |
| 420 | public: |
| 421 | PythonGRPCGenerator(const Parser &parser, const std::string &filename) |
| 422 | : BaseGenerator(parser, "", filename, "", "" /*Unused*/, "swift") {} |
| 423 | |
| 424 | bool generate() { |
| 425 | code_.Clear(); |
| 426 | code_ += |
| 427 | "# Generated by the gRPC Python protocol compiler plugin. " |
| 428 | "DO NOT EDIT!\n"; |
| 429 | code_ += "import grpc\n"; |
| 430 | |
| 431 | FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguagePython); |
| 432 | |
| 433 | for (int i = 0; i < file.service_count(); i++) { |
| 434 | auto service = file.service(i); |
| 435 | code_ += grpc_python_generator::Generate(&file, service.get()); |
| 436 | } |
| 437 | const auto final_code = code_.ToString(); |
| 438 | const auto filename = GenerateFileName(); |
| 439 | return SaveFile(filename.c_str(), final_code, false); |
| 440 | } |
| 441 | |
| 442 | std::string GenerateFileName() { |
| 443 | std::string namespace_dir; |
| 444 | auto &namespaces = parser_.namespaces_.back()->components; |
| 445 | for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { |
| 446 | if (it != namespaces.begin()) namespace_dir += kPathSeparator; |
| 447 | namespace_dir += *it; |
| 448 | } |
| 449 | std::string grpc_py_filename = namespace_dir; |
| 450 | if (!namespace_dir.empty()) grpc_py_filename += kPathSeparator; |
| 451 | return grpc_py_filename + file_name_ + "_grpc_fb.py"; |
| 452 | } |
| 453 | }; |
| 454 | |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 455 | bool GeneratePythonGRPC(const Parser &parser, const std::string & /*path*/, |
| 456 | const std::string &file_name) { |
| 457 | int nservices = 0; |
| 458 | for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); |
| 459 | ++it) { |
| 460 | if (!(*it)->generated) nservices++; |
| 461 | } |
| 462 | if (!nservices) return true; |
| 463 | |
James Kuszmaul | 8e62b02 | 2022-03-22 09:33:25 -0700 | [diff] [blame^] | 464 | return PythonGRPCGenerator(parser, file_name).generate(); |
Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame] | 465 | } |
| 466 | |
| 467 | class SwiftGRPCGenerator : public flatbuffers::BaseGenerator { |
| 468 | private: |
| 469 | CodeWriter code_; |
| 470 | |
| 471 | public: |
| 472 | SwiftGRPCGenerator(const Parser &parser, const std::string &path, |
| 473 | const std::string &filename) |
| 474 | : BaseGenerator(parser, path, filename, "", "" /*Unused*/, "swift") {} |
| 475 | |
| 476 | bool generate() { |
| 477 | code_.Clear(); |
| 478 | code_ += "// Generated GRPC code for FlatBuffers swift!"; |
| 479 | code_ += grpc_swift_generator::GenerateHeader(); |
| 480 | FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageSwift); |
| 481 | for (int i = 0; i < file.service_count(); i++) { |
| 482 | auto service = file.service(i); |
| 483 | code_ += grpc_swift_generator::Generate(&file, service.get()); |
| 484 | } |
| 485 | const auto final_code = code_.ToString(); |
| 486 | const auto filename = GeneratedFileName(path_, file_name_); |
| 487 | return SaveFile(filename.c_str(), final_code, false); |
| 488 | } |
| 489 | |
| 490 | static std::string GeneratedFileName(const std::string &path, |
| 491 | const std::string &file_name) { |
| 492 | return path + file_name + ".grpc.swift"; |
| 493 | } |
| 494 | }; |
| 495 | |
| 496 | bool GenerateSwiftGRPC(const Parser &parser, const std::string &path, |
| 497 | const std::string &file_name) { |
| 498 | int nservices = 0; |
| 499 | for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); |
| 500 | ++it) { |
| 501 | if (!(*it)->generated) nservices++; |
| 502 | } |
| 503 | if (!nservices) return true; |
| 504 | return SwiftGRPCGenerator(parser, path, file_name).generate(); |
| 505 | } |
| 506 | |
| 507 | class TSGRPCGenerator : public flatbuffers::BaseGenerator { |
| 508 | private: |
| 509 | CodeWriter code_; |
| 510 | |
| 511 | public: |
| 512 | TSGRPCGenerator(const Parser &parser, const std::string &path, |
| 513 | const std::string &filename) |
| 514 | : BaseGenerator(parser, path, filename, "", "" /*Unused*/, "ts") {} |
| 515 | |
| 516 | bool generate() { |
| 517 | code_.Clear(); |
| 518 | FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageTS); |
| 519 | |
| 520 | for (int i = 0; i < file.service_count(); i++) { |
| 521 | auto service = file.service(i); |
| 522 | code_ += grpc_ts_generator::Generate(&file, service.get(), file_name_); |
| 523 | const auto ts_name = GeneratedFileName(path_, file_name_); |
| 524 | if (!SaveFile(ts_name.c_str(), code_.ToString(), false)) return false; |
| 525 | |
| 526 | code_.Clear(); |
| 527 | code_ += grpc_ts_generator::GenerateInterface(&file, service.get(), |
| 528 | file_name_); |
| 529 | const auto ts_interface_name = GeneratedFileName(path_, file_name_, true); |
| 530 | if (!SaveFile(ts_interface_name.c_str(), code_.ToString(), false)) |
| 531 | return false; |
| 532 | } |
| 533 | return true; |
| 534 | } |
| 535 | |
| 536 | static std::string GeneratedFileName(const std::string &path, |
| 537 | const std::string &file_name, |
| 538 | const bool is_interface = false) { |
| 539 | if (is_interface) return path + file_name + "_grpc.d.ts"; |
| 540 | return path + file_name + "_grpc.js"; |
| 541 | } |
| 542 | }; |
| 543 | |
| 544 | bool GenerateTSGRPC(const Parser &parser, const std::string &path, |
| 545 | const std::string &file_name) { |
| 546 | int nservices = 0; |
| 547 | for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); |
| 548 | ++it) { |
| 549 | if (!(*it)->generated) nservices++; |
| 550 | } |
| 551 | if (!nservices) return true; |
| 552 | return TSGRPCGenerator(parser, path, file_name).generate(); |
| 553 | } |
| 554 | |
Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 555 | } // namespace flatbuffers |
| 556 | |
| 557 | #if defined(_MSC_VER) |
| 558 | # pragma warning(pop) |
| 559 | #endif |