// GenerateCommonStubs is the core of the plugin package. // It generates an interface based on the ServiceDescriptorProto that is used // by the other two halves of the plugin. func (p *Plugin) GenerateCommonStubs(svc *descriptor.ServiceDescriptorProto) { name := generator.CamelCase(*svc.Name) p.P("// ", name, " is an interface satisfied by the generated client and") p.P("// which must be implemented by the object wrapped by the server.") p.P("type ", name, " interface {") p.In() for _, m := range svc.Method { method := generator.CamelCase(*m.Name) iType := p.ObjectNamed(*m.InputType) oType := p.ObjectNamed(*m.OutputType) p.P(method, "(in *", p.TypeName(iType), ", out *", p.TypeName(oType), ") error") } p.Out() p.P("}") }
func generateService(g *generator.Generator, s *descriptor.ServiceDescriptorProto) { // interface g.P() g.P("type ", s.Name, " interface {") g.In() for _, m := range s.Method { g.P(generator.CamelCase(*m.Name), "(req *", typeName(g, *m.InputType), ", resp *", typeName(g, *m.OutputType), ") error") } g.Out() g.P("}") // register g.P() g.P("func Register", s.Name, "(service ", s.Name, ") {") g.In() g.P("rpc.RegisterName(", strconv.Quote(*s.Name), ", service)") g.Out() g.P("}") client_name := *s.Name + "Client" // new client g.P() g.P("func New", client_name, "(conn io.ReadWriteCloser) *", client_name, " {") g.In() g.P("codec := muduorpc.NewClientCodec(conn)") g.P("client := rpc.NewClientWithCodec(codec)") g.P("return &", client_name, "{client}") g.Out() g.P("}") // client g.P() g.P("type ", client_name, " struct {") g.In() g.P("client *rpc.Client") g.Out() g.P("}") // client methods g.P() g.P("func (c *", client_name, ") Close () error {") g.In() g.P("return c.client.Close()") g.Out() g.P("}") for _, m := range s.Method { g.P() g.P("func (c *", client_name, ") ", generator.CamelCase(*m.Name), "(req *", typeName(g, *m.InputType), ", resp *", typeName(g, *m.OutputType), ") error {") g.In() name := *s.Name + "." + *m.Name g.P("return c.client.Call(", strconv.Quote(name), ", req, resp)") g.Out() g.P("}") } }
func inspect_root_file(filename, treename string) []pb_field { f := croot.OpenFile(filename, "read", "ROOT file", 1, 0) if f == nil { fmt.Printf("**error** could not open ROOT file [%s]\n", filename) os.Exit(1) } defer f.Close("") tree := f.GetTree(treename) if tree == nil { fmt.Printf("**error** could not retrieve Tree [%s] from file [%s]\n", treename, filename) } //tree.Print("*") branches := tree.GetListOfBranches() fmt.Printf(" #-branches: %v\n", branches.GetSize()) imax := branches.GetSize() type stringset map[string]struct{} pb_fields := []pb_field{} for i := int64(0); i < imax; i++ { obj := branches.At(i) br := obj.(croot.Branch) typename := br.GetClassName() if typename == "" { leaf := tree.GetLeaf(br.GetName()) typename = leaf.GetTypeName() } if *verbose { fmt.Printf(" [%d] -> [%v] (%v) (type:%v)\n", i, obj.GetName(), br.ClassName(), typename) } name := br.GetName() pb_type, isrepeated := get_pb_type(typename) accept := true if *brsel != "" { accept = false for _, pattern := range strings.Split(*brsel, ",") { switch pattern[0] { case '-': matched, err := filepath.Match(pattern[1:], name) if err == nil && matched { accept = false break } case '+': matched, err := filepath.Match(pattern[1:], name) if err == nil && matched { accept = true break } default: matched, err := filepath.Match(pattern, name) if err == nil && matched { accept = true break } } } } if accept { pb_fields = append(pb_fields, pb_field{ Name: pb_gen.CamelCase(name), Type: pb_type, Id: <-gen_id, Branch: name, repeated: isrepeated, }) } } return pb_fields }
// GenerateRPCStubs generates the net/rpc-based stubs. // It generates an RPC client implementation of the interface as well as three // helper functions to create the Client and Server necessary to utilize the // service over RPC. func (p *Plugin) GenerateRPCStubs(svc *descriptor.ServiceDescriptorProto) { p.rpcImports = true name := generator.CamelCase(*svc.Name) p.P("// internal wrapper for type-safe RPC calling") p.P("type rpc", name, "Client struct {") p.In() p.P("*rpc.Client") p.Out() p.P("}") for _, m := range svc.Method { method := generator.CamelCase(*m.Name) iType := p.ObjectNamed(*m.InputType) oType := p.ObjectNamed(*m.OutputType) p.P("func (this rpc", name, "Client) ", method, "(in *", p.TypeName(iType), ", out *", p.TypeName(oType), ") error {") p.In() p.P(`return this.Call("`, name, ".", method, `", in, out)`) p.Out() p.P("}") } p.P() p.P("// New", name, "Client returns an *rpc.Client wrapper for calling the methods of") p.P("// ", name, " remotely.") p.P("func New", name, "Client(conn net.Conn) ", name, " {") p.In() p.P("return rpc", name, "Client{rpc.NewClientWithCodec(codec.NewClientCodec(conn))}") p.Out() p.P("}") p.P() p.P("// Serve", name, " serves the given ", name, " backend implementation on conn.") p.P("func Serve", name, "(conn net.Conn, backend ", name, ") error {") p.In() p.P("srv := rpc.NewServer()") p.P(`if err := srv.RegisterName("`, name, `", backend); err != nil {`) p.In() p.P("return err") p.Out() p.P("}") p.P("srv.ServeCodec(codec.NewServerCodec(conn))") p.P("return nil") p.Out() p.P("}") p.P() p.P("// Dial", name, " returns a ", name, " for calling the ", name, " servince at addr (TCP).") p.P("func Dial", name, "(addr string) (", name, ", error) {") p.In() p.P(`conn, err := net.Dial("tcp", addr)`) p.P("if err != nil {") p.In() p.P("return nil, err") p.Out() p.P("}") p.P("return New", name, "Client(conn), nil") p.Out() p.P("}") p.P() p.P("// ListenAndServe", name, " serves the given ", name, " backend implementation") p.P("// on all connections accepted as a result of listening on addr (TCP).") p.P("func ListenAndServe", name, "(addr string, backend ", name, ") error {") p.In() p.P(`clients, err := net.Listen("tcp", addr)`) p.P("if err != nil {") p.In() p.P("return err") p.Out() p.P("}") p.P("srv := rpc.NewServer()") p.P(`if err := srv.RegisterName("`, name, `", backend); err != nil {`) p.In() p.P("return err") p.Out() p.P("}") p.P("for {") p.In() p.P("conn, err := clients.Accept()") p.P("if err != nil {") p.In() p.P("return err") p.Out() p.P("}") p.P("go srv.ServeCodec(codec.NewServerCodec(conn))") p.Out() p.P("}") p.P(`panic("unreachable")`) p.Out() p.P("}") }
// GenerateWebStubs generates the webrpc stubs. // It generates a webrpc client implementation of the interface as well as // webrpc handlers and a helper function. func (p *Plugin) GenerateWebStubs(svc *descriptor.ServiceDescriptorProto) { p.webImports = true name := generator.CamelCase(*svc.Name) p.P(`// `, name, `Web is the web-based RPC version of the interface which`) p.P(`// must be implemented by the object wrapped by the webrpc server.`) p.P(`type `, name, `Web interface {`) p.In() for _, m := range svc.Method { method := generator.CamelCase(*m.Name) iType := p.ObjectNamed(*m.InputType) oType := p.ObjectNamed(*m.OutputType) p.P(method, "(r *http.Request, in *", p.TypeName(iType), ", out *", p.TypeName(oType), ") error") } p.Out() p.P(`}`) p.P() p.P("// internal wrapper for type-safe webrpc calling") p.P("type rpc", name, "WebClient struct {") p.In() p.P("remote *url.URL") p.P("protocol webrpc.Protocol") p.Out() p.P("}") p.P() for _, m := range svc.Method { method := generator.CamelCase(*m.Name) iType := p.ObjectNamed(*m.InputType) oType := p.ObjectNamed(*m.OutputType) p.P("func (this rpc", name, "WebClient) ", method, "(in *", p.TypeName(iType), ", out *", p.TypeName(oType), ") error {") p.In() p.P(`return webrpc.Post(this.protocol, this.remote, "/`, name, "/", method, `", in, out)`) p.Out() p.P("}") p.P() } p.P(`// Register a `, name, `Web implementation with the given webrpc ServeMux.`) p.P(`// If mux is nil, the default webrpc.ServeMux is used.`) p.P(`func Register`, name, `Web(this `, name, `Web, mux webrpc.ServeMux) error {`) p.In() p.P(`if mux == nil {`) p.In() p.P(`mux = webrpc.DefaultServeMux`) p.Out() p.P(`}`) for _, m := range svc.Method { method := generator.CamelCase(*m.Name) iType := p.ObjectNamed(*m.InputType) oType := p.ObjectNamed(*m.OutputType) p.P(`if err := mux.Handle("/`, name, "/", method, `", func(c *webrpc.Call) error {`) p.In() p.P(`in, out := new(`, p.TypeName(iType), `), new(`, p.TypeName(oType), `)`) p.P(`if err := c.ReadRequest(in); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) p.P(`if err := this.`, method, `(c.Request, in, out); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) p.P(`return c.WriteResponse(out)`) p.Out() p.P("}); err != nil {") p.In() p.P("return err") p.Out() p.P("}") } p.P("return nil") p.Out() p.P("}") p.P() p.P("// New", name, "WebClient returns a webrpc wrapper for calling the methods of ", name) p.P("// remotely via the web. The remote URL is the base URL of the webrpc server.") p.P("func New", name, "WebClient(pro webrpc.Protocol, remote *url.URL) ", name, " {") p.In() p.P("return rpc", name, "WebClient{remote, pro}") p.Out() p.P("}") }