| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 | /* * * Copyright 2014, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * *     * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. *     * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. *     * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include <cctype>#include <string>#include <map>#include <vector>#include "src/compiler/ruby_generator.h"#include "src/compiler/ruby_generator_helpers-inl.h"#include "src/compiler/ruby_generator_map-inl.h"#include "src/compiler/ruby_generator_string-inl.h"#include <google/protobuf/io/printer.h>#include <google/protobuf/io/zero_copy_stream_impl_lite.h>#include <google/protobuf/descriptor.pb.h>#include <google/protobuf/descriptor.h>using google::protobuf::FileDescriptor;using google::protobuf::ServiceDescriptor;using google::protobuf::MethodDescriptor;using google::protobuf::io::Printer;using google::protobuf::io::StringOutputStream;using std::map;using std::vector;namespace grpc_ruby_generator {namespace {// Prints out the method using the ruby gRPC DSL.void PrintMethod(const MethodDescriptor *method, const std::string &package,                 Printer *out) {  std::string input_type = RubyTypeOf(method->input_type()->name(), package);  if (method->client_streaming()) {    input_type = "stream(" + input_type + ")";  }  std::string output_type = RubyTypeOf(method->output_type()->name(), package);  if (method->server_streaming()) {    output_type = "stream(" + output_type + ")";  }  std::map<std::string, std::string> method_vars = ListToDict({      "mth.name", method->name(), "input.type", input_type, "output.type",      output_type,  });  out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n");}// Prints out the service using the ruby gRPC DSL.void PrintService(const ServiceDescriptor *service, const std::string &package,                  Printer *out) {  if (service->method_count() == 0) {    return;  }  // Begin the service module  std::map<std::string, std::string> module_vars = ListToDict({      "module.name", CapitalizeFirst(service->name()),  });  out->Print(module_vars, "module $module.name$\n");  out->Indent();  // TODO(temiola): add documentation  std::string doc = "TODO: add proto service documentation here";  std::map<std::string, std::string> template_vars = ListToDict({      "Documentation", doc,  });  out->Print("\n");  out->Print(template_vars, "# $Documentation$\n");  out->Print("class Service\n");  // Write the indented class body.  out->Indent();  out->Print("\n");  out->Print("include GRPC::GenericService\n");  out->Print("\n");  out->Print("self.marshal_class_method = :encode\n");  out->Print("self.unmarshal_class_method = :decode\n");  std::map<std::string, std::string> pkg_vars = ListToDict({      "service.name", service->name(), "pkg.name", package,  });  out->Print(pkg_vars, "self.service_name = '$pkg.name$.$service.name$'\n");  out->Print("\n");  for (int i = 0; i < service->method_count(); ++i) {    PrintMethod(service->method(i), package, out);  }  out->Outdent();  out->Print("end\n");  out->Print("\n");  out->Print("Stub = Service.rpc_stub_class\n");  // End the service module  out->Outdent();  out->Print("end\n");}}  // namespacestd::string GetServices(const FileDescriptor *file) {  std::string output;  StringOutputStream output_stream(&output);  Printer out(&output_stream, '$');  // Don't write out any output if there no services, to avoid empty service  // files being generated for proto files that don't declare any.  if (file->service_count() == 0) {    return output;  }  // Write out a file header.  std::map<std::string, std::string> header_comment_vars = ListToDict({      "file.name", file->name(), "file.package", file->package(),  });  out.Print("# Generated by the protocol buffer compiler.  DO NOT EDIT!\n");  out.Print(header_comment_vars,            "# Source: $file.name$ for package '$file.package$'\n");  out.Print("\n");  out.Print("require 'grpc'\n");  // Write out require statemment to import the separately generated file  // that defines the messages used by the service. This is generated by the  // main ruby plugin.  std::map<std::string, std::string> dep_vars = ListToDict({      "dep.name", MessagesRequireName(file),  });  out.Print(dep_vars, "require '$dep.name$'\n");  // Write out services within the modules  out.Print("\n");  std::vector<std::string> modules = Split(file->package(), '.');  for (size_t i = 0; i < modules.size(); ++i) {    std::map<std::string, std::string> module_vars = ListToDict({        "module.name", CapitalizeFirst(modules[i]),    });    out.Print(module_vars, "module $module.name$\n");    out.Indent();  }  for (int i = 0; i < file->service_count(); ++i) {    auto service = file->service(i);    PrintService(service, file->package(), &out);  }  for (size_t i = 0; i < modules.size(); ++i) {    out.Outdent();    out.Print("end\n");  }  return output;}}  // namespace grpc_ruby_generator
 |