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, m middleware.Middleware) (interface{}, error) {
var in {{.Request}}
{{if ne (len .Vars) 0}}
if err := http1.BindVars(req, &in); err != nil {
return nil, err
}
{{end}}
{{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}}
h := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.({{$.ServiceType}}Server).{{.Name}}(ctx, &in)
}
out, err := m(h)(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())
}