proto_parser

package
v0.0.0-...-420bf1b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2022 License: MIT Imports: 29 Imported by: 1

README

proto-parser

分析proto文件进行代码自动注入与生成

已将其集成至 tker 中 以工具化标准化的方式进行数据定义

预备工作:

  • 安装 protoc-go-inject-tag

    go get github.com/favadi/protoc-go-inject-tag

Documentation

Index

Constants

View Source
const (
	ErrCodeName  = "ErrCode"
	NameModel    = "Model"
	NameAPIGroup = "API"
	NameReq      = "Req"
	NameResp     = "Resp"
	NameGormTag  = "@gorm"
)

Message 名字前后缀相关

View Source
const (
	RegexpBson              = "@bson:(\\s)*([a-zA-Z0-9_-]+)"
	RegexpJson              = "@json:[\\s]*([a-zA-Z0-9_-]+)"
	RegexpGorm              = "@gorm:[\\s]*([a-zA-Z0-9_\\-:<>;\\(\\)\\s]+)"
	RegexpJsonStyle         = "@json_style:\\s*([a-zA-Z0-9_]+)"
	RegexpGroupRouter       = "@route_group:\\s*([\\w]*)"
	RegexpGroupRouterAPI    = "@route_api:\\s*([\\w|/]*)"
	RegexpRouterGenTo       = "@gen_to:\\s*([\\w|/|\\.]*)"
	RegexpRouterRpcAuthor   = "@author:\\s*(.*)"
	RegexpRouterRpcDesc     = "@desc:\\s*(.*)"
	RegexpRouterRpcMethod   = "@method:\\s*([\\w]*)"
	RegexpRouterRpcURL      = "@api:\\s*([\\w|/]*)"
	RegexpAddModel          = "@model:\\s*true"
	RegexpMiddlewareContent = "@middleware:[\\s]*([^\\s].*)"
	RegexpMiddlewareFunc    = "([a-zA-Z0-9_/\\-]*)\\[(.*?)*\\]"
	RegexpRpcGen            = "@rpc_gen:\\s*true"
	RegexpFreq              = "@freq:[\\s]*(\\d+\\s\\d+\\s\\d+)"
)

正则相关

