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:
anqiansong
2022-01-11 20:34:25 +08:00
committed by GitHub
parent 2203809e5e
commit 9b592b3dee
13 changed files with 495 additions and 79 deletions

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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]
}