protogen: add an option to rewrite import paths
This allows us to implement the import_prefix parameter in the v1
protoc-gen-go.
Drop support for import_prefix in protogen, and explicitly produce an
error if it is used in the v2 protoc-gen-go.
Change-Id: I66136b6b3affa3c0e9a93dc565619c90c42c0ecc
Reviewed-on: https://go-review.googlesource.com/138257
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/protogen/protogen.go b/protogen/protogen.go
index 87e643c..80e7dc1 100644
--- a/protogen/protogen.go
+++ b/protogen/protogen.go
@@ -100,6 +100,7 @@
enumsByName map[protoreflect.FullName]*Enum
pathType pathType
genFiles []*GeneratedFile
+ opts *Options
err error
}
@@ -129,6 +130,11 @@
// if *value { ... }
// })
ParamFunc func(name, value string) error
+
+ // ImportRewriteFunc is called with the import path of each package
+ // imported by a generated file. It returns the import path to use
+ // for this package.
+ ImportRewriteFunc func(GoImportPath) GoImportPath
}
// New returns a new Plugin.
@@ -144,6 +150,7 @@
fileReg: protoregistry.NewFiles(),
messagesByName: make(map[protoreflect.FullName]*Message),
enumsByName: make(map[protoreflect.FullName]*Enum),
+ opts: opts,
}
packageNames := make(map[string]GoPackageName) // filename -> package name
@@ -158,8 +165,6 @@
switch param {
case "":
// Ignore.
- case "import_prefix":
- // TODO
case "import_path":
packageImportPath = GoImportPath(value)
case "paths":
@@ -712,6 +717,7 @@
// A GeneratedFile is a generated file.
type GeneratedFile struct {
+ gen *Plugin
filename string
goImportPath GoImportPath
buf bytes.Buffer
@@ -724,6 +730,7 @@
// and import path.
func (gen *Plugin) NewGeneratedFile(filename string, goImportPath GoImportPath) *GeneratedFile {
g := &GeneratedFile{
+ gen: gen,
filename: filename,
goImportPath: goImportPath,
packageNames: make(map[GoImportPath]GoPackageName),
@@ -876,8 +883,14 @@
importPaths = append(importPaths, string(importPath))
}
sort.Strings(importPaths)
+ rewriteImport := func(importPath string) string {
+ if f := g.gen.opts.ImportRewriteFunc; f != nil {
+ return string(f(GoImportPath(importPath)))
+ }
+ return importPath
+ }
for _, importPath := range importPaths {
- astutil.AddNamedImport(fset, file, string(g.packageNames[GoImportPath(importPath)]), importPath)
+ astutil.AddNamedImport(fset, file, string(g.packageNames[GoImportPath(importPath)]), rewriteImport(importPath))
}
for importPath := range g.manualImports {
if _, ok := g.packageNames[importPath]; ok {
diff --git a/protogen/protogen_test.go b/protogen/protogen_test.go
index 237226c..6d8e5af 100644
--- a/protogen/protogen_test.go
+++ b/protogen/protogen_test.go
@@ -307,6 +307,42 @@
}
}
+func TestImportRewrites(t *testing.T) {
+ gen, err := New(&pluginpb.CodeGeneratorRequest{}, &Options{
+ ImportRewriteFunc: func(i GoImportPath) GoImportPath {
+ return "prefix/" + i
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ g := gen.NewGeneratedFile("foo.go", "golang.org/x/foo")
+ g.P("package foo")
+ g.P("var _ = ", GoIdent{GoName: "X", GoImportPath: "golang.org/x/bar"})
+ want := `package foo
+
+import bar "prefix/golang.org/x/bar"
+
+var _ = bar.X
+`
+ got, err := g.Content()
+ if err != nil {
+ t.Fatalf("g.Content() = %v", err)
+ }
+ if want != string(got) {
+ t.Fatalf(`want:
+==========
+%v
+==========
+
+got:
+==========
+%v
+==========`,
+ want, string(got))
+ }
+}
+
// makeRequest returns a CodeGeneratorRequest for the given protoc inputs.
//
// It does this by running protoc with the current binary as the protoc-gen-go