[Go] Working on a go example plus fixing go grpc code (#6448)
authormustiikhalil <mustii@mmk.one>
Fri, 19 Feb 2021 09:47:59 +0000 (12:47 +0300)
committerGitHub <noreply@github.com>
Fri, 19 Feb 2021 09:47:59 +0000 (12:47 +0300)
Implemented server.go and half implemented client.go

Finishes implementation for greeter go example

Update grpc code for monster.fbs

Adds a couple of cpp methods

Adhere to gofmt standards

Adds a readme for issues with grpc

19 files changed:
.gitignore
grpc/examples/README.md [new file with mode: 0644]
grpc/examples/generate.sh [new file with mode: 0644]
grpc/examples/go/greeter/.gitignore [new file with mode: 0644]
grpc/examples/go/greeter/README.md [new file with mode: 0644]
grpc/examples/go/greeter/client/go.mod [new file with mode: 0644]
grpc/examples/go/greeter/client/main.go [new file with mode: 0644]
grpc/examples/go/greeter/models/Greeter_grpc.go [new file with mode: 0644]
grpc/examples/go/greeter/models/HelloReply.go [new file with mode: 0644]
grpc/examples/go/greeter/models/HelloRequest.go [new file with mode: 0644]
grpc/examples/go/greeter/models/go.mod [new file with mode: 0644]
grpc/examples/go/greeter/server/go.mod [new file with mode: 0644]
grpc/examples/go/greeter/server/main.go [new file with mode: 0644]
grpc/examples/greeter.fbs [new file with mode: 0644]
grpc/src/compiler/go_generator.cc
grpc/src/compiler/schema_interface.h
grpc/tests/go_test.go
src/idl_gen_grpc.cpp
tests/MyGame/Example/MonsterStorage_grpc.go

index 02d6651..2a9f92c 100644 (file)
@@ -140,4 +140,6 @@ yarn-error.log
 .cache/
 /flatbuffers.lib
 .cmake/
-**/dist
\ No newline at end of file
+**/dist
+**/vendor
+**/go.sum
diff --git a/grpc/examples/README.md b/grpc/examples/README.md
new file mode 100644 (file)
index 0000000..f5694a8
--- /dev/null
@@ -0,0 +1,7 @@
+## Languages known issues
+
+### Go
+
+- Always requires the `content-type` of the payload to be set to `application/grpc+flatbuffers`
+
+example: `.SayHello(ctx, b, grpc.CallContentSubtype("flatbuffers"))`
\ No newline at end of file
diff --git a/grpc/examples/generate.sh b/grpc/examples/generate.sh
new file mode 100644 (file)
index 0000000..4f48191
--- /dev/null
@@ -0,0 +1,18 @@
+current_dir=`pwd`
+
+cd ../..
+
+main_dir=`pwd`
+
+cd ${current_dir}
+
+alias fbc='${main_dir}/Debug/flatc'
+generator="--grpc $current_dir/greeter.fbs"
+
+# Regenerate Go lang code
+cd go/
+
+cd greeter
+fbc --go ${generator}
+
+cd ../..
\ No newline at end of file
diff --git a/grpc/examples/go/greeter/.gitignore b/grpc/examples/go/greeter/.gitignore
new file mode 100644 (file)
index 0000000..535db5e
--- /dev/null
@@ -0,0 +1,2 @@
+**/server
+**/client
\ No newline at end of file
diff --git a/grpc/examples/go/greeter/README.md b/grpc/examples/go/greeter/README.md
new file mode 100644 (file)
index 0000000..3390508
--- /dev/null
@@ -0,0 +1,25 @@
+# Go Greeter example
+
+## Project Structure
+
+    .
+    ├── server                   # Server module
+    ├── client                   # Client module
+    ├── models                   # Flatbuffers models & main grpc code.
+    └── README.md
+
+## How to run Server:
+
+- `cd server`
+
+- `go clean`
+
+- `go run main.go`
+
+## How to run Client:
+
+- `cd client`
+
+- `go clean`
+
+- `go run main.go --name NAME`
\ No newline at end of file
diff --git a/grpc/examples/go/greeter/client/go.mod b/grpc/examples/go/greeter/client/go.mod
new file mode 100644 (file)
index 0000000..19689dd
--- /dev/null
@@ -0,0 +1,11 @@
+module github.com/google/flatbuffers/grpc/examples/go/greeter/client
+
+go 1.15
+
+replace github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0 => ../models
+
+require (
+       github.com/google/flatbuffers v1.12.0
+       github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0
+       google.golang.org/grpc v1.35.0
+)
diff --git a/grpc/examples/go/greeter/client/main.go b/grpc/examples/go/greeter/client/main.go
new file mode 100644 (file)
index 0000000..4993576
--- /dev/null
@@ -0,0 +1,74 @@
+package main
+
+import (
+       "context"
+       "flag"
+       "fmt"
+       "io"
+       "log"
+       "time"
+
+       flatbuffers "github.com/google/flatbuffers/go"
+       models "github.com/google/flatbuffers/grpc/examples/go/greeter/models"
+       "google.golang.org/grpc"
+)
+
+var (
+       addr = "3000"
+       name = flag.String("name", "Flatbuffers", "name to be sent to server :D")
+)
+
+func printSayHello(client models.GreeterClient, name string) {
+       log.Printf("Name to be sent (%s)", name)
+       b := flatbuffers.NewBuilder(0)
+       i := b.CreateString(name)
+       models.HelloRequestStart(b)
+       models.HelloRequestAddName(b, i)
+       b.Finish(models.HelloRequestEnd(b))
+
+       ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+       defer cancel()
+       request, err := client.SayHello(ctx, b, grpc.CallContentSubtype("flatbuffers"))
+       if err != nil {
+               log.Fatalf("%v.SayHello(_) = _, %v: ", client, err)
+       }
+       log.Printf("server said %q", request.Message())
+}
+
+func printSayManyHello(client models.GreeterClient, name string) {
+       log.Printf("Name to be sent (%s)", name)
+       b := flatbuffers.NewBuilder(0)
+       i := b.CreateString(name)
+       models.HelloRequestStart(b)
+       models.HelloRequestAddName(b, i)
+       b.Finish(models.HelloRequestEnd(b))
+
+       ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+       defer cancel()
+       stream, err := client.SayManyHellos(ctx, b, grpc.CallContentSubtype("flatbuffers"))
+       if err != nil {
+               log.Fatalf("%v.SayManyHellos(_) = _, %v", client, err)
+       }
+       for {
+               request, err := stream.Recv()
+               if err == io.EOF {
+                       break
+               }
+               if err != nil {
+                       log.Fatalf("%v.SayManyHellos(_) = _, %v", client, err)
+               }
+               log.Printf("server said %q", request.Message())
+       }
+}
+
+func main() {
+       flag.Parse()
+       conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", 3000), grpc.WithInsecure(), grpc.WithCodec(flatbuffers.FlatbuffersCodec{}))
+       if err != nil {
+               log.Fatalf("fail to dial: %v", err)
+       }
+       defer conn.Close()
+       client := models.NewGreeterClient(conn)
+       printSayHello(client, *name)
+       printSayManyHello(client, *name)
+}
diff --git a/grpc/examples/go/greeter/models/Greeter_grpc.go b/grpc/examples/go/greeter/models/Greeter_grpc.go
new file mode 100644 (file)
index 0000000..9a2405c
--- /dev/null
@@ -0,0 +1,158 @@
+//Generated by gRPC Go plugin
+//If you make any local changes, they will be lost
+//source: greeter
+
+package models
+
+import (
+       context "context"
+       flatbuffers "github.com/google/flatbuffers/go"
+       grpc "google.golang.org/grpc"
+       "google.golang.org/grpc/codes"
+       "google.golang.org/grpc/status"
+)
+
+// Client API for Greeter service
+type GreeterClient interface {
+       SayHello(ctx context.Context, in *flatbuffers.Builder,
+               opts ...grpc.CallOption) (*HelloReply, error)
+       SayManyHellos(ctx context.Context, in *flatbuffers.Builder,
+               opts ...grpc.CallOption) (Greeter_SayManyHellosClient, error)
+}
+
+type greeterClient struct {
+       cc grpc.ClientConnInterface
+}
+
+func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient {
+       return &greeterClient{cc}
+}
+
+func (c *greeterClient) SayHello(ctx context.Context, in *flatbuffers.Builder,
+       opts ...grpc.CallOption) (*HelloReply, error) {
+       out := new(HelloReply)
+       err := c.cc.Invoke(ctx, "/models.Greeter/SayHello", in, out, opts...)
+       if err != nil {
+               return nil, err
+       }
+       return out, nil
+}
+
+func (c *greeterClient) SayManyHellos(ctx context.Context, in *flatbuffers.Builder,
+       opts ...grpc.CallOption) (Greeter_SayManyHellosClient, error) {
+       stream, err := c.cc.NewStream(ctx, &_Greeter_serviceDesc.Streams[0], "/models.Greeter/SayManyHellos", opts...)
+       if err != nil {
+               return nil, err
+       }
+       x := &greeterSayManyHellosClient{stream}
+       if err := x.ClientStream.SendMsg(in); err != nil {
+               return nil, err
+       }
+       if err := x.ClientStream.CloseSend(); err != nil {
+               return nil, err
+       }
+       return x, nil
+}
+
+type Greeter_SayManyHellosClient interface {
+       Recv() (*HelloReply, error)
+       grpc.ClientStream
+}
+
+type greeterSayManyHellosClient struct {
+       grpc.ClientStream
+}
+
+func (x *greeterSayManyHellosClient) Recv() (*HelloReply, error) {
+       m := new(HelloReply)
+       if err := x.ClientStream.RecvMsg(m); err != nil {
+               return nil, err
+       }
+       return m, nil
+}
+
+// Server API for Greeter service
+type GreeterServer interface {
+       SayHello(context.Context, *HelloRequest) (*flatbuffers.Builder, error)
+       SayManyHellos(*HelloRequest, Greeter_SayManyHellosServer) error
+       mustEmbedUnimplementedGreeterServer()
+}
+
+type UnimplementedGreeterServer struct {
+}
+
+func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*flatbuffers.Builder, error) {
+       return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
+}
+
+func (UnimplementedGreeterServer) SayManyHellos(*HelloRequest, Greeter_SayManyHellosServer) error {
+       return status.Errorf(codes.Unimplemented, "method SayManyHellos not implemented")
+}
+
+func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer() {}
+
+type UnsafeGreeterServer interface {
+       mustEmbedUnimplementedGreeterServer()
+}
+
+func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
+       s.RegisterService(&_Greeter_serviceDesc, srv)
+}
+
+func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context,
+       dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+       in := new(HelloRequest)
+       if err := dec(in); err != nil {
+               return nil, err
+       }
+       if interceptor == nil {
+               return srv.(GreeterServer).SayHello(ctx, in)
+       }
+       info := &grpc.UnaryServerInfo{
+               Server:     srv,
+               FullMethod: "/models.Greeter/SayHello",
+       }
+
+       handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+               return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
+       }
+       return interceptor(ctx, in, info, handler)
+}
+func _Greeter_SayManyHellos_Handler(srv interface{}, stream grpc.ServerStream) error {
+       m := new(HelloRequest)
+       if err := stream.RecvMsg(m); err != nil {
+               return err
+       }
+       return srv.(GreeterServer).SayManyHellos(m, &greeterSayManyHellosServer{stream})
+}
+
+type Greeter_SayManyHellosServer interface {
+       Send(*flatbuffers.Builder) error
+       grpc.ServerStream
+}
+
+type greeterSayManyHellosServer struct {
+       grpc.ServerStream
+}
+
+func (x *greeterSayManyHellosServer) Send(m *flatbuffers.Builder) error {
+       return x.ServerStream.SendMsg(m)
+}
+
+var _Greeter_serviceDesc = grpc.ServiceDesc{
+       ServiceName: "models.Greeter",
+       HandlerType: (*GreeterServer)(nil),
+       Methods: []grpc.MethodDesc{
+               {
+                       MethodName: "SayHello",
+                       Handler:    _Greeter_SayHello_Handler,
+               },
+       },
+       Streams: []grpc.StreamDesc{
+               {
+                       StreamName:    "SayManyHellos",
+                       Handler:       _Greeter_SayManyHellos_Handler,
+                       ServerStreams: true,
+               },
+       },
+}
diff --git a/grpc/examples/go/greeter/models/HelloReply.go b/grpc/examples/go/greeter/models/HelloReply.go
new file mode 100644 (file)
index 0000000..bb5db40
--- /dev/null
@@ -0,0 +1,52 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package models
+
+import (
+       flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type HelloReply struct {
+       _tab flatbuffers.Table
+}
+
+func GetRootAsHelloReply(buf []byte, offset flatbuffers.UOffsetT) *HelloReply {
+       n := flatbuffers.GetUOffsetT(buf[offset:])
+       x := &HelloReply{}
+       x.Init(buf, n+offset)
+       return x
+}
+
+func GetSizePrefixedRootAsHelloReply(buf []byte, offset flatbuffers.UOffsetT) *HelloReply {
+       n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
+       x := &HelloReply{}
+       x.Init(buf, n+offset+flatbuffers.SizeUint32)
+       return x
+}
+
+func (rcv *HelloReply) Init(buf []byte, i flatbuffers.UOffsetT) {
+       rcv._tab.Bytes = buf
+       rcv._tab.Pos = i
+}
+
+func (rcv *HelloReply) Table() flatbuffers.Table {
+       return rcv._tab
+}
+
+func (rcv *HelloReply) Message() []byte {
+       o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+       if o != 0 {
+               return rcv._tab.ByteVector(o + rcv._tab.Pos)
+       }
+       return nil
+}
+
+func HelloReplyStart(builder *flatbuffers.Builder) {
+       builder.StartObject(1)
+}
+func HelloReplyAddMessage(builder *flatbuffers.Builder, message flatbuffers.UOffsetT) {
+       builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(message), 0)
+}
+func HelloReplyEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+       return builder.EndObject()
+}
diff --git a/grpc/examples/go/greeter/models/HelloRequest.go b/grpc/examples/go/greeter/models/HelloRequest.go
new file mode 100644 (file)
index 0000000..52feab9
--- /dev/null
@@ -0,0 +1,52 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package models
+
+import (
+       flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type HelloRequest struct {
+       _tab flatbuffers.Table
+}
+
+func GetRootAsHelloRequest(buf []byte, offset flatbuffers.UOffsetT) *HelloRequest {
+       n := flatbuffers.GetUOffsetT(buf[offset:])
+       x := &HelloRequest{}
+       x.Init(buf, n+offset)
+       return x
+}
+
+func GetSizePrefixedRootAsHelloRequest(buf []byte, offset flatbuffers.UOffsetT) *HelloRequest {
+       n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
+       x := &HelloRequest{}
+       x.Init(buf, n+offset+flatbuffers.SizeUint32)
+       return x
+}
+
+func (rcv *HelloRequest) Init(buf []byte, i flatbuffers.UOffsetT) {
+       rcv._tab.Bytes = buf
+       rcv._tab.Pos = i
+}
+
+func (rcv *HelloRequest) Table() flatbuffers.Table {
+       return rcv._tab
+}
+
+func (rcv *HelloRequest) Name() []byte {
+       o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+       if o != 0 {
+               return rcv._tab.ByteVector(o + rcv._tab.Pos)
+       }
+       return nil
+}
+
+func HelloRequestStart(builder *flatbuffers.Builder) {
+       builder.StartObject(1)
+}
+func HelloRequestAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) {
+       builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(name), 0)
+}
+func HelloRequestEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+       return builder.EndObject()
+}
diff --git a/grpc/examples/go/greeter/models/go.mod b/grpc/examples/go/greeter/models/go.mod
new file mode 100644 (file)
index 0000000..01976de
--- /dev/null
@@ -0,0 +1,8 @@
+module github.com/google/flatbuffers/grpc/examples/go/greeter/models
+
+go 1.15
+
+require (
+       github.com/google/flatbuffers v1.12.0
+       google.golang.org/grpc v1.35.0
+)
diff --git a/grpc/examples/go/greeter/server/go.mod b/grpc/examples/go/greeter/server/go.mod
new file mode 100644 (file)
index 0000000..2572fee
--- /dev/null
@@ -0,0 +1,11 @@
+module github.com/google/flatbuffers/grpc/examples/go/greeter/server
+
+go 1.15
+
+replace github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0 => ../models
+
+require (
+       github.com/google/flatbuffers v1.12.0
+       github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0
+       google.golang.org/grpc v1.35.0
+)
diff --git a/grpc/examples/go/greeter/server/main.go b/grpc/examples/go/greeter/server/main.go
new file mode 100644 (file)
index 0000000..6191420
--- /dev/null
@@ -0,0 +1,78 @@
+package main
+
+import (
+       "context"
+       "fmt"
+       "log"
+       "net"
+
+       flatbuffers "github.com/google/flatbuffers/go"
+       models "github.com/google/flatbuffers/grpc/examples/go/greeter/models"
+       "google.golang.org/grpc"
+       "google.golang.org/grpc/encoding"
+)
+
+var (
+       greetings = [...]string{"Hi", "Hallo", "Ciao"}
+)
+
+type greeterServer struct {
+       models.UnimplementedGreeterServer
+}
+
+func (s *greeterServer) SayHello(ctx context.Context, request *models.HelloRequest) (*flatbuffers.Builder, error) {
+       v := request.Name()
+       var m string
+       if v == nil {
+               m = "Unknown"
+       } else {
+               m = string(v)
+       }
+       b := flatbuffers.NewBuilder(0)
+       idx := b.CreateString("welcome " + m)
+       models.HelloReplyStart(b)
+       models.HelloReplyAddMessage(b, idx)
+       b.Finish(models.HelloReplyEnd(b))
+       return b, nil
+}
+
+func (s *greeterServer) SayManyHellos(request *models.HelloRequest, stream models.Greeter_SayManyHellosServer) error {
+       v := request.Name()
+       var m string
+       if v == nil {
+               m = "Unknown"
+       } else {
+               m = string(v)
+       }
+       b := flatbuffers.NewBuilder(0)
+
+       for _, greeting := range greetings {
+               idx := b.CreateString(greeting + " " + m)
+               models.HelloReplyStart(b)
+               models.HelloReplyAddMessage(b, idx)
+               b.Finish(models.HelloReplyEnd(b))
+               if err := stream.Send(b); err != nil {
+                       return err
+               }
+       }
+       return nil
+}
+
+func newServer() *greeterServer {
+       s := &greeterServer{}
+       return s
+}
+
+func main() {
+       lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", 3000))
+       if err != nil {
+               log.Fatalf("failed to listen: %v", err)
+       }
+       grpcServer := grpc.NewServer()
+       encoding.RegisterCodec(flatbuffers.FlatbuffersCodec{})
+       models.RegisterGreeterServer(grpcServer, newServer())
+       if err := grpcServer.Serve(lis); err != nil {
+               fmt.Print(err)
+               panic(err)
+       }
+}
diff --git a/grpc/examples/greeter.fbs b/grpc/examples/greeter.fbs
new file mode 100644 (file)
index 0000000..651fb67
--- /dev/null
@@ -0,0 +1,14 @@
+namespace models;
+
+table HelloReply {
+  message:string;
+}
+
+table HelloRequest {
+  name:string;
+}
+
+rpc_service Greeter {
+  SayHello(HelloRequest):HelloReply;
+  SayManyHellos(HelloRequest):HelloReply (streaming: "server");
+}
index 604828d..d646451 100644 (file)
@@ -70,6 +70,17 @@ grpc::string exportName(grpc::string s) {
        return s;
 }
 
