func (p *html) Generate(file *generator.FileDescriptor) { p.PluginImports = generator.NewPluginImports(p.Generator) httpPkg := p.NewImport("net/http") p.jsonPkg = p.NewImport("encoding/json") p.ioPkg = p.NewImport("io") contextPkg := p.NewImport("golang.org/x/net/context") p.reflectPkg = p.NewImport("reflect") p.stringsPkg = p.NewImport("strings") p.strconvPkg = p.NewImport("strconv") logPkg := p.NewImport("log") grpcPkg := p.NewImport("google.golang.org/grpc") p.P(`var DefaultHtmlStringer = func(req, resp interface{}) ([]byte, error) {`) p.In() p.P(`header := []byte("<p><div class=\"container\"><pre>")`) p.P(`data, err := `, p.jsonPkg.Use(), `.MarshalIndent(resp, "", "\t")`) p.P(`if err != nil {`) p.In() p.P(`return nil, err`) p.Out() p.P(`}`) p.P(`footer := []byte("</pre></div></p>")`) p.P(`return append(append(header, data...), footer...), nil`) p.Out() p.P(`}`) p.P(`func Serve(httpAddr, grpcAddr string, stringer func(req, resp interface{}) ([]byte, error), opts ...`, grpcPkg.Use(), `.DialOption) {`) p.In() p.P(`conn, err := `, grpcPkg.Use(), `.Dial(grpcAddr, opts...)`) p.P(`if err != nil {`) p.In() p.P(logPkg.Use(), `.Fatalf("Dial(%q) = %v", grpcAddr, err)`) p.Out() p.P(`}`) for _, s := range file.GetService() { origServName := s.GetName() servName := generator.CamelCase(origServName) p.P(origServName, `Client := New`, servName, `Client(conn)`) p.P(origServName, `Server := NewHTML`, servName, `Server(`, origServName, `Client, stringer)`) for _, m := range s.GetMethod() { p.P(httpPkg.Use(), `.HandleFunc("/`, servName, `/`, m.GetName(), `", `, origServName, `Server.`, m.GetName(), `)`) } } p.P(`if err := `, httpPkg.Use(), `.ListenAndServe(httpAddr, nil); err != nil {`) p.In() p.P(logPkg.Use(), `.Fatal(err)`) p.Out() p.P(`}`) p.Out() p.P(`}`) for _, s := range file.GetService() { origServName := s.GetName() servName := generator.CamelCase(origServName) p.P(`type html`, servName, ` struct {`) p.In() p.P(`client `, servName, `Client`) p.P(`stringer func(req, resp interface{}) ([]byte, error)`) p.Out() p.P(`}`) p.P(`func NewHTML`, servName, `Server(client `, servName, `Client, stringer func(req, resp interface{}) ([]byte, error)) *html`, servName, ` {`) p.In() p.P(`return &html`, servName, `{client, stringer}`) p.Out() p.P(`}`) for _, m := range s.GetMethod() { p.generateFormFunc(servName, m) p.P(``) p.P(`func (this *html`, servName, `) `, m.GetName(), `(w `, httpPkg.Use(), `.ResponseWriter, req *`, httpPkg.Use(), `.Request) {`) p.In() p.P("w.Write([]byte(Header(`", servName, "`,`", m.GetName(), "`)))") p.P(`jsonString := req.FormValue("json")`) p.P(`someValue := false`) p.RecordTypeUse(m.GetInputType()) p.P(`msg := &`, p.typeName(m.GetInputType()), `{}`) p.P(`if len(jsonString) > 0 {`) p.In() p.P(`err := `, p.jsonPkg.Use(), `.Unmarshal([]byte(jsonString), msg)`) p.writeError(errString) p.P(`someValue = true`) p.Out() p.P(`}`) p.P(`w.Write([]byte(Form`, servName, `_`, m.GetName(), `))`) p.P(`if someValue {`) p.In() if !m.GetClientStreaming() { if !m.GetServerStreaming() { p.P(`reply, err := this.client.`, m.GetName(), `(`, contextPkg.Use(), `.Background(), msg)`) p.writeError(errString) p.P(`out, err := this.stringer(msg, reply)`) p.writeError(errString) p.P(`w.Write(out)`) } else { p.P(`down, err := this.client.`, m.GetName(), `(`, contextPkg.Use(), `.Background(), msg)`) p.writeError(errString) p.P(`for {`) p.In() p.P(`reply, err := down.Recv()`) p.writeError(`break`) p.P(`out, err := this.stringer(msg, reply)`) p.writeError(errString) p.P(`w.Write(out)`) p.P(`w.(`, httpPkg.Use(), `.Flusher).Flush()`) p.Out() p.P(`}`) } } else { if !m.GetServerStreaming() { p.P(`up, err := this.client.Upstream(`, contextPkg.Use(), `.Background())`) p.writeError(errString) p.P(`err = up.Send(msg)`) p.writeError(errString) p.P(`reply, err := up.CloseAndRecv()`) p.writeError(errString) p.P(`out, err := this.stringer(msg, reply)`) p.writeError(errString) p.P(`w.Write(out)`) } else { p.P(`bidi, err := this.client.Bidi(`, contextPkg.Use(), `.Background())`) p.writeError(errString) p.P(`err = bidi.Send(msg)`) p.writeError(errString) p.P(`reply, err := bidi.Recv()`) p.writeError(errString) p.P(`out, err := this.stringer(msg, reply)`) p.writeError(errString) p.P(`w.Write(out)`) } } p.Out() p.P(`}`) p.P("w.Write([]byte(Footer))") p.Out() p.P(`}`) } } header1 := ` <html> <head> <title>` header2 := `</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> </head> <body> ` footer := ` </body> </html> ` p.P("var Header func(servName, methodName string) string = func(servName, methodName string) string {") p.In() p.P("return `", header1, "` + servName + `:` + methodName + `", header2, "`") p.Out() p.P(`}`) p.P("var Footer string = `", footer, "`") }