Merge pull request #23 from iamqizhao/master
Revise codegen plugin to accommodate more cases and fix some bugs
This commit is contained in:
Коммит
801d1972f4
|
@ -42,6 +42,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
// TODO(zhaoq): Support go_package option.
|
||||
namespace grpc_go_generator {
|
||||
|
||||
bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
|
||||
|
@ -88,25 +89,42 @@ std::string BadToUnderscore(std::string str) {
|
|||
return str;
|
||||
}
|
||||
|
||||
const string GetFullName(const string& selfPkg,
|
||||
const string& msgPkg,
|
||||
const string& msgName) {
|
||||
if (selfPkg == msgPkg) {
|
||||
return msgName;
|
||||
string GenerateFullGoPackage(const google::protobuf::FileDescriptor* file) {
|
||||
// In opensouce environment, assume each directory has at most one package.
|
||||
size_t pos = file->name().find_last_of('/');
|
||||
if (pos != string::npos) {
|
||||
return file->name().substr(0, pos);
|
||||
}
|
||||
return BadToUnderscore(msgPkg) + "." + msgName;
|
||||
return "";
|
||||
}
|
||||
|
||||
const string GetFullMessageQualifiedName(
|
||||
const google::protobuf::Descriptor* desc,
|
||||
set<string>& imports,
|
||||
map<string, string>& import_alias) {
|
||||
string pkg = GenerateFullGoPackage(desc->file());
|
||||
if (imports.find(pkg) == imports.end()) {
|
||||
// The message is in the same package as the services definition.
|
||||
return desc->name();
|
||||
}
|
||||
if (import_alias.find(pkg) != import_alias.end()) {
|
||||
// The message is in a package whose name is as same as the one consisting
|
||||
// of the service definition. Use the alias to differentiate.
|
||||
return import_alias[pkg] + "." + desc->name();
|
||||
}
|
||||
return BadToUnderscore(desc->file()->package()) + "." + desc->name();
|
||||
}
|
||||
|
||||
void PrintClientMethodDef(google::protobuf::io::Printer* printer,
|
||||
const google::protobuf::MethodDescriptor* method,
|
||||
map<string, string>* vars) {
|
||||
map<string, string>* vars,
|
||||
set<string>& imports,
|
||||
map<string, string>& import_alias) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = GetFullName((*vars)["PackageName"],
|
||||
method->input_type()->file()->package(),
|
||||
method->input_type()->name());
|
||||
(*vars)["Response"] = GetFullName((*vars)["PackageName"],
|
||||
method->output_type()->file()->package(),
|
||||
method->output_type()->name());
|
||||
(*vars)["Request"] =
|
||||
GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
|
||||
(*vars)["Response"] =
|
||||
GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
|
||||
if (NoStreaming(method)) {
|
||||
printer->Print(*vars,
|
||||
"\t$Method$(ctx context.Context, in *$Request$, opts "
|
||||
|
@ -130,14 +148,14 @@ void PrintClientMethodDef(google::protobuf::io::Printer* printer,
|
|||
|
||||
void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
|
||||
const google::protobuf::MethodDescriptor* method,
|
||||
map<string, string>* vars) {
|
||||
map<string, string>* vars,
|
||||
set<string>& imports,
|
||||
map<string, string>& import_alias) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = GetFullName((*vars)["PackageName"],
|
||||
method->input_type()->file()->package(),
|
||||
method->input_type()->name());
|
||||
(*vars)["Response"] = GetFullName((*vars)["PackageName"],
|
||||
method->output_type()->file()->package(),
|
||||
method->output_type()->name());
|
||||
(*vars)["Request"] =
|
||||
GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
|
||||
(*vars)["Response"] =
|
||||
GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
|
||||
if (NoStreaming(method)) {
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -279,12 +297,14 @@ void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
|
|||
|
||||
void PrintClient(google::protobuf::io::Printer* printer,
|
||||
const google::protobuf::ServiceDescriptor* service,
|
||||
map<string, string>* vars) {
|
||||
map<string, string>* vars,
|
||||
set<string>& imports,
|
||||
map<string, string>& import_alias) {
|
||||
(*vars)["Service"] = service->name();
|
||||
(*vars)["ServiceStruct"] = LowerCaseService(service->name());
|
||||
printer->Print(*vars, "type $Service$Client interface {\n");
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
PrintClientMethodDef(printer, service->method(i), vars);
|
||||
PrintClientMethodDef(printer, service->method(i), vars, imports, import_alias);
|
||||
}
|
||||
printer->Print("}\n\n");
|
||||
|
||||
|
@ -298,20 +318,20 @@ void PrintClient(google::protobuf::io::Printer* printer,
|
|||
"\treturn &$ServiceStruct$Client{cc}\n"
|
||||
"}\n\n");
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
PrintClientMethodImpl(printer, service->method(i), vars);
|
||||
PrintClientMethodImpl(printer, service->method(i), vars, imports, import_alias);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintServerMethodDef(google::protobuf::io::Printer* printer,
|
||||
const google::protobuf::MethodDescriptor* method,
|
||||
map<string, string>* vars) {
|
||||
map<string, string>* vars,
|
||||
set<string>& imports,
|
||||
map<string, string>& import_alias) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = GetFullName((*vars)["PackageName"],
|
||||
method->input_type()->file()->package(),
|
||||
method->input_type()->name());
|
||||
(*vars)["Response"] = GetFullName((*vars)["PackageName"],
|
||||
method->output_type()->file()->package(),
|
||||
method->output_type()->name());
|
||||
(*vars)["Request"] =
|
||||
GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
|
||||
(*vars)["Response"] =
|
||||
GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
|
||||
if (NoStreaming(method)) {
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -328,14 +348,14 @@ void PrintServerMethodDef(google::protobuf::io::Printer* printer,
|
|||
|
||||
void PrintServerHandler(google::protobuf::io::Printer* printer,
|
||||
const google::protobuf::MethodDescriptor* method,
|
||||
map<string, string>* vars) {
|
||||
map<string, string>* vars,
|
||||
set<string>& imports,
|
||||
map<string, string>& import_alias) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = GetFullName((*vars)["PackageName"],
|
||||
method->input_type()->file()->package(),
|
||||
method->input_type()->name());
|
||||
(*vars)["Response"] = GetFullName((*vars)["PackageName"],
|
||||
method->output_type()->file()->package(),
|
||||
method->output_type()->name());
|
||||
(*vars)["Request"] =
|
||||
GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
|
||||
(*vars)["Response"] =
|
||||
GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
|
||||
if (NoStreaming(method)) {
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -473,11 +493,13 @@ void PrintServerStreamingMethodDesc(
|
|||
|
||||
void PrintServer(google::protobuf::io::Printer* printer,
|
||||
const google::protobuf::ServiceDescriptor* service,
|
||||
map<string, string>* vars) {
|
||||
map<string, string>* vars,
|
||||
set<string>& imports,
|
||||
map<string, string>& import_alias) {
|
||||
(*vars)["Service"] = service->name();
|
||||
printer->Print(*vars, "type $Service$Server interface {\n");
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
PrintServerMethodDef(printer, service->method(i), vars);
|
||||
PrintServerMethodDef(printer, service->method(i), vars, imports, import_alias);
|
||||
}
|
||||
printer->Print("}\n\n");
|
||||
|
||||
|
@ -487,7 +509,7 @@ void PrintServer(google::protobuf::io::Printer* printer,
|
|||
"}\n\n");
|
||||
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
PrintServerHandler(printer, service->method(i), vars);
|
||||
PrintServerHandler(printer, service->method(i), vars, imports, import_alias);
|
||||
}
|
||||
|
||||
printer->Print(*vars,
|
||||
|
@ -513,42 +535,53 @@ void PrintServer(google::protobuf::io::Printer* printer,
|
|||
"}\n\n");
|
||||
}
|
||||
|
||||
bool IsSelfImport(const google::protobuf::FileDescriptor* self,
|
||||
const google::protobuf::FileDescriptor* import) {
|
||||
if (GenerateFullGoPackage(self) == GenerateFullGoPackage(import)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrintMessageImports(
|
||||
google::protobuf::io::Printer* printer,
|
||||
const google::protobuf::FileDescriptor* file,
|
||||
map<string, string>* vars) {
|
||||
map<string, string>* vars,
|
||||
set<string>* imports,
|
||||
map<string, string>* import_alias) {
|
||||
set<const google::protobuf::FileDescriptor*> descs;
|
||||
set<string> importedPkgs;
|
||||
for (int i = 0; i < file->service_count(); ++i) {
|
||||
const google::protobuf::ServiceDescriptor* service = file->service(i);
|
||||
for (int j = 0; j < service->method_count(); ++j) {
|
||||
const google::protobuf::MethodDescriptor* method = service->method(i);
|
||||
// Remove duplicated imports.
|
||||
if (importedPkgs.find(
|
||||
method->input_type()->file()->package()) == importedPkgs.end()) {
|
||||
const google::protobuf::MethodDescriptor* method = service->method(j);
|
||||
if (!IsSelfImport(file, method->input_type()->file())) {
|
||||
descs.insert(method->input_type()->file());
|
||||
importedPkgs.insert(method->input_type()->file()->package());
|
||||
}
|
||||
if (importedPkgs.find(
|
||||
method->output_type()->file()->package()) == importedPkgs.end()) {
|
||||
if (!IsSelfImport(file, method->output_type()->file())) {
|
||||
descs.insert(method->output_type()->file());
|
||||
importedPkgs.insert(method->output_type()->file()->package());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for (auto fd : descs) {
|
||||
if (fd->package() == (*vars)["PackageName"]) {
|
||||
continue;
|
||||
string pkg = GenerateFullGoPackage(fd);
|
||||
if (pkg != "") {
|
||||
auto ret = imports->insert(pkg);
|
||||
// Use ret.second to guarantee if a package spans multiple files, it only
|
||||
// gets 1 alias.
|
||||
if (ret.second && file->package() == fd->package()) {
|
||||
// the same package name in different directories. Require an alias.
|
||||
(*import_alias)[pkg] = "apb" + std::to_string(idx++);
|
||||
}
|
||||
}
|
||||
string name = fd->name();
|
||||
string import_path = "import \"";
|
||||
if (name.find('/') == string::npos) {
|
||||
// Assume all the proto in the same directory belong to the same package.
|
||||
continue;
|
||||
} else {
|
||||
import_path += name.substr(0, name.find_last_of('/')) + "\"";
|
||||
}
|
||||
for (auto import : *imports) {
|
||||
string import_path = "import ";
|
||||
if (import_alias->find(import) != import_alias->end()) {
|
||||
import_path += (*import_alias)[import] + " ";
|
||||
}
|
||||
import_path += "\"" + import + "\"";
|
||||
printer->Print(import_path.c_str());
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
@ -560,7 +593,8 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
|
|||
google::protobuf::io::StringOutputStream output_stream(&output);
|
||||
google::protobuf::io::Printer printer(&output_stream, '$');
|
||||
map<string, string> vars;
|
||||
|
||||
map<string, string> import_alias;
|
||||
set<string> imports;
|
||||
string package_name = !file->options().go_package().empty()
|
||||
? file->options().go_package()
|
||||
: file->package();
|
||||
|
@ -578,7 +612,7 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
|
|||
"\tproto \"github.com/golang/protobuf/proto\"\n"
|
||||
")\n\n");
|
||||
|
||||
PrintMessageImports(&printer, file, &vars);
|
||||
PrintMessageImports(&printer, file, &vars, &imports, &import_alias);
|
||||
|
||||
// $Package$ is used to fully qualify method names.
|
||||
vars["Package"] = file->package();
|
||||
|
@ -587,9 +621,9 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
|
|||
}
|
||||
|
||||
for (int i = 0; i < file->service_count(); ++i) {
|
||||
PrintClient(&printer, file->service(0), &vars);
|
||||
PrintClient(&printer, file->service(0), &vars, imports, import_alias);
|
||||
printer.Print("\n");
|
||||
PrintServer(&printer, file->service(0), &vars);
|
||||
PrintServer(&printer, file->service(0), &vars, imports, import_alias);
|
||||
printer.Print("\n");
|
||||
}
|
||||
return output;
|
||||
|
|
|
@ -195,16 +195,15 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
var server *rpc.Server
|
||||
server := rpc.NewServer()
|
||||
testpb.RegisterService(server, &testServer{})
|
||||
if *useTLS {
|
||||
creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate credentials %v", err)
|
||||
}
|
||||
server = rpc.NewServer(lis, rpc.WithServerTLS(creds))
|
||||
server.Serve(creds.NewListener(lis))
|
||||
} else {
|
||||
server = rpc.NewServer(lis)
|
||||
server.Serve(lis)
|
||||
}
|
||||
testpb.RegisterService(server, &testServer{})
|
||||
server.Run()
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ import (
|
|||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/google/grpc-go/rpc/codes"
|
||||
"github.com/google/grpc-go/rpc/credentials"
|
||||
"github.com/google/grpc-go/rpc/metadata"
|
||||
"github.com/google/grpc-go/rpc/transport"
|
||||
"golang.org/x/net/context"
|
||||
|
@ -86,16 +85,15 @@ type service struct {
|
|||
|
||||
// Server is a gRPC server to serve RPC requests.
|
||||
type Server struct {
|
||||
lis net.Listener
|
||||
opts options
|
||||
mu sync.Mutex
|
||||
lis map[net.Listener]bool
|
||||
conns map[transport.ServerTransport]bool
|
||||
m map[string]*service // service name -> service info
|
||||
}
|
||||
|
||||
type options struct {
|
||||
maxConcurrentStreams uint32
|
||||
connCreds credentials.TransportAuthenticator
|
||||
}
|
||||
|
||||
// ServerOption sets options.
|
||||
|
@ -109,25 +107,15 @@ func MaxConcurrentStreams(n uint32) ServerOption {
|
|||
}
|
||||
}
|
||||
|
||||
// WithServerTLS returns an Option that consists of the input TLSCredentials.
|
||||
func WithServerTLS(creds credentials.TransportAuthenticator) ServerOption {
|
||||
return func(o *options) {
|
||||
o.connCreds = creds
|
||||
}
|
||||
}
|
||||
|
||||
// NewServer creates a gRPC server which has no service registered and has not
|
||||
// started to accept requests yet.
|
||||
func NewServer(lis net.Listener, opt ...ServerOption) *Server {
|
||||
func NewServer(opt ...ServerOption) *Server {
|
||||
var opts options
|
||||
for _, o := range opt {
|
||||
o(&opts)
|
||||
}
|
||||
if opts.connCreds != nil {
|
||||
lis = opts.connCreds.NewListener(lis)
|
||||
}
|
||||
return &Server{
|
||||
lis: lis,
|
||||
lis: make(map[net.Listener]bool),
|
||||
opts: opts,
|
||||
conns: make(map[transport.ServerTransport]bool),
|
||||
m: make(map[string]*service),
|
||||
|
@ -135,7 +123,8 @@ func NewServer(lis net.Listener, opt ...ServerOption) *Server {
|
|||
}
|
||||
|
||||
// RegisterService register a service and its implementation to the gRPC
|
||||
// server. Called from the IDL generated code.
|
||||
// server. Called from the IDL generated code. This must be called before
|
||||
// invoking Serve.
|
||||
func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
@ -164,12 +153,26 @@ func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {
|
|||
s.m[sd.ServiceName] = srv
|
||||
}
|
||||
|
||||
// Run makes the server start to accept connections on s.lis. Upon each received
|
||||
// connection request, it creates a ServerTransport and starts receiving gRPC
|
||||
// requests from it. Non-nil error returns if something goes wrong.
|
||||
func (s *Server) Run() error {
|
||||
// Serve accepts incoming connections on the listener lis, creating a new
|
||||
// ServerTransport and service goroutine for each. The service goroutines
|
||||
// read gRPC request and then call the registered handlers to reply to them.
|
||||
// Service returns when lis.Accept fails.
|
||||
func (s *Server) Serve(lis net.Listener) error {
|
||||
s.mu.Lock()
|
||||
if s.lis == nil {
|
||||
s.mu.Unlock()
|
||||
return fmt.Errorf("the server has been stopped")
|
||||
}
|
||||
s.lis[lis] = true
|
||||
s.mu.Unlock()
|
||||
defer func() {
|
||||
lis.Close()
|
||||
s.mu.Lock()
|
||||
delete(s.lis, lis)
|
||||
s.mu.Unlock()
|
||||
}()
|
||||
for {
|
||||
c, err := s.lis.Accept()
|
||||
c, err := lis.Accept()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -312,11 +315,15 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
|
|||
// Stop stops the gRPC server. Once it returns, the server stops accepting
|
||||
// connection requests and closes all the connected connections.
|
||||
func (s *Server) Stop() {
|
||||
s.lis.Close()
|
||||
s.mu.Lock()
|
||||
listeners := s.lis
|
||||
s.lis = nil
|
||||
cs := s.conns
|
||||
s.conns = nil
|
||||
s.mu.Unlock()
|
||||
for lis := range listeners {
|
||||
lis.Close()
|
||||
}
|
||||
for c := range cs {
|
||||
c.Close()
|
||||
}
|
||||
|
|
|
@ -157,18 +157,18 @@ func setUp(useTLS bool, maxStream uint32) (s *rpc.Server, mc testpb.MathClient)
|
|||
if err != nil {
|
||||
log.Fatalf("Failed to parse listener address: %v", err)
|
||||
}
|
||||
s = rpc.NewServer(rpc.MaxConcurrentStreams(maxStream))
|
||||
ms := &mathServer{}
|
||||
testpb.RegisterService(s, ms)
|
||||
if useTLS {
|
||||
creds, err := credentials.NewServerTLSFromFile(tlsDir+"server1.pem", tlsDir+"server1.key")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate credentials %v", err)
|
||||
}
|
||||
s = rpc.NewServer(lis, rpc.MaxConcurrentStreams(maxStream), rpc.WithServerTLS(creds))
|
||||
go s.Serve(creds.NewListener(lis))
|
||||
} else {
|
||||
s = rpc.NewServer(lis, rpc.MaxConcurrentStreams(maxStream))
|
||||
go s.Serve(lis)
|
||||
}
|
||||
ms := &mathServer{}
|
||||
testpb.RegisterService(s, ms)
|
||||
go s.Run()
|
||||
addr := "localhost:" + port
|
||||
var conn *rpc.ClientConn
|
||||
if useTLS {
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: test.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package test is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
test.proto
|
||||
|
||||
It has these top-level messages:
|
||||
DivArgs
|
||||
DivReply
|
||||
FibArgs
|
||||
Num
|
||||
FibReply
|
||||
*/
|
||||
package test
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = math.Inf
|
||||
|
||||
type DivArgs struct {
|
||||
Dividend *int64 `protobuf:"varint,1,req,name=dividend" json:"dividend,omitempty"`
|
||||
Divisor *int64 `protobuf:"varint,2,req,name=divisor" json:"divisor,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DivArgs) Reset() { *m = DivArgs{} }
|
||||
func (m *DivArgs) String() string { return proto.CompactTextString(m) }
|
||||
func (*DivArgs) ProtoMessage() {}
|
||||
|
||||
func (m *DivArgs) GetDividend() int64 {
|
||||
if m != nil && m.Dividend != nil {
|
||||
return *m.Dividend
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DivArgs) GetDivisor() int64 {
|
||||
if m != nil && m.Divisor != nil {
|
||||
return *m.Divisor
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type DivReply struct {
|
||||
Quotient *int64 `protobuf:"varint,1,req,name=quotient" json:"quotient,omitempty"`
|
||||
Remainder *int64 `protobuf:"varint,2,req,name=remainder" json:"remainder,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DivReply) Reset() { *m = DivReply{} }
|
||||
func (m *DivReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*DivReply) ProtoMessage() {}
|
||||
|
||||
func (m *DivReply) GetQuotient() int64 {
|
||||
if m != nil && m.Quotient != nil {
|
||||
return *m.Quotient
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DivReply) GetRemainder() int64 {
|
||||
if m != nil && m.Remainder != nil {
|
||||
return *m.Remainder
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type FibArgs struct {
|
||||
Limit *int64 `protobuf:"varint,1,opt,name=limit" json:"limit,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *FibArgs) Reset() { *m = FibArgs{} }
|
||||
func (m *FibArgs) String() string { return proto.CompactTextString(m) }
|
||||
func (*FibArgs) ProtoMessage() {}
|
||||
|
||||
func (m *FibArgs) GetLimit() int64 {
|
||||
if m != nil && m.Limit != nil {
|
||||
return *m.Limit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Num struct {
|
||||
Num *int64 `protobuf:"varint,1,req,name=num" json:"num,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Num) Reset() { *m = Num{} }
|
||||
func (m *Num) String() string { return proto.CompactTextString(m) }
|
||||
func (*Num) ProtoMessage() {}
|
||||
|
||||
func (m *Num) GetNum() int64 {
|
||||
if m != nil && m.Num != nil {
|
||||
return *m.Num
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type FibReply struct {
|
||||
Count *int64 `protobuf:"varint,1,req,name=count" json:"count,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *FibReply) Reset() { *m = FibReply{} }
|
||||
func (m *FibReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*FibReply) ProtoMessage() {}
|
||||
|
||||
func (m *FibReply) GetCount() int64 {
|
||||
if m != nil && m.Count != nil {
|
||||
return *m.Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"github.com/google/grpc-go/rpc"
|
||||
context "golang.org/x/net/context"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
type MathClient interface {
|
||||
Div(ctx context.Context, in *DivArgs, opts ...rpc.CallOption) (*DivReply, error)
|
||||
DivMany(ctx context.Context, opts ...rpc.CallOption) (Math_DivManyClient, error)
|
||||
Fib(ctx context.Context, m *FibArgs, opts ...rpc.CallOption) (Math_FibClient, error)
|
||||
Sum(ctx context.Context, opts ...rpc.CallOption) (Math_SumClient, error)
|
||||
}
|
||||
|
||||
type mathClient struct {
|
||||
cc *rpc.ClientConn
|
||||
}
|
||||
|
||||
func NewMathClient(cc *rpc.ClientConn) MathClient {
|
||||
return &mathClient{cc}
|
||||
}
|
||||
|
||||
func (c *mathClient) Div(ctx context.Context, in *DivArgs, opts ...rpc.CallOption) (*DivReply, error) {
|
||||
out := new(DivReply)
|
||||
err := rpc.Invoke(ctx, "/test.Math/Div", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *mathClient) DivMany(ctx context.Context, opts ...rpc.CallOption) (Math_DivManyClient, error) {
|
||||
stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/DivMany", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mathDivManyClient{stream}, nil
|
||||
}
|
||||
|
||||
type Math_DivManyClient interface {
|
||||
Send(*DivArgs) error
|
||||
Recv() (*DivReply, error)
|
||||
rpc.ClientStream
|
||||
}
|
||||
|
||||
type mathDivManyClient struct {
|
||||
rpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *mathDivManyClient) Send(m *DivArgs) error {
|
||||
return x.ClientStream.SendProto(m)
|
||||
}
|
||||
|
||||
func (x *mathDivManyClient) Recv() (*DivReply, error) {
|
||||
m := new(DivReply)
|
||||
if err := x.ClientStream.RecvProto(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *mathClient) Fib(ctx context.Context, m *FibArgs, opts ...rpc.CallOption) (Math_FibClient, error) {
|
||||
stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/Fib", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &mathFibClient{stream}
|
||||
if err := x.ClientStream.SendProto(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type Math_FibClient interface {
|
||||
Recv() (*Num, error)
|
||||
rpc.ClientStream
|
||||
}
|
||||
|
||||
type mathFibClient struct {
|
||||
rpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *mathFibClient) Recv() (*Num, error) {
|
||||
m := new(Num)
|
||||
if err := x.ClientStream.RecvProto(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *mathClient) Sum(ctx context.Context, opts ...rpc.CallOption) (Math_SumClient, error) {
|
||||
stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/Sum", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mathSumClient{stream}, nil
|
||||
}
|
||||
|
||||
type Math_SumClient interface {
|
||||
Send(*Num) error
|
||||
CloseAndRecv() (*Num, error)
|
||||
rpc.ClientStream
|
||||
}
|
||||
|
||||
type mathSumClient struct {
|
||||
rpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *mathSumClient) Send(m *Num) error {
|
||||
return x.ClientStream.SendProto(m)
|
||||
}
|
||||
|
||||
func (x *mathSumClient) CloseAndRecv() (*Num, error) {
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := new(Num)
|
||||
if err := x.ClientStream.RecvProto(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Read EOF.
|
||||
if err := x.ClientStream.RecvProto(m); err == io.EOF {
|
||||
return m, io.EOF
|
||||
}
|
||||
// gRPC protocol violation.
|
||||
return m, fmt.Errorf("Violate gRPC client streaming protocol: no EOF after the response.")
|
||||
}
|
||||
|
||||
|
||||
type MathServer interface {
|
||||
Div(context.Context, *DivArgs) (*DivReply, error)
|
||||
DivMany(Math_DivManyServer) error
|
||||
Fib(*FibArgs, Math_FibServer) error
|
||||
Sum(Math_SumServer) error
|
||||
}
|
||||
|
||||
func RegisterService(s *rpc.Server, srv MathServer) {
|
||||
s.RegisterService(&_Math_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Math_Div_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
|
||||
in := new(DivArgs)
|
||||
if err := proto.Unmarshal(buf, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := srv.(MathServer).Div(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func _Math_DivMany_Handler(srv interface{}, stream rpc.ServerStream) error {
|
||||
return srv.(MathServer).DivMany(&mathDivManyServer{stream})
|
||||
}
|
||||
|
||||
type Math_DivManyServer interface {
|
||||
Send(*DivReply) error
|
||||
Recv() (*DivArgs, error)
|
||||
rpc.ServerStream
|
||||
}
|
||||
|
||||
type mathDivManyServer struct {
|
||||
rpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *mathDivManyServer) Send(m *DivReply) error {
|
||||
return x.ServerStream.SendProto(m)
|
||||
}
|
||||
|
||||
func (x *mathDivManyServer) Recv() (*DivArgs, error) {
|
||||
m := new(DivArgs)
|
||||
if err := x.ServerStream.RecvProto(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _Math_Fib_Handler(srv interface{}, stream rpc.ServerStream) error {
|
||||
m := new(FibArgs)
|
||||
if err := stream.RecvProto(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(MathServer).Fib(m, &mathFibServer{stream})
|
||||
}
|
||||
|
||||
type Math_FibServer interface {
|
||||
Send(*Num) error
|
||||
rpc.ServerStream
|
||||
}
|
||||
|
||||
type mathFibServer struct {
|
||||
rpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *mathFibServer) Send(m *Num) error {
|
||||
return x.ServerStream.SendProto(m)
|
||||
}
|
||||
|
||||
func _Math_Sum_Handler(srv interface{}, stream rpc.ServerStream) error {
|
||||
return srv.(MathServer).Sum(&mathSumServer{stream})
|
||||
}
|
||||
|
||||
type Math_SumServer interface {
|
||||
SendAndClose(*Num) error
|
||||
Recv() (*Num, error)
|
||||
rpc.ServerStream
|
||||
}
|
||||
|
||||
type mathSumServer struct {
|
||||
rpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *mathSumServer) SendAndClose(m *Num) error {
|
||||
if err := x.ServerStream.SendProto(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *mathSumServer) Recv() (*Num, error) {
|
||||
m := new(Num)
|
||||
if err := x.ServerStream.RecvProto(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
var _Math_serviceDesc = rpc.ServiceDesc{
|
||||
ServiceName: "test.Math",
|
||||
HandlerType: (*MathServer)(nil),
|
||||
Methods: []rpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Div",
|
||||
Handler: _Math_Div_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []rpc.StreamDesc{
|
||||
{
|
||||
StreamName: "DivMany",
|
||||
Handler: _Math_DivMany_Handler,
|
||||
},
|
||||
{
|
||||
StreamName: "Fib",
|
||||
Handler: _Math_Fib_Handler,
|
||||
},
|
||||
{
|
||||
StreamName: "Sum",
|
||||
Handler: _Math_Sum_Handler,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче