Merge pull request #23 from iamqizhao/master

Revise codegen plugin to accommodate more cases and fix some bugs
This commit is contained in:
Qi Zhao 2015-02-02 17:05:46 -08:00 коммит произвёл iamqizhao
Родитель 796d00c003 4a1cba09a6
Коммит 801d1972f4
6 изменённых файлов: 585 добавлений и 95 удалений

Просмотреть файл

@ -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 {

157
rpc/test/testdata/tmp/test.pb.go поставляемый Normal file
Просмотреть файл

@ -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() {
}

293
rpc/test/testdata/tmp/test_grpc.pb.go поставляемый Normal file
Просмотреть файл

@ -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,
},
},
}