Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support generating GetAnnotation method for enum #202

Merged
merged 4 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions generator/golang/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ type Features struct {
EnableRefInterface bool `enable_ref_interface:"Generate Interface field without pointer type when 'thrift.is_interface=\"true\"' annotation is set to types in referred thrift."`
UseOption bool `use_option:"Parse specific Thrift annotations into struct-style option fields. If key not match, thriftgo will just ignore it."`
// ForceUseOption bool `use_option:"Forcefully parse all Thrift annotations into struct-style option fields. If parsing is not possible, an error will be thrown."`
NoFmt bool `no_fmt:"To achieve faster generation speed, skipping the formatting of Golang code can improve performance by approximately 50%."`
SkipEmpty bool `skip_empty:"If there's not content in file, just skip it. Later this feature will be a default feature."`
NoProcessor bool `no_processor:" Do not generate default thrift processor and client. Later this feature will be a default feature."`
NoFmt bool `no_fmt:"To achieve faster generation speed, skipping the formatting of Golang code can improve performance by approximately 50%."`
SkipEmpty bool `skip_empty:"If there's not content in file, just skip it. Later this feature will be a default feature."`
NoProcessor bool `no_processor:" Do not generate default thrift processor and client. Later this feature will be a default feature."`
GetEnumAnnotation bool `get_enum_annotation:"Generate GetAnnotation method for enum types."`
}

var defaultFeatures = Features{
Expand Down Expand Up @@ -107,6 +108,7 @@ var defaultFeatures = Features{
EnableNestedStruct: false,
NoAliasTypeReflectionMethod: false,
EnableRefInterface: false,
GetEnumAnnotation: false,
}

type param struct {
Expand Down
20 changes: 20 additions & 0 deletions generator/golang/templates/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,25 @@ func (p *{{$EnumType}}) Value() (driver.Value, error) {
return int{{if Features.EnumAsINT32}}32{{else}}64{{end}}(*p), nil
}
{{- end}}{{/* if .Features.ScanValueForEnum */}}

{{- if Features.GetEnumAnnotation}}
var annotations_{{$EnumType}} = map[{{$EnumType}}]map[string][]string{
{{- range .Values}}
{{.GoName}}: map[string][]string{
{{genAnnotations .}}
},
{{- end}}
}

func (p {{$EnumType}}) GetAnnotation(key string) []string {
switch p {
{{- range .Values}}
case {{.GoName}}:
return annotations_{{$EnumType}}[{{.GoName}}][key]
{{- end}}
}
return nil
}
{{- end}}{{/* if Features.GenGetEnumAnnotation */}}
{{end}}
`
21 changes: 20 additions & 1 deletion generator/golang/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,8 @@ func (cu *CodeUtils) BuildFuncMap() template.FuncMap {
})
return ret
},
"backquoted": BackQuoted,
"backquoted": BackQuoted,
"genAnnotations": genAnnotations,
}
return m
}
Expand Down Expand Up @@ -479,3 +480,21 @@ func JoinPath(elem ...string) string {
func BackQuoted(s string) string {
return "`" + s + "`"
}

func genAnnotations(t interface{ GetAnnotations() parser.Annotations }) string {
annos := t.GetAnnotations()
if len(annos) <= 0 {
return ""
}
var res strings.Builder
for _, anno := range annos {
vals := anno.Values
quoteVals := make([]string, len(vals))
felix021 marked this conversation as resolved.
Show resolved Hide resolved
for i, val := range vals {
quoteVals[i] = BackQuoted(val)
}
valStr := strings.Join(quoteVals, ",")
res.WriteString(fmt.Sprintf("`%s`: []string{%s},\n", anno.Key, valStr))
}
return res.String()
}
167 changes: 167 additions & 0 deletions generator/golang/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package golang

import (
"github.com/cloudwego/thriftgo/parser"
"testing"
)

Expand Down Expand Up @@ -55,3 +56,169 @@ func TestLowerCamelCase(t *testing.T) {
}
}
}

func TestGenAnnotations(t *testing.T) {
cases := []struct {
desc string
getter func() interface{ GetAnnotations() parser.Annotations }
expected string
}{
{
desc: "normal case",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{"val"},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{`val`},\n",
},
{
desc: "single value seperated by comma",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{"val1,val2"},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{`val1,val2`},\n",
},
{
desc: "single empty value",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{""},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{``},\n",
},
{
desc: "multiple keys",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key1",
Values: []string{"val1,val2"},
},
{
Key: "key2",
Values: []string{"val3,val4"},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key1`: []string{`val1,val2`},\n`key2`: []string{`val3,val4`},\n",
},
{
desc: "single key, multiple values",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{"val1", "val2"},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{`val1`,`val2`},\n",
},
{
desc: "double quotes are not escaped",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{`\"val\"`},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{`\\\"val\\\"`},\n",
},
{
desc: "double quotes are escaped",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{"\"val\""},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{`\"val\"`},\n",
},
{
desc: "single quotes are not escaped",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{`\'val\'`},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{`\\'val\\'`},\n",
},
{
desc: "single quotes are escaped",
getter: func() interface{ GetAnnotations() parser.Annotations } {
annos := parser.Annotations{
{
Key: "key",
Values: []string{"'val'"},
},
}
return &parser.EnumValue{
Annotations: annos,
}
},
expected: "`key`: []string{`'val'`},\n",
},
{
desc: "nil Annotations",
getter: func() interface{ GetAnnotations() parser.Annotations } {
return &parser.EnumValue{}
},
expected: ``,
},
}

for _, c := range cases {
t.Run(c.desc, func(t *testing.T) {
arg := c.getter()
res := genAnnotations(arg)
if res != c.expected {
t.Logf("genAnnotations(%+v) => %q. Expected: %q", arg, res, c.expected)
t.Fail()
}
})
}
}
Loading