protoc-gen-go: generate imports consistent with previous protoc-gen-go

Include references to the proto, fmt, and math packages, consistent with
the ones in the previous generator:

	// Reference imports to suppress errors if they are not otherwise used.
	var _ = proto.Marshal
	var _ = fmt.Errorf
	var _ = math.Inf

Sort imports with ast.SortImports to ensure gofmt-compatible output.

Copy the protoc-gen-go/testdata/imports test files from
github.com/golang/protobuf.

Change-Id: I263e2ac750d03596ae9cb23609049d5ef1016205
Reviewed-on: https://go-review.googlesource.com/135361
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/cmd/protoc-gen-go/main.go b/cmd/protoc-gen-go/main.go
index c7d9f8d..a6bc626 100644
--- a/cmd/protoc-gen-go/main.go
+++ b/cmd/protoc-gen-go/main.go
@@ -89,6 +89,21 @@
 	g.P()
 	g.P("package ", f.GoPackageName)
 	g.P()
+
+	// These references are not necessary, since we automatically add
+	// all necessary imports before formatting the generated file.
+	//
+	// This section exists to generate output more consistent with
+	// the previous version of protoc-gen-go, to make it easier to
+	// detect unintended variations.
+	//
+	// TODO: Eventually remove this.
+	g.P("// Reference imports to suppress errors if they are not otherwise used.")
+	g.P("var _ = ", protogen.GoIdent{GoImportPath: protoPackage, GoName: "Marshal"})
+	g.P("var _ = ", protogen.GoIdent{GoImportPath: "fmt", GoName: "Errorf"})
+	g.P("var _ = ", protogen.GoIdent{GoImportPath: "math", GoName: "Inf"})
+	g.P()
+
 	g.P("// This is a compile-time assertion to ensure that this generated file")
 	g.P("// is compatible with the proto package it is being compiled against.")
 	g.P("// A compilation error at this line likely means your copy of the")
diff --git a/cmd/protoc-gen-go/testdata/comments/comments.pb.go b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
index 675f72c..22046f4 100644
--- a/cmd/protoc-gen-go/testdata/comments/comments.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
@@ -5,7 +5,16 @@
 
 package proto2
 
-import proto "github.com/golang/protobuf/proto"
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
diff --git a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
index a72a731..fecfca3 100644
--- a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
+++ b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
@@ -3,7 +3,16 @@
 
 package fieldnames
 