+void GenerateError(grpc_generator::Printer *printer,
+                   std::map<grpc::string, grpc::string> vars,
+                   const bool multiple_return = true) {
+  printer->Print(vars, "if $Error_Check$ {\n");
+  printer->Indent();
+  vars["Return"] = multiple_return ? "nil, err" : "err";
+  printer->Print(vars, "return $Return$\n");
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
 // Generates imports for the service
 void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printer,
                      std::map<grpc::string, grpc::string> vars) {
@@ -78,14 +89,13 @@ void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printe
        printer->Print("//If you make any local changes, they will be lost\n");
        printer->Print(vars, "//source: $filename$\n\n");
        printer->Print(vars, "package $Package$\n\n");
-       if (file->additional_headers() != "") {
-               printer->Print(file->additional_headers().c_str());
-               printer->Print("\n\n");
-       }
        printer->Print("import (\n");
        printer->Indent();
        printer->Print(vars, "$context$ \"context\"\n");
+  printer->Print("flatbuffers \"github.com/google/flatbuffers/go\"\n");
        printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
+  printer->Print("\"google.golang.org/grpc/codes\"\n");
+  printer->Print("\"google.golang.org/grpc/status\"\n");
        printer->Outdent();
        printer->Print(")\n\n");
 }
@@ -93,15 +103,15 @@ void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printe
 // Generates Server method signature source
 void GenerateServerMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
                                    std::map<grpc::string, grpc::string> vars) {
-       vars["Method"] = exportName(method->name());
+  vars["Method"] = exportName(method->name());
        vars["Request"] = method->get_input_type_name();
        vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
        if (method->NoStreaming()) {
-               printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)");
+               printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)$Ending$");
        } else if (ServerOnlyStreaming(method)) {
-               printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error");
+               printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error$Ending$");
        } else {
-               printer->Print(vars, "$Method$($Service$_$Method$Server) error");
+               printer->Print(vars, "$Method$($Service$_$Method$Server) error$Ending$");
        }
 }
 
