Feature rpc protoc (#1251)
* code generation by protoc * generate pb by protoc direct * support: grpc code generation by protoc directly * format code * check --go_out & --go-grpc_out * fix typo * Update version * fix typo * optimize: remove deprecated unit test * format code Co-authored-by: anqiansong <anqiansong@bytedance.com>
This commit is contained in:
@@ -14,23 +14,44 @@ import (
|
||||
type RPCGenerator struct {
|
||||
g Generator
|
||||
cfg *conf.Config
|
||||
ctx *ZRpcContext
|
||||
}
|
||||
|
||||
type RPCGeneratorOption func(g *RPCGenerator)
|
||||
|
||||
type ZRpcContext struct {
|
||||
Src string
|
||||
ProtocCmd string
|
||||
ProtoGenGrpcDir string
|
||||
ProtoGenGoDir string
|
||||
Output string
|
||||
}
|
||||
|
||||
// NewDefaultRPCGenerator wraps Generator with configure
|
||||
func NewDefaultRPCGenerator(style string) (*RPCGenerator, error) {
|
||||
func NewDefaultRPCGenerator(style string, options ...RPCGeneratorOption) (*RPCGenerator, error) {
|
||||
cfg, err := conf.NewConfig(style)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRPCGenerator(NewDefaultGenerator(), cfg), nil
|
||||
return NewRPCGenerator(NewDefaultGenerator(), cfg, options...), nil
|
||||
}
|
||||
|
||||
// NewRPCGenerator creates an instance for RPCGenerator
|
||||
func NewRPCGenerator(g Generator, cfg *conf.Config) *RPCGenerator {
|
||||
return &RPCGenerator{
|
||||
func NewRPCGenerator(g Generator, cfg *conf.Config, options ...RPCGeneratorOption) *RPCGenerator {
|
||||
out := &RPCGenerator{
|
||||
g: g,
|
||||
cfg: cfg,
|
||||
}
|
||||
for _, opt := range options {
|
||||
opt(out)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func WithZRpcContext(c *ZRpcContext) RPCGeneratorOption {
|
||||
return func(g *RPCGenerator) {
|
||||
g.ctx = c
|
||||
}
|
||||
}
|
||||
|
||||
// Generate generates an rpc service, through the proto file,
|
||||
@@ -63,7 +84,7 @@ func (g *RPCGenerator) Generate(src, target string, protoImportPath []string, go
|
||||
return err
|
||||
}
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto, g.cfg)
|
||||
dirCtx, err := mkdir(projectCtx, proto, g.cfg, g.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -73,7 +94,7 @@ func (g *RPCGenerator) Generate(src, target string, protoImportPath []string, go
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenPb(dirCtx, protoImportPath, proto, g.cfg, goOptions...)
|
||||
err = g.g.GenPb(dirCtx, protoImportPath, proto, g.cfg, g.ctx, goOptions...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ package {{.filePackage}}
|
||||
import (
|
||||
"context"
|
||||
|
||||
{{.package}}
|
||||
{{.pbPackage}}
|
||||
{{if ne .pbPackage .protoGoPackage}}{{.protoGoPackage}}{{end}}
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
@@ -100,14 +101,15 @@ func (g *DefaultGenerator) GenCall(ctx DirContext, proto parser.Proto, cfg *conf
|
||||
aliasKeys := alias.KeysStr()
|
||||
sort.Strings(aliasKeys)
|
||||
err = util.With("shared").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"name": callFilename,
|
||||
"alias": strings.Join(aliasKeys, pathx.NL),
|
||||
"head": head,
|
||||
"filePackage": dir.Base,
|
||||
"package": fmt.Sprintf(`"%s"`, ctx.GetPb().Package),
|
||||
"serviceName": stringx.From(service.Name).ToCamel(),
|
||||
"functions": strings.Join(functions, pathx.NL),
|
||||
"interface": strings.Join(iFunctions, pathx.NL),
|
||||
"name": callFilename,
|
||||
"alias": strings.Join(aliasKeys, pathx.NL),
|
||||
"head": head,
|
||||
"filePackage": dir.Base,
|
||||
"pbPackage": fmt.Sprintf(`"%s"`, ctx.GetPb().Package),
|
||||
"protoGoPackage": fmt.Sprintf(`"%s"`, ctx.GetProtoGo().Package),
|
||||
"serviceName": stringx.From(service.Name).ToCamel(),
|
||||
"functions": strings.Join(functions, pathx.NL),
|
||||
"interface": strings.Join(iFunctions, pathx.NL),
|
||||
}, filename, true)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -15,5 +15,5 @@ type Generator interface {
|
||||
GenLogic(ctx DirContext, proto parser.Proto, cfg *conf.Config) error
|
||||
GenServer(ctx DirContext, proto parser.Proto, cfg *conf.Config) error
|
||||
GenSvc(ctx DirContext, proto parser.Proto, cfg *conf.Config) error
|
||||
GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, cfg *conf.Config, goOptions ...string) error
|
||||
GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, cfg *conf.Config, c *ZRpcContext, goOptions ...string) error
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package generator
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -16,7 +17,12 @@ const googleProtocGenGoErr = `--go_out: protoc-gen-go: plugins are not supported
|
||||
|
||||
// GenPb generates the pb.go file, which is a layer of packaging for protoc to generate gprc,
|
||||
// but the commands and flags in protoc are not completely joined in goctl. At present, proto_path(-I) is introduced
|
||||
func (g *DefaultGenerator) GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, _ *conf.Config, goOptions ...string) error {
|
||||
func (g *DefaultGenerator) GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, _ *conf.Config, c *ZRpcContext, goOptions ...string) error {
|
||||
if c != nil {
|
||||
return g.genPbDirect(c)
|
||||
}
|
||||
|
||||
// deprecated: use genPbDirect instead.
|
||||
dir := ctx.GetPb()
|
||||
cw := new(bytes.Buffer)
|
||||
directory, base := filepath.Split(proto.Src)
|
||||
@@ -103,3 +109,14 @@ go get -u github.com/golang/protobuf/protoc-gen-go`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *DefaultGenerator) genPbDirect(c *ZRpcContext) error {
|
||||
g.log.Debug(c.ProtocCmd)
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = execx.Run(c.ProtocCmd, pwd)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
|
||||
type {{.server}}Server struct {
|
||||
svcCtx *svc.ServiceContext
|
||||
{{.unimplementedServer}}
|
||||
}
|
||||
|
||||
func New{{.server}}Server(svcCtx *svc.ServiceContext) *{{.server}}Server {
|
||||
@@ -83,11 +84,12 @@ func (g *DefaultGenerator) GenServer(ctx DirContext, proto parser.Proto, cfg *co
|
||||
}
|
||||
|
||||
err = util.With("server").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"head": head,
|
||||
"server": stringx.From(service.Name).ToCamel(),
|
||||
"imports": strings.Join(imports.KeysStr(), pathx.NL),
|
||||
"funcs": strings.Join(funcList, pathx.NL),
|
||||
"notStream": notStream,
|
||||
"head": head,
|
||||
"unimplementedServer": fmt.Sprintf("%s.Unimplemented%sServer", proto.PbPackage, stringx.From(service.Name).ToCamel()),
|
||||
"server": stringx.From(service.Name).ToCamel(),
|
||||
"imports": strings.Join(imports.KeysStr(), pathx.NL),
|
||||
"funcs": strings.Join(funcList, pathx.NL),
|
||||
"notStream": notStream,
|
||||
}, serverFile, true)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ const (
|
||||
server = "server"
|
||||
svc = "svc"
|
||||
pb = "pb"
|
||||
protoGo = "proto-go"
|
||||
call = "call"
|
||||
)
|
||||
|
||||
@@ -34,6 +35,7 @@ type (
|
||||
GetServer() Dir
|
||||
GetSvc() Dir
|
||||
GetPb() Dir
|
||||
GetProtoGo() Dir
|
||||
GetMain() Dir
|
||||
GetServiceName() stringx.String
|
||||
}
|
||||
@@ -51,7 +53,7 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func mkdir(ctx *ctx.ProjectContext, proto parser.Proto, _ *conf.Config) (DirContext, error) {
|
||||
func mkdir(ctx *ctx.ProjectContext, proto parser.Proto, _ *conf.Config, c *ZRpcContext) (DirContext, error) {
|
||||
inner := make(map[string]Dir)
|
||||
etcDir := filepath.Join(ctx.WorkDir, "etc")
|
||||
internalDir := filepath.Join(ctx.WorkDir, "internal")
|
||||
@@ -60,6 +62,12 @@ func mkdir(ctx *ctx.ProjectContext, proto parser.Proto, _ *conf.Config) (DirCont
|
||||
serverDir := filepath.Join(internalDir, "server")
|
||||
svcDir := filepath.Join(internalDir, "svc")
|
||||
pbDir := filepath.Join(ctx.WorkDir, proto.GoPackage)
|
||||
protoGoDir := pbDir
|
||||
if c != nil {
|
||||
pbDir = c.ProtoGenGrpcDir
|
||||
protoGoDir = c.ProtoGenGoDir
|
||||
}
|
||||
|
||||
callDir := filepath.Join(ctx.WorkDir, strings.ToLower(stringx.From(proto.Service.Name).ToCamel()))
|
||||
if strings.EqualFold(proto.Service.Name, proto.GoPackage) {
|
||||
callDir = filepath.Join(ctx.WorkDir, strings.ToLower(stringx.From(proto.Service.Name+"_client").ToCamel()))
|
||||
@@ -100,11 +108,19 @@ func mkdir(ctx *ctx.ProjectContext, proto parser.Proto, _ *conf.Config) (DirCont
|
||||
Package: filepath.ToSlash(filepath.Join(ctx.Path, strings.TrimPrefix(svcDir, ctx.Dir))),
|
||||
Base: filepath.Base(svcDir),
|
||||
}
|
||||
|
||||
inner[pb] = Dir{
|
||||
Filename: pbDir,
|
||||
Package: filepath.ToSlash(filepath.Join(ctx.Path, strings.TrimPrefix(pbDir, ctx.Dir))),
|
||||
Base: filepath.Base(pbDir),
|
||||
}
|
||||
|
||||
inner[protoGo] = Dir{
|
||||
Filename: protoGoDir,
|
||||
Package: filepath.ToSlash(filepath.Join(ctx.Path, strings.TrimPrefix(protoGoDir, ctx.Dir))),
|
||||
Base: filepath.Base(protoGoDir),
|
||||
}
|
||||
|
||||
inner[call] = Dir{
|
||||
Filename: callDir,
|
||||
Package: filepath.ToSlash(filepath.Join(ctx.Path, strings.TrimPrefix(callDir, ctx.Dir))),
|
||||
@@ -155,6 +171,10 @@ func (d *defaultDirContext) GetPb() Dir {
|
||||
return d.inner[pb]
|
||||
}
|
||||
|
||||
func (d *defaultDirContext) GetProtoGo() Dir {
|
||||
return d.inner[protoGo]
|
||||
}
|
||||
|
||||
func (d *defaultDirContext) GetMain() Dir {
|
||||
return d.inner[wd]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user