tools/gen-go-enum/main.go (175 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package main import ( "flag" "fmt" "html/template" "log" "os" "strings" ) type Strings []string func (t *Strings) String() string { return fmt.Sprint(*t) } func (t *Strings) Set(value string) error { *t = append(*t, value) return nil } type viewData struct { ClassName string PackageName string EnumName string EnumValues []string } func snakeCase(name string) string { if name == "" { return "" } var s string for k, v := range []rune(name) { if v >= 'A' && v <= 'Z' { if k > 0 { s += "_" } v += 32 } s += string(v) } return s } func pascalCase(name string) string { if name == "" { return "" } var s string for _, v := range strings.Split(name, "_") { runes := []rune(v) for k, vv := range runes { if k == 0 { if vv >= 'a' && vv <= 'z' { vv -= 32 } } else if vv >= 'A' && vv <= 'Z' { vv += 32 } s += string(vv) } } return s } const ( usage = `gen-go-enum can generate golang code for hessian2 java enum. Usage: gen-go-enum -c java_classname [-p golang_package_name] [-e golang_enum_name] -v java_enum_value [-v java_enum_value] [-o target_file] Options -c java class name (eg: com.test.enums.TestEnum) -p golang package name, use 'enum' when not specified (eg: test_enums) -e golang enum type name, use java class name when not specified (eg: TestEnum) -v java enum values, can specify multiple (eg: -v TEST1 -v TEST2 -v TEST3) -o golang code file path, stored in the current directory when not specified Example gen-go-enum -c com.test.enums.TestColorEnum -v RED -v BLUE -v YELLOW gen-go-enum -c com.test.enums.TestColorEnum -p test_enums -e ColorEnum -v RED -v BLUE -v YELLOW -o ./color_enum.go ` enumTempl = `package {{.PackageName}} import ( "strconv" ) import ( hessian "github.com/apache/dubbo-go-hessian2" ) const ( {{- range $index, $value := .EnumValues }} {{$.EnumName}}{{ pascalCase $value}}{{ if eq $index 0 }} {{$.EnumName}} = iota{{ end }} {{- end }} ) var _{{.EnumName}}Values = map[{{.EnumName}}]string{ {{- range $index, $value := .EnumValues }} {{$.EnumName}}{{ pascalCase $value}}: "{{$value}}", {{- end }} } var _{{.EnumName}}Entities = map[string]{{.EnumName}}{ {{- range $index, $value := .EnumValues }} "{{$value}}": {{$.EnumName}}{{ pascalCase $value}}, {{- end }} } type {{.EnumName}} hessian.JavaEnum func (e {{.EnumName}}) JavaClassName() string { return "{{.ClassName}}" } func (e {{.EnumName}}) String() string { if v, ok := _{{.EnumName}}Values[e]; ok { return v } return strconv.Itoa(int(e)) } func (e {{.EnumName}}) EnumValue(s string) hessian.JavaEnum { if v, ok := _{{.EnumName}}Entities[s]; ok { return hessian.JavaEnum(v) } return hessian.InvalidJavaEnum } func New{{.EnumName}}(s string) {{.EnumName}} { if v, ok := _{{.EnumName}}Entities[s]; ok { return v } return {{.EnumName}}(hessian.InvalidJavaEnum) } func init() { for v := range _{{.EnumName}}Values { hessian.RegisterJavaEnum(v) } }` ) var ( className string packageName string enumName string enumValues Strings targetFile string ) func init() { flag.StringVar(&className, "c", "", "") flag.StringVar(&packageName, "p", "enum", "") flag.StringVar(&enumName, "e", "", "") flag.Var(&enumValues, "v", "") flag.StringVar(&targetFile, "o", "", "") flag.Usage = func() { fmt.Print(usage) } } func main() { flag.Parse() if className == "" || len(enumValues) == 0 { flag.Usage() return } if packageName == "" { packageName = "enum" } if enumName == "" { classItems := strings.Split(className, ".") enumName = classItems[len(classItems)-1] } if targetFile == "" { targetFile = snakeCase(enumName) + ".go" } tmpl, err := template.New("enum").Funcs(template.FuncMap{"pascalCase": pascalCase}).Parse(enumTempl) if err != nil { log.Fatalln("Error: can't parse code template!!!", err) } fd, err := os.Create(targetFile) if err != nil { log.Fatalln("Error: can't open target file!!!", err) } defer func() { _ = fd.Close() }() err = tmpl.Execute(fd, &viewData{ ClassName: className, PackageName: packageName, EnumName: enumName, EnumValues: enumValues, }) if err != nil { log.Fatalln("Error: can't write target file!!!", err) } fmt.Printf("Create file '%s'!\n", targetFile) }