@@ -110,28 +120,36 @@ void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::
        vars["Method"] = exportName(method->name());
        vars["Request"] = method->get_input_type_name();
        vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
-       vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
+       vars["FullMethodName"] = "/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
        vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
        if (method->NoStreaming()) {
                printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
                printer->Indent();
                printer->Print(vars, "in := new($Request$)\n");
-               printer->Print("if err := dec(in); err != nil { return nil, err }\n");
-               printer->Print(vars, "if interceptor == nil { return srv.($Service$Server).$Method$(ctx, in) }\n");
+    vars["Error_Check"] = "err := dec(in); err != nil";
+    GenerateError(printer, vars);
+    printer->Print("if interceptor == nil {\n");
+    printer->Indent();
+    printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, in)\n");
+    printer->Outdent();
+    printer->Print("}\n");
                printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
                printer->Indent();
-               printer->Print("Server: srv,\n");
+               printer->Print("Server:     srv,\n");
                printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
                printer->Outdent();
-               printer->Print("}\n\n");
+               printer->Print("}\n");
+    printer->Outdent();
+    printer->Print("\n");
+    printer->Indent();
                printer->Print(vars, "handler := func(ctx $context$.Context, req interface{}) (interface{}, error) {\n");
                printer->Indent();
-               printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(* $Request$))\n");
+               printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(*$Request$))\n");
                printer->Outdent();
                printer->Print("}\n");
                printer->Print("return interceptor(ctx, in, info, handler)\n");
                printer->Outdent();