View Source
const CompleteRouteGenerateAndPackageTpl = `` /* 924-byte string literal not displayed */
View Source
const CompleteRouteGenerateTpl = `` /* 870-byte string literal not displayed */
View Source
const ErrCodeTpl = `` /* 457-byte string literal not displayed */
View Source
const FreqTpl = `` /* 251-byte string literal not displayed */
View Source
const FuncRouteGenerateBindFuncTpl = `` /* 194-byte string literal not displayed */
View Source
const FuncRouteGenerateTpl = `` /* 467-byte string literal not displayed */
View Source
const GroupRouterTpl = `// Code generated by proto_parser. DO NOT EDIT.

package {{.PackageName}}

import ({{range $pkg := .GroupRouterImportPkg}}
	"{{$pkg}}"{{end}}
	"gitter.top/tk/tk/core"
)

{{range $srvName, $srvRPC := .GroupRouterMap}}
type {{$srvName}}Impl interface { ` + `{{range $apiIndex, $api := $srvRPC.Apis}}
	{{$api.FuncName}}(ctx *core.Context, req *{{$api.ReqName}}) (resp *{{$api.RespName}}, err error){{end}}
}
{{end}}
var (
	{{range $srvName, $srvRPC := .GroupRouterMap}}{{$srvName}}GroupRouterMap = map[string]*core.GroupRouter{
		"{{$srvName}}": &core.GroupRouter{
			RouterPrefix: "{{$srvRPC.RouterPrefix}}",
			Apis: map[string]*core.GroupRouterNode{ {{range $apiName, $api := $srvRPC.Apis}}
				"{{$api.FuncName}}": {
					API:      "{{$api.RouterPath}}",
					Method:   "{{$api.Method}}",
					Author:   "{{$api.Author}}",
					Describe: "{{$api.Describe}}",{{$mwl := len $api.Mws}}{{if ne $mwl 0}}
					Middlewares: []gin.HandlerFunc{ {{range $mwName := $api.Mws}}
						{{$mwName}},{{end}} 
					},{{end}}
				},{{end}}
			},{{$mwl := len $srvRPC.Mws}}{{if ne $mwl 0}}
			Middlewares: []gin.HandlerFunc{ {{range $mwName := $srvRPC.Mws}}
				{{$mwName}},{{end}} 
			},{{end}}
		},
	}
	{{end}}
)
`
View Source
const ModelFieldTpl = `` /* 794-byte string literal not displayed */
View Source
const ModelTpl = `` /* 1333-byte string literal not displayed */
View Source
const OutputMDTpl = `
**简要描述:**

- {{.Node.Describe}}

**请求URL:**
- ` + "`" + `{{.Node.RouterPath}}` + "`" + `

**请求方式:**
- {{.Node.Method}}

**对接人:**
- {{.Node.Author}}

**参数:**

{{if not_body_empty .ReqBody}}
|参数名|必选|类型|说明|
| :---- | :--- | :----- | ----- |{{range $field := .ReqFields}}
| {{$field.FieldName}} | {{if $field.IsRequire}}是{{else}}否{{end}} | {{$field.FieldType}} | {{$field.FieldDesc}} |{{end}}
{{else}}> 该接口没有请求参数{{end}}

**请求示例**
` + "```json" + `
{{.ReqBody}}
` + "```" + `

**返回示例**
` + "```json" + `
{{.RespBody}}
` + "```" + `

**返回参数说明**
{{if not_body_empty .RespBody}}
|参数名|类型|说明|
| :---- | :---- | ----- |{{range $field := .RespFields}}
| {{$field.FieldName}} | {{$field.FieldType}} | {{$field.FieldDesc}} |{{end}}
{{$enums := len .EnumFields}}
{{if ne $enums 0}}**枚举说明**
{{range $enumType, $enumFields := .EnumFields}}
|枚举类型|枚举参数|枚举数值|枚举说明|
| :---- | :--- | :----- | ----- |{{range $fieldInfo := $enumFields}}
| {{$enumType}} | {{$fieldInfo.FieldName}} | {{$fieldInfo.FieldValue}} | {{$fieldInfo.FieldDesc}} |{{end}}
{{end}}
{{end}}{{else}}> 该接口不需要关注输出而应该关注错误码{{end}}
{{$errcs := len .ErrCodeList}}{{if ne $errcs 0}}**接口返回错误码**

|错误标注|错误码|说明|
| :---- | :---- | ---- |{{range $e := .ErrCodeList}}{{$defCode := eq $e.Code 0}}{{$defDesc := eq $e.Desc ""}}
| {{$e.Name}} | {{if and $defCode $defDesc}}-{{else}}{{$e.Code}}{{end}} | {{if and $defCode $defDesc}}其他项目中的错误码{{else}}{{$e.Desc}}{{end}} |{{end}}
{{end}}`

Variables

View Source
var (
	// ModelTplNotGenerateGetScopeFunc 控制 ModelTpl 模板不生成 GetScope 函数
	ModelTplNotGenerateGetScopeFunc bool
	// FreqRuleOutput 限频规则输出路径
	FreqRuleOutput string
)

全局变量相关

Functions

func AddAPI

func AddAPI(pbFile, groupRouter, apiName, method string) error

AddAPI 生成一个API 并自动生成Req/Resp

func AddRPC

func AddRPC(pbFile, srvName, apiName string) error

AddRPC 生成一个RPC 并自动生成Req/Resp

func AddRoute

func AddRoute(pbFile, routeName, api, genTo string) error

AddRoute 生成路由组

func AddSvc

func AddSvc(pbFile, svcName, genTo string) error

AddSvc 生成service

func CodeGen

func CodeGen(config *CodeGenConfig) error

CodeGen 代码自动生成 自动注入bson; 自动抽离 model 的字段 自定义注入json; 自定义表名 table_name 自动生成路由->请求结构体映射; 自动生成mongo index

