| Index: third_party/grpc/src/compiler/ruby_generator.cc
|
| diff --git a/third_party/grpc/src/compiler/ruby_generator.cc b/third_party/grpc/src/compiler/ruby_generator.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..299137519f8d4517cda22756f043f77d552e7b73
|
| --- /dev/null
|
| +++ b/third_party/grpc/src/compiler/ruby_generator.cc
|
| @@ -0,0 +1,171 @@
|
| +/*
|
| + *
|
| + * Copyright 2015, 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 <map>
|
| +#include <vector>
|
| +
|
| +#include "src/compiler/config.h"
|
| +#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"
|
| +
|
| +using grpc::protobuf::FileDescriptor;
|
| +using grpc::protobuf::ServiceDescriptor;
|
| +using grpc::protobuf::MethodDescriptor;
|
| +using grpc::protobuf::io::Printer;
|
| +using grpc::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 grpc::string &package,
|
| + Printer *out) {
|
| + grpc::string input_type = RubyTypeOf(method->input_type()->name(), package);
|
| + if (method->client_streaming()) {
|
| + input_type = "stream(" + input_type + ")";
|
| + }
|
| + grpc::string output_type = RubyTypeOf(method->output_type()->name(), package);
|
| + if (method->server_streaming()) {
|
| + output_type = "stream(" + output_type + ")";
|
| + }
|
| + std::map<grpc::string, grpc::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 grpc::string &package,
|
| + Printer *out) {
|
| + if (service->method_count() == 0) {
|
| + return;
|
| + }
|
| +
|
| + // Begin the service module
|
| + std::map<grpc::string, grpc::string> module_vars =
|
| + ListToDict({"module.name", CapitalizeFirst(service->name()), });
|
| + out->Print(module_vars, "module $module.name$\n");
|
| + out->Indent();
|
| +
|
| + // TODO(temiola): add documentation
|
| + grpc::string doc = "TODO: add proto service documentation here";
|
| + std::map<grpc::string, grpc::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<grpc::string, grpc::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");
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +grpc::string GetServices(const FileDescriptor *file) {
|
| + grpc::string output;
|
| + {
|
| + // Scope the output stream so it closes and finalizes output to the string.
|
| +
|
| + 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<grpc::string, grpc::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<grpc::string, grpc::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<grpc::string> modules = Split(file->package(), '.');
|
| + for (size_t i = 0; i < modules.size(); ++i) {
|
| + std::map<grpc::string, grpc::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
|
|
|