github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/language/proto/gen/gen_known_imports.go (about) 1 /* Copyright 2018 The Bazel Authors. All rights reserved. 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 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 // gen_known_imports generates a .go file that with a map from either proto or 17 // go import strings to Bazel label strings. The imports for all languages 18 // are stored in a proto.csv file. 19 20 package main 21 22 import ( 23 "bufio" 24 "bytes" 25 "encoding/csv" 26 "flag" 27 "fmt" 28 "go/format" 29 "log" 30 "os" 31 "path/filepath" 32 "text/template" 33 34 "github.com/bazelbuild/bazel-gazelle/label" 35 ) 36 37 var progName = filepath.Base(os.Args[0]) 38 39 var knownImportsTpl = template.Must(template.New("known_imports.go").Parse(` 40 // Generated by language/proto/gen/gen_known_imports.go 41 // From {{.ProtoCsv}} 42 43 package {{.Package}} 44 45 import "github.com/bazelbuild/bazel-gazelle/label" 46 47 var {{.Var}} = map[string]label.Label{ 48 {{range .Bindings}} 49 {{printf "%q: label.Label{Repo: %q, Pkg: %q, Name: %q}" .Import .Label.Repo .Label.Pkg .Label.Name}}, 50 {{- end}} 51 } 52 `)) 53 54 type data struct { 55 ProtoCsv, Package, Var string 56 Bindings []binding 57 } 58 59 type binding struct { 60 Import string 61 Label label.Label 62 } 63 64 func main() { 65 log.SetPrefix(progName + ": ") 66 log.SetFlags(0) 67 if err := run(os.Args[1:]); err != nil { 68 log.Fatal(err) 69 } 70 } 71 72 func run(args []string) (err error) { 73 fs := flag.NewFlagSet(progName, flag.ExitOnError) 74 var protoCsvPath, knownImportsPath, package_, var_ string 75 var keyColumn, valueColumn int 76 fs.StringVar(&protoCsvPath, "proto_csv", "", "path to proto.csv input file") 77 fs.StringVar(&knownImportsPath, "known_imports", "", "path to known_imports.go output file") 78 fs.StringVar(&package_, "package", "", "package name in generated file") 79 fs.StringVar(&var_, "var", "", "var name in generated file") 80 fs.IntVar(&keyColumn, "key", 0, "key column number") 81 fs.IntVar(&valueColumn, "value", 1, "value column number") 82 if err = fs.Parse(args); err != nil { 83 return fmt.Errorf("invalid flag: %v", err) 84 } 85 if protoCsvPath == "" { 86 return fmt.Errorf("-proto_csv not set") 87 } 88 if knownImportsPath == "" { 89 return fmt.Errorf("-known_imports not set") 90 } 91 if package_ == "" { 92 return fmt.Errorf("-package not set") 93 } 94 if var_ == "" { 95 return fmt.Errorf("-var not set") 96 } 97 98 protoCsvFile, err := os.Open(protoCsvPath) 99 if err != nil { 100 return err 101 } 102 r := csv.NewReader(bufio.NewReader(protoCsvFile)) 103 r.Comment = '#' 104 r.FieldsPerRecord = 4 105 records, err := r.ReadAll() 106 protoCsvFile.Close() 107 if err != nil { 108 return err 109 } 110 data := data{ 111 ProtoCsv: protoCsvPath, 112 Package: package_, 113 Var: var_, 114 } 115 seen := make(map[string]label.Label) 116 for _, rec := range records { 117 imp := rec[keyColumn] 118 lbl, err := label.Parse(rec[valueColumn]) 119 if err != nil { 120 return err 121 } 122 if seenLabel, ok := seen[imp]; ok { 123 if !seenLabel.Equal(lbl) { 124 return fmt.Errorf("for key %s, multiple values (%s and %s)", imp, seenLabel, lbl) 125 } 126 continue 127 } 128 seen[imp] = lbl 129 data.Bindings = append(data.Bindings, binding{imp, lbl}) 130 } 131 132 knownImportsBuf := &bytes.Buffer{} 133 if err := knownImportsTpl.Execute(knownImportsBuf, data); err != nil { 134 return err 135 } 136 knownImportsData, err := format.Source(knownImportsBuf.Bytes()) 137 if err != nil { 138 return err 139 } 140 if err := os.WriteFile(knownImportsPath, knownImportsData, 0o666); err != nil { 141 return err 142 } 143 144 return nil 145 }