func GenModelCode

func GenModelCode(packageName, srcPath string) error

func GormTagGenerate

func GormTagGenerate(field, tag, typ string) string

GormTagGenerate gorm注入tag

func IsBodyEmpty

func IsBodyEmpty(s string) bool

IsBodyEmpty 是否不需要关心文档返回

func IsOuterProjectErrorCode

func IsOuterProjectErrorCode(err string) bool

IsOuterProjectErrorCode 是否是项目外部的错误码

func Len

func Len(s string) int

Len 返回字符串长度

func NotBodyEmpty

func NotBodyEmpty(s string) bool

NotBodyEmpty 是否文档为空

func OutputMD

func OutputMD(pbFile, srv, rpc string, includes []string) error

OutputMD 输出markdown文档

func ParseProto

func ParseProto(pbFile string) (midFile string, err error)

ParseProto 传入proto文件 返回中间proto文件和错误信息

Types

type AstTree

type AstTree struct {
	// contains filtered or unexported fields
}

type CodeGenConfig

type CodeGenConfig struct {
	PbFilePath       string   // 需要生成的proto文件路径 支持目录但不支持正则
	OutputPath       string   // 代码需要生成到什么位置
	GrpcOutputPath   string   // grpc代码需要生成到什么位置
	IncludePbFiles   []string // 生成的代码引用到的其他proto文件列表
	OutputNeedFormat bool     // 生成位置的代码是否需要用 gofmt 格式化一下
	NoGetScopeFunc   bool     // 生成的代码不要包含 mdbc 的 GetScope 函数
	DbDriveType      string   // 数据库驱动类型
	FreqOutput       string   // 限频文件输出路径
}

type ErrCodeInfo

type ErrCodeInfo struct {
	ErrCode int
	ErrName string
	ErrMsg  string
}

type FreqConfig

type FreqConfig struct {
	Minute int64
	Hour   int64
	Day    int64
}

type FreqMap

type FreqMap map[string]FreqConfig

FreqMap 接口限频配置

func (*FreqMap) Exist

func (f *FreqMap) Exist(key string) bool

Exist 是否存在接口限频

type GroupRouter

type GroupRouter struct {
	RouterPrefix string             // 路由前缀
	GenTo        string             // 生成位置
	Apis         []*GroupRouterNode // 路由节点
	Mws          []string           // 组公共路由中间件
}

GroupRouter 组路由聚合

type GroupRouterNode

type GroupRouterNode struct {
	FuncName   string // 函数名
	RouterPath string // 路由路径
	Method     string // 请求类型 POST/GET...
	Author     string // 接口作者
	Describe   string // 描述
	ReqName    string
	RespName   string

	Mws []string // 单一路由中间件
	// contains filtered or unexported fields
}

GroupRouterNode 组路由节点

type IndexField

type IndexField struct {
	Field string // 字段
	Sort  int    // 排序 1 升序 -1倒叙
}

type IndexInfo

type IndexInfo struct {
	Unique             bool          // 唯一索引
	Name               string        // 索引名称
	TTLIndex           bool          // 是否是TTL索引
	ExpireAfterSeconds int64         // 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间
	Fields             []*IndexField // 联合索引
}

type MDocs

type MDocs struct {
	Node         *GroupRouterNode
	ReqName      string
	RspName      string
	Req          *proto.Message
	Rsp          *proto.Message
	ReqBody      string
	RespBody     string
	ReqFields    []*MDocsField
	RespFields   []*MDocsField
	EnumFields   map[string][]*MDocsField
	ErrCodeMap   map[string]MDocsErrCodeField
	ErrCodeList  MDocsErrCodes
	FieldJSONMap map[string]string
}

MDocs 文档数据

type MDocsErrCodeField

type MDocsErrCodeField struct {
	Code int    // 错误码
	Pkg  string // 这个错误码所对应的包
	Name string // 错误码的名字
	Desc string // 错误码的描述
}

MDocsErrCodeField rpc文档的错误码说明

type MDocsErrCodes