-import proto "github.com/golang/protobuf/proto"
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
diff --git a/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go b/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
new file mode 100644
index 0000000..e58ba47
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
@@ -0,0 +1,68 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/fmt/m.proto
+
+package fmt
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type M struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M) Reset()         { *m = M{} }
+func (m *M) String() string { return proto.CompactTextString(m) }
+func (*M) ProtoMessage()    {}
+func (*M) Descriptor() ([]byte, []int) {
+	return fileDescriptor_72c126fcd452e392, []int{0}
+}
+func (m *M) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M.Unmarshal(m, b)
+}
+func (m *M) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M.Marshal(b, m, deterministic)
+}
+func (m *M) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M.Merge(m, src)
+}
+func (m *M) XXX_Size() int {
+	return xxx_messageInfo_M.Size(m)
+}
+func (m *M) XXX_DiscardUnknown() {
+	xxx_messageInfo_M.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*M)(nil), "fmt.M")
+}
+
+func init() { proto.RegisterFile("imports/fmt/m.proto", fileDescriptor_72c126fcd452e392) }
+
+var fileDescriptor_72c126fcd452e392 = []byte{
+	// 109 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xce, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x4f, 0xcb, 0x2d, 0xd1, 0xcf, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17,
+	0x62, 0x4e, 0xcb, 0x2d, 0x51, 0x62, 0xe6, 0x62, 0xf4, 0x75, 0xb2, 0x8f, 0xb2, 0x4d, 0xcf, 0x2c,
+	0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x07,
+	0x2b, 0x4a, 0x2a, 0x4d, 0x83, 0x30, 0x92, 0x75, 0xd3, 0x53, 0xf3, 0x74, 0xd3, 0xf3, 0xf5, 0x4b,
+	0x52, 0x8b, 0x4b, 0x52, 0x12, 0x4b, 0x12, 0xf5, 0x91, 0x8c, 0x4c, 0x62, 0x03, 0xab, 0x31, 0x06,
+	0x04, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xc9, 0xee, 0xbe, 0x68, 0x00, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/fmt/m.proto b/cmd/protoc-gen-go/testdata/imports/fmt/m.proto
new file mode 100644
index 0000000..4a5c2d1
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/fmt/m.proto
@@ -0,0 +1,8 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+package fmt;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/fmt";
+message M {}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
new file mode 100644
index 0000000..36012e1
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
@@ -0,0 +1,134 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_a_1/m1.proto
+
+package test_a_1
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type E1 int32
+
+const (
+	E1_E1_ZERO E1 = 0
+)
+
+var E1_name = map[int32]string{
+	0: "E1_ZERO",
+}
+
+var E1_value = map[string]int32{
+	"E1_ZERO": 0,
+}
+
+func (x E1) String() string {
+	return proto.EnumName(E1_name, int32(x))
+}
+
+func (E1) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_c1091de3fa870a14, []int{0}
+}
+
+type M1 struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M1) Reset()         { *m = M1{} }
+func (m *M1) String() string { return proto.CompactTextString(m) }
+func (*M1) ProtoMessage()    {}
+func (*M1) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c1091de3fa870a14, []int{0}
+}
+func (m *M1) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M1.Unmarshal(m, b)
+}
+func (m *M1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M1.Marshal(b, m, deterministic)
+}
+func (m *M1) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M1.Merge(m, src)
+}
+func (m *M1) XXX_Size() int {
+	return xxx_messageInfo_M1.Size(m)
+}
+func (m *M1) XXX_DiscardUnknown() {
+	xxx_messageInfo_M1.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M1 proto.InternalMessageInfo
+
+type M1_1 struct {
+	M1                   *M1      `protobuf:"bytes,1,opt,name=m1,proto3" json:"m1,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M1_1) Reset()         { *m = M1_1{} }
+func (m *M1_1) String() string { return proto.CompactTextString(m) }
+func (*M1_1) ProtoMessage()    {}
+func (*M1_1) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c1091de3fa870a14, []int{1}
+}
+func (m *M1_1) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M1_1.Unmarshal(m, b)
+}
+func (m *M1_1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M1_1.Marshal(b, m, deterministic)
+}
+func (m *M1_1) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M1_1.Merge(m, src)
+}
+func (m *M1_1) XXX_Size() int {
+	return xxx_messageInfo_M1_1.Size(m)
+}
+func (m *M1_1) XXX_DiscardUnknown() {
+	xxx_messageInfo_M1_1.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M1_1 proto.InternalMessageInfo
+
+func (m *M1_1) GetM1() *M1 {
+	if m != nil {
+		return m.M1
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*M1)(nil), "test.a.M1")
+	proto.RegisterType((*M1_1)(nil), "test.a.M1_1")
+	proto.RegisterEnum("test.a.E1", E1_name, E1_value)
+}
+
+func init() { proto.RegisterFile("imports/test_a_1/m1.proto", fileDescriptor_c1091de3fa870a14) }
+
+var fileDescriptor_c1091de3fa870a14 = []byte{
+	// 165 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x4f, 0x8c, 0x37, 0xd4, 0xcf, 0x35, 0xd4,
+	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0x09, 0xe9, 0x25, 0x2a, 0xb1, 0x70, 0x31, 0xf9,
+	0x1a, 0x2a, 0x29, 0x71, 0xb1, 0xf8, 0x1a, 0xc6, 0x1b, 0x0a, 0x49, 0x71, 0x31, 0xe5, 0x1a, 0x4a,
+	0x30, 0x2a, 0x30, 0x6a, 0x70, 0x1b, 0x71, 0xe9, 0x41, 0x94, 0xe8, 0xf9, 0x1a, 0x06, 0x31, 0xe5,
+	0x1a, 0x6a, 0x09, 0x72, 0x31, 0xb9, 0x1a, 0x0a, 0x71, 0x73, 0xb1, 0xbb, 0x1a, 0xc6, 0x47, 0xb9,
+	0x06, 0xf9, 0x0b, 0x30, 0x38, 0xb9, 0x44, 0x39, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25,
+	0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, 0xeb, 0x83, 0xcd, 0x4f, 0x2a, 0x4d, 0x83,
+	0x30, 0x92, 0x75, 0xd3, 0x53, 0xf3, 0x74, 0xd3, 0xf3, 0xc1, 0x4e, 0x48, 0x49, 0x2c, 0x49, 0xd4,
+	0x47, 0x77, 0x53, 0x12, 0x1b, 0x58, 0xa1, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xae, 0xc9,
+	0xcd, 0xae, 0x00, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.proto b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.proto
new file mode 100644
index 0000000..220928f
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.proto
@@ -0,0 +1,17 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+package test.a;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1";
+
+message M1 {}
+
+message M1_1 {
+  M1 m1 = 1;
+}
+
+enum E1 {
+  E1_ZERO = 0;
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
new file mode 100644
index 0000000..a87cecc
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
@@ -0,0 +1,69 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_a_1/m2.proto
+
+package test_a_1
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type M2 struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M2) Reset()         { *m = M2{} }
+func (m *M2) String() string { return proto.CompactTextString(m) }
+func (*M2) ProtoMessage()    {}
+func (*M2) Descriptor() ([]byte, []int) {
+	return fileDescriptor_20cf27515c0d621c, []int{0}
+}
+func (m *M2) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M2.Unmarshal(m, b)
+}
+func (m *M2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M2.Marshal(b, m, deterministic)
+}
+func (m *M2) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M2.Merge(m, src)
+}
+func (m *M2) XXX_Size() int {
+	return xxx_messageInfo_M2.Size(m)
+}
+func (m *M2) XXX_DiscardUnknown() {
+	xxx_messageInfo_M2.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M2 proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*M2)(nil), "test.a.M2")
+}
+
+func init() { proto.RegisterFile("imports/test_a_1/m2.proto", fileDescriptor_20cf27515c0d621c) }
+
+var fileDescriptor_20cf27515c0d621c = []byte{
+	// 114 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x4f, 0x8c, 0x37, 0xd4, 0xcf, 0x35, 0xd2,
+	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0x09, 0xe9, 0x25, 0x2a, 0xb1, 0x70, 0x31, 0xf9,
+	0x1a, 0x39, 0xb9, 0x44, 0x39, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea,
+	0xa7, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, 0xeb, 0x83, 0x15, 0x26, 0x95, 0xa6, 0x41, 0x18, 0xc9, 0xba,
+	0xe9, 0xa9, 0x79, 0xba, 0xe9, 0xf9, 0x60, 0xb3, 0x52, 0x12, 0x4b, 0x12, 0xf5, 0xd1, 0x0d, 0x4f,
+	0x62, 0x03, 0x2b, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xe3, 0xe0, 0x7e, 0xc0, 0x77, 0x00,
+	0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.proto b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.proto
new file mode 100644
index 0000000..6ea0651
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.proto
@@ -0,0 +1,8 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+package test.a;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1";
+message M2 {}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
new file mode 100644
index 0000000..437e3f8
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
@@ -0,0 +1,69 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_a_2/m3.proto
+
+package test_a_2
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type M3 struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M3) Reset()         { *m = M3{} }
+func (m *M3) String() string { return proto.CompactTextString(m) }
+func (*M3) ProtoMessage()    {}
+func (*M3) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ff9d8f834875c9c5, []int{0}
+}
+func (m *M3) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M3.Unmarshal(m, b)
+}
+func (m *M3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M3.Marshal(b, m, deterministic)
+}
+func (m *M3) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M3.Merge(m, src)
+}
+func (m *M3) XXX_Size() int {
+	return xxx_messageInfo_M3.Size(m)
+}
+func (m *M3) XXX_DiscardUnknown() {
+	xxx_messageInfo_M3.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M3 proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*M3)(nil), "test.a.M3")
+}
+
+func init() { proto.RegisterFile("imports/test_a_2/m3.proto", fileDescriptor_ff9d8f834875c9c5) }
+
+var fileDescriptor_ff9d8f834875c9c5 = []byte{
+	// 114 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x4f, 0x8c, 0x37, 0xd2, 0xcf, 0x35, 0xd6,
+	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0x09, 0xe9, 0x25, 0x2a, 0xb1, 0x70, 0x31, 0xf9,
+	0x1a, 0x3b, 0xb9, 0x44, 0x39, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea,
+	0xa7, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, 0xeb, 0x83, 0x15, 0x26, 0x95, 0xa6, 0x41, 0x18, 0xc9, 0xba,
+	0xe9, 0xa9, 0x79, 0xba, 0xe9, 0xf9, 0x60, 0xb3, 0x52, 0x12, 0x4b, 0x12, 0xf5, 0xd1, 0x0d, 0x4f,
+	0x62, 0x03, 0x2b, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x23, 0x86, 0x27, 0x47, 0x77, 0x00,
+	0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.proto b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.proto
new file mode 100644
index 0000000..bc0d5a6
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.proto
@@ -0,0 +1,8 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+package test.a;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_2";
+message M3 {}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
new file mode 100644
index 0000000..9f35f3f
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
@@ -0,0 +1,69 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_a_2/m4.proto
+
+package test_a_2
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type M4 struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M4) Reset()         { *m = M4{} }
+func (m *M4) String() string { return proto.CompactTextString(m) }
+func (*M4) ProtoMessage()    {}
+func (*M4) Descriptor() ([]byte, []int) {
+	return fileDescriptor_fdd24f82f6c5a786, []int{0}
+}
+func (m *M4) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M4.Unmarshal(m, b)
+}
+func (m *M4) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M4.Marshal(b, m, deterministic)
+}
+func (m *M4) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M4.Merge(m, src)
+}
+func (m *M4) XXX_Size() int {
+	return xxx_messageInfo_M4.Size(m)
+}
+func (m *M4) XXX_DiscardUnknown() {
+	xxx_messageInfo_M4.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M4 proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*M4)(nil), "test.a.M4")
+}
+
+func init() { proto.RegisterFile("imports/test_a_2/m4.proto", fileDescriptor_fdd24f82f6c5a786) }
+
+var fileDescriptor_fdd24f82f6c5a786 = []byte{
+	// 114 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x4f, 0x8c, 0x37, 0xd2, 0xcf, 0x35, 0xd1,
+	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0x09, 0xe9, 0x25, 0x2a, 0xb1, 0x70, 0x31, 0xf9,
+	0x9a, 0x38, 0xb9, 0x44, 0x39, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea,
+	0xa7, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, 0xeb, 0x83, 0x15, 0x26, 0x95, 0xa6, 0x41, 0x18, 0xc9, 0xba,
+	0xe9, 0xa9, 0x79, 0xba, 0xe9, 0xf9, 0x60, 0xb3, 0x52, 0x12, 0x4b, 0x12, 0xf5, 0xd1, 0x0d, 0x4f,
+	0x62, 0x03, 0x2b, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x58, 0xcb, 0x10, 0xc8, 0x77, 0x00,
+	0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.proto b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.proto
new file mode 100644
index 0000000..bc5158a
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.proto
@@ -0,0 +1,8 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+package test.a;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_2";
+message M4 {}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
new file mode 100644
index 0000000..a54118d
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
@@ -0,0 +1,69 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_b_1/m1.proto
+
+package beta
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type M1 struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M1) Reset()         { *m = M1{} }
+func (m *M1) String() string { return proto.CompactTextString(m) }
+func (*M1) ProtoMessage()    {}
+func (*M1) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7f49573d035512a8, []int{0}
+}
+func (m *M1) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M1.Unmarshal(m, b)
+}
+func (m *M1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M1.Marshal(b, m, deterministic)
+}
+func (m *M1) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M1.Merge(m, src)
+}
+func (m *M1) XXX_Size() int {
+	return xxx_messageInfo_M1.Size(m)
+}
+func (m *M1) XXX_DiscardUnknown() {
+	xxx_messageInfo_M1.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M1 proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*M1)(nil), "test.b.part1.M1")
+}
+
+func init() { proto.RegisterFile("imports/test_b_1/m1.proto", fileDescriptor_7f49573d035512a8) }
+
+var fileDescriptor_7f49573d035512a8 = []byte{
+	// 125 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x4f, 0x8a, 0x37, 0xd4, 0xcf, 0x35, 0xd4,
+	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x01, 0x09, 0xe9, 0x25, 0xe9, 0x15, 0x24, 0x16, 0x95,
+	0x18, 0x2a, 0xb1, 0x70, 0x31, 0xf9, 0x1a, 0x3a, 0x79, 0x46, 0xb9, 0xa7, 0x67, 0x96, 0x64, 0x94,
+	0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, 0xeb, 0x83, 0x95, 0x27,
+	0x95, 0xa6, 0x41, 0x18, 0xc9, 0xba, 0xe9, 0xa9, 0x79, 0xba, 0xe9, 0xf9, 0x60, 0x13, 0x53, 0x12,
+	0x4b, 0x12, 0xf5, 0xd1, 0xad, 0xb0, 0x4e, 0x4a, 0x2d, 0x49, 0x4c, 0x62, 0x03, 0xab, 0x36, 0x06,
+	0x04, 0x00, 0x00, 0xff, 0xff, 0x4a, 0xf1, 0x3b, 0x7f, 0x82, 0x00, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.proto b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.proto
new file mode 100644
index 0000000..ab294b7
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.proto
@@ -0,0 +1,8 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+package test.b.part1;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_b_1;beta";
+message M1 {}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
new file mode 100644
index 0000000..2b86237
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
@@ -0,0 +1,69 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_b_1/m2.proto
+
+package beta
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type M2 struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *M2) Reset()         { *m = M2{} }
+func (m *M2) String() string { return proto.CompactTextString(m) }
+func (*M2) ProtoMessage()    {}
+func (*M2) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a1becddceeb586f2, []int{0}
+}
+func (m *M2) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_M2.Unmarshal(m, b)
+}
+func (m *M2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_M2.Marshal(b, m, deterministic)
+}
+func (m *M2) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M2.Merge(m, src)
+}
+func (m *M2) XXX_Size() int {
+	return xxx_messageInfo_M2.Size(m)
+}
+func (m *M2) XXX_DiscardUnknown() {
+	xxx_messageInfo_M2.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_M2 proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*M2)(nil), "test.b.part2.M2")
+}
+
+func init() { proto.RegisterFile("imports/test_b_1/m2.proto", fileDescriptor_a1becddceeb586f2) }
+
+var fileDescriptor_a1becddceeb586f2 = []byte{
+	// 125 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x4f, 0x8a, 0x37, 0xd4, 0xcf, 0x35, 0xd2,
+	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x01, 0x09, 0xe9, 0x25, 0xe9, 0x15, 0x24, 0x16, 0x95,
+	0x18, 0x29, 0xb1, 0x70, 0x31, 0xf9, 0x1a, 0x39, 0x79, 0x46, 0xb9, 0xa7, 0x67, 0x96, 0x64, 0x94,
+	0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, 0xeb, 0x83, 0x95, 0x27,
+	0x95, 0xa6, 0x41, 0x18, 0xc9, 0xba, 0xe9, 0xa9, 0x79, 0xba, 0xe9, 0xf9, 0x60, 0x13, 0x53, 0x12,
+	0x4b, 0x12, 0xf5, 0xd1, 0xad, 0xb0, 0x4e, 0x4a, 0x2d, 0x49, 0x4c, 0x62, 0x03, 0xab, 0x36, 0x06,
+	0x04, 0x00, 0x00, 0xff, 0xff, 0x44, 0x29, 0xbe, 0x6d, 0x82, 0x00, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.proto b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.proto
new file mode 100644
index 0000000..4f3a1a4
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.proto
@@ -0,0 +1,8 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+package test.b.part2;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_b_1;beta";
+message M2 {}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
new file mode 100644
index 0000000..58e1437
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
@@ -0,0 +1,80 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_import_a1m1.proto
+
+package imports
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	test_a_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type A1M1 struct {
+	F                    *test_a_1.M1 `protobuf:"bytes,1,opt,name=f,proto3" json:"f,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
+	XXX_unrecognized     []byte       `json:"-"`
+	XXX_sizecache        int32        `json:"-"`
+}
+
+func (m *A1M1) Reset()         { *m = A1M1{} }
+func (m *A1M1) String() string { return proto.CompactTextString(m) }
+func (*A1M1) ProtoMessage()    {}
+func (*A1M1) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3b904a47327455f3, []int{0}
+}
+func (m *A1M1) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_A1M1.Unmarshal(m, b)
+}
+func (m *A1M1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_A1M1.Marshal(b, m, deterministic)
+}
+func (m *A1M1) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_A1M1.Merge(m, src)
+}
+func (m *A1M1) XXX_Size() int {
+	return xxx_messageInfo_A1M1.Size(m)
+}
+func (m *A1M1) XXX_DiscardUnknown() {
+	xxx_messageInfo_A1M1.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_A1M1 proto.InternalMessageInfo
+
+func (m *A1M1) GetF() *test_a_1.M1 {
+	if m != nil {
+		return m.F
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*A1M1)(nil), "test.A1M1")
+}
+
+func init() { proto.RegisterFile("imports/test_import_a1m1.proto", fileDescriptor_3b904a47327455f3) }
+
+var fileDescriptor_3b904a47327455f3 = []byte{
+	// 149 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcb, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x87, 0x70, 0xe2, 0x13, 0x0d, 0x73, 0x0d,
+	0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x58, 0x40, 0xe2, 0x52, 0x92, 0x28, 0xaa, 0x12, 0xe3,
+	0x0d, 0xf5, 0x61, 0x0a, 0x94, 0x14, 0xb8, 0x58, 0x1c, 0x0d, 0x7d, 0x0d, 0x85, 0x24, 0xb8, 0x18,
+	0xd3, 0x24, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0xb8, 0xf4, 0x40, 0xca, 0xf4, 0x12, 0xf5, 0x7c,
+	0x0d, 0x83, 0x18, 0xd3, 0x9c, 0xac, 0xa3, 0x2c, 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92,
+	0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0x73, 0x12, 0xf3, 0xd2, 0xf5, 0xc1, 0x9a, 0x93, 0x4a, 0xd3, 0x20,
+	0x8c, 0x64, 0xdd, 0xf4, 0xd4, 0x3c, 0xdd, 0xf4, 0x7c, 0xb0, 0xf9, 0x29, 0x89, 0x25, 0x89, 0xfa,
+	0x50, 0x0b, 0x93, 0xd8, 0xc0, 0xf2, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x84, 0x2f, 0x18,
+	0x23, 0xa8, 0x00, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.proto b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.proto
new file mode 100644
index 0000000..f7bb246
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.proto
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+
+package test;
+
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports";
+
+import "imports/test_a_1/m1.proto";
+
+message A1M1 {
+  test.a.M1 f = 1;
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
new file mode 100644
index 0000000..0586065
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
@@ -0,0 +1,80 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_import_a1m2.proto
+
+package imports
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	test_a_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type A1M2 struct {
+	F                    *test_a_1.M2 `protobuf:"bytes,1,opt,name=f,proto3" json:"f,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
+	XXX_unrecognized     []byte       `json:"-"`
+	XXX_sizecache        int32        `json:"-"`
+}
+
+func (m *A1M2) Reset()         { *m = A1M2{} }
+func (m *A1M2) String() string { return proto.CompactTextString(m) }
+func (*A1M2) ProtoMessage()    {}
+func (*A1M2) Descriptor() ([]byte, []int) {
+	return fileDescriptor_bdb27b114687957d, []int{0}
+}
+func (m *A1M2) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_A1M2.Unmarshal(m, b)
+}
+func (m *A1M2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_A1M2.Marshal(b, m, deterministic)
+}
+func (m *A1M2) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_A1M2.Merge(m, src)
+}
+func (m *A1M2) XXX_Size() int {
+	return xxx_messageInfo_A1M2.Size(m)
+}
+func (m *A1M2) XXX_DiscardUnknown() {
+	xxx_messageInfo_A1M2.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_A1M2 proto.InternalMessageInfo
+
+func (m *A1M2) GetF() *test_a_1.M2 {
+	if m != nil {
+		return m.F
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*A1M2)(nil), "test.A1M2")
+}
+
+func init() { proto.RegisterFile("imports/test_import_a1m2.proto", fileDescriptor_bdb27b114687957d) }
+
+var fileDescriptor_bdb27b114687957d = []byte{
+	// 149 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcb, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x87, 0x70, 0xe2, 0x13, 0x0d, 0x73, 0x8d,
+	0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x58, 0x40, 0xe2, 0x52, 0x92, 0x28, 0xaa, 0x12, 0xe3,
+	0x0d, 0xf5, 0x61, 0x0a, 0x94, 0x14, 0xb8, 0x58, 0x1c, 0x0d, 0x7d, 0x8d, 0x84, 0x24, 0xb8, 0x18,
+	0xd3, 0x24, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0xb8, 0xf4, 0x40, 0xca, 0xf4, 0x12, 0xf5, 0x7c,
+	0x8d, 0x82, 0x18, 0xd3, 0x9c, 0xac, 0xa3, 0x2c, 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92,
+	0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0x73, 0x12, 0xf3, 0xd2, 0xf5, 0xc1, 0x9a, 0x93, 0x4a, 0xd3, 0x20,
+	0x8c, 0x64, 0xdd, 0xf4, 0xd4, 0x3c, 0xdd, 0xf4, 0x7c, 0xb0, 0xf9, 0x29, 0x89, 0x25, 0x89, 0xfa,
+	0x50, 0x0b, 0x93, 0xd8, 0xc0, 0xf2, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x88, 0xfb,
+	0xea, 0xa8, 0x00, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.proto b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.proto
new file mode 100644
index 0000000..4a2e12c
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.proto
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+
+package test;
+
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports";
+
+import "imports/test_a_1/m2.proto";
+
+message A1M2 {
+  test.a.M2 f = 1;
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
new file mode 100644
index 0000000..6722483
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
@@ -0,0 +1,138 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imports/test_import_all.proto
+
+package imports
+
+import (
+	fmt "fmt"
+	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"
+	test_b_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_b_1"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+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"`
+	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
+	XXX_unrecognized     []byte       `json:"-"`
+	XXX_sizecache        int32        `json:"-"`
+}
+
+func (m *All) Reset()         { *m = All{} }
+func (m *All) String() string { return proto.CompactTextString(m) }
+func (*All) ProtoMessage()    {}
+func (*All) Descriptor() ([]byte, []int) {
+	return fileDescriptor_324466f0afc16f77, []int{0}
+}
+func (m *All) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_All.Unmarshal(m, b)
+}
+func (m *All) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_All.Marshal(b, m, deterministic)
+}
+func (m *All) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_All.Merge(m, src)
+}
+func (m *All) XXX_Size() int {
+	return xxx_messageInfo_All.Size(m)
+}
+func (m *All) XXX_DiscardUnknown() {
+	xxx_messageInfo_All.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_All proto.InternalMessageInfo
+
+func (m *All) GetAm1() *test_a_1.M1 {
+	if m != nil {
+		return m.Am1
+	}
+	return nil
+}
+
+func (m *All) GetAm2() *test_a_1.M2 {
+	if m != nil {
+		return m.Am2
+	}
+	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
+	}
+	return nil
+}
+
+func (m *All) GetBm2() *test_b_1.M2 {
+	if m != nil {
+		return m.Bm2
+	}
+	return nil
+}
+
+func (m *All) GetFmt() *fmt1.M {
+	if m != nil {
+		return m.Fmt
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*All)(nil), "test.All")
+}
+
+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,
+	0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_all.proto b/cmd/protoc-gen-go/testdata/imports/test_import_all.proto
new file mode 100644
index 0000000..7b62a69
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_all.proto
@@ -0,0 +1,31 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+
+package test;
+
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports";
+
+// test_a_1/m*.proto are in the same Go package and proto package.
+// test_a_*/*.proto are in different Go packages, but the same proto package.
+// test_b_1/*.proto are in the same Go package, but different proto packages.
+// 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_b_1/m1.proto";
+import "imports/test_b_1/m2.proto";
+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;
+}
diff --git a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
index 57ba0c4..7842bc7 100644
--- a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
@@ -3,7 +3,16 @@
 
 package proto2
 
