-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpackage.go
130 lines (116 loc) · 4.43 KB
/
package.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package protokit
import (
"path"
"path/filepath"
"strings"
"github.com/jhump/protoreflect/desc"
)
// 获取fd这个文件的golang package path,relative模式下有特殊处理
func GolangPackagePathAndName(fd *desc.FileDescriptor, basePackagePath string, golangRelative bool) (string, string) {
packageName := ""
packagePath := ""
rootPath := basePackagePath
fileBasePath := filepath.Dir(fd.GetName())
// for windows filepath.dir return a\\b
fileBasePath = strings.ReplaceAll(fileBasePath, "\\", "/")
// golang package 优先proto中的golang package定义 => proto package => 依赖目录结构
protoGolangPackage := fd.AsFileDescriptorProto().GetOptions().GetGoPackage()
protoProtoPackageAsGolangPackage := strings.ReplaceAll(fd.AsFileDescriptorProto().GetPackage(), ".", "_")
if protoGolangPackage == "" {
protoGolangPackage = strings.ToLower(protoProtoPackageAsGolangPackage)
}
if protoGolangPackage == "" {
// 以文件名作准
protoGolangPackage = (strings.Split(fd.GetFile().GetName(), "."))[0]
}
packageSlice := strings.Split(protoGolangPackage, "/")
packageName = packageSlice[len(packageSlice)-1]
// protoGolangPackage的最后一个字段作为package名称,但是path是目录相关的
if golangRelative && fileBasePath != "google/protobuf" {
if fileBasePath == "" || fileBasePath == "." {
// fixme FunPlus Puzzle Game使用问题兼容
// fixme 如果获取到的proto在根目录下,relative模式下,package path不再完全依赖于file path,将package name纳package path
fileBasePath = packageName
}
packagePath = path.Join(rootPath, fileBasePath)
return packagePath, packageName
}
return protoGolangPackage, packageName
}
//(*OuterTestT1)(nil), // 2: msg.Outer.test_t1
//(*OuterTest_T2)(nil), // 3: msg.Outer.test_T2
//(*Outer_TestT3)(nil), // 4: msg.Outer.Test_t3
//(*Outer_Test_T4)(nil), // 5: msg.Outer.Test_T4
//(*Outer_Test_T5)(nil), // 6: msg.Outer.Test__t5
//(*Outer_Test__T6)(nil), // 7: msg.Outer.Test__T6
//(*Outer_TestT7__)(nil), // 8: msg.Outer.Test_t7__
//(*Outer_TestT8__)(nil), // 9: msg.Outer.Test_t8__
//(*Outer_Test____T9__)(nil), // 10: msg.Outer.Test_____t9__
// goPackageName通过方法GetGolangPackageName获取,如果传入.或者空,则返回struct名称不带package名字
func GoStructNameWithGolangPackage(fullyQualifiedName string, protoPackagePath, goPackageName string) string {
protoPackageWithDot := strings.ReplaceAll(protoPackagePath, "/", ".")
fullyQualifiedName = strings.TrimPrefix(fullyQualifiedName, ".")
nameWithoutProtoPackage := strings.TrimPrefix(fullyQualifiedName, protoPackageWithDot)
structName := GoStructNameFromFullyQualifiedNameTrimProtoPackage(nameWithoutProtoPackage)
structName = strings.TrimPrefix(structName, "/")
if goPackageName == "." || goPackageName == "" {
return strings.TrimPrefix(structName, ".")
}
return goPackageName + "." + strings.TrimPrefix(structName, ".")
}
var keywords = map[string]struct{}{
"Reset": {},
"String": {},
"ProtoMessage": {},
"ProtoReflect": {},
"Descriptor": {},
}
func GoFieldName(s string) string {
s = strings.Title(s)
if _, ok := keywords[s]; ok {
return s + "_"
}
return goName(s)
}
func goName(s string) string {
var ns string
var toUpper bool
for j, c := range s {
if toUpper {
ns += strings.ToUpper(string(c))
toUpper = false
continue
}
if c == '_' {
if j == 0 {
ns += string('X')
} else if j < len(s)-1 && ('a' <= s[j+1] && s[j+1] <= 'z') {
toUpper = true
} else {
ns += string(c)
}
} else if '0' <= s[j] && s[j] <= '9' {
ns += string(c)
toUpper = true
} else {
ns += string(c)
}
}
return ns
}
// 由fullyQualifiedName 转换到 golang struct名称,fullyQualifiedName需要去除掉proto package的名称
// 底层无法自动判定proto package名称依赖上层传递
// FunPlus.ServerCommon.Config.ActivityData : proto package名称为FunPlus.ServerCommon.Config
// msg.Outer.Test_____t9__ : proto package名称为msg
func GoStructNameFromFullyQualifiedNameTrimProtoPackage(fullyQualifiedNameWithoutProtoPackage string) string {
fullyQualifiedNameWithoutProtoPackage = strings.TrimPrefix(fullyQualifiedNameWithoutProtoPackage, ".")
nameParts := strings.Split(fullyQualifiedNameWithoutProtoPackage, ".")
ret := ""
for i, s := range nameParts {
if 'A' <= s[0] && s[0] <= 'Z' && i != 0 {
ret += "_"
}
ret += goName(strings.Title(s))
}
return ret
}