type MDocsErrCodes []MDocsErrCodeField

func (MDocsErrCodes) SortStableUsing

func (ss MDocsErrCodes) SortStableUsing(less func(a, b MDocsErrCodeField) bool) MDocsErrCodes

SortStableUsing works similar to sort.SliceStable. However, unlike sort.SliceStable the slice returned will be reallocated as to not modify the input slice.

type MDocsField

type MDocsField struct {
	FieldName  string // 字段名 对应json字段
	FieldType  string // 字段类型
	FieldDesc  string // 字段说明
	IsRequire  bool   // 是否必须
	FieldValue int    // 字段值
}

MDocsField 字段描述

type ModelFieldStruct

type ModelFieldStruct struct {
	StructFieldName string
	DbFieldName     string
	Comment         string
}

type ProtoVisitor

type ProtoVisitor struct {
	CurMsg *proto.Message
	// key 是msg嵌套层级 依靠_维持
	AllMsgMap      map[string]*proto.Message
	ModelMsgMap    map[string]*proto.Message
	OpenBsonMsgMap map[string]*proto.Message // 开启了bson支持的message
	// key是field的最终层级 依靠_维持 value是bson_tag或者原字段名称(没找到直接按照原名称写入)
	BsonTagMap map[string]string
	// 包名
	PackageName string
	// MDocDepPkgName 文档依赖的包名
	MDocDepPkgName string
	// 注入的table_name map
	ModelTableNameMap map[string]string
	// 注入err_code
	ErrCodeList []*ErrCodeInfo
	// model字段映射
	ModelFieldStructMap map[string]map[string]ModelFieldStruct
	// 索引
	ModelIndexMap map[string]*IndexInfo
	// 路由注册 srvName:GroupRouter
	GroupRouterMap map[string]*GroupRouter
	// 路由注册 导入哪些包
	GroupRouterImportPkg []string
	// MD输出
	MDoc *MDocs
	// MD输出时依赖message列表 package=>message_name=>message
	MDocDepMessageMap map[string]map[string]*proto.Message
	MDocDepEnum       map[string]map[string]*proto.Enum
	// api对应的srv列表
	APIGroupSrvMap map[string]*proto.Service
	SrvMap         map[string]*proto.Service
	AllEnumMap     map[string]*proto.Enum
	// 已实现的路由 srv:rpc_name:rpc
	ImplementedRouter map[string]*positionSrv
	// 当前处理到的枚举类型
	ErrCodeEnum *proto.Enum
	// 所有错误字段 pkg.errCode: errorCode
	ErrCodeEnumFieldMap map[string]MDocsErrCodeField
	// 函数名=>注释
	FuncCommentMap map[string]string
	// 限频路径=>struct{}
	FreqMap FreqMap
	// contains filtered or unexported fields
}
var Visitor *ProtoVisitor

func (*ProtoVisitor) AddApiSrv

func (p *ProtoVisitor) AddApiSrv(srvName string, srv *proto.Service)

func (*ProtoVisitor) AddBsonTag

func (p *ProtoVisitor) AddBsonTag(key, value string)

func (*ProtoVisitor) AddDocEnum

func (p *ProtoVisitor) AddDocEnum(enumName string, docs []*MDocsField)

func (*ProtoVisitor) AddDocJSONMap

func (p *ProtoVisitor) AddDocJSONMap(fieldName, jsonName string)

func (*ProtoVisitor) AddEnum

func (p *ProtoVisitor) AddEnum(enumName string, e *proto.Enum)

func (*ProtoVisitor) AddErrCode

func (p *ProtoVisitor) AddErrCode(code int, name, msg string)

func (*ProtoVisitor) AddErrCodeEnumField

func (p *ProtoVisitor) AddErrCodeEnumField(name string, field MDocsErrCodeField)

AddErrCodeEnumField 添加错误码

func (*ProtoVisitor) AddFreq

func (p *ProtoVisitor) AddFreq(key string, c FreqConfig)

AddFreq 添加限频规则

func (*ProtoVisitor) AddFuncComment

