You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.4 KiB
112 lines
3.4 KiB
package naming
|
|
|
|
import (
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/bilibili/kratos/tool/protobuf/pkg/utils"
|
|
"github.com/golang/protobuf/protoc-gen-go/descriptor"
|
|
"github.com/pkg/errors"
|
|
"github.com/siddontang/go/ioutil2"
|
|
)
|
|
|
|
// GetVersionPrefix 根据go包名获取api版本前缀
|
|
// @param pkg 从proto获取到的对应的go报名
|
|
// @return 如果是v*开始的 返回v*
|
|
// 否则返回空
|
|
func GetVersionPrefix(pkg string) string {
|
|
if pkg == "" {
|
|
return ""
|
|
}
|
|
if pkg[:1] == "v" {
|
|
return pkg
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GenFileName returns the output name for the generated Go file.
|
|
func GenFileName(f *descriptor.FileDescriptorProto, suffix string) string {
|
|
name := *f.Name
|
|
if ext := path.Ext(name); ext == ".pb" || ext == ".proto" || ext == ".protodevel" {
|
|
name = name[:len(name)-len(ext)]
|
|
}
|
|
name += suffix
|
|
return name
|
|
}
|
|
|
|
func ServiceName(service *descriptor.ServiceDescriptorProto) string {
|
|
return utils.CamelCase(service.GetName())
|
|
}
|
|
|
|
// MethodName ...
|
|
func MethodName(method *descriptor.MethodDescriptorProto) string {
|
|
return utils.CamelCase(method.GetName())
|
|
}
|
|
|
|
// GetGoImportPathForPb 得到 proto 文件对应的 go import路径
|
|
// protoFilename is the proto file name
|
|
// 可能根本无法得到proto文件的具体路径, 只能假设 proto 的filename 是相对当前目录的
|
|
// 假设 protoAbsolutePath = wd/protoFilename
|
|
func GetGoImportPathForPb(protoFilename string, moduleImportPath string, moduleDirName string) (importPath string, err error) {
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
panic("cannot get working directory")
|
|
}
|
|
absPath := wd + "/" + protoFilename
|
|
if !ioutil2.FileExists(absPath) {
|
|
err = errors.New("Cannot find proto file path of " + protoFilename)
|
|
return "", err
|
|
}
|
|
index := strings.Index(absPath, moduleDirName)
|
|
if index == -1 {
|
|
return "", errors.Errorf("proto file %s is not inside project %s", protoFilename, moduleDirName)
|
|
}
|
|
relativePath := absPath[index:]
|
|
importPath = filepath.Dir(relativePath)
|
|
return importPath, nil
|
|
}
|
|
|
|
// GoPackageNameForProtoFile returns the Go package name to use in the generated Go file.
|
|
// The result explicitly reports whether the name came from an option go_package
|
|
// statement. If explicit is false, the name was derived from the protocol
|
|
// buffer's package statement or the input file name.
|
|
func GoPackageName(f *descriptor.FileDescriptorProto) (name string, explicit bool) {
|
|
// Does the file have a "go_package" option?
|
|
if _, pkg, ok := goPackageOption(f); ok {
|
|
return pkg, true
|
|
}
|
|
|
|
// Does the file have a package clause?
|
|
if pkg := f.GetPackage(); pkg != "" {
|
|
return pkg, false
|
|
}
|
|
// Use the file base name.
|
|
return utils.BaseName(f.GetName()), false
|
|
}
|
|
|
|
// goPackageOption interprets the file's go_package option.
|
|
// If there is no go_package, it returns ("", "", false).
|
|
// If there's a simple name, it returns ("", pkg, true).
|
|
// If the option implies an import path, it returns (impPath, pkg, true).
|
|
func goPackageOption(f *descriptor.FileDescriptorProto) (impPath, pkg string, ok bool) {
|
|
pkg = f.GetOptions().GetGoPackage()
|
|
if pkg == "" {
|
|
return
|
|
}
|
|
ok = true
|
|
// The presence of a slash implies there's an import path.
|
|
slash := strings.LastIndex(pkg, "/")
|
|
if slash < 0 {
|
|
return
|
|
}
|
|
impPath, pkg = pkg, pkg[slash+1:]
|
|
// A semicolon-delimited suffix overrides the package name.
|
|
sc := strings.IndexByte(impPath, ';')
|
|
if sc < 0 {
|
|
return
|
|
}
|
|
impPath, pkg = impPath[:sc], impPath[sc+1:]
|
|
return
|
|
}
|
|
|