// 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 := file.GetPackage() + "." + origServName servName := generator.CamelCase(origServName) g.P("// Server API for ", servName, " service") g.P() // Server interface. serverType := servName + "Server" g.P() g.P("func New", servName, "Mux(h ", serverType, ", prefix string) *web.Mux {") g.P(" t := _", serverType, "{}") g.P(" t.handler = h") g.P(" router := web.New()") for _, method := range service.Method { path := strings.ToLower(servName) + "/" + method.GetName() methName := generator.CamelCase(method.GetName()) // there should be a better way to get the options m := method.GetOptions().String() if m != "" { parts := strings.Split(m, "\"") if len(parts) == 3 { if parts[0] == "10000:" { path = parts[1] } } } g.P("router.Handle(prefix+\"", strings.ToLower(path), "\", t.", methName, ")") } g.P(" return router") g.P("}") g.P() g.P("type _", serverType, " struct {") g.P(" handler ", serverType) g.P("}") g.P() // Server handler implementations. for _, method := range service.Method { g.generateServerMethod(servName, method) } }
// 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()) 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 }