148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen/*
248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * Copyright 2014 Google Inc. All rights reserved.
348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen *
448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * Licensed under the Apache License, Version 2.0 (the "License");
548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * you may not use this file except in compliance with the License.
648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * You may obtain a copy of the License at
748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen *
848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen *     http://www.apache.org/licenses/LICENSE-2.0
948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen *
1048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * Unless required by applicable law or agreed to in writing, software
1148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * distributed under the License is distributed on an "AS IS" BASIS,
1248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * See the License for the specific language governing permissions and
1448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen * limitations under the License.
1548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen */
1648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
1748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen// independent from idl_parser, since this code is not needed for most clients
1848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
1948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen#include "flatbuffers/flatbuffers.h"
2048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen#include "flatbuffers/idl.h"
2148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen#include "flatbuffers/util.h"
22a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain#include "flatbuffers/code_generators.h"
2348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
2448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen#include "src/compiler/cpp_generator.h"
25a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain#include "src/compiler/go_generator.h"
2648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
2748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssennamespace flatbuffers {
2848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
292e7806ede0ed83a615894002897031cfab426e44Harsh Vardhanclass FlatBufMethod : public grpc_generator::Method {
3048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen public:
3148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  enum Streaming { kNone, kClient, kServer, kBiDi };
3248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
3348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  FlatBufMethod(const RPCCall *method)
3448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    : method_(method) {
3548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    streaming_ = kNone;
3648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    auto val = method_->attributes.Lookup("streaming");
3748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    if (val) {
3848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      if (val->constant == "client") streaming_ = kClient;
3948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      if (val->constant == "server") streaming_ = kServer;
4048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      if (val->constant == "bidi") streaming_ = kBiDi;
4148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    }
4248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
4348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
4448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string name() const { return method_->name; }
4548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
4648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string GRPCType(const StructDef &sd) const {
4748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return "flatbuffers::BufferRef<" + sd.name + ">";
4848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
4948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
5048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string input_type_name() const {
5148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return GRPCType(*method_->request);
5248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
5348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string output_type_name() const {
5448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return GRPCType(*method_->response);
5548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
5648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
57a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  std::string input_name() const {
58a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    return (*method_->request).name;
59a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  }
60a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain
61a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  std::string output_name() const {
62a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    return (*method_->response).name;
63a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  }
64a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain
6548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  bool NoStreaming() const { return streaming_ == kNone; }
6648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  bool ClientOnlyStreaming() const { return streaming_ == kClient; }
6748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  bool ServerOnlyStreaming() const { return streaming_ == kServer; }
6848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  bool BidiStreaming() const { return streaming_ == kBiDi; }
6948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
7048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen private:
7148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  const RPCCall *method_;
7248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  Streaming streaming_;
7348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen};
7448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
752e7806ede0ed83a615894002897031cfab426e44Harsh Vardhanclass FlatBufService : public grpc_generator::Service {
7648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen public:
7748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  FlatBufService(const ServiceDef *service) : service_(service) {}
7848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
7948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string name() const { return service_->name; }
8048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
8148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  int method_count() const {
8248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return static_cast<int>(service_->calls.vec.size());
8348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  };
8448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
852e7806ede0ed83a615894002897031cfab426e44Harsh Vardhan  std::unique_ptr<const grpc_generator::Method> method(int i) const {
862e7806ede0ed83a615894002897031cfab426e44Harsh Vardhan    return std::unique_ptr<const grpc_generator::Method>(
8748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen          new FlatBufMethod(service_->calls.vec[i]));
8848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  };
8948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
9048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen private:
9148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  const ServiceDef *service_;
9248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen};
9348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
942e7806ede0ed83a615894002897031cfab426e44Harsh Vardhanclass FlatBufPrinter : public grpc_generator::Printer {
9548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen public:
9648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  FlatBufPrinter(std::string *str)
9748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    : str_(str), escape_char_('$'), indent_(0) {}
9848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
9948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  void Print(const std::map<std::string, std::string> &vars,
10048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen             const char *string_template) {
10148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    std::string s = string_template;
10248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    // Replace any occurrences of strings in "vars" that are surrounded
10348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    // by the escape character by what they're mapped to.
10448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    size_t pos;
10548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    while ((pos = s.find(escape_char_)) != std::string::npos) {
10648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      // Found an escape char, must also find the closing one.
10748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      size_t pos2 = s.find(escape_char_, pos + 1);
10848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      // If placeholder not closed, ignore.
10948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      if (pos2 == std::string::npos) break;
11048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      auto it = vars.find(s.substr(pos + 1, pos2 - pos - 1));
11148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      // If unknown placeholder, ignore.
11248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      if (it == vars.end()) break;
11348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      // Subtitute placeholder.
11448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      s.replace(pos, pos2 - pos + 1, it->second);
11548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    }
11648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    Print(s.c_str());
11748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
11848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
11948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  void Print(const char *s) {
12048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    // Add this string, but for each part separated by \n, add indentation.
12148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    for (;;) {
12248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      // Current indentation.
12348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      str_->insert(str_->end(), indent_ * 2, ' ');
12448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      // See if this contains more than one line.
1255ea2b49f58462728a895bc61ba290f16bed220d3吴凡      const char * lf = strchr(s, '\n');
12648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      if (lf) {
12748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen        (*str_) += std::string(s, lf + 1);
12848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen        s = lf + 1;
12948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen        if (!*s) break;  // Only continue if there's more lines.
13048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      } else {
13148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen        (*str_) += s;
13248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen        break;
13348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      }
13448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    }
13548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
13648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
13748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  void Indent() { indent_++; }
13848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  void Outdent() { indent_--; assert(indent_ >= 0); }
13948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
14048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen private:
14148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string *str_;
14248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  char escape_char_;
14348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  int indent_;
14448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen};
14548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
1462e7806ede0ed83a615894002897031cfab426e44Harsh Vardhanclass FlatBufFile : public grpc_generator::File {
14748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen public:
14848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  FlatBufFile(const Parser &parser, const std::string &file_name)
14948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    : parser_(parser), file_name_(file_name) {}
150ce3e7fbd72191da6602e910818c46018df08a515Wouter van Oortmerssen  FlatBufFile &operator=(const FlatBufFile &);
15148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
15248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string filename() const { return file_name_; }
15348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string filename_without_ext() const {
15448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return StripExtension(file_name_);
15548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
15648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
15748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string message_header_ext() const { return "_generated.h"; }
15848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string service_header_ext() const { return ".grpc.fb.h"; }
15948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
16048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string package() const {
16148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return parser_.namespaces_.back()->GetFullyQualifiedName("");
16248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
16348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
16448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::vector<std::string> package_parts() const {
16548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return parser_.namespaces_.back()->components;
16648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
16748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
16848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string additional_headers() const {
16948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return "#include \"flatbuffers/grpc.h\"\n";
17048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
17148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
172a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  std::string additional_imports() const {
173a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    return "import \"github.com/google/flatbuffers/go\"";
174a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  }
175a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain
17648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  int service_count() const {
17748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    return static_cast<int>(parser_.services_.vec.size());
17848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  };
17948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
1802e7806ede0ed83a615894002897031cfab426e44Harsh Vardhan  std::unique_ptr<const grpc_generator::Service> service(int i) const {
1812e7806ede0ed83a615894002897031cfab426e44Harsh Vardhan    return std::unique_ptr<const grpc_generator::Service> (
18248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen          new FlatBufService(parser_.services_.vec[i]));
18348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
18448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
1852e7806ede0ed83a615894002897031cfab426e44Harsh Vardhan  std::unique_ptr<grpc_generator::Printer> CreatePrinter(std::string *str) const {
1862e7806ede0ed83a615894002897031cfab426e44Harsh Vardhan    return std::unique_ptr<grpc_generator::Printer>(
18748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen          new FlatBufPrinter(str));
18848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
18948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
19048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen private:
19148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  const Parser &parser_;
19248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  const std::string &file_name_;
19348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen};
19448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
195a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jainclass GoGRPCGenerator : public flatbuffers::BaseGenerator {
196a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain public:
197a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  GoGRPCGenerator(const Parser &parser, const std::string &path,
198a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain                  const std::string &file_name)
199a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    : BaseGenerator(parser, path, file_name, "", "" /*Unused*/),
200a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain      parser_(parser), path_(path), file_name_(file_name) {}
201a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain
202a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  bool generate() {
203a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    FlatBufFile file(parser_, file_name_);
204a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    grpc_go_generator::Parameters p;
205a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    p.custom_method_io_type = "flatbuffers.Builder";
206a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    for (int i = 0; i < file.service_count(); i++) {
207a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain      auto service = file.service(i);
208a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain      const Definition *def = parser_.services_.vec[i];
209a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain      p.package_name = LastNamespacePart(*(def->defined_namespace));
210a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain      std::string output = grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
211a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain      std::string filename = NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go";
212a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain      if (!flatbuffers::SaveFile(filename.c_str(), output, false))
213a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain        return false;
214a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    }
215a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    return true;
216a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  }
217a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain
218a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain protected:
219a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  const Parser &parser_;
220a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  const std::string &path_, &file_name_;
221a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain};
222a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain
223a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jainbool GenerateGoGRPC(const Parser &parser,
224a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain                    const std::string &path,
225a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain                    const std::string &file_name) {
226a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  int nservices = 0;
227a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  for (auto it = parser.services_.vec.begin();
228a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain       it != parser.services_.vec.end(); ++it) {
229a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain    if (!(*it)->generated) nservices++;
230a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  }
231a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  if (!nservices) return true;
232a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain  return GoGRPCGenerator(parser, path, file_name).generate();
233a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain}
234a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jain
235a31ddd2bb38f719996137c9c35bc702f2abaefa5Ronak Jainbool GenerateCppGRPC(const Parser &parser,
23648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen                  const std::string &/*path*/,
23748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen                  const std::string &file_name) {
23848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
23948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  int nservices = 0;
24048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  for (auto it = parser.services_.vec.begin();
24148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen       it != parser.services_.vec.end(); ++it) {
24248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen    if (!(*it)->generated) nservices++;
24348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  }
24448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  if (!nservices) return true;
24548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
24648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  grpc_cpp_generator::Parameters generator_parameters;
24748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  // TODO(wvo): make the other parameters in this struct configurable.
24848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  generator_parameters.use_system_headers = true;
24948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
25048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  FlatBufFile fbfile(parser, file_name);
25148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
25248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string header_code =
25348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) +
25448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) +
25548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) +
25648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters);
25748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
25848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  std::string source_code =
25948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) +
26048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) +
26148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
26248f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen      grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
26348f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
26448f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen  return flatbuffers::SaveFile((file_name + ".grpc.fb.h").c_str(),
26548f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen                               header_code, false) &&
26648f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen         flatbuffers::SaveFile((file_name + ".grpc.fb.cc").c_str(),
26748f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen                               source_code, false);
26848f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen}
26948f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
27048f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen}  // namespace flatbuffers
27148f37f9e0a04f2b60046dda7fef20a8b0ebc1a70Wouter van Oortmerssen
272