cmd/protoc-gen-go: don't chain public imports

Consider the case:

	a.proto publicly imports b.proto
	b.proto publicly imports c.proto

Should a.pb.go include symbols defined in c.pb.go?

Historically, it has not. As of #155677, it does. Regardless of which behavior
is preferable, #155677 produces broken code in some common situations: If
a.proto also publicly imports c.proto, we now generate two copies of the
forwarding decls for that file.

Restore the pre-#155677 behavior to avoid this breakage.

Change-Id: I283600b3be19eac2c3b3c14233bb69fa64661581
Reviewed-on: https://go-review.googlesource.com/c/156348
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Damien Neil 2019-01-06 16:29:14 -08:00
parent 84395510fc
commit a7cbd06b9b
2 changed files with 15 additions and 5 deletions

View File

@ -200,7 +200,7 @@ func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, imp
gen.Error(err)
return
}
genForward := func(tok token.Token, name string) {
genForward := func(tok token.Token, name string, expr ast.Expr) {
// Don't import unexported symbols.
r, _ := utf8.DecodeRuneInString(name)
if !unicode.IsUpper(r) {
@ -210,6 +210,13 @@ func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, imp
if name == impFile.GoDescriptorIdent.GoName {
return
}
// Don't import decls referencing a symbol defined in another package.
// i.e., don't import decls which are themselves public imports:
//
// type T = somepackage.T
if _, ok := expr.(*ast.SelectorExpr); ok {
return
}
g.P(tok, " ", name, " = ", impFile.GoImportPath.Ident(name))
}
g.P("// Symbols defined in public import of ", imp.Path())
@ -220,10 +227,14 @@ func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, imp
for _, spec := range decl.Specs {
switch spec := spec.(type) {
case *ast.TypeSpec:
genForward(decl.Tok, spec.Name.Name)
genForward(decl.Tok, spec.Name.Name, spec.Type)
case *ast.ValueSpec:
for _, name := range spec.Names {
genForward(decl.Tok, name.Name)
for i, name := range spec.Names {
var expr ast.Expr
if i < len(spec.Values) {
expr = spec.Values[i]
}
genForward(decl.Tok, name.Name, expr)
}
case *ast.ImportSpec:
default:

View File

@ -20,7 +20,6 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// Symbols defined in public import of import_public/sub/a.proto
type Sub2Message = sub.Sub2Message
type E = sub.E
const E_ZERO = sub.E_ZERO