-               printer->Print("}\n\n");
+               printer->Print("}\n");
                return;
        }
        vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
@@ -139,7 +157,8 @@ void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::
        printer->Indent();
        if (ServerOnlyStreaming(method)) {
                printer->Print(vars, "m := new($Request$)\n");
-               printer->Print(vars, "if err := stream.RecvMsg(m); err != nil { return err }\n");
+    vars["Error_Check"] = "err := stream.RecvMsg(m); err != nil";
+    GenerateError(printer, vars, false);
                printer->Print(vars, "return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
        } else {
                printer->Print(vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
@@ -151,16 +170,16 @@ void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::
        bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
        bool genSendAndClose = ClientOnlyStreaming(method);
 
-       printer->Print(vars, "type $Service$_$Method$Server interface { \n");
+       printer->Print(vars, "type $Service$_$Method$Server interface {\n");
        printer->Indent();
        if (genSend) {
-               printer->Print(vars, "Send(* $Response$) error\n");
+               printer->Print(vars, "Send(*$Response$) error\n");
        }
        if (genRecv) {
-               printer->Print(vars, "Recv() (* $Request$, error)\n");
+               printer->Print(vars, "Recv() (*$Request$, error)\n");
        }
        if (genSendAndClose) {
-               printer->Print(vars, "SendAndClose(* $Response$) error\n");
+               printer->Print(vars, "SendAndClose(*$Response$) error\n");
        }
        printer->Print(vars, "$grpc$.ServerStream\n");
        printer->Outdent();
@@ -183,7 +202,8 @@ void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::
                printer->Print(vars, "func (x *$StreamType$) Recv() (*$Request$, error) {\n");
                printer->Indent();
                printer->Print(vars, "m := new($Request$)\n");
-               printer->Print("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }\n");
+    vars["Error_Check"] = "err := x.ServerStream.RecvMsg(m); err != nil";
+    GenerateError(printer, vars);
                printer->Print("return m, nil\n");
                printer->Outdent();
                printer->Print("}\n\n");
@@ -206,43 +226,47 @@ void GenerateClientMethodSignature(const grpc_generator::Method *method, grpc_ge
        if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
                vars["Request"] = "";
        }
-       vars["Response"] = "* " + method->get_output_type_name();
+       vars["Response"] = "*" + method->get_output_type_name();
        if (ClientOnlyStreaming(method) || method->BidiStreaming() || ServerOnlyStreaming(method)) {
                vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client" ;
        }
-       printer->Print(vars, "$Method$(ctx $context$.Context$Request$, \n\topts... $grpc$.CallOption) ($Response$, error)");
+       printer->Print(vars, "$Method$(ctx $context$.Context$Request$,\n\topts ...$grpc$.CallOption) ($Response$, error)$Ending$");
 }
 
 // Generates Client method source
 void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
                           std::map<grpc::string, grpc::string> vars) {
        printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
+  vars["Ending"] = " {\n";
        GenerateClientMethodSignature(method, printer, vars);
-       printer->Print(" {\n");
        printer->Indent();
        vars["Method"] = exportName(method->name());
        vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
        vars["Response"] = method->get_output_type_name();
-       vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
+       vars["FullMethodName"] = "/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
        if (method->NoStreaming()) {
                printer->Print(vars, "out := new($Response$)\n");
-               printer->Print(vars, "err := $grpc$.Invoke(ctx, \"$FullMethodName$\", in, out, c.cc, opts...)\n");
-               printer->Print("if err != nil { return nil, err }\n");
+               printer->Print(vars, "err := c.cc.Invoke(ctx, \"$FullMethodName$\", in, out, opts...)\n");
+    vars["Error_Check"] = "err != nil";
+    GenerateError(printer, vars);
                printer->Print("return out, nil\n");
                printer->Outdent();
                printer->Print("}\n\n");
                return;
        }
        vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
-       printer->Print(vars, "stream, err := $grpc$.NewClientStream(ctx, &$MethodDesc$, c.cc, \"$FullMethodName$\", opts...)\n");
-       printer->Print("if err != nil { return nil, err }\n");
+       printer->Print(vars, "stream, err := c.cc.NewStream(ctx, &$MethodDesc$, \"$FullMethodName$\", opts...)\n");
+  vars["Error_Check"] = "err != nil";
+  GenerateError(printer, vars);
 
        printer->Print(vars, "x := &$StreamType${stream}\n");
        if (ServerOnlyStreaming(method)) {
-               printer->Print("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }\n");
-               printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
+    vars["Error_Check"] = "err := x.ClientStream.SendMsg(in); err != nil";
+    GenerateError(printer, vars);
+    vars["Error_Check"] = "err := x.ClientStream.CloseSend(); err != nil";
+    GenerateError(printer, vars);
        }
-       printer->Print("return x,nil\n");
+       printer->Print("return x, nil\n");
        printer->Outdent();
        printer->Print("}\n\n");
 
@@ -267,7 +291,7 @@ void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::
        printer->Print("}\n\n");
 
        //Stream Client
-       printer->Print(vars, "type $StreamType$ struct{\n");
+       printer->Print(vars, "type $StreamType$ struct {\n");
        printer->Indent();
        printer->Print(vars, "$grpc$.ClientStream\n");
        printer->Outdent();
@@ -285,7 +309,8 @@ void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::
                printer->Print(vars, "func (x *$StreamType$) Recv() (*$Response$, error) {\n");
                printer->Indent();
                printer->Print(vars, "m := new($Response$)\n");
-               printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
+    vars["Error_Check"] = "err := x.ClientStream.RecvMsg(m); err != nil";
+    GenerateError(printer, vars);
                printer->Print("return m, nil\n");
                printer->Outdent();
                printer->Print("}\n\n");
@@ -294,9 +319,11 @@ void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::
        if (genCloseAndRecv) {
                printer->Print(vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
                printer->Indent();
-               printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
-               printer->Print(vars, "m := new ($Response$)\n");
-               printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
+    vars["Error_Check"] = "err := x.ClientStream.CloseSend(); err != nil";
+    GenerateError(printer, vars);
+               printer->Print(vars, "m := new($Response$)\n");
+    vars["Error_Check"] = "err := x.ClientStream.RecvMsg(m); err != nil";
+    GenerateError(printer, vars);
                printer->Print("return m, nil\n");
                printer->Outdent();
                printer->Print("}\n\n");
@@ -309,11 +336,11 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
        vars["Service"] = exportName(service->name());
        // Client Interface
        printer->Print(vars, "// Client API for $Service$ service\n");
-       printer->Print(vars, "type $Service$Client interface{\n");
+       printer->Print(vars, "type $Service$Client interface {\n");
        printer->Indent();
+  vars["Ending"] = "\n";
        for (int i = 0; i < service->method_count(); i++) {
                GenerateClientMethodSignature(service->method(i).get(), printer, vars);
-               printer->Print("\n");
        }
        printer->Outdent();
        printer->Print("}\n\n");
@@ -322,12 +349,12 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
        vars["ServiceUnexported"] = unexportName(vars["Service"]);
        printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
        printer->Indent();
-       printer->Print(vars, "cc *$grpc$.ClientConn\n");
+       printer->Print(vars, "cc $grpc$.ClientConnInterface\n");
        printer->Outdent();
        printer->Print("}\n\n");
 
        // NewClient
-       printer->Print(vars, "func New$Service$Client(cc *$grpc$.ClientConn) $Service$Client {\n");
+       printer->Print(vars, "func New$Service$Client(cc $grpc$.ClientConnInterface) $Service$Client {\n");
        printer->Indent();
        printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
        printer->Outdent();
@@ -351,15 +378,41 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
        printer->Print(vars, "// Server API for $Service$ service\n");
        printer->Print(vars, "type $Service$Server interface {\n");
        printer->Indent();
+  vars["Ending"] = "\n";
        for (int i = 0; i < service->method_count(); i++) {
                GenerateServerMethodSignature(service->method(i).get(), printer, vars);
-               printer->Print("\n");
        }
+  printer->Print(vars, "mustEmbedUnimplemented$Service$Server()\n");
        printer->Outdent();
        printer->Print("}\n\n");
 
+  printer->Print(vars, "type Unimplemented$Service$Server struct {\n");
+  printer->Print("}\n\n");
+
+  vars["Ending"] = " {\n";
+  for (int i = 0; i < service->method_count(); i++) {
+    auto method = service->method(i);
+    vars["Method"] = exportName(method->name());
+    vars["Nil"] = method->NoStreaming() ? "nil, " : "";
+    printer->Print(vars, "func (Unimplemented$Service$Server) ");
+    GenerateServerMethodSignature(method.get(), printer, vars);
+    printer->Indent();
+    printer->Print(vars, "return $Nil$status.Errorf(codes.Unimplemented, \"method $Method$ not implemented\")\n");
+    printer->Outdent();
+    printer->Print("}\n");
+    printer->Print("\n");
+  }
+
+  printer->Print(vars, "func (Unimplemented$Service$Server) mustEmbedUnimplemented$Service$Server() {}");
+  printer->Print("\n\n");
+
+  printer->Print(vars, "type Unsafe$Service$Server interface {\n");
+  printer->Indent();
+  printer->Print(vars, "mustEmbedUnimplemented$Service$Server()\n");
+  printer->Outdent();
+  printer->Print("}\n\n");
        // Server registration.
-       printer->Print(vars, "func Register$Service$Server(s *$grpc$.Server, srv $Service$Server) {\n");
+       printer->Print(vars, "func Register$Service$Server(s $grpc$.ServiceRegistrar, srv $Service$Server) {\n");
        printer->Indent();
        printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
        printer->Outdent();
@@ -367,26 +420,25 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
 
        for (int i = 0; i < service->method_count(); i++) {
                GenerateServerMethod(service->method(i).get(), printer, vars);
-               printer->Print("\n");
        }
 
 
        //Service Descriptor
        printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
        printer->Indent();
-       printer->Print(vars, "ServiceName: \"$ServicePrefix$.$Service$\",\n");
+       printer->Print(vars, "ServiceName: \"$ServicePrefix$$Service$\",\n");
        printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
        printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
        printer->Indent();
        for (int i = 0; i < service->method_count(); i++) {
                auto method = service->method(i);
-               vars["Method"] = method->name();
+               vars["Method"] = exportName(method->name());
                vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
                if (method->NoStreaming()) {
                        printer->Print("{\n");
                        printer->Indent();
                        printer->Print(vars, "MethodName: \"$Method$\",\n");
-                       printer->Print(vars, "Handler: $Handler$, \n");
+                       printer->Print(vars, "Handler:    $Handler$,\n");
                        printer->Outdent();
                        printer->Print("},\n");
                }
@@ -397,13 +449,13 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
        printer->Indent();
        for (int i = 0; i < service->method_count(); i++) {
                auto method = service->method(i);
-               vars["Method"] = method->name();
+               vars["Method"] = exportName(method->name());
                vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
                if (!method->NoStreaming()) {
                        printer->Print("{\n");
                        printer->Indent();
-                       printer->Print(vars, "StreamName: \"$Method$\",\n");
-                       printer->Print(vars, "Handler: $Handler$, \n");
+                       printer->Print(vars, "StreamName:    \"$Method$\",\n");
+                       printer->Print(vars, "Handler:       $Handler$,\n");
                        if (ClientOnlyStreaming(method.get())) {
                                printer->Print("ClientStreams: true,\n");
                        } else if (ServerOnlyStreaming(method.get())) {
@@ -419,7 +471,7 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
        printer->Outdent();
        printer->Print("},\n");
        printer->Outdent();
-       printer->Print("}\n\n");
+       printer->Print("}\n");
 
 }
 
@@ -429,11 +481,14 @@ grpc::string GenerateServiceSource(grpc_generator::File *file,
                                    const grpc_generator::Service *service,
                                    grpc_go_generator::Parameters *parameters) {
        grpc::string out;
-       auto p = file->CreatePrinter(&out);
+       auto p = file->CreatePrinter(&out, '\t');
+  p->SetIndentationSize(1);
        auto printer = p.get();
        std::map<grpc::string, grpc::string> vars;
        vars["Package"] = parameters->package_name;
        vars["ServicePrefix"] = parameters->service_prefix;
+  if (!parameters->service_prefix.empty())
+    vars["ServicePrefix"].append(".");
        vars["grpc"] = "grpc";
        vars["context"] = "context";
        GenerateImports(file, printer, vars);
index c03ffe7..0449498 100644 (file)
@@ -93,6 +93,7 @@ struct Printer {
   virtual void Print(const std::map<grpc::string, grpc::string> &vars,
                      const char *template_string) = 0;
   virtual void Print(const char *string) = 0;
+  virtual void SetIndentationSize(const int size) = 0;
   virtual void Indent() = 0;
   virtual void Outdent() = 0;
 };
@@ -111,7 +112,8 @@ struct File : public CommentHolder {
   virtual int service_count() const = 0;
   virtual std::unique_ptr<const Service> service(int i) const = 0;
 
-  virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
+  virtual std::unique_ptr<Printer> CreatePrinter(
+      grpc::string *str, const char indentation_type = ' ') const = 0;
 };
 }  // namespace grpc_generator
 
index 1268169..260e236 100644 (file)
@@ -2,12 +2,14 @@ package testing
 
 import (
        "../../tests/MyGame/Example"
+       flatbuffers "github.com/google/flatbuffers/go"
 
        "context"
        "net"
        "testing"
 
        "google.golang.org/grpc"
+       "google.golang.org/grpc/encoding"
 )
 
 type server struct{}
@@ -75,7 +77,7 @@ func TestGRPC(t *testing.T) {
                t.Fatalf("Failed to listen: %v", err)
        }
        ser := grpc.NewServer()
-  encoding.RegisterCodec(flatbuffers.FlatbuffersCodec{})
+       encoding.RegisterCodec(flatbuffers.FlatbuffersCodec{})
        Example.RegisterMonsterStorageServer(ser, &server{})
        go func() {
                if err := ser.Serve(lis); err != nil {
index 394ebe3..9beb10c 100644 (file)
@@ -146,7 +146,12 @@ class FlatBufService : public grpc_generator::Service {
 
 class FlatBufPrinter : public grpc_generator::Printer {
  public:
-  FlatBufPrinter(std::string *str) : str_(str), escape_char_('$'), indent_(0) {}
+  FlatBufPrinter(std::string *str, const char indentation_type)
+      : str_(str),
+        escape_char_('$'),
+        indent_(0),
+        indentation_size_(2),
+        indentation_type_(indentation_type) {}
 
   void Print(const std::map<std::string, std::string> &vars,
              const char *string_template) {
@@ -173,7 +178,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
     // Add this string, but for each part separated by \n, add indentation.
     for (;;) {
       // Current indentation.
-      str_->insert(str_->end(), indent_ * 2, ' ');
+      str_->insert(str_->end(), indent_ * indentation_size_, indentation_type_);
       // See if this contains more than one line.
       const char *lf = strchr(s, '\n');
       if (lf) {
@@ -187,6 +192,11 @@ class FlatBufPrinter : public grpc_generator::Printer {
     }
   }
 
+  void SetIndentationSize(const int size) {
+    FLATBUFFERS_ASSERT(str_->empty());
+    indentation_size_ = size;
+  }
+
   void Indent() { indent_++; }
 
   void Outdent() {
@@ -198,6 +208,8 @@ class FlatBufPrinter : public grpc_generator::Printer {
   std::string *str_;
   char escape_char_;
   int indent_;
+  int indentation_size_;
+  char indentation_type_;
 };
 
 class FlatBufFile : public grpc_generator::File {
@@ -277,8 +289,9 @@ class FlatBufFile : public grpc_generator::File {
   }
 
   std::unique_ptr<grpc_generator::Printer> CreatePrinter(
-      std::string *str) const {
-    return std::unique_ptr<grpc_generator::Printer>(new FlatBufPrinter(str));
+      std::string *str, const char indentation_type = ' ') const {
+    return std::unique_ptr<grpc_generator::Printer>(
+        new FlatBufPrinter(str, indentation_type));
   }
 
  private:
index deeec29..4d9f104 100644 (file)
 
 package Example
 
-import "github.com/google/flatbuffers/go"
-
 import (
-  context "context"
-  grpc "google.golang.org/grpc"
+       context "context"
+       flatbuffers "github.com/google/flatbuffers/go"
+       grpc "google.golang.org/grpc"
+       "google.golang.org/grpc/codes"
+       "google.golang.org/grpc/status"
 )
 
 // Client API for MonsterStorage service
-type MonsterStorageClient interface{
-  Store(ctx context.Context, in *flatbuffers.Builder, 
-       opts... grpc.CallOption) (* Stat, error)  
-  Retrieve(ctx context.Context, in *flatbuffers.Builder, 
-       opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error)  
-  GetMaxHitPoint(ctx context.Context, 
-       opts... grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error)  
-  GetMinMaxHitPoints(ctx context.Context, 
-       opts... grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error)  
+type MonsterStorageClient interface {
+       Store(ctx context.Context, in *flatbuffers.Builder,
+               opts ...grpc.CallOption) (*Stat, error)
+       Retrieve(ctx context.Context, in *flatbuffers.Builder,
+               opts ...grpc.CallOption) (MonsterStorage_RetrieveClient, error)
+       GetMaxHitPoint(ctx context.Context,
+               opts ...grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error)
+       GetMinMaxHitPoints(ctx context.Context,
+               opts ...grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error)
 }
 
 type monsterStorageClient struct {
-  cc *grpc.ClientConn
+       cc grpc.ClientConnInterface
 }
 
-func NewMonsterStorageClient(cc *grpc.ClientConn) MonsterStorageClient {
-  return &monsterStorageClient{cc}
+func NewMonsterStorageClient(cc grpc.ClientConnInterface) MonsterStorageClient {
+       return &monsterStorageClient{cc}
 }
 
-func (c *monsterStorageClient) Store(ctx context.Context, in *flatbuffers.Builder, 
-       opts... grpc.CallOption) (* Stat, error) {
-  out := new(Stat)
-  err := grpc.Invoke(ctx, "/MyGame.Example.MonsterStorage/Store", in, out, c.cc, opts...)
-  if err != nil { return nil, err }
-  return out, nil
+func (c *monsterStorageClient) Store(ctx context.Context, in *flatbuffers.Builder,
+       opts ...grpc.CallOption) (*Stat, error) {
+       out := new(Stat)
+       err := c.cc.Invoke(ctx, "/MyGame.Example.MonsterStorage/Store", in, out, opts...)
+       if err != nil {
+               return nil, err
+       }
+       return out, nil
 }
 
-func (c *monsterStorageClient) Retrieve(ctx context.Context, in *flatbuffers.Builder, 
-       opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error) {
-  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[0], c.cc, "/MyGame.Example.MonsterStorage/Retrieve", opts...)
-  if err != nil { return nil, err }
-  x := &monsterStorageRetrieveClient{stream}
-  if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }
-  if err := x.ClientStream.CloseSend(); err != nil { return nil, err }
-  return x,nil
+func (c *monsterStorageClient) Retrieve(ctx context.Context, in *flatbuffers.Builder,
+       opts ...grpc.CallOption) (MonsterStorage_RetrieveClient, error) {
+       stream, err := c.cc.NewStream(ctx, &_MonsterStorage_serviceDesc.Streams[0], "/MyGame.Example.MonsterStorage/Retrieve", opts...)
+       if err != nil {
+               return nil, err
+       }
+       x := &monsterStorageRetrieveClient{stream}
+       if err := x.ClientStream.SendMsg(in); err != nil {
+               return nil, err
+       }
+       if err := x.ClientStream.CloseSend(); err != nil {
+               return nil, err
+       }
+       return x, nil
 }
 
 type MonsterStorage_RetrieveClient interface {
-  Recv() (*Monster, error)
-  grpc.ClientStream
+       Recv() (*Monster, error)
+       grpc.ClientStream
 }
 
-type monsterStorageRetrieveClient struct{
-  grpc.ClientStream
+type monsterStorageRetrieveClient struct {
+       grpc.ClientStream
 }
 
 func (x *monsterStorageRetrieveClient) Recv() (*Monster, error) {
-  m := new(Monster)
-  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
-  return m, nil
+       m := new(Monster)
+       if err := x.ClientStream.RecvMsg(m); err != nil {
+               return nil, err
+       }
+       return m, nil
 }
 
-func (c *monsterStorageClient) GetMaxHitPoint(ctx context.Context, 
-       opts... grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error) {
-  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[1], c.cc, "/MyGame.Example.MonsterStorage/GetMaxHitPoint", opts...)
-  if err != nil { return nil, err }
-  x := &monsterStorageGetMaxHitPointClient{stream}
-  return x,nil
+func (c *monsterStorageClient) GetMaxHitPoint(ctx context.Context,
+       opts ...grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error) {
+       stream, err := c.cc.NewStream(ctx, &_MonsterStorage_serviceDesc.Streams[1], "/MyGame.Example.MonsterStorage/GetMaxHitPoint", opts...)
+       if err != nil {
+               return nil, err
+       }
+       x := &monsterStorageGetMaxHitPointClient{stream}
+       return x, nil
 }
 
 type MonsterStorage_GetMaxHitPointClient interface {
-  Send(*flatbuffers.Builder) error
-  CloseAndRecv() (*Stat, error)
-  grpc.ClientStream
+       Send(*flatbuffers.Builder) error
+       CloseAndRecv() (*Stat, error)
+       grpc.ClientStream
 }
 
-type monsterStorageGetMaxHitPointClient struct{
-  grpc.ClientStream
+type monsterStorageGetMaxHitPointClient struct {
+       grpc.ClientStream
 }
 
 func (x *monsterStorageGetMaxHitPointClient) Send(m *flatbuffers.Builder) error {
-  return x.ClientStream.SendMsg(m)
+       return x.ClientStream.SendMsg(m)
 }
 
 func (x *monsterStorageGetMaxHitPointClient) CloseAndRecv() (*Stat, error) {
-  if err := x.ClientStream.CloseSend(); err != nil { return nil, err }
-  m := new (Stat)
-  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
-  return m, nil
-}
-
-func (c *monsterStorageClient) GetMinMaxHitPoints(ctx context.Context, 
-       opts... grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error) {
-  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[2], c.cc, "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints", opts...)
-  if err != nil { return nil, err }
-  x := &monsterStorageGetMinMaxHitPointsClient{stream}
-  return x,nil
+       if err := x.ClientStream.CloseSend(); err != nil {
+               return nil, err
+       }
+       m := new(Stat)
+       if err := x.ClientStream.RecvMsg(m); err != nil {
+               return nil, err
+       }
+       return m, nil
+}
+
+func (c *monsterStorageClient) GetMinMaxHitPoints(ctx context.Context,
+       opts ...grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error) {
+       stream, err := c.cc.NewStream(ctx, &_MonsterStorage_serviceDesc.Streams[2], "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints", opts...)
+       if err != nil {
+               return nil, err
+       }
+       x := &monsterStorageGetMinMaxHitPointsClient{stream}
+       return x, nil
 }
 
 type MonsterStorage_GetMinMaxHitPointsClient interface {
-  Send(*flatbuffers.Builder) error
-  Recv() (*Stat, error)
-  grpc.ClientStream
+       Send(*flatbuffers.Builder) error
+       Recv() (*Stat, error)
+       grpc.ClientStream
 }
 
-type monsterStorageGetMinMaxHitPointsClient struct{
-  grpc.ClientStream
+type monsterStorageGetMinMaxHitPointsClient struct {
+       grpc.ClientStream
 }
 
 func (x *monsterStorageGetMinMaxHitPointsClient) Send(m *flatbuffers.Builder) error {
-  return x.ClientStream.SendMsg(m)
+       return x.ClientStream.SendMsg(m)
 }
 
 func (x *monsterStorageGetMinMaxHitPointsClient) Recv() (*Stat, error) {
-  m := new(Stat)
-  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
-  return m, nil
+       m := new(Stat)
+       if err := x.ClientStream.RecvMsg(m); err != nil {
+               return nil, err
+       }
+       return m, nil
 }
 
 // Server API for MonsterStorage service
 type MonsterStorageServer interface {
-  Store(context.Context, *Monster) (*flatbuffers.Builder, error)  
-  Retrieve(*Stat, MonsterStorage_RetrieveServer) error  
-  GetMaxHitPoint(MonsterStorage_GetMaxHitPointServer) error  
-  GetMinMaxHitPoints(MonsterStorage_GetMinMaxHitPointsServer) error  
+       Store(context.Context, *Monster) (*flatbuffers.Builder, error)
+       Retrieve(*Stat, MonsterStorage_RetrieveServer) error
+       GetMaxHitPoint(MonsterStorage_GetMaxHitPointServer) error
+       GetMinMaxHitPoints(MonsterStorage_GetMinMaxHitPointsServer) error
+       mustEmbedUnimplementedMonsterStorageServer()
 }
 
-func RegisterMonsterStorageServer(s *grpc.Server, srv MonsterStorageServer) {
-  s.RegisterService(&_MonsterStorage_serviceDesc, srv)
+type UnimplementedMonsterStorageServer struct {
 }
 
-func _MonsterStorage_Store_Handler(srv interface{}, ctx context.Context,
-       dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-  in := new(Monster)
-  if err := dec(in); err != nil { return nil, err }
-  if interceptor == nil { return srv.(MonsterStorageServer).Store(ctx, in) }
-  info := &grpc.UnaryServerInfo{
-    Server: srv,
-    FullMethod: "/MyGame.Example.MonsterStorage/Store",
-  }
-  
-  handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-    return srv.(MonsterStorageServer).Store(ctx, req.(* Monster))
-  }
-  return interceptor(ctx, in, info, handler)
+func (UnimplementedMonsterStorageServer) Store(context.Context, *Monster) (*flatbuffers.Builder, error) {
+       return nil, status.Errorf(codes.Unimplemented, "method Store not implemented")
+}
+
+func (UnimplementedMonsterStorageServer) Retrieve(*Stat, MonsterStorage_RetrieveServer) error {
+       return status.Errorf(codes.Unimplemented, "method Retrieve not implemented")
+}
+
+func (UnimplementedMonsterStorageServer) GetMaxHitPoint(MonsterStorage_GetMaxHitPointServer) error {
+       return status.Errorf(codes.Unimplemented, "method GetMaxHitPoint not implemented")
+}
+
+func (UnimplementedMonsterStorageServer) GetMinMaxHitPoints(MonsterStorage_GetMinMaxHitPointsServer) error {
+       return status.Errorf(codes.Unimplemented, "method GetMinMaxHitPoints not implemented")
 }
 
+func (UnimplementedMonsterStorageServer) mustEmbedUnimplementedMonsterStorageServer() {}
 
+type UnsafeMonsterStorageServer interface {
+       mustEmbedUnimplementedMonsterStorageServer()
+}
+
+func RegisterMonsterStorageServer(s grpc.ServiceRegistrar, srv MonsterStorageServer) {
+       s.RegisterService(&_MonsterStorage_serviceDesc, srv)
+}
+
+func _MonsterStorage_Store_Handler(srv interface{}, ctx context.Context,
+       dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+       in := new(Monster)
+       if err := dec(in); err != nil {
+               return nil, err
+       }
+       if interceptor == nil {
+               return srv.(MonsterStorageServer).Store(ctx, in)
+       }
+       info := &grpc.UnaryServerInfo{
+               Server:     srv,
+               FullMethod: "/MyGame.Example.MonsterStorage/Store",
+       }
+
+       handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+               return srv.(MonsterStorageServer).Store(ctx, req.(*Monster))
+       }
+       return interceptor(ctx, in, info, handler)
+}
 func _MonsterStorage_Retrieve_Handler(srv interface{}, stream grpc.ServerStream) error {
-  m := new(Stat)
-  if err := stream.RecvMsg(m); err != nil { return err }
-  return srv.(MonsterStorageServer).Retrieve(m, &monsterStorageRetrieveServer{stream})
+       m := new(Stat)
+       if err := stream.RecvMsg(m); err != nil {
+               return err
+       }
+       return srv.(MonsterStorageServer).Retrieve(m, &monsterStorageRetrieveServer{stream})
 }
 
-type MonsterStorage_RetrieveServer interface { 
-  Send(* flatbuffers.Builder) error
-  grpc.ServerStream
+type MonsterStorage_RetrieveServer interface {
+       Send(*flatbuffers.Builder) error
+       grpc.ServerStream
 }
 
 type monsterStorageRetrieveServer struct {
-  grpc.ServerStream
+       grpc.ServerStream
 }
 
 func (x *monsterStorageRetrieveServer) Send(m *flatbuffers.Builder) error {
-  return x.ServerStream.SendMsg(m)
+       return x.ServerStream.SendMsg(m)
 }
 
-
 func _MonsterStorage_GetMaxHitPoint_Handler(srv interface{}, stream grpc.ServerStream) error {
-  return srv.(MonsterStorageServer).GetMaxHitPoint(&monsterStorageGetMaxHitPointServer{stream})
+       return srv.(MonsterStorageServer).GetMaxHitPoint(&monsterStorageGetMaxHitPointServer{stream})
 }
 
-type MonsterStorage_GetMaxHitPointServer interface { 
-  Recv() (* Monster, error)
-  SendAndClose(* flatbuffers.Builder) error
-  grpc.ServerStream
+type MonsterStorage_GetMaxHitPointServer interface {
+       Recv() (*Monster, error)
+       SendAndClose(*flatbuffers.Builder) error
+       grpc.ServerStream
 }
 
 type monsterStorageGetMaxHitPointServer struct {
-  grpc.ServerStream
+       grpc.ServerStream
 }
 
 func (x *monsterStorageGetMaxHitPointServer) Recv() (*Monster, error) {
-  m := new(Monster)
-  if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }
-  return m, nil
+       m := new(Monster)
+       if err := x.ServerStream.RecvMsg(m); err != nil {
+               return nil, err
+       }
+       return m, nil
 }
 
 func (x *monsterStorageGetMaxHitPointServer) SendAndClose(m *flatbuffers.Builder) error {
-  return x.ServerStream.SendMsg(m)
+       return x.ServerStream.SendMsg(m)
 }
 
-
 func _MonsterStorage_GetMinMaxHitPoints_Handler(srv interface{}, stream grpc.ServerStream) error {
-  return srv.(MonsterStorageServer).GetMinMaxHitPoints(&monsterStorageGetMinMaxHitPointsServer{stream})
+       return srv.(MonsterStorageServer).GetMinMaxHitPoints(&monsterStorageGetMinMaxHitPointsServer{stream})
 }
 
-type MonsterStorage_GetMinMaxHitPointsServer interface { 
-  Send(* flatbuffers.Builder) error
-  Recv() (* Monster, error)
-  grpc.ServerStream
+type MonsterStorage_GetMinMaxHitPointsServer interface {
+       Send(*flatbuffers.Builder) error
+       Recv() (*Monster, error)
+       grpc.ServerStream
 }
 
 type monsterStorageGetMinMaxHitPointsServer struct {
-  grpc.ServerStream
+       grpc.ServerStream
 }
 
 func (x *monsterStorageGetMinMaxHitPointsServer) Send(m *flatbuffers.Builder) error {
-  return x.ServerStream.SendMsg(m)
+       return x.ServerStream.SendMsg(m)
 }
 
 func (x *monsterStorageGetMinMaxHitPointsServer) Recv() (*Monster, error) {
-  m := new(Monster)
-  if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }
-  return m, nil
+       m := new(Monster)
+       if err := x.ServerStream.RecvMsg(m); err != nil {
+               return nil, err
+       }
+       return m, nil
 }
 
-
 var _MonsterStorage_serviceDesc = grpc.ServiceDesc{
-  ServiceName: "MyGame.Example.MonsterStorage",
-  HandlerType: (*MonsterStorageServer)(nil),
-  Methods: []grpc.MethodDesc{
-    {
-      MethodName: "Store",
-      Handler: _MonsterStorage_Store_Handler, 
-    },
-  },
-  Streams: []grpc.StreamDesc{
-    {
-      StreamName: "Retrieve",
-      Handler: _MonsterStorage_Retrieve_Handler, 
-      ServerStreams: true,
-    },
-    {
-      StreamName: "GetMaxHitPoint",
-      Handler: _MonsterStorage_GetMaxHitPoint_Handler, 
-      ClientStreams: true,
-    },
-    {
-      StreamName: "GetMinMaxHitPoints",
-      Handler: _MonsterStorage_GetMinMaxHitPoints_Handler, 
-      ServerStreams: true,
-      ClientStreams: true,
-    },
-  },
+       ServiceName: "MyGame.Example.MonsterStorage",
+       HandlerType: (*MonsterStorageServer)(nil),
+       Methods: []grpc.MethodDesc{
+               {
+                       MethodName: "Store",
+                       Handler:    _MonsterStorage_Store_Handler,
+               },
+       },
+       Streams: []grpc.StreamDesc{
+               {
+                       StreamName:    "Retrieve",
+                       Handler:       _MonsterStorage_Retrieve_Handler,
+                       ServerStreams: true,
+               },
+               {
+                       StreamName:    "GetMaxHitPoint",
+                       Handler:       _MonsterStorage_GetMaxHitPoint_Handler,
+                       ClientStreams: true,
+               },
+               {
+                       StreamName:    "GetMinMaxHitPoints",
+                       Handler:       _MonsterStorage_GetMinMaxHitPoints_Handler,
+                       ServerStreams: true,
+                       ClientStreams: true,
+               },
+       },
 }
-