func fillTreeWithMethod(tree *tree, key string, proto *descriptor.MethodDescriptorProto, loc string, locs map[string]*descriptor.SourceCodeInfo_Location) *method { key = fmt.Sprintf("%s.%s", key, proto.GetName()) tree.methods[key] = &method{key: key, comment: getComment(loc, locs), MethodDescriptorProto: proto} if input, ok := tree.messages[proto.GetInputType()]; ok { tree.methods[key].input = input } if proto.GetClientStreaming() { tree.methods[key].inputStream = true } if output, ok := tree.messages[proto.GetOutputType()]; ok { tree.methods[key].output = output } if proto.GetServerStreaming() { tree.methods[key].outputStream = true } if proto.Options != nil && protobuf.HasExtension(proto.Options, gateway.E_Http) { ext, err := protobuf.GetExtension(proto.Options, gateway.E_Http) if err == nil { if opts, ok := ext.(*gateway.HttpRule); ok { if endpoint := newEndpoint(opts); endpoint != nil { tree.methods[key].endpoints = append(tree.methods[key].endpoints, endpoint) } for _, opts := range opts.AdditionalBindings { if endpoint := newEndpoint(opts); endpoint != nil { tree.methods[key].endpoints = append(tree.methods[key].endpoints, endpoint) } } } } } return tree.methods[key] }
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()) g.P() serverType := servName + "Server" g.P("// _", serverType, ".", methName, "(", inType, ") ", outType) g.P("var _ = ", inType, "{} // to prevent error, if not directly used") g.P("var _ = ", outType, "{} // to prevent error, if not directly used") g.P("func (impl* _", serverType, " )", methName, "(c web.C, w http.ResponseWriter, r *http.Request) {") if method.GetServerStreaming() || method.GetClientStreaming() { g.P(" w.WriteHeader(501)") g.P(" w.Write([]byte(`Streaming functions over http are not supported`))") g.P(" return") } else { g.P(" in := ", inType, "{}") g.P(" content, err := ioutil.ReadAll(r.Body)") g.P(" defer r.Body.Close()") g.P(" if err != nil {") g.P(" w.WriteHeader(408)") g.P(" w.Write([]byte(err.Error()))") g.P(" log.Println(err.Error())") g.P(" return") g.P(" }") g.P(" err = json.Unmarshal(content, &in)") g.P(" if err != nil {") g.P(" w.WriteHeader(400)") g.P(" w.Write([]byte(err.Error()))") g.P(" log.Println(err.Error())") g.P(" return") g.P(" }") g.P(" res,err := impl.handler.", methName, "(context.Background(),&in)") g.P(" if err != nil {") g.P(" w.WriteHeader(500)") g.P(" w.Write([]byte(err.Error()))") g.P(" log.Println(err.Error())") g.P(" return") g.P(" }") g.P(" json.NewEncoder(w).Encode(res)") } g.P("}") g.P() return hname }
// 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) }
// 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 parsePath(msgs map[string]message, method *google_protobuf.MethodDescriptorProto, path string) (ret []field) { parts := strings.Split(path, "/") for _, p := range parts { if len(p) > 0 && p[0] == '{' && p[len(p)-1] == '}' { found := false for _, field := range msgs[method.GetInputType()].Fields { if field.ProtoName == p[1:len(p)-1] { ret = append(ret, field) found = true } } if !found { ret = append(ret, field{"", ""}) } } else { ret = append(ret, field{"", ""}) } } return }
func (r *Registry) newMethod(svc *Service, md *descriptor.MethodDescriptorProto, opts *options.HttpRule) (*Method, error) { requestType, err := r.LookupMsg(svc.File.GetPackage(), md.GetInputType()) if err != nil { return nil, err } responseType, err := r.LookupMsg(svc.File.GetPackage(), md.GetOutputType()) if err != nil { return nil, err } meth := &Method{ Service: svc, MethodDescriptorProto: md, RequestType: requestType, ResponseType: responseType, } newBinding := func(opts *options.HttpRule, idx int) (*Binding, error) { var ( httpMethod string pathTemplate string ) switch { case opts.GetGet() != "": httpMethod = "GET" pathTemplate = opts.GetGet() if opts.Body != "" { return nil, fmt.Errorf("needs request body even though http method is GET: %s", md.GetName()) } case opts.GetPut() != "": httpMethod = "PUT" pathTemplate = opts.GetPut() case opts.GetPost() != "": httpMethod = "POST" pathTemplate = opts.GetPost() case opts.GetDelete() != "": httpMethod = "DELETE" pathTemplate = opts.GetDelete() if opts.Body != "" { return nil, fmt.Errorf("needs request body even though http method is DELETE: %s", md.GetName()) } case opts.GetPatch() != "": httpMethod = "PATCH" pathTemplate = opts.GetPatch() case opts.GetCustom() != nil: custom := opts.GetCustom() httpMethod = custom.Kind pathTemplate = custom.Path default: glog.Errorf("No pattern specified in google.api.HttpRule: %s", md.GetName()) return nil, fmt.Errorf("none of pattern specified") } parsed, err := httprule.Parse(pathTemplate) if err != nil { return nil, err } tmpl := parsed.Compile() if md.GetClientStreaming() && len(tmpl.Fields) > 0 { return nil, fmt.Errorf("cannot use path parameter in client streaming") } b := &Binding{ Method: meth, Index: idx, PathTmpl: tmpl, HTTPMethod: httpMethod, } for _, f := range tmpl.Fields { param, err := r.newParam(meth, f) if err != nil { return nil, err } b.PathParams = append(b.PathParams, param) } // TODO(yugui) Handle query params b.Body, err = r.newBody(meth, opts.Body) if err != nil { return nil, err } return b, nil } b, err := newBinding(opts, 0) if err != nil { return nil, err } meth.Bindings = append(meth.Bindings, b) for i, additional := range opts.GetAdditionalBindings() { if len(additional.AdditionalBindings) > 0 { return nil, fmt.Errorf("additional_binding in additional_binding not allowed: %s.%s", svc.GetName(), meth.GetName()) } b, err := newBinding(additional, i+1) if err != nil { return nil, err } meth.Bindings = append(meth.Bindings, b) } return meth, nil }
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() } }
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() } }
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()) g.P("// methName: ", methName) g.P("// hname: ", hname) g.P("// servName: ", servName) g.P("// method.GetName(): ", method.GetName()) g.P("// inType: ", inType) g.P("// outType: ", outType) g.P() serverType := servName + "Server" g.P("func (impl* _", serverType, " )_", methName, "(c web.C, w http.ResponseWriter, r *http.Request) {") g.P(" in := ", inType, "{}") g.P(" content, err := ioutil.ReadAll(r.Body)") g.P(" defer r.Body.Close()") g.P(" if err != nil {") g.P(" w.WriteHeader(400)") g.P(" w.Write([]byte(err.Error()))") g.P(" fmt.Println(err.Error())") g.P(" return") g.P(" }") g.P(" err = json.Unmarshal(content, in)") g.P(" if err != nil {") g.P(" w.WriteHeader(400)") g.P(" w.Write([]byte(err.Error()))") g.P(" fmt.Println(err.Error())") g.P(" return") g.P(" }") //g.P(" return err") //g.P(" if request2Json(r, &in, w) != nil {") //g.P(" return") //g.P(" }") //g.P(" json.NewEncoder(w).Encode(handler.logic.setContext(&c).ConnectionTest(in))") g.P(" res,err := impl.handler.", methName, "(context.TODO(),&in)") g.P(" if err != nil {") g.P(" w.WriteHeader(400)") g.P(" w.Write([]byte(err.Error()))") g.P(" fmt.Println(err.Error())") g.P(" return") g.P(" }") g.P(" json.NewEncoder(w).Encode(res)") g.P("}") g.P() /*if !method.GetServerStreaming() && !method.GetClientStreaming() { g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, codec ", grpcPkg, ".Codec, buf []byte) (interface{}, error) {") g.P("in := new(", inType, ")") g.P("if err := codec.Unmarshal(buf, 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() } */ g.P() return hname }