// generateClientSignature returns the client-side signature for a method. func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string { origMethName := method.GetName() methName := generator.CamelCase(origMethName) if reservedClientName[methName] { methName += "_" } reqArg := ", in *" + g.typeName(method.GetInputType()) if method.GetClientStreaming() { reqArg = "" } respName := "*" + g.typeName(method.GetOutputType()) if method.GetServerStreaming() || method.GetClientStreaming() { respName = servName + "_" + generator.CamelCase(origMethName) + "Client" } return fmt.Sprintf("%s(ctx %s.Context%s, opts ...%s.CallOption) (%s, error)", methName, contextPkg, reqArg, grpcPkg, respName) }
func (p *protorpcPlugin) genServiceInterface( file *generator.FileDescriptor, svc *descriptor.ServiceDescriptorProto, ) { const serviceInterfaceTmpl = ` type {{.ServiceName}} interface { {{.CallMethodList}} } ` const callMethodTmpl = ` {{.MethodName}}(in *{{.ArgsType}}, out *{{.ReplyType}}) error` // gen call method list var callMethodList string for _, m := range svc.Method { out := bytes.NewBuffer([]byte{}) t := template.Must(template.New("").Parse(callMethodTmpl)) t.Execute(out, &struct{ ServiceName, MethodName, ArgsType, ReplyType string }{ ServiceName: generator.CamelCase(svc.GetName()), MethodName: generator.CamelCase(m.GetName()), ArgsType: p.TypeName(p.ObjectNamed(m.GetInputType())), ReplyType: p.TypeName(p.ObjectNamed(m.GetOutputType())), }) callMethodList += out.String() p.RecordTypeUse(m.GetInputType()) p.RecordTypeUse(m.GetOutputType()) } // gen all interface code { out := bytes.NewBuffer([]byte{}) t := template.Must(template.New("").Parse(serviceInterfaceTmpl)) t.Execute(out, &struct{ ServiceName, CallMethodList string }{ ServiceName: generator.CamelCase(svc.GetName()), CallMethodList: callMethodList, }) p.P(out.String()) } }
// generateServerSignature returns the server-side signature for a method. func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string { origMethName := method.GetName() methName := generator.CamelCase(origMethName) if reservedClientName[methName] { methName += "_" } var reqArgs []string ret := "error" if !method.GetServerStreaming() && !method.GetClientStreaming() { reqArgs = append(reqArgs, contextPkg+".Context") ret = "(*" + g.typeName(method.GetOutputType()) + ", error)" } if !method.GetClientStreaming() { reqArgs = append(reqArgs, "*"+g.typeName(method.GetInputType())) } if method.GetServerStreaming() || method.GetClientStreaming() { reqArgs = append(reqArgs, servName+"_"+generator.CamelCase(origMethName)+"Server") } return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret }
func (g *grpc) generateServerMethod(servName string, method *pb.MethodDescriptorProto) string { methName := generator.CamelCase(method.GetName()) hname := fmt.Sprintf("_%s_%s_Handler", servName, methName) inType := g.typeName(method.GetInputType()) outType := g.typeName(method.GetOutputType()) if !method.GetServerStreaming() && !method.GetClientStreaming() { g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, dec func(interface{}) error) (interface{}, error) {") g.P("in := new(", inType, ")") g.P("if err := dec(in); err != nil { return nil, err }") g.P("out, err := srv.(", servName, "Server).", methName, "(ctx, in)") g.P("if err != nil { return nil, err }") g.P("return out, nil") g.P("}") g.P() return hname } streamType := unexport(servName) + methName + "Server" g.P("func ", hname, "(srv interface{}, stream ", grpcPkg, ".ServerStream) error {") if !method.GetClientStreaming() { g.P("m := new(", inType, ")") g.P("if err := stream.RecvMsg(m); err != nil { return err }") g.P("return srv.(", servName, "Server).", methName, "(m, &", streamType, "{stream})") } else { g.P("return srv.(", servName, "Server).", methName, "(&", streamType, "{stream})") } g.P("}") g.P() genSend := method.GetServerStreaming() genSendAndClose := !method.GetServerStreaming() genRecv := method.GetClientStreaming() // Stream auxiliary types and methods. g.P("type ", servName, "_", methName, "Server interface {") if genSend { g.P("Send(*", outType, ") error") } if genSendAndClose { g.P("SendAndClose(*", outType, ") error") } if genRecv { g.P("Recv() (*", inType, ", error)") } g.P(grpcPkg, ".ServerStream") g.P("}") g.P() g.P("type ", streamType, " struct {") g.P(grpcPkg, ".ServerStream") g.P("}") g.P() if genSend { g.P("func (x *", streamType, ") Send(m *", outType, ") error {") g.P("return x.ServerStream.SendMsg(m)") g.P("}") g.P() } if genSendAndClose { g.P("func (x *", streamType, ") SendAndClose(m *", outType, ") error {") g.P("return x.ServerStream.SendMsg(m)") g.P("}") g.P() } if genRecv { g.P("func (x *", streamType, ") Recv() (*", inType, ", error) {") g.P("m := new(", inType, ")") g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }") g.P("return m, nil") g.P("}") g.P() } return hname }
func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) { sname := fmt.Sprintf("/%s/%s", fullServName, method.GetName()) methName := generator.CamelCase(method.GetName()) inType := g.typeName(method.GetInputType()) outType := g.typeName(method.GetOutputType()) g.P("func (c *", unexport(servName), "Client) ", g.generateClientSignature(servName, method), "{") if !method.GetServerStreaming() && !method.GetClientStreaming() { g.P("out := new(", outType, ")") // TODO: Pass descExpr to Invoke. g.P("err := ", grpcPkg, `.Invoke(ctx, "`, sname, `", in, out, c.cc, opts...)`) g.P("if err != nil { return nil, err }") g.P("return out, nil") g.P("}") g.P() return } streamType := unexport(servName) + methName + "Client" g.P("stream, err := ", grpcPkg, ".NewClientStream(ctx, ", descExpr, `, c.cc, "`, sname, `", opts...)`) g.P("if err != nil { return nil, err }") g.P("x := &", streamType, "{stream}") if !method.GetClientStreaming() { g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }") g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") } g.P("return x, nil") g.P("}") g.P() genSend := method.GetClientStreaming() genRecv := method.GetServerStreaming() genCloseAndRecv := !method.GetServerStreaming() // Stream auxiliary types and methods. g.P("type ", servName, "_", methName, "Client interface {") if genSend { g.P("Send(*", inType, ") error") } if genRecv { g.P("Recv() (*", outType, ", error)") } if genCloseAndRecv { g.P("CloseAndRecv() (*", outType, ", error)") } g.P(grpcPkg, ".ClientStream") g.P("}") g.P() g.P("type ", streamType, " struct {") g.P(grpcPkg, ".ClientStream") g.P("}") g.P() if genSend { g.P("func (x *", streamType, ") Send(m *", inType, ") error {") g.P("return x.ClientStream.SendMsg(m)") g.P("}") g.P() } if genRecv { g.P("func (x *", streamType, ") Recv() (*", outType, ", error) {") g.P("m := new(", outType, ")") g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") g.P("return m, nil") g.P("}") g.P() } if genCloseAndRecv { g.P("func (x *", streamType, ") CloseAndRecv() (*", outType, ", error) {") g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") g.P("m := new(", outType, ")") g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") g.P("return m, nil") g.P("}") g.P() } }
// generateService generates all the code for the named service. func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) { path := fmt.Sprintf("6,%d", index) // 6 means service. origServName := service.GetName() fullServName := origServName if pkg := file.GetPackage(); pkg != "" { fullServName = pkg + "." + fullServName } servName := generator.CamelCase(origServName) g.P() g.P("// Client API for ", servName, " service") g.P() // Client interface. g.P("type ", servName, "Client interface {") for i, method := range service.Method { g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. g.P(g.generateClientSignature(servName, method)) } g.P("}") g.P() // Client structure. g.P("type ", unexport(servName), "Client struct {") g.P("cc *", grpcPkg, ".ClientConn") g.P("}") g.P() // NewClient factory. g.P("func New", servName, "Client (cc *", grpcPkg, ".ClientConn) ", servName, "Client {") g.P("return &", unexport(servName), "Client{cc}") g.P("}") g.P() var methodIndex, streamIndex int serviceDescVar := "_" + servName + "_serviceDesc" // Client method implementations. for _, method := range service.Method { var descExpr string if !method.GetServerStreaming() && !method.GetClientStreaming() { // Unary RPC method descExpr = fmt.Sprintf("&%s.Methods[%d]", serviceDescVar, methodIndex) methodIndex++ } else { // Streaming RPC method descExpr = fmt.Sprintf("&%s.Streams[%d]", serviceDescVar, streamIndex) streamIndex++ } g.generateClientMethod(servName, fullServName, serviceDescVar, method, descExpr) } g.P("// Server API for ", servName, " service") g.P() // Server interface. serverType := servName + "Server" g.P("type ", serverType, " interface {") for i, method := range service.Method { g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. g.P(g.generateServerSignature(servName, method)) } g.P("}") g.P() // Server registration. g.P("func Register", servName, "Server(s *", grpcPkg, ".Server, srv ", serverType, ") {") g.P("s.RegisterService(&", serviceDescVar, `, srv)`) g.P("}") g.P() // Server handler implementations. var handlerNames []string for _, method := range service.Method { hname := g.generateServerMethod(servName, method) handlerNames = append(handlerNames, hname) } // Service descriptor. g.P("var ", serviceDescVar, " = ", grpcPkg, ".ServiceDesc {") g.P("ServiceName: ", strconv.Quote(fullServName), ",") g.P("HandlerType: (*", serverType, ")(nil),") g.P("Methods: []", grpcPkg, ".MethodDesc{") for i, method := range service.Method { if method.GetServerStreaming() || method.GetClientStreaming() { continue } g.P("{") g.P("MethodName: ", strconv.Quote(method.GetName()), ",") g.P("Handler: ", handlerNames[i], ",") g.P("},") } g.P("},") g.P("Streams: []", grpcPkg, ".StreamDesc{") for i, method := range service.Method { if !method.GetServerStreaming() && !method.GetClientStreaming() { continue } g.P("{") g.P("StreamName: ", strconv.Quote(method.GetName()), ",") g.P("Handler: ", handlerNames[i], ",") if method.GetServerStreaming() { g.P("ServerStreams: true,") } if method.GetClientStreaming() { g.P("ClientStreams: true,") } g.P("},") } g.P("},") g.P("}") g.P() }
func (p *protorpcPlugin) genServiceClient( file *generator.FileDescriptor, svc *descriptor.ServiceDescriptorProto, ) { const clientHelperFuncTmpl = ` type {{.ServiceName}}Client struct { *rpc.Client } // New{{.ServiceName}}Client returns a {{.ServiceName}} stub to handle // requests to the set of {{.ServiceName}} at the other end of the connection. func New{{.ServiceName}}Client(conn io.ReadWriteCloser) (*{{.ServiceName}}Client) { c := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) return &{{.ServiceName}}Client{c} } {{.MethodList}} // Dial{{.ServiceName}} connects to an {{.ServiceName}} at the specified network address. func Dial{{.ServiceName}}(network, addr string) (*{{.ServiceName}}Client, error) { c, err := protorpc.Dial(network, addr) if err != nil { return nil, err } return &{{.ServiceName}}Client{c}, nil } // Dial{{.ServiceName}}Timeout connects to an {{.ServiceName}} at the specified network address. func Dial{{.ServiceName}}Timeout(network, addr string, timeout time.Duration) (*{{.ServiceName}}Client, error) { c, err := protorpc.DialTimeout(network, addr, timeout) if err != nil { return nil, err } return &{{.ServiceName}}Client{c}, nil } ` const clientMethodTmpl = ` func (c *{{.ServiceName}}Client) {{.MethodName}}(in *{{.ArgsType}}) (out *{{.ReplyType}}, err error) { if in == nil { in = new({{.ArgsType}}) } out = new({{.ReplyType}}) if err = c.Call("{{.ServiceRegisterName}}.{{.MethodName}}", in, out); err != nil { return nil, err } return out, nil }` // gen client method list var methodList string for _, m := range svc.Method { out := bytes.NewBuffer([]byte{}) t := template.Must(template.New("").Parse(clientMethodTmpl)) t.Execute(out, &struct{ ServiceName, ServiceRegisterName, MethodName, ArgsType, ReplyType string }{ ServiceName: generator.CamelCase(svc.GetName()), ServiceRegisterName: p.makeServiceRegisterName( file, file.GetPackage(), generator.CamelCase(svc.GetName()), ), MethodName: generator.CamelCase(m.GetName()), ArgsType: p.TypeName(p.ObjectNamed(m.GetInputType())), ReplyType: p.TypeName(p.ObjectNamed(m.GetOutputType())), }) methodList += out.String() } // gen all client code { out := bytes.NewBuffer([]byte{}) t := template.Must(template.New("").Parse(clientHelperFuncTmpl)) t.Execute(out, &struct{ PackageName, ServiceName, MethodList string }{ PackageName: file.GetPackage(), ServiceName: generator.CamelCase(svc.GetName()), MethodList: methodList, }) p.P(out.String()) } }
func (p *protorpcPlugin) genServiceServer( file *generator.FileDescriptor, svc *descriptor.ServiceDescriptorProto, ) { const serviceHelperFunTmpl = ` // Accept{{.ServiceName}}Client accepts connections on the listener and serves requests // for each incoming connection. Accept blocks; the caller typically // invokes it in a go statement. func Accept{{.ServiceName}}Client(lis net.Listener, x {{.ServiceName}}) { srv := rpc.NewServer() if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { log.Fatal(err) } for { conn, err := lis.Accept() if err != nil { log.Fatalf("lis.Accept(): %v\n", err) } go srv.ServeCodec(protorpc.NewServerCodec(conn)) } } // Register{{.ServiceName}} publish the given {{.ServiceName}} implementation on the server. func Register{{.ServiceName}}(srv *rpc.Server, x {{.ServiceName}}) error { if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { return err } return nil } // New{{.ServiceName}}Server returns a new {{.ServiceName}} Server. func New{{.ServiceName}}Server(x {{.ServiceName}}) *rpc.Server { srv := rpc.NewServer() if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { log.Fatal(err) } return srv } // ListenAndServe{{.ServiceName}} listen announces on the local network address laddr // and serves the given {{.ServiceName}} implementation. func ListenAndServe{{.ServiceName}}(network, addr string, x {{.ServiceName}}) error { lis, err := net.Listen(network, addr) if err != nil { return err } defer lis.Close() srv := rpc.NewServer() if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { return err } for { conn, err := lis.Accept() if err != nil { log.Fatalf("lis.Accept(): %v\n", err) } go srv.ServeCodec(protorpc.NewServerCodec(conn)) } } ` { out := bytes.NewBuffer([]byte{}) t := template.Must(template.New("").Parse(serviceHelperFunTmpl)) t.Execute(out, &struct{ PackageName, ServiceName, ServiceRegisterName string }{ PackageName: file.GetPackage(), ServiceName: generator.CamelCase(svc.GetName()), ServiceRegisterName: p.makeServiceRegisterName( file, file.GetPackage(), generator.CamelCase(svc.GetName()), ), }) p.P(out.String()) } }
// LHS returns a left-hand-side expression in go for this field. func (c FieldPathComponent) LHS() string { if c.Target.Message.File.proto2() { return fmt.Sprintf("Get%s()", gogen.CamelCase(c.Name)) } return gogen.CamelCase(c.Name) }
// RHS returns a right-hand-side expression in go for this field. func (c FieldPathComponent) RHS() string { return gogen.CamelCase(c.Name) }
func camelCase(in string) string { // Remove any additional underscores, e.g. convert `foo_1` into `foo1`. return strings.Replace(generator.CamelCase(in), "_", "", -1) }
func (g *micro) generateServerMethod(servName string, method *pb.MethodDescriptorProto) string { methName := generator.CamelCase(method.GetName()) hname := fmt.Sprintf("_%s_%s_Handler", servName, methName) serveType := servName + "Handler" inType := g.typeName(method.GetInputType()) outType := g.typeName(method.GetOutputType()) if !method.GetServerStreaming() && !method.GetClientStreaming() { g.P("func (h *", servName, ") ", methName, "(ctx ", contextPkg, ".Context, in *", inType, ", out *", outType, ") error {") g.P("return h.", serveType, ".", methName, "(ctx, in, out)") g.P("}") g.P() return hname } streamType := unexport(servName) + methName + "Stream" g.P("func (h *", servName, ") ", methName, "(ctx ", contextPkg, ".Context, stream server.Streamer) error {") if !method.GetClientStreaming() { g.P("m := new(", inType, ")") g.P("if err := stream.Recv(m); err != nil { return err }") g.P("return h.", serveType, ".", methName, "(ctx, m, &", streamType, "{stream})") } else { g.P("return h.", serveType, ".", methName, "(ctx, &", streamType, "{stream})") } g.P("}") g.P() genSend := method.GetServerStreaming() // genSendAndClose := !method.GetServerStreaming() genRecv := method.GetClientStreaming() // Stream auxiliary types and methods. g.P("type ", servName, "_", methName, "Stream interface {") g.P("SendMsg(interface{}) error") g.P("RecvMsg(interface{}) error") g.P("Close() error") if genSend { g.P("Send(*", outType, ") error") } /* if genSendAndClose { g.P("SendAndClose(*", outType, ") error") } */ if genRecv { g.P("Recv() (*", inType, ", error)") } g.P("}") g.P() g.P("type ", streamType, " struct {") g.P("stream ", serverPkg, ".Streamer") g.P("}") g.P() g.P("func (x *", streamType, ") Close() error {") g.P("return x.stream.Close()") g.P("}") g.P() g.P("func (x *", streamType, ") SendMsg(m interface{}) error {") g.P("return x.stream.Send(m)") g.P("}") g.P() g.P("func (x *", streamType, ") RecvMsg(m interface{}) error {") g.P("return x.stream.Recv(m)") g.P("}") g.P() if genSend { g.P("func (x *", streamType, ") Send(m *", outType, ") error {") g.P("return x.stream.Send(m)") g.P("}") g.P() } /* if genSendAndClose { g.P("func (x *", streamType, ") SendAndClose(m *", outType, ") error {") g.P("return x.Streamer.SendR(m)") g.P("}") g.P() } */ if genRecv { g.P("func (x *", streamType, ") Recv() (*", inType, ", error) {") g.P("m := new(", inType, ")") g.P("if err := x.stream.Recv(m); err != nil { return nil, err }") g.P("return m, nil") g.P("}") g.P() } return hname }
func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) { reqMethod := fmt.Sprintf("%s.%s", servName, method.GetName()) methName := generator.CamelCase(method.GetName()) inType := g.typeName(method.GetInputType()) outType := g.typeName(method.GetOutputType()) g.P("func (c *", unexport(servName), "Client) ", g.generateClientSignature(servName, method), "{") if !method.GetServerStreaming() && !method.GetClientStreaming() { g.P(`req := c.c.NewRequest(c.serviceName, "`, reqMethod, `", in)`) g.P("out := new(", outType, ")") // TODO: Pass descExpr to Invoke. g.P("err := ", `c.c.Call(ctx, req, out, opts...)`) g.P("if err != nil { return nil, err }") g.P("return out, nil") g.P("}") g.P() return } streamType := unexport(servName) + methName + "Client" g.P(`req := c.c.NewRequest(c.serviceName, "`, reqMethod, `", &`, inType, `{})`) g.P("stream, err := c.c.Stream(ctx, req, opts...)") g.P("if err != nil { return nil, err }") if !method.GetClientStreaming() { g.P("if err := stream.Send(in); err != nil { return nil, err }") } g.P("return &", streamType, "{stream}, nil") g.P("}") g.P() genSend := method.GetClientStreaming() genRecv := method.GetServerStreaming() //genCloseAndRecv := !method.GetServerStreaming() // Stream auxiliary types and methods. g.P("type ", servName, "_", methName, "Client interface {") g.P("SendMsg(interface{}) error") g.P("RecvMsg(interface{}) error") g.P("Close() error") if genSend { g.P("Send(*", inType, ") error") } if genRecv { g.P("Recv() (*", outType, ", error)") } g.P("}") g.P() g.P("type ", streamType, " struct {") g.P("stream ", clientPkg, ".Streamer") g.P("}") g.P() g.P("func (x *", streamType, ") Close() error {") g.P("return x.stream.Close()") g.P("}") g.P() g.P("func (x *", streamType, ") SendMsg(m interface{}) error {") g.P("return x.stream.Send(m)") g.P("}") g.P() g.P("func (x *", streamType, ") RecvMsg(m interface{}) error {") g.P("return x.stream.Recv(m)") g.P("}") g.P() if genSend { g.P("func (x *", streamType, ") Send(m *", inType, ") error {") g.P("return x.stream.Send(m)") g.P("}") g.P() } if genRecv { g.P("func (x *", streamType, ") Recv() (*", outType, ", error) {") g.P("m := new(", outType, ")") g.P("err := x.stream.Recv(m)") g.P("if err != nil {") g.P("return nil, err") g.P("}") g.P("return m, nil") g.P("}") g.P() } }
// generateService generates all the code for the named service. func (g *micro) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) { path := fmt.Sprintf("6,%d", index) // 6 means service. origServName := service.GetName() serviceName := strings.ToLower(service.GetName()) if pkg := file.GetPackage(); pkg != "" { serviceName = pkg } servName := generator.CamelCase(origServName) g.P() g.P("// Client API for ", servName, " service") g.P() // Client interface. g.P("type ", servName, "Client interface {") for i, method := range service.Method { g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. g.P(g.generateClientSignature(servName, method)) } g.P("}") g.P() // Client structure. g.P("type ", unexport(servName), "Client struct {") g.P("c ", clientPkg, ".Client") g.P("serviceName string") g.P("}") g.P() // NewClient factory. g.P("func New", servName, "Client (serviceName string, c ", clientPkg, ".Client) ", servName, "Client {") g.P("if c == nil {") g.P("c = ", clientPkg, ".NewClient()") g.P("}") g.P("if len(serviceName) == 0 {") g.P(`serviceName = "`, serviceName, `"`) g.P("}") g.P("return &", unexport(servName), "Client{") g.P("c: c,") g.P("serviceName: serviceName,") g.P("}") g.P("}") g.P() var methodIndex, streamIndex int serviceDescVar := "_" + servName + "_serviceDesc" // Client method implementations. for _, method := range service.Method { var descExpr string if !method.GetServerStreaming() { // Unary RPC method descExpr = fmt.Sprintf("&%s.Methods[%d]", serviceDescVar, methodIndex) methodIndex++ } else { // Streaming RPC method descExpr = fmt.Sprintf("&%s.Streams[%d]", serviceDescVar, streamIndex) streamIndex++ } g.generateClientMethod(serviceName, servName, serviceDescVar, method, descExpr) } g.P("// Server API for ", servName, " service") g.P() // Server interface. serverType := servName + "Handler" g.P("type ", serverType, " interface {") for i, method := range service.Method { g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. g.P(g.generateServerSignature(servName, method)) } g.P("}") g.P() // Server registration. g.P("func Register", servName, "Handler(s ", serverPkg, ".Server, hdlr ", serverType, ", opts ...", serverPkg, ".HandlerOption) {") g.P("s.Handle(s.NewHandler(&", servName, "{hdlr}, opts...))") g.P("}") g.P() // Handler type g.P("type ", servName, " struct {") g.P(serverType) g.P("}") g.P() // Server handler implementations. var handlerNames []string for _, method := range service.Method { hname := g.generateServerMethod(servName, method) handlerNames = append(handlerNames, hname) } /* // Service descriptor. g.P("var ", serviceDescVar, " = ", serverPkg, ".ServiceDesc {") g.P("ServiceName: ", strconv.Quote(fullServName), ",") g.P("HandlerType: (*", serverType, ")(nil),") g.P("Methods: []", serverPkg, ".MethodDesc{") for i, method := range service.Method { if method.GetServerStreaming() || method.GetClientStreaming() { continue } g.P("{") g.P("MethodName: ", strconv.Quote(method.GetName()), ",") g.P("Handler: ", handlerNames[i], ",") g.P("},") } g.P("},") g.P("Streams: []", serverPkg, ".StreamDesc{") for i, method := range service.Method { if !method.GetServerStreaming() && !method.GetClientStreaming() { continue } g.P("{") g.P("StreamName: ", strconv.Quote(method.GetName()), ",") g.P("Handler: ", handlerNames[i], ",") if method.GetServerStreaming() { g.P("ServerStreams: true,") } if method.GetClientStreaming() { g.P("ClientStreams: true,") } g.P("},") } g.P("},") g.P("}") g.P() */ }