package main import ( "bytes" "html/template" "strings" ) var httpTemplate = ` type {{.ServiceType}}HTTPServer interface { {{range .MethodSets}} {{.Name}}(context.Context, *{{.Request}}) (*{{.Reply}}, error) {{end}} } func Register{{.ServiceType}}HTTPServer(s http1.ServiceRegistrar, srv {{.ServiceType}}HTTPServer) { s.RegisterService(&_HTTP_{{.ServiceType}}_serviceDesc, srv) } {{range .Methods}} func _HTTP_{{$.ServiceType}}_{{.Name}}_{{.Num}}(srv interface{}, ctx context.Context, req *http.Request, dec func(interface{}) error) (interface{}, error) { var in {{.Request}} {{if eq .Body ""}} if err := http1.BindForm(req, &in); err != nil { return nil, err } {{else if eq .Body ".*"}} if err := dec(&in); err != nil { return nil, err } {{else}} if err := dec(in{{.Body}}); err != nil { return nil, err } {{end}} {{if ne (len .Vars) 0}} if err := http1.BindVars(req, &in); err != nil { return nil, err } {{end}} out, err := srv.({{$.ServiceType}}Server).{{.Name}}(ctx, &in) if err != nil { return nil, err } return out{{.ResponseBody}}, nil } {{end}} var _HTTP_{{.ServiceType}}_serviceDesc = http1.ServiceDesc{ ServiceName: "{{.ServiceName}}", Methods: []http1.MethodDesc{ {{range .Methods}} { Path: "{{.Path}}", Method: "{{.Method}}", Handler: _HTTP_{{$.ServiceType}}_{{.Name}}_{{.Num}}, }, {{end}} }, Metadata: "{{.Metadata}}", } ` type serviceDesc struct { ServiceType string // Greeter ServiceName string // helloworld.Greeter Metadata string // api/helloworld/helloworld.proto Methods []*methodDesc MethodSets map[string]*methodDesc } type methodDesc struct { // method Name string Num int Vars []string Forms []string Request string Reply string // http_rule Path string Method string Body string ResponseBody string } func (s *serviceDesc) execute() string { s.MethodSets = make(map[string]*methodDesc) for _, m := range s.Methods { s.MethodSets[m.Name] = m } buf := new(bytes.Buffer) tmpl, err := template.New("http").Parse(strings.TrimSpace(httpTemplate)) if err != nil { panic(err) } if err := tmpl.Execute(buf, s); err != nil { panic(err) } return string(buf.Bytes()) }