cmd/protoc-gen-go: generate blank imports for unused proto dependencies

Generate Go imports for all packages imported by the .proto source file,
even if they are not referenced.

Change-Id: I116bdf460ab441d205b42606b2b05b315ed68954
Reviewed-on: https://go-review.googlesource.com/136358
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Damien Neil 2018-09-19 12:51:36 -07:00
parent 73ac885dab
commit 2e0c3da5a4
4 changed files with 44 additions and 42 deletions

View File

@ -148,15 +148,19 @@ func walkMessages(messages []*protogen.Message, f func(*protogen.Message)) {
}
func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File, imp protoreflect.FileImport) {
if !imp.IsPublic {
return
}
impFile, ok := gen.FileByName(imp.Path())
if !ok {
return
}
if impFile.GoImportPath == f.GoImportPath {
// Don't generate aliases for types in the same Go package.
// Don't generate imports or aliases for types in the same Go package.
return
}
// Generate imports for all dependencies, even if they are not
// referenced, because other code and tools depend on having the
// full transitive closure of protocol buffer types in the binary.
g.Import(impFile.GoImportPath)
if !imp.IsPublic {
return
}
var enums []*protogen.Enum

View File

@ -8,7 +8,7 @@ import (
proto "github.com/golang/protobuf/proto"
fmt1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/fmt"
test_a_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
test_a_2 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_2"
_ "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_2"
test_b_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_b_1"
math "math"
)
@ -27,8 +27,6 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type All struct {
Am1 *test_a_1.M1 `protobuf:"bytes,1,opt,name=am1,proto3" json:"am1,omitempty"`
Am2 *test_a_1.M2 `protobuf:"bytes,2,opt,name=am2,proto3" json:"am2,omitempty"`
Am3 *test_a_2.M3 `protobuf:"bytes,3,opt,name=am3,proto3" json:"am3,omitempty"`
Am4 *test_a_2.M4 `protobuf:"bytes,4,opt,name=am4,proto3" json:"am4,omitempty"`
Bm1 *test_b_1.M1 `protobuf:"bytes,5,opt,name=bm1,proto3" json:"bm1,omitempty"`
Bm2 *test_b_1.M2 `protobuf:"bytes,6,opt,name=bm2,proto3" json:"bm2,omitempty"`
Fmt *fmt1.M `protobuf:"bytes,7,opt,name=fmt,proto3" json:"fmt,omitempty"`
@ -76,20 +74,6 @@ func (m *All) GetAm2() *test_a_1.M2 {
return nil
}
func (m *All) GetAm3() *test_a_2.M3 {
if m != nil {
return m.Am3
}
return nil
}
func (m *All) GetAm4() *test_a_2.M4 {
if m != nil {
return m.Am4
}
return nil
}
func (m *All) GetBm1() *test_b_1.M1 {
if m != nil {
return m.Bm1
@ -118,22 +102,21 @@ func init() {
func init() { proto.RegisterFile("imports/test_import_all.proto", fileDescriptor_324466f0afc16f77) }
var fileDescriptor_324466f0afc16f77 = []byte{
// 258 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0xd0, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x06, 0x60, 0x15, 0x97, 0x20, 0x99, 0x05, 0x85, 0xc5, 0x20, 0x90, 0x50, 0x27, 0x96, 0xda,
0xb2, 0x9d, 0x05, 0x31, 0xc1, 0xde, 0xa5, 0x23, 0x4b, 0x64, 0x97, 0xc6, 0x54, 0xf2, 0xd5, 0x51,
0x7a, 0x7d, 0x5e, 0x5e, 0x05, 0xd9, 0x07, 0x12, 0x84, 0x66, 0x4b, 0xfe, 0xef, 0xb7, 0xce, 0x3e,
0x7e, 0xbf, 0x83, 0x3e, 0x0d, 0x78, 0x50, 0xb8, 0x3d, 0x60, 0x4b, 0x3f, 0xad, 0x8b, 0x51, 0xf6,
0x43, 0xc2, 0x54, 0xcf, 0x73, 0x7c, 0x7b, 0xf3, 0xa7, 0xe4, 0x5a, 0xad, 0x40, 0x53, 0xe1, 0x14,
0x99, 0x09, 0x32, 0x0a, 0xec, 0x34, 0x35, 0x27, 0xc9, 0x4f, 0xcf, 0xf2, 0xbf, 0x67, 0x5d, 0xff,
0x50, 0x07, 0xa8, 0x80, 0xc2, 0xc5, 0xe7, 0x8c, 0xb3, 0x97, 0x18, 0xeb, 0x3b, 0xce, 0x1c, 0x68,
0x31, 0x7b, 0x98, 0x3d, 0x5e, 0x1a, 0x2e, 0xf3, 0x69, 0xe9, 0xe4, 0x4a, 0xaf, 0x73, 0x4c, 0x6a,
0xc4, 0xd9, 0x48, 0x4d, 0x56, 0x43, 0x6a, 0x05, 0x1b, 0xa9, 0xcd, 0x6a, 0x49, 0x1b, 0x31, 0x1f,
0x69, 0x93, 0xb5, 0xa9, 0x17, 0x9c, 0x79, 0xd0, 0xe2, 0xbc, 0xe8, 0x15, 0xa9, 0x97, 0xbd, 0x1b,
0x50, 0x97, 0xe9, 0x1e, 0x34, 0x75, 0x8c, 0xa8, 0xfe, 0x77, 0x4c, 0xb9, 0x83, 0x07, 0x53, 0x0b,
0xce, 0x3a, 0x40, 0x71, 0x51, 0x3a, 0x95, 0xec, 0x00, 0xe5, 0x6a, 0x9d, 0xa3, 0xd7, 0xe7, 0xb7,
0xa7, 0xb0, 0xc3, 0x8f, 0xa3, 0x97, 0x9b, 0x04, 0x2a, 0xa4, 0xe8, 0xf6, 0x41, 0x95, 0xc7, 0xfb,
0x63, 0x47, 0x1f, 0x9b, 0x65, 0xd8, 0xee, 0x97, 0x21, 0x95, 0xa5, 0xbd, 0x3b, 0x74, 0xea, 0x7b,
0x55, 0xbe, 0x2a, 0x6e, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x95, 0x39, 0xa3, 0x82, 0x03, 0x02,
// 242 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0xcf, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x06, 0x60, 0x85, 0x40, 0x90, 0xcc, 0x82, 0xc2, 0x62, 0x10, 0x48, 0xa8, 0x13, 0x4b, 0x6d,
0xf9, 0xca, 0x82, 0x98, 0x60, 0xef, 0xd2, 0x91, 0x25, 0xf2, 0x95, 0xda, 0x54, 0xf2, 0xd5, 0x51,
0x7a, 0x7d, 0x22, 0x5e, 0x14, 0xd9, 0x06, 0x09, 0x68, 0xb2, 0x25, 0xff, 0xf7, 0xfb, 0x4e, 0x27,
0xee, 0xb6, 0xd4, 0xc7, 0x81, 0xf7, 0x9a, 0x37, 0x7b, 0xee, 0xca, 0x4f, 0x67, 0x43, 0x50, 0xfd,
0x10, 0x39, 0xb6, 0xa7, 0x29, 0xbe, 0xb9, 0xfe, 0x53, 0xb2, 0x9d, 0xd1, 0x64, 0x4a, 0x61, 0x8c,
0x60, 0x82, 0x40, 0xd3, 0x62, 0x9a, 0x1e, 0x47, 0x09, 0xa7, 0x77, 0xe1, 0xef, 0x5d, 0x57, 0x3f,
0xe4, 0x88, 0x35, 0x95, 0x70, 0xf6, 0x59, 0x89, 0xfa, 0x25, 0x84, 0xf6, 0x56, 0xd4, 0x96, 0x8c,
0xac, 0xee, 0xab, 0x87, 0x0b, 0x10, 0x2a, 0xbd, 0x56, 0x56, 0x2d, 0xcd, 0x2a, 0xc5, 0x45, 0x41,
0x9e, 0xfc, 0x53, 0x48, 0x0a, 0xed, 0x4c, 0xd4, 0x48, 0x46, 0x9e, 0x65, 0xbd, 0x2c, 0x8a, 0xaa,
0xb7, 0x03, 0x9b, 0x3c, 0x01, 0xc9, 0x94, 0x0e, 0xc8, 0xe6, 0xb8, 0x03, 0x79, 0x0e, 0x12, 0xb4,
0x52, 0xd4, 0x8e, 0x58, 0x9e, 0xe7, 0x4e, 0xa3, 0x1c, 0xb1, 0x5a, 0xae, 0x52, 0xf4, 0xfa, 0xfc,
0xf6, 0xe4, 0xb7, 0xfc, 0x71, 0x40, 0xb5, 0x8e, 0xa4, 0x7d, 0x0c, 0x76, 0xe7, 0x75, 0x3e, 0x00,
0x0f, 0xae, 0x7c, 0xac, 0xe7, 0x7e, 0xb3, 0x9b, 0xfb, 0x98, 0x0f, 0x7f, 0xb7, 0x6c, 0xf5, 0xf7,
0xb9, 0xd8, 0x64, 0x5f, 0x7c, 0x05, 0x00, 0x00, 0xff, 0xff, 0x88, 0x0e, 0xe2, 0x9f, 0xc7, 0x01,
0x00, 0x00,
}

View File

@ -14,8 +14,8 @@ option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports";
// fmt/m.proto has a package name which conflicts with "fmt".
import "imports/test_a_1/m1.proto";
import "imports/test_a_1/m2.proto";
import "imports/test_a_2/m3.proto";
import "imports/test_a_2/m4.proto";
import "imports/test_a_2/m3.proto"; // unused in this file
import "imports/test_a_2/m4.proto"; // unused in this file
import "imports/test_b_1/m1.proto";
import "imports/test_b_1/m2.proto";
import "imports/fmt/m.proto";
@ -23,8 +23,6 @@ import "imports/fmt/m.proto";
message All {
test.a.M1 am1 = 1;
test.a.M2 am2 = 2;
test.a.M3 am3 = 3;
test.a.M4 am4 = 4;
test.b.part1.M1 bm1 = 5;
test.b.part2.M2 bm2 = 6;
fmt.M fmt = 7;

View File

@ -706,6 +706,7 @@ type GeneratedFile struct {
buf bytes.Buffer
packageNames map[GoImportPath]GoPackageName
usedPackageNames map[GoPackageName]bool
manualImports map[GoImportPath]bool
}
// NewGeneratedFile creates a new generated file with the given filename
@ -716,6 +717,7 @@ func (gen *Plugin) NewGeneratedFile(filename string, goImportPath GoImportPath)
goImportPath: goImportPath,
packageNames: make(map[GoImportPath]GoPackageName),
usedPackageNames: make(map[GoPackageName]bool),
manualImports: make(map[GoImportPath]bool),
}
gen.genFiles = append(gen.genFiles, g)
return g
@ -759,6 +761,15 @@ func (g *GeneratedFile) QualifiedGoIdent(ident GoIdent) string {
return string(packageName) + "." + ident.GoName
}
// Import ensures a package is imported by the generated file.
//
// Packages referenced by QualifiedGoIdent are automatically imported.
// Explicitly importing a package with Import is generally only necessary
// when the import will be blank (import _ "package").
func (g *GeneratedFile) Import(importPath GoImportPath) {
g.manualImports[importPath] = true
}
// Write implements io.Writer.
func (g *GeneratedFile) Write(p []byte) (n int, err error) {
return g.buf.Write(p)
@ -795,6 +806,12 @@ func (g *GeneratedFile) Content() ([]byte, error) {
for _, importPath := range importPaths {
astutil.AddNamedImport(fset, file, string(g.packageNames[GoImportPath(importPath)]), importPath)
}
for importPath := range g.manualImports {
if _, ok := g.packageNames[importPath]; ok {
continue
}
astutil.AddNamedImport(fset, file, "_", string(importPath))
}
ast.SortImports(fset, file)
var out bytes.Buffer