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