add new helpers
This commit is contained in:
parent
7e17e4319f
commit
decb64ccd8
@ -52,6 +52,7 @@ func NewGenericServiceTemplateBasedEncoder(templateDir string, service *descript
|
|||||||
if debug {
|
if debug {
|
||||||
log.Printf("new encoder: file=%q service=%q template-dir=%q", file.GetName(), service.GetName(), templateDir)
|
log.Printf("new encoder: file=%q service=%q template-dir=%q", file.GetName(), service.GetName(), templateDir)
|
||||||
}
|
}
|
||||||
|
pgghelpers.InitPathMap(file)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -68,6 +69,8 @@ func NewGenericTemplateBasedEncoder(templateDir string, file *descriptor.FileDes
|
|||||||
if debug {
|
if debug {
|
||||||
log.Printf("new encoder: file=%q template-dir=%q", file.GetName(), templateDir)
|
log.Printf("new encoder: file=%q template-dir=%q", file.GetName(), templateDir)
|
||||||
}
|
}
|
||||||
|
pgghelpers.InitPathMap(file)
|
||||||
|
pgghelpers.InitPathMap(file)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@ var ProtoHelpersFuncMap = template.FuncMap{
|
|||||||
"isFieldRepeated": isFieldRepeated,
|
"isFieldRepeated": isFieldRepeated,
|
||||||
"haskellType": haskellType,
|
"haskellType": haskellType,
|
||||||
"goType": goType,
|
"goType": goType,
|
||||||
|
"goZeroValue": goZeroValue,
|
||||||
"goTypeWithPackage": goTypeWithPackage,
|
"goTypeWithPackage": goTypeWithPackage,
|
||||||
"jsType": jsType,
|
"jsType": jsType,
|
||||||
"jsSuffixReserved": jsSuffixReservedKeyword,
|
"jsSuffixReserved": jsSuffixReservedKeyword,
|
||||||
@ -110,6 +111,183 @@ var ProtoHelpersFuncMap = template.FuncMap{
|
|||||||
"urlHasVarsFromMessage": urlHasVarsFromMessage,
|
"urlHasVarsFromMessage": urlHasVarsFromMessage,
|
||||||
"lowerGoNormalize": lowerGoNormalize,
|
"lowerGoNormalize": lowerGoNormalize,
|
||||||
"goNormalize": goNormalize,
|
"goNormalize": goNormalize,
|
||||||
|
"leadingComment": leadingComment,
|
||||||
|
"trailingComment": trailingComment,
|
||||||
|
"leadingDetachedComments": leadingDetachedComments,
|
||||||
|
"stringFieldExtension": stringFieldExtension,
|
||||||
|
"boolFieldExtension": boolFieldExtension,
|
||||||
|
"isFieldMap": isFieldMap,
|
||||||
|
"fieldMapKeyType": fieldMapKeyType,
|
||||||
|
"fieldMapValueType": fieldMapValueType,
|
||||||
|
"replaceDict": replaceDict,
|
||||||
|
}
|
||||||
|
|
||||||
|
var pathMap map[interface{}]*descriptor.SourceCodeInfo_Location
|
||||||
|
|
||||||
|
func InitPathMap(file *descriptor.FileDescriptorProto) {
|
||||||
|
pathMap = make(map[interface{}]*descriptor.SourceCodeInfo_Location)
|
||||||
|
addToPathMap(file.GetSourceCodeInfo(), file, []int32{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitPathMaps(files []*descriptor.FileDescriptorProto) {
|
||||||
|
pathMap = make(map[interface{}]*descriptor.SourceCodeInfo_Location)
|
||||||
|
for _, file := range files {
|
||||||
|
addToPathMap(file.GetSourceCodeInfo(), file, []int32{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addToPathMap(info *descriptor.SourceCodeInfo, i interface{}, path []int32) {
|
||||||
|
loc := findLoc(info, path)
|
||||||
|
if loc != nil {
|
||||||
|
pathMap[i] = loc
|
||||||
|
}
|
||||||
|
switch d := i.(type) {
|
||||||
|
case *descriptor.FileDescriptorProto:
|
||||||
|
for index, descriptor := range d.MessageType {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 4, index))
|
||||||
|
}
|
||||||
|
for index, descriptor := range d.EnumType {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 5, index))
|
||||||
|
}
|
||||||
|
for index, descriptor := range d.Service {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 6, index))
|
||||||
|
}
|
||||||
|
case *descriptor.DescriptorProto:
|
||||||
|
for index, descriptor := range d.Field {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 2, index))
|
||||||
|
}
|
||||||
|
for index, descriptor := range d.NestedType {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 3, index))
|
||||||
|
}
|
||||||
|
for index, descriptor := range d.EnumType {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 4, index))
|
||||||
|
}
|
||||||
|
case *descriptor.EnumDescriptorProto:
|
||||||
|
for index, descriptor := range d.Value {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 2, index))
|
||||||
|
}
|
||||||
|
case *descriptor.ServiceDescriptorProto:
|
||||||
|
for index, descriptor := range d.Method {
|
||||||
|
addToPathMap(info, descriptor, newPath(path, 2, index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPath(base []int32, field int32, index int) []int32 {
|
||||||
|
p := append([]int32{}, base...)
|
||||||
|
p = append(p, field, int32(index))
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func findLoc(info *descriptor.SourceCodeInfo, path []int32) *descriptor.SourceCodeInfo_Location {
|
||||||
|
for _, loc := range info.GetLocation() {
|
||||||
|
if samePath(loc.Path, path) {
|
||||||
|
return loc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func samePath(a, b []int32) bool {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i, p := range a {
|
||||||
|
if p != b[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func findSourceInfoLocation(i interface{}) *descriptor.SourceCodeInfo_Location {
|
||||||
|
if pathMap == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return pathMap[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func leadingComment(i interface{}) string {
|
||||||
|
loc := pathMap[i]
|
||||||
|
return loc.GetLeadingComments()
|
||||||
|
}
|
||||||
|
func trailingComment(i interface{}) string {
|
||||||
|
loc := pathMap[i]
|
||||||
|
return loc.GetTrailingComments()
|
||||||
|
}
|
||||||
|
func leadingDetachedComments(i interface{}) []string {
|
||||||
|
loc := pathMap[i]
|
||||||
|
return loc.GetLeadingDetachedComments()
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringFieldExtension(fieldId int32, f *descriptor.FieldDescriptorProto) string {
|
||||||
|
if f == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if f.Options == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var extendedType *descriptor.FieldOptions
|
||||||
|
var extensionType *string
|
||||||
|
|
||||||
|
eds := proto.RegisteredExtensions(f.Options)
|
||||||
|
if eds[fieldId] == nil {
|
||||||
|
ed := &proto.ExtensionDesc{
|
||||||
|
ExtendedType: extendedType,
|
||||||
|
ExtensionType: extensionType,
|
||||||
|
Field: fieldId,
|
||||||
|
Tag: fmt.Sprintf("bytes,%d", fieldId),
|
||||||
|
}
|
||||||
|
proto.RegisterExtension(ed)
|
||||||
|
eds = proto.RegisteredExtensions(f.Options)
|
||||||
|
}
|
||||||
|
|
||||||
|
ext, err := proto.GetExtension(f.Options, eds[fieldId])
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
str, ok := ext.(*string)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return *str
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolFieldExtension(fieldId int32, f *descriptor.FieldDescriptorProto) bool {
|
||||||
|
if f == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if f.Options == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var extendedType *descriptor.FieldOptions
|
||||||
|
var extensionType *bool
|
||||||
|
|
||||||
|
eds := proto.RegisteredExtensions(f.Options)
|
||||||
|
if eds[fieldId] == nil {
|
||||||
|
ed := &proto.ExtensionDesc{
|
||||||
|
ExtendedType: extendedType,
|
||||||
|
ExtensionType: extensionType,
|
||||||
|
Field: fieldId,
|
||||||
|
Tag: fmt.Sprintf("varint,%d", fieldId),
|
||||||
|
}
|
||||||
|
proto.RegisterExtension(ed)
|
||||||
|
eds = proto.RegisteredExtensions(f.Options)
|
||||||
|
}
|
||||||
|
|
||||||
|
ext, err := proto.GetExtension(f.Options, eds[fieldId])
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
str, ok := ext.(*bool)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return *str
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -180,6 +358,9 @@ func isFieldMessage(f *descriptor.FieldDescriptorProto) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isFieldRepeated(f *descriptor.FieldDescriptorProto) bool {
|
func isFieldRepeated(f *descriptor.FieldDescriptorProto) bool {
|
||||||
|
if f == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if f.Type != nil && f.Label != nil && *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
|
if f.Type != nil && f.Label != nil && *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -187,6 +368,98 @@ func isFieldRepeated(f *descriptor.FieldDescriptorProto) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isFieldMap(f *descriptor.FieldDescriptorProto, m *descriptor.DescriptorProto) bool {
|
||||||
|
if f.TypeName == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
shortName := shortType(*f.TypeName)
|
||||||
|
var nt *descriptor.DescriptorProto
|
||||||
|
for _, t := range m.NestedType {
|
||||||
|
if *t.Name == shortName {
|
||||||
|
nt = t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nt == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range nt.Field {
|
||||||
|
switch *f.Name {
|
||||||
|
case "key":
|
||||||
|
if *f.Number != 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case "value":
|
||||||
|
if *f.Number != 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func fieldMapKeyType(f *descriptor.FieldDescriptorProto, m *descriptor.DescriptorProto) *descriptor.FieldDescriptorProto {
|
||||||
|
if f.TypeName == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
shortName := shortType(*f.TypeName)
|
||||||
|
var nt *descriptor.DescriptorProto
|
||||||
|
for _, t := range m.NestedType {
|
||||||
|
if *t.Name == shortName {
|
||||||
|
nt = t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nt == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range nt.Field {
|
||||||
|
if *f.Name == "key" {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func fieldMapValueType(f *descriptor.FieldDescriptorProto, m *descriptor.DescriptorProto) *descriptor.FieldDescriptorProto {
|
||||||
|
if f.TypeName == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
shortName := shortType(*f.TypeName)
|
||||||
|
var nt *descriptor.DescriptorProto
|
||||||
|
for _, t := range m.NestedType {
|
||||||
|
if *t.Name == shortName {
|
||||||
|
nt = t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nt == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range nt.Field {
|
||||||
|
if *f.Name == "value" {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func goTypeWithPackage(f *descriptor.FieldDescriptorProto) string {
|
func goTypeWithPackage(f *descriptor.FieldDescriptorProto) string {
|
||||||
pkg := ""
|
pkg := ""
|
||||||
if *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE || *f.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
|
if *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE || *f.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
|
||||||
@ -319,6 +592,38 @@ func goType(pkg string, f *descriptor.FieldDescriptorProto) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func goZeroValue(f *descriptor.FieldDescriptorProto) string {
|
||||||
|
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
|
||||||
|
return "nil"
|
||||||
|
}
|
||||||
|
switch *f.Type {
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
|
||||||
|
return "0.0"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_FLOAT:
|
||||||
|
return "0.0"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_INT64:
|
||||||
|
return "0"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_UINT64:
|
||||||
|
return "0"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_INT32:
|
||||||
|
return "0"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_UINT32:
|
||||||
|
return "0"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_BOOL:
|
||||||
|
return "false"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_STRING:
|
||||||
|
return "\"\""
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
|
||||||
|
return "nil"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_BYTES:
|
||||||
|
return "0"
|
||||||
|
case descriptor.FieldDescriptorProto_TYPE_ENUM:
|
||||||
|
return "nil"
|
||||||
|
default:
|
||||||
|
return "nil"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func jsType(f *descriptor.FieldDescriptorProto) string {
|
func jsType(f *descriptor.FieldDescriptorProto) string {
|
||||||
template := "%s"
|
template := "%s"
|
||||||
if isFieldRepeated(f) {
|
if isFieldRepeated(f) {
|
||||||
@ -502,3 +807,14 @@ func formatID(base string, formatted string) string {
|
|||||||
}
|
}
|
||||||
return formatted
|
return formatted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func replaceDict(src string, dict map[string]interface{}) string {
|
||||||
|
for old, v := range dict {
|
||||||
|
new, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
src = strings.Replace(src, old, new, -1)
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user