func (p *ProtoVisitor) AddFuncComment(name string, comment string)

AddFuncComment 给函数添加注释覆盖

func (*ProtoVisitor) AddImplRouter

func (p *ProtoVisitor) AddImplRouter(srv, to string, rpc *proto.RPC)

func (*ProtoVisitor) AddIndexField

func (p *ProtoVisitor) AddIndexField(name string, field *IndexField) error

func (*ProtoVisitor) AddMDocDepEnum

func (p *ProtoVisitor) AddMDocDepEnum(name string, m *proto.Enum)

AddMDocDepEnum 添加依赖message的依赖列表

func (*ProtoVisitor) AddMDocDepMessage

func (p *ProtoVisitor) AddMDocDepMessage(name string, m *proto.Message)

AddMDocDepMessage 添加依赖message的依赖列表

func (*ProtoVisitor) AddModelMsg

func (p *ProtoVisitor) AddModelMsg(fullPath string, m *proto.Message)

func (*ProtoVisitor) AddModelTableName

func (p *ProtoVisitor) AddModelTableName(key, value string)

func (*ProtoVisitor) AddMsg

func (p *ProtoVisitor) AddMsg(fullPath string, m *proto.Message)

func (*ProtoVisitor) AddRouterGroup

func (p *ProtoVisitor) AddRouterGroup(srvName string, gr *GroupRouter)

func (*ProtoVisitor) AddSrv

func (p *ProtoVisitor) AddSrv(srvName string, srv *proto.Service)

func (*ProtoVisitor) AddTTLIndexField

func (p *ProtoVisitor) AddTTLIndexField(name string, expiredTime int64, field *IndexField) error

func (*ProtoVisitor) AddUniqueIndexField

func (p *ProtoVisitor) AddUniqueIndexField(name string, field *IndexField) error

func (*ProtoVisitor) VisitComment

func (p *ProtoVisitor) VisitComment(e *proto.Comment)

func (*ProtoVisitor) VisitEnum

func (p *ProtoVisitor) VisitEnum(e *proto.Enum)

func (*ProtoVisitor) VisitEnumField

func (p *ProtoVisitor) VisitEnumField(i *proto.EnumField)

func (*ProtoVisitor) VisitExtensions

func (p *ProtoVisitor) VisitExtensions(e *proto.Extensions)

func (*ProtoVisitor) VisitGroup

func (p *ProtoVisitor) VisitGroup(g *proto.Group)

func (*ProtoVisitor) VisitImport

func (p *ProtoVisitor) VisitImport(i *proto.Import)

func (*ProtoVisitor) VisitMapField

func (p *ProtoVisitor) VisitMapField(f *proto.MapField)

func (*ProtoVisitor) VisitMessage

func (p *ProtoVisitor) VisitMessage(m *proto.Message)

func (*ProtoVisitor) VisitNormalField

func (p *ProtoVisitor) VisitNormalField(i *proto.NormalField)

func (*ProtoVisitor) VisitOneof

func (p *ProtoVisitor) VisitOneof(o *proto.Oneof)

func (*ProtoVisitor) VisitOneofField

func (p *ProtoVisitor) VisitOneofField(o *proto.OneOfField)

func (*ProtoVisitor) VisitOption

func (p *ProtoVisitor) VisitOption(o *proto.Option)

func (*ProtoVisitor) VisitPackage

func (p *ProtoVisitor) VisitPackage(pkg *proto.Package)

func (*ProtoVisitor) VisitRPC

func (p *ProtoVisitor) VisitRPC(r *proto.RPC)

func (*ProtoVisitor) VisitReserved

func (p *ProtoVisitor) VisitReserved(r *proto.Reserved)

func (*ProtoVisitor) VisitService

func (p *ProtoVisitor) VisitService(v *proto.Service)

func (*ProtoVisitor) VisitSyntax

func (p *ProtoVisitor) VisitSyntax(s *proto.Syntax)

type StructField

type StructField struct {
	StructFieldName string
	DbFieldName     string
}

type Style

type Style int

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL