github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/_utils/terror_gen/gen.go (about) 1 // Copyright 2019 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package main 15 16 import ( 17 "bytes" 18 "fmt" 19 "go/ast" 20 "go/parser" 21 "go/token" 22 "os" 23 "strings" 24 "text/template" 25 ) 26 27 const ( 28 templateCheckerFile = "checker_template.go" 29 generatedCheckerFile = "checker_generated.go" 30 ) 31 32 var templatePlaceHolder = []byte("// TODO: fillin me") 33 34 func getErrorInstances(filepath string) []string { 35 fset := token.NewFileSet() 36 parserMode := parser.ParseComments 37 var ( 38 fileAst *ast.File 39 err error 40 result = make([]string, 0, 100) 41 ) 42 43 fileAst, err = parser.ParseFile(fset, filepath, nil, parserMode) 44 if err != nil { 45 panic(err) 46 } 47 48 for _, d := range fileAst.Decls { 49 switch decl := d.(type) { 50 case *ast.GenDecl: 51 specs := decl.Specs 52 for _, spec := range specs { 53 vs, ok := spec.(*ast.ValueSpec) 54 if !ok { 55 continue 56 } 57 name := vs.Names[0].Name 58 if strings.HasPrefix(name, "Err") { 59 result = append(result, name) 60 } 61 } 62 } 63 } 64 return result 65 } 66 67 func genFile(names []string) { 68 var ( 69 buf, genBuf bytes.Buffer 70 content []byte 71 err error 72 ) 73 content, err = os.ReadFile(templateCheckerFile) 74 if err != nil { 75 panic(err) 76 } 77 fmt.Fprint(&buf, "\n") 78 for _, name := range names { 79 fmt.Fprintf(&buf, "\t{\"%s\", terror.%s},\n", name, name) 80 } 81 82 data := map[string]interface{}{ 83 "ErrList": buf.String(), 84 "CheckerFile": generatedCheckerFile, 85 } 86 t := template.Must(template.New(generatedCheckerFile).Parse(string(content))) 87 err = t.Execute(&genBuf, data) 88 if err != nil { 89 panic(err) 90 } 91 err = os.WriteFile(generatedCheckerFile, genBuf.Bytes(), 0o600) 92 if err != nil { 93 panic(err) 94 } 95 } 96 97 func main() { 98 names := getErrorInstances(os.Args[1]) 99 genFile(names) 100 }