-import proto "github.com/golang/protobuf/proto"
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
diff --git a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
index 87ab5ed..273fced 100644
--- a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
@@ -4,10 +4,16 @@
 package proto2
 
 import (
+	fmt "fmt"
 	proto "github.com/golang/protobuf/proto"
 	math "math"
 )
 
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
diff --git a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
index 64ecad2..f06711d 100644
--- a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
@@ -3,7 +3,16 @@
 
 package proto2
 
-import proto "github.com/golang/protobuf/proto"
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
diff --git a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
index 0fe87d6..1812234 100644
--- a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
@@ -3,7 +3,16 @@
 
 package proto2
 
-import proto "github.com/golang/protobuf/proto"
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
diff --git a/cmd/protoc-gen-go/testdata/proto3/enum.pb.go b/cmd/protoc-gen-go/testdata/proto3/enum.pb.go
index bb0e294..bf9dfbd 100644
--- a/cmd/protoc-gen-go/testdata/proto3/enum.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto3/enum.pb.go
@@ -3,7 +3,16 @@
 
 package proto3
 
-import proto "github.com/golang/protobuf/proto"
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
diff --git a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
index 4ccfc13..26d8165 100644
--- a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
@@ -3,7 +3,16 @@
 
 package proto3
 
-import proto "github.com/golang/protobuf/proto"
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
diff --git a/protogen/protogen.go b/protogen/protogen.go
index 0064afa..29a6289 100644
--- a/protogen/protogen.go
+++ b/protogen/protogen.go
@@ -14,6 +14,7 @@
 	"bufio"
 	"bytes"
 	"fmt"
+	"go/ast"
 	"go/parser"
 	"go/printer"
 	"go/token"
@@ -701,7 +702,7 @@
 	// Reformat generated code.
 	original := g.buf.Bytes()
 	fset := token.NewFileSet()
-	ast, err := parser.ParseFile(fset, "", original, parser.ParseComments)
+	file, err := parser.ParseFile(fset, "", original, parser.ParseComments)
 	if err != nil {
 		// Print out the bad code with line numbers.
 		// This should never happen in practice, but it can while changing generated code
@@ -721,11 +722,12 @@
 	}
 	sort.Strings(importPaths)
 	for _, importPath := range importPaths {
-		astutil.AddNamedImport(fset, ast, string(g.packageNames[GoImportPath(importPath)]), importPath)
+		astutil.AddNamedImport(fset, file, string(g.packageNames[GoImportPath(importPath)]), importPath)
 	}
+	ast.SortImports(fset, file)
 
 	var out bytes.Buffer
-	if err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(&out, fset, ast); err != nil {
+	if err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(&out, fset, file); err != nil {
 		return nil, fmt.Errorf("%v: can not reformat Go source: %v", g.filename, err)
 	}
 	// TODO: Annotations.
diff --git a/protogen/protogen_test.go b/protogen/protogen_test.go
index f35068a..237226c 100644
--- a/protogen/protogen_test.go
+++ b/protogen/protogen_test.go
@@ -279,8 +279,8 @@
 
 import (
 	bar "golang.org/x/bar"
-	bar1 "golang.org/y/bar"
 	baz "golang.org/x/baz"
+	bar1 "golang.org/y/bar"
 )
 
 var _ = X      // "golang.org/x/foo"