Przeglądaj źródła

protoc-gen-go: fix generation of public imports (#549)

(*Generator).DefaultPackageName returns either a qualified ("pkg.name") or
unqualified ("name") name.

Prior to commit 9d4962b4, it based this decision on whether the
name was in the package we're generating code for.  After this
commit, it bases this on whether the name is in the file we're
currently generating code for. i.e., what was once an invariant
across all files is no longer.

This is mostly fine, except for one case: We run the generator
across files we do not generate code for, in order to build a list
of symbols used to generate code for public imports. This change
caused some of those symbols to no longer be qualified.

In particular, this causes bad generation for wrapper types of
publicly imported messages that contain a field whose type is
another message in the same publicly imported package.

Fix this. Clean up some effectively dead code in SetPackageNames
at the same time. Fix tests to catch this case. (It wouldn't have
caught it anyway, but imp.proto is supposed to contain a public import.
This seems to have been lost when exporting code to git. Fixed.)
Damien Neil 7 lat temu
rodzic
commit
80c8f76451

+ 1 - 1
Makefile

@@ -35,7 +35,7 @@ install:
 	go install ./proto ./jsonpb ./ptypes ./protoc-gen-go
 	go install ./proto ./jsonpb ./ptypes ./protoc-gen-go
 
 
 test:
 test:
-	go test ./...
+	go test ./... ./protoc-gen-go/testdata
 
 
 clean:
 clean:
 	go clean ./...
 	go clean ./...

+ 13 - 37
protoc-gen-go/generator/generator.go

@@ -95,6 +95,8 @@ func RegisterPlugin(p Plugin) {
 // A GoImportPath is the import path of a Go package. e.g., "google.golang.org/genproto/protobuf".
 // A GoImportPath is the import path of a Go package. e.g., "google.golang.org/genproto/protobuf".
 type GoImportPath string
 type GoImportPath string
 
 
+func (p GoImportPath) String() string { return strconv.Quote(string(p)) }
+
 // A GoPackageName is the name of a Go package. e.g., "protobuf".
 // A GoPackageName is the name of a Go package. e.g., "protobuf".
 type GoPackageName string
 type GoPackageName string
 
 
@@ -567,7 +569,7 @@ type Generator struct {
 
 
 	Pkg map[string]string // The names under which we import support packages
 	Pkg map[string]string // The names under which we import support packages
 
 
-	packageName      GoPackageName                  // What we're calling ourselves.
+	outputImportPath GoImportPath                   // Package we're generating code for.
 	allFiles         []*FileDescriptor              // All files in the tree
 	allFiles         []*FileDescriptor              // All files in the tree
 	allFilesByName   map[string]*FileDescriptor     // All files by filename.
 	allFilesByName   map[string]*FileDescriptor     // All files by filename.
 	genFiles         []*FileDescriptor              // Those files we will generate output for.
 	genFiles         []*FileDescriptor              // Those files we will generate output for.
@@ -677,7 +679,7 @@ func (g *Generator) CommandLineParameters(parameter string) {
 // Otherwise it returns the empty string.
 // Otherwise it returns the empty string.
 func (g *Generator) DefaultPackageName(obj Object) string {
 func (g *Generator) DefaultPackageName(obj Object) string {
 	importPath := obj.GoImportPath()
 	importPath := obj.GoImportPath()
-	if importPath == g.file.importPath {
+	if importPath == g.outputImportPath {
 		return ""
 		return ""
 	}
 	}
 	return string(g.GoPackageName(importPath)) + "."
 	return string(g.GoPackageName(importPath)) + "."
@@ -769,46 +771,20 @@ func (g *Generator) defaultGoPackage() GoPackageName {
 // The package name must agree across all files being generated.
 // The package name must agree across all files being generated.
 // It also defines unique package names for all imported files.
 // It also defines unique package names for all imported files.
 func (g *Generator) SetPackageNames() {
 func (g *Generator) SetPackageNames() {
-	// Register the name for this package.  It will be the first name
-	// registered so is guaranteed to be unmodified.
-	pkg, explicit := g.genFiles[0].goPackageName()
-
-	// Check all files for an explicit go_package option.
-	for _, f := range g.genFiles {
-		thisPkg, thisExplicit := f.goPackageName()
-		if thisExplicit {
-			if !explicit {
-				// Let this file's go_package option serve for all input files.
-				pkg, explicit = thisPkg, true
-			} else if thisPkg != pkg {
-				g.Fail("inconsistent package names:", string(thisPkg), string(pkg))
-			}
-		}
-	}
+	g.outputImportPath = g.genFiles[0].importPath
 
 
-	// If we don't have an explicit go_package option but we have an
-	// import path, use that.
-	if !explicit {
-		p := g.defaultGoPackage()
-		if p != "" {
-			pkg, explicit = p, true
+	// Check that all files have a consistent package name and import path.
+	pkg, _ := g.genFiles[0].goPackageName()
+	for _, f := range g.genFiles[1:] {
+		if a, b := g.genFiles[0].importPath, f.importPath; a != b {
+			g.Fail(fmt.Sprint("inconsistent package import paths: ", a, b))
 		}
 		}
-	}
-
-	// If there was no go_package and no import path to use,
-	// double-check that all the inputs have the same implicit
-	// Go package name.
-	if !explicit {
-		for _, f := range g.genFiles {
-			thisPkg, _ := f.goPackageName()
-			if thisPkg != pkg {
-				g.Fail("inconsistent package names:", string(thisPkg), string(pkg))
-			}
+		thisPkg, _ := f.goPackageName()
+		if pkg != thisPkg {
+			g.Fail(fmt.Sprint("inconsistent package names: ", thisPkg, pkg))
 		}
 		}
 	}
 	}
 
 
-	g.packageName = pkg
-
 	// Names of support packages. These never vary (if there are conflicts,
 	// Names of support packages. These never vary (if there are conflicts,
 	// we rename the conflicting package), so this could be removed someday.
 	// we rename the conflicting package), so this could be removed someday.
 	g.Pkg = map[string]string{
 	g.Pkg = map[string]string{

+ 102 - 39
protoc-gen-go/testdata/imp/imp.pb.go

@@ -6,6 +6,8 @@ package imp // import "github.com/golang/protobuf/protoc-gen-go/testdata/imp"
 import proto "github.com/golang/protobuf/proto"
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import fmt "fmt"
 import math "math"
 import math "math"
+import imp2 "github.com/golang/protobuf/protoc-gen-go/testdata/imp/imp2"
+import imp3 "github.com/golang/protobuf/protoc-gen-go/testdata/imp/imp3"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
@@ -18,6 +20,67 @@ var _ = math.Inf
 // proto package needs to be updated.
 // proto package needs to be updated.
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 
+// PubliclyImportedMessage from public import imp/imp2/imp2.proto
+type PubliclyImportedMessage imp2.PubliclyImportedMessage
+
+func (m *PubliclyImportedMessage) Reset()         { (*imp2.PubliclyImportedMessage)(m).Reset() }
+func (m *PubliclyImportedMessage) String() string { return (*imp2.PubliclyImportedMessage)(m).String() }
+func (*PubliclyImportedMessage) ProtoMessage()    {}
+func (m *PubliclyImportedMessage) XXX_Unmarshal(buf []byte) error {
+	return (*imp2.PubliclyImportedMessage)(m).XXX_Unmarshal(buf)
+}
+func (m *PubliclyImportedMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return (*imp2.PubliclyImportedMessage)(m).XXX_Marshal(b, deterministic)
+}
+func (m *PubliclyImportedMessage) XXX_Size() int { return (*imp2.PubliclyImportedMessage)(m).XXX_Size() }
+func (m *PubliclyImportedMessage) XXX_DiscardUnknown() {
+	(*imp2.PubliclyImportedMessage)(m).XXX_DiscardUnknown()
+}
+func (m *PubliclyImportedMessage) GetField() int64 {
+	return (*imp2.PubliclyImportedMessage)(m).GetField()
+}
+
+// PubliclyImportedMessage2 from public import imp/imp2/imp2.proto
+type PubliclyImportedMessage2 imp2.PubliclyImportedMessage2
+
+func (m *PubliclyImportedMessage2) Reset() { (*imp2.PubliclyImportedMessage2)(m).Reset() }
+func (m *PubliclyImportedMessage2) String() string {
+	return (*imp2.PubliclyImportedMessage2)(m).String()
+}
+func (*PubliclyImportedMessage2) ProtoMessage() {}
+func (m *PubliclyImportedMessage2) XXX_Unmarshal(buf []byte) error {
+	return (*imp2.PubliclyImportedMessage2)(m).XXX_Unmarshal(buf)
+}
+func (m *PubliclyImportedMessage2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return (*imp2.PubliclyImportedMessage2)(m).XXX_Marshal(b, deterministic)
+}
+func (m *PubliclyImportedMessage2) XXX_Size() int {
+	return (*imp2.PubliclyImportedMessage2)(m).XXX_Size()
+}
+func (m *PubliclyImportedMessage2) XXX_DiscardUnknown() {
+	(*imp2.PubliclyImportedMessage2)(m).XXX_DiscardUnknown()
+}
+func (m *PubliclyImportedMessage2) GetField() *PubliclyImportedMessage {
+	return (*PubliclyImportedMessage)((*imp2.PubliclyImportedMessage2)(m).GetField())
+}
+
+// PubliclyImportedEnum from public import imp/imp2/imp2.proto
+type PubliclyImportedEnum imp2.PubliclyImportedEnum
+
+var PubliclyImportedEnum_name = imp2.PubliclyImportedEnum_name
+var PubliclyImportedEnum_value = imp2.PubliclyImportedEnum_value
+
+func (x PubliclyImportedEnum) String() string { return (imp2.PubliclyImportedEnum)(x).String() }
+func (x PubliclyImportedEnum) Enum() *PubliclyImportedEnum {
+	return (*PubliclyImportedEnum)((imp2.PubliclyImportedEnum)(x).Enum())
+}
+func (x *PubliclyImportedEnum) UnmarshalJSON(data []byte) error {
+	return (*imp2.PubliclyImportedEnum)(x).UnmarshalJSON(data)
+}
+
+const PubliclyImportedEnum_GLASSES = PubliclyImportedEnum(imp2.PubliclyImportedEnum_GLASSES)
+const PubliclyImportedEnum_HAIR = PubliclyImportedEnum(imp2.PubliclyImportedEnum_HAIR)
+
 type ImportedMessage_Owner int32
 type ImportedMessage_Owner int32
 
 
 const (
 const (
@@ -51,15 +114,15 @@ func (x *ImportedMessage_Owner) UnmarshalJSON(data []byte) error {
 	return nil
 	return nil
 }
 }
 func (ImportedMessage_Owner) EnumDescriptor() ([]byte, []int) {
 func (ImportedMessage_Owner) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptor_imp_81275c260ac30f8b, []int{0, 0}
+	return fileDescriptor_imp_6424de66809c2ae5, []int{0, 0}
 }
 }
 
 
 type ImportedMessage struct {
 type ImportedMessage struct {
 	Field *int64 `protobuf:"varint,1,req,name=field" json:"field,omitempty"`
 	Field *int64 `protobuf:"varint,1,req,name=field" json:"field,omitempty"`
 	// The forwarded getters for these fields are fiddly to get right.
 	// The forwarded getters for these fields are fiddly to get right.
-	LocalMsg   *ImportedMessage2       `protobuf:"bytes,2,opt,name=local_msg,json=localMsg" json:"local_msg,omitempty"`
-	ForeignMsg *ForeignImportedMessage `protobuf:"bytes,3,opt,name=foreign_msg,json=foreignMsg" json:"foreign_msg,omitempty"`
-	EnumField  *ImportedMessage_Owner  `protobuf:"varint,4,opt,name=enum_field,json=enumField,enum=imp.ImportedMessage_Owner" json:"enum_field,omitempty"`
+	LocalMsg   *ImportedMessage2            `protobuf:"bytes,2,opt,name=local_msg,json=localMsg" json:"local_msg,omitempty"`
+	ForeignMsg *imp3.ForeignImportedMessage `protobuf:"bytes,3,opt,name=foreign_msg,json=foreignMsg" json:"foreign_msg,omitempty"`
+	EnumField  *ImportedMessage_Owner       `protobuf:"varint,4,opt,name=enum_field,json=enumField,enum=imp.ImportedMessage_Owner" json:"enum_field,omitempty"`
 	// Types that are valid to be assigned to Union:
 	// Types that are valid to be assigned to Union:
 	//	*ImportedMessage_State
 	//	*ImportedMessage_State
 	Union                        isImportedMessage_Union      `protobuf_oneof:"union"`
 	Union                        isImportedMessage_Union      `protobuf_oneof:"union"`
@@ -77,7 +140,7 @@ func (m *ImportedMessage) Reset()         { *m = ImportedMessage{} }
 func (m *ImportedMessage) String() string { return proto.CompactTextString(m) }
 func (m *ImportedMessage) String() string { return proto.CompactTextString(m) }
 func (*ImportedMessage) ProtoMessage()    {}
 func (*ImportedMessage) ProtoMessage()    {}
 func (*ImportedMessage) Descriptor() ([]byte, []int) {
 func (*ImportedMessage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_imp_81275c260ac30f8b, []int{0}
+	return fileDescriptor_imp_6424de66809c2ae5, []int{0}
 }
 }
 
 
 var extRange_ImportedMessage = []proto.ExtensionRange{
 var extRange_ImportedMessage = []proto.ExtensionRange{
@@ -136,7 +199,7 @@ func (m *ImportedMessage) GetLocalMsg() *ImportedMessage2 {
 	return nil
 	return nil
 }
 }
 
 
-func (m *ImportedMessage) GetForeignMsg() *ForeignImportedMessage {
+func (m *ImportedMessage) GetForeignMsg() *imp3.ForeignImportedMessage {
 	if m != nil {
 	if m != nil {
 		return m.ForeignMsg
 		return m.ForeignMsg
 	}
 	}
@@ -245,7 +308,7 @@ func (m *ImportedMessage2) Reset()         { *m = ImportedMessage2{} }
 func (m *ImportedMessage2) String() string { return proto.CompactTextString(m) }
 func (m *ImportedMessage2) String() string { return proto.CompactTextString(m) }
 func (*ImportedMessage2) ProtoMessage()    {}
 func (*ImportedMessage2) ProtoMessage()    {}
 func (*ImportedMessage2) Descriptor() ([]byte, []int) {
 func (*ImportedMessage2) Descriptor() ([]byte, []int) {
-	return fileDescriptor_imp_81275c260ac30f8b, []int{1}
+	return fileDescriptor_imp_6424de66809c2ae5, []int{1}
 }
 }
 func (m *ImportedMessage2) XXX_Unmarshal(b []byte) error {
 func (m *ImportedMessage2) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_ImportedMessage2.Unmarshal(m, b)
 	return xxx_messageInfo_ImportedMessage2.Unmarshal(m, b)
@@ -276,7 +339,7 @@ func (m *ImportedExtendable) Reset()         { *m = ImportedExtendable{} }
 func (m *ImportedExtendable) String() string { return proto.CompactTextString(m) }
 func (m *ImportedExtendable) String() string { return proto.CompactTextString(m) }
 func (*ImportedExtendable) ProtoMessage()    {}
 func (*ImportedExtendable) ProtoMessage()    {}
 func (*ImportedExtendable) Descriptor() ([]byte, []int) {
 func (*ImportedExtendable) Descriptor() ([]byte, []int) {
-	return fileDescriptor_imp_81275c260ac30f8b, []int{2}
+	return fileDescriptor_imp_6424de66809c2ae5, []int{2}
 }
 }
 
 
 func (m *ImportedExtendable) MarshalJSON() ([]byte, error) {
 func (m *ImportedExtendable) MarshalJSON() ([]byte, error) {
@@ -319,35 +382,35 @@ func init() {
 	proto.RegisterEnum("imp.ImportedMessage_Owner", ImportedMessage_Owner_name, ImportedMessage_Owner_value)
 	proto.RegisterEnum("imp.ImportedMessage_Owner", ImportedMessage_Owner_name, ImportedMessage_Owner_value)
 }
 }
 
 
-func init() { proto.RegisterFile("imp/imp.proto", fileDescriptor_imp_81275c260ac30f8b) }
-
-var fileDescriptor_imp_81275c260ac30f8b = []byte{
-	// 421 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x4f, 0x8b, 0xd4, 0x30,
-	0x18, 0xc6, 0x4d, 0xff, 0xec, 0xb4, 0xef, 0xe0, 0x5a, 0x82, 0x4a, 0x99, 0xbd, 0x84, 0x9e, 0xea,
-	0xca, 0x76, 0xa0, 0x22, 0xba, 0x8b, 0x17, 0x17, 0x67, 0x71, 0x91, 0xa2, 0xf4, 0xe0, 0x61, 0x2f,
-	0x43, 0x66, 0x9a, 0x89, 0xc5, 0x26, 0x29, 0x4d, 0xaa, 0xee, 0xf7, 0xf0, 0xfb, 0x56, 0x9a, 0xae,
-	0x22, 0xc3, 0xe8, 0xde, 0x9e, 0xe7, 0xe1, 0xf7, 0xe4, 0x4d, 0x9b, 0x17, 0x1e, 0xd6, 0xa2, 0x5d,
-	0xd6, 0xa2, 0xcd, 0xda, 0x4e, 0x19, 0x85, 0xdd, 0x5a, 0xb4, 0x8b, 0xe3, 0xbb, 0x2c, 0x9f, 0xc2,
-	0x3f, 0xfe, 0xc5, 0xe4, 0x93, 0x9f, 0x1e, 0x3c, 0xba, 0x16, 0xad, 0xea, 0x0c, 0xab, 0x0a, 0xa6,
-	0x35, 0xe5, 0x0c, 0x3f, 0x06, 0x7f, 0x57, 0xb3, 0xa6, 0x8a, 0x11, 0x71, 0x52, 0xb7, 0x9c, 0x0c,
-	0xce, 0x21, 0x6c, 0xd4, 0x96, 0x36, 0x6b, 0xa1, 0x79, 0xec, 0x10, 0x94, 0xce, 0xf3, 0x27, 0xd9,
-	0x38, 0x6d, 0xaf, 0x9e, 0x97, 0x81, 0xe5, 0x0a, 0xcd, 0xf1, 0x1b, 0x98, 0xef, 0x54, 0xc7, 0x6a,
-	0x2e, 0x6d, 0xcb, 0xb5, 0xad, 0x13, 0xdb, 0xba, 0x9a, 0xf2, 0xbd, 0x72, 0x09, 0x77, 0xfc, 0xd8,
-	0x3e, 0x07, 0x60, 0xb2, 0x17, 0xeb, 0xe9, 0x32, 0x1e, 0x41, 0xe9, 0x71, 0xbe, 0x38, 0x34, 0x32,
-	0xfb, 0xf8, 0x5d, 0xb2, 0xae, 0x0c, 0x47, 0xfa, 0xca, 0x5e, 0xf6, 0x29, 0xf8, 0xda, 0x50, 0xc3,
-	0xe2, 0x90, 0xa0, 0xd4, 0x7f, 0xff, 0xa0, 0x9c, 0x2c, 0xc6, 0xe0, 0x49, 0x2a, 0x58, 0xec, 0x13,
-	0x37, 0x0d, 0x4b, 0xab, 0x71, 0x06, 0xde, 0x46, 0x69, 0x1d, 0x1f, 0x11, 0xf7, 0x9e, 0x01, 0x96,
-	0xc3, 0xcf, 0xc0, 0x13, 0x4c, 0xa8, 0x78, 0x46, 0xdc, 0x7f, 0xff, 0x03, 0x8b, 0xe0, 0x73, 0x98,
-	0x09, 0xcd, 0xd7, 0x82, 0xb6, 0x71, 0x60, 0x69, 0x72, 0xf0, 0xf4, 0x42, 0xf3, 0x82, 0xb6, 0x2b,
-	0x69, 0xba, 0xdb, 0xf2, 0x48, 0x58, 0xb3, 0xf8, 0x04, 0xf3, 0xbf, 0x62, 0x1c, 0x81, 0xfb, 0x95,
-	0xdd, 0xc6, 0x88, 0xa0, 0x34, 0x2c, 0x47, 0x89, 0x9f, 0x83, 0xff, 0x8d, 0x36, 0x3d, 0xfb, 0xff,
-	0x5b, 0x4c, 0xcc, 0x85, 0xf3, 0x1a, 0x25, 0x27, 0xe0, 0xdb, 0xcf, 0xc0, 0x01, 0x78, 0xef, 0xde,
-	0x7e, 0x5e, 0x45, 0x68, 0x54, 0xc5, 0xf5, 0x87, 0x55, 0xe4, 0x9c, 0x7a, 0xc1, 0x4d, 0xc4, 0x2e,
-	0x67, 0xe0, 0xf7, 0xb2, 0x56, 0x32, 0xc1, 0x10, 0xed, 0x1f, 0x95, 0x24, 0x80, 0x7f, 0x67, 0xab,
-	0x1f, 0x86, 0xc9, 0x8a, 0x6e, 0x1a, 0x76, 0x1a, 0x04, 0x55, 0x34, 0x0c, 0xc3, 0x30, 0xbb, 0x70,
-	0x02, 0x74, 0xf9, 0xea, 0xe6, 0x25, 0xaf, 0xcd, 0x97, 0x7e, 0x93, 0x6d, 0x95, 0x58, 0x72, 0xd5,
-	0x50, 0xc9, 0x97, 0x76, 0xd3, 0x36, 0xfd, 0x6e, 0x12, 0xdb, 0x33, 0xce, 0xe4, 0x19, 0x57, 0x4b,
-	0xc3, 0xb4, 0xa9, 0xa8, 0xa1, 0xe3, 0x3a, 0xfe, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xe4, 0x5b,
-	0xa3, 0xbc, 0x02, 0x00, 0x00,
+func init() { proto.RegisterFile("imp/imp.proto", fileDescriptor_imp_6424de66809c2ae5) }
+
+var fileDescriptor_imp_6424de66809c2ae5 = []byte{
+	// 427 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0x4d, 0x6f, 0xd4, 0x30,
+	0x10, 0xad, 0xf3, 0xd1, 0x4d, 0x66, 0x05, 0x44, 0xe6, 0x43, 0xd1, 0xf6, 0x62, 0xe5, 0x14, 0x8a,
+	0x9a, 0x95, 0x82, 0x10, 0xb4, 0xe2, 0x42, 0xc5, 0x56, 0x54, 0x28, 0xa2, 0xca, 0x81, 0x43, 0x2f,
+	0x2b, 0xef, 0xc6, 0x6b, 0x22, 0x62, 0x3b, 0x8a, 0x1d, 0xa0, 0xff, 0x83, 0xff, 0x1b, 0x14, 0xa7,
+	0x20, 0xb4, 0x2a, 0xf4, 0x32, 0x7a, 0xf3, 0xfc, 0xde, 0xcc, 0xd8, 0x1e, 0x78, 0x50, 0x8b, 0x76,
+	0x59, 0x8b, 0x36, 0x6b, 0x3b, 0x65, 0x14, 0x76, 0x6b, 0xd1, 0x2e, 0x1e, 0xdf, 0x72, 0xb9, 0x0d,
+	0xd3, 0xc9, 0x1f, 0xf2, 0xa5, 0x0d, 0x13, 0x99, 0xfc, 0xf4, 0xe0, 0xd1, 0xa5, 0x68, 0x55, 0x67,
+	0x58, 0x55, 0x30, 0xad, 0x29, 0x67, 0xf8, 0x09, 0xf8, 0xbb, 0x9a, 0x35, 0x55, 0x8c, 0x88, 0x93,
+	0xba, 0xe5, 0x94, 0xe0, 0x1c, 0xc2, 0x46, 0x6d, 0x69, 0xb3, 0x16, 0x9a, 0xc7, 0x0e, 0x41, 0xe9,
+	0x3c, 0x7f, 0x9a, 0x8d, 0x7d, 0xf7, 0xec, 0x79, 0x19, 0x58, 0x5d, 0xa1, 0x39, 0x7e, 0x0b, 0xf3,
+	0x9d, 0xea, 0x58, 0xcd, 0xa5, 0x75, 0xb9, 0xd6, 0x75, 0x64, 0x5d, 0x17, 0x13, 0xbf, 0x67, 0x2e,
+	0xe1, 0x56, 0x3f, 0xba, 0x4f, 0x01, 0x98, 0xec, 0xc5, 0x7a, 0x1a, 0xc6, 0x23, 0x28, 0x7d, 0x98,
+	0x2f, 0xee, 0x6a, 0x99, 0x7d, 0xfa, 0x2e, 0x59, 0x57, 0x86, 0xa3, 0xfa, 0xc2, 0x0e, 0xfb, 0x0c,
+	0x7c, 0x6d, 0xa8, 0x61, 0x71, 0x48, 0x50, 0xea, 0x7f, 0x38, 0x28, 0xa7, 0x14, 0x63, 0xf0, 0x24,
+	0x15, 0x2c, 0xf6, 0x89, 0x9b, 0x86, 0xa5, 0xc5, 0x38, 0x03, 0x6f, 0xa3, 0xb4, 0x8e, 0x0f, 0x89,
+	0x7b, 0x4f, 0x03, 0xab, 0xc3, 0xcf, 0xc1, 0x13, 0x4c, 0xa8, 0x78, 0x46, 0xdc, 0x7f, 0xbf, 0x81,
+	0x95, 0xe0, 0x53, 0x98, 0x09, 0xcd, 0xd7, 0x82, 0xb6, 0x71, 0x60, 0xd5, 0xe4, 0xce, 0xea, 0x85,
+	0xe6, 0x05, 0x6d, 0x57, 0xd2, 0x74, 0x37, 0xe5, 0xa1, 0xb0, 0xc9, 0xe2, 0x0a, 0xe6, 0x7f, 0xd1,
+	0x38, 0x02, 0xf7, 0x2b, 0xbb, 0x89, 0x11, 0x41, 0x69, 0x58, 0x8e, 0x10, 0xbf, 0x00, 0xff, 0x1b,
+	0x6d, 0x7a, 0xf6, 0xff, 0xbf, 0x98, 0x34, 0x67, 0xce, 0x1b, 0x94, 0x1c, 0x81, 0x6f, 0xaf, 0x81,
+	0x03, 0xf0, 0xde, 0xbf, 0xfb, 0xbc, 0x8a, 0xd0, 0x88, 0x8a, 0xcb, 0x8f, 0xab, 0xc8, 0x39, 0xf6,
+	0x82, 0xeb, 0x88, 0x9d, 0xcf, 0xc0, 0xef, 0x65, 0xad, 0x64, 0x82, 0x21, 0xda, 0x2f, 0x95, 0x24,
+	0x80, 0x7f, 0x73, 0xab, 0x1f, 0x86, 0xc9, 0x8a, 0x6e, 0x1a, 0x76, 0x1c, 0x04, 0x55, 0x34, 0x0c,
+	0xc3, 0x30, 0x3b, 0x73, 0x02, 0x74, 0xfe, 0xfa, 0xfa, 0x15, 0xaf, 0xcd, 0x97, 0x7e, 0x93, 0x6d,
+	0x95, 0x58, 0x72, 0xd5, 0x50, 0xc9, 0x97, 0x76, 0xd3, 0x36, 0xfd, 0x6e, 0x02, 0xdb, 0x13, 0xce,
+	0xe4, 0x09, 0x57, 0x4b, 0xc3, 0xb4, 0xa9, 0xa8, 0xa1, 0xe3, 0x3a, 0x5e, 0x1d, 0xfc, 0x0a, 0x00,
+	0x00, 0xff, 0xff, 0xe7, 0x7a, 0x0f, 0x3a, 0xc8, 0x02, 0x00, 0x00,
 }
 }

+ 2 - 2
protoc-gen-go/testdata/imp/imp.proto

@@ -35,8 +35,8 @@ package imp;
 
 
 option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imp";
 option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imp";
 
 
-import "imp/imp2.proto";
-import "imp/imp3.proto";
+import public "imp/imp2/imp2.proto";
+import "imp/imp3/imp3.proto";
 
 
 message ImportedMessage {
 message ImportedMessage {
   required int64 field = 1;
   required int64 field = 1;

+ 0 - 115
protoc-gen-go/testdata/imp/imp2.pb.go

@@ -1,115 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: imp/imp2.proto
-
-package imp // import "github.com/golang/protobuf/protoc-gen-go/testdata/imp"
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import 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 PubliclyImportedEnum int32
-
-const (
-	PubliclyImportedEnum_GLASSES PubliclyImportedEnum = 1
-	PubliclyImportedEnum_HAIR    PubliclyImportedEnum = 2
-)
-
-var PubliclyImportedEnum_name = map[int32]string{
-	1: "GLASSES",
-	2: "HAIR",
-}
-var PubliclyImportedEnum_value = map[string]int32{
-	"GLASSES": 1,
-	"HAIR":    2,
-}
-
-func (x PubliclyImportedEnum) Enum() *PubliclyImportedEnum {
-	p := new(PubliclyImportedEnum)
-	*p = x
-	return p
-}
-func (x PubliclyImportedEnum) String() string {
-	return proto.EnumName(PubliclyImportedEnum_name, int32(x))
-}
-func (x *PubliclyImportedEnum) UnmarshalJSON(data []byte) error {
-	value, err := proto.UnmarshalJSONEnum(PubliclyImportedEnum_value, data, "PubliclyImportedEnum")
-	if err != nil {
-		return err
-	}
-	*x = PubliclyImportedEnum(value)
-	return nil
-}
-func (PubliclyImportedEnum) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptor_imp2_dcbceb16a8ff78d7, []int{0}
-}
-
-type PubliclyImportedMessage struct {
-	Field                *int64   `protobuf:"varint,1,opt,name=field" json:"field,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PubliclyImportedMessage) Reset()         { *m = PubliclyImportedMessage{} }
-func (m *PubliclyImportedMessage) String() string { return proto.CompactTextString(m) }
-func (*PubliclyImportedMessage) ProtoMessage()    {}
-func (*PubliclyImportedMessage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_imp2_dcbceb16a8ff78d7, []int{0}
-}
-func (m *PubliclyImportedMessage) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PubliclyImportedMessage.Unmarshal(m, b)
-}
-func (m *PubliclyImportedMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PubliclyImportedMessage.Marshal(b, m, deterministic)
-}
-func (dst *PubliclyImportedMessage) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PubliclyImportedMessage.Merge(dst, src)
-}
-func (m *PubliclyImportedMessage) XXX_Size() int {
-	return xxx_messageInfo_PubliclyImportedMessage.Size(m)
-}
-func (m *PubliclyImportedMessage) XXX_DiscardUnknown() {
-	xxx_messageInfo_PubliclyImportedMessage.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PubliclyImportedMessage proto.InternalMessageInfo
-
-func (m *PubliclyImportedMessage) GetField() int64 {
-	if m != nil && m.Field != nil {
-		return *m.Field
-	}
-	return 0
-}
-
-func init() {
-	proto.RegisterType((*PubliclyImportedMessage)(nil), "imp.PubliclyImportedMessage")
-	proto.RegisterEnum("imp.PubliclyImportedEnum", PubliclyImportedEnum_name, PubliclyImportedEnum_value)
-}
-
-func init() { proto.RegisterFile("imp/imp2.proto", fileDescriptor_imp2_dcbceb16a8ff78d7) }
-
-var fileDescriptor_imp2_dcbceb16a8ff78d7 = []byte{
-	// 171 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcb, 0xcc, 0x2d, 0xd0,
-	0xcf, 0xcc, 0x2d, 0x30, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xce, 0xcc, 0x2d, 0x50,
-	0xd2, 0xe7, 0x12, 0x0f, 0x28, 0x4d, 0xca, 0xc9, 0x4c, 0xce, 0xa9, 0xf4, 0xcc, 0x2d, 0xc8, 0x2f,
-	0x2a, 0x49, 0x4d, 0xf1, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, 0x15, 0x12, 0xe1, 0x62, 0x4d, 0xcb,
-	0x4c, 0xcd, 0x49, 0x91, 0x60, 0x54, 0x60, 0xd4, 0x60, 0x0e, 0x82, 0x70, 0xb4, 0x74, 0xb9, 0x44,
-	0xd0, 0x35, 0xb8, 0xe6, 0x95, 0xe6, 0x0a, 0x71, 0x73, 0xb1, 0xbb, 0xfb, 0x38, 0x06, 0x07, 0xbb,
-	0x06, 0x0b, 0x30, 0x0a, 0x71, 0x70, 0xb1, 0x78, 0x38, 0x7a, 0x06, 0x09, 0x30, 0x39, 0x99, 0x47,
-	0x99, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xe7, 0x24,
-	0xe6, 0xa5, 0xeb, 0x83, 0xed, 0x4f, 0x2a, 0x4d, 0x83, 0x30, 0x92, 0x75, 0xd3, 0x53, 0xf3, 0x74,
-	0xd3, 0xf3, 0xf5, 0x4b, 0x52, 0x8b, 0x4b, 0x52, 0x12, 0x4b, 0x12, 0x41, 0x8e, 0x04, 0x04, 0x00,
-	0x00, 0xff, 0xff, 0x32, 0x18, 0x4d, 0x15, 0xae, 0x00, 0x00, 0x00,
-}

+ 156 - 0
protoc-gen-go/testdata/imp/imp2/imp2.pb.go

@@ -0,0 +1,156 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: imp/imp2/imp2.proto
+
+package imp2 // import "github.com/golang/protobuf/protoc-gen-go/testdata/imp/imp2"
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import 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 PubliclyImportedEnum int32
+
+const (
+	PubliclyImportedEnum_GLASSES PubliclyImportedEnum = 1
+	PubliclyImportedEnum_HAIR    PubliclyImportedEnum = 2
+)
+
+var PubliclyImportedEnum_name = map[int32]string{
+	1: "GLASSES",
+	2: "HAIR",
+}
+var PubliclyImportedEnum_value = map[string]int32{
+	"GLASSES": 1,
+	"HAIR":    2,
+}
+
+func (x PubliclyImportedEnum) Enum() *PubliclyImportedEnum {
+	p := new(PubliclyImportedEnum)
+	*p = x
+	return p
+}
+func (x PubliclyImportedEnum) String() string {
+	return proto.EnumName(PubliclyImportedEnum_name, int32(x))
+}
+func (x *PubliclyImportedEnum) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(PubliclyImportedEnum_value, data, "PubliclyImportedEnum")
+	if err != nil {
+		return err
+	}
+	*x = PubliclyImportedEnum(value)
+	return nil
+}
+func (PubliclyImportedEnum) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_imp2_a81b5fa1a6dca420, []int{0}
+}
+
+type PubliclyImportedMessage struct {
+	Field                *int64   `protobuf:"varint,1,opt,name=field" json:"field,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *PubliclyImportedMessage) Reset()         { *m = PubliclyImportedMessage{} }
+func (m *PubliclyImportedMessage) String() string { return proto.CompactTextString(m) }
+func (*PubliclyImportedMessage) ProtoMessage()    {}
+func (*PubliclyImportedMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_imp2_a81b5fa1a6dca420, []int{0}
+}
+func (m *PubliclyImportedMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PubliclyImportedMessage.Unmarshal(m, b)
+}
+func (m *PubliclyImportedMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PubliclyImportedMessage.Marshal(b, m, deterministic)
+}
+func (dst *PubliclyImportedMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PubliclyImportedMessage.Merge(dst, src)
+}
+func (m *PubliclyImportedMessage) XXX_Size() int {
+	return xxx_messageInfo_PubliclyImportedMessage.Size(m)
+}
+func (m *PubliclyImportedMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_PubliclyImportedMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PubliclyImportedMessage proto.InternalMessageInfo
+
+func (m *PubliclyImportedMessage) GetField() int64 {
+	if m != nil && m.Field != nil {
+		return *m.Field
+	}
+	return 0
+}
+
+type PubliclyImportedMessage2 struct {
+	Field                *PubliclyImportedMessage `protobuf:"bytes,1,opt,name=field" json:"field,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
+	XXX_unrecognized     []byte                   `json:"-"`
+	XXX_sizecache        int32                    `json:"-"`
+}
+
+func (m *PubliclyImportedMessage2) Reset()         { *m = PubliclyImportedMessage2{} }
+func (m *PubliclyImportedMessage2) String() string { return proto.CompactTextString(m) }
+func (*PubliclyImportedMessage2) ProtoMessage()    {}
+func (*PubliclyImportedMessage2) Descriptor() ([]byte, []int) {
+	return fileDescriptor_imp2_a81b5fa1a6dca420, []int{1}
+}
+func (m *PubliclyImportedMessage2) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PubliclyImportedMessage2.Unmarshal(m, b)
+}
+func (m *PubliclyImportedMessage2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PubliclyImportedMessage2.Marshal(b, m, deterministic)
+}
+func (dst *PubliclyImportedMessage2) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PubliclyImportedMessage2.Merge(dst, src)
+}
+func (m *PubliclyImportedMessage2) XXX_Size() int {
+	return xxx_messageInfo_PubliclyImportedMessage2.Size(m)
+}
+func (m *PubliclyImportedMessage2) XXX_DiscardUnknown() {
+	xxx_messageInfo_PubliclyImportedMessage2.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PubliclyImportedMessage2 proto.InternalMessageInfo
+
+func (m *PubliclyImportedMessage2) GetField() *PubliclyImportedMessage {
+	if m != nil {
+		return m.Field
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*PubliclyImportedMessage)(nil), "imp.PubliclyImportedMessage")
+	proto.RegisterType((*PubliclyImportedMessage2)(nil), "imp.PubliclyImportedMessage2")
+	proto.RegisterEnum("imp.PubliclyImportedEnum", PubliclyImportedEnum_name, PubliclyImportedEnum_value)
+}
+
+func init() { proto.RegisterFile("imp/imp2/imp2.proto", fileDescriptor_imp2_a81b5fa1a6dca420) }
+
+var fileDescriptor_imp2_a81b5fa1a6dca420 = []byte{
+	// 198 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xce, 0xcc, 0x2d, 0xd0,
+	0xcf, 0xcc, 0x2d, 0x30, 0x02, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xcc, 0x99, 0xb9,
+	0x05, 0x4a, 0xfa, 0x5c, 0xe2, 0x01, 0xa5, 0x49, 0x39, 0x99, 0xc9, 0x39, 0x95, 0x9e, 0xb9, 0x05,
+	0xf9, 0x45, 0x25, 0xa9, 0x29, 0xbe, 0xa9, 0xc5, 0xc5, 0x89, 0xe9, 0xa9, 0x42, 0x22, 0x5c, 0xac,
+	0x69, 0x99, 0xa9, 0x39, 0x29, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x10, 0x8e, 0x92, 0x1f,
+	0x97, 0x04, 0x0e, 0x0d, 0x46, 0x42, 0x46, 0xc8, 0x3a, 0xb8, 0x8d, 0x64, 0xf4, 0x32, 0x73, 0x0b,
+	0xf4, 0x70, 0xa8, 0x86, 0x9a, 0xa7, 0xa5, 0xcb, 0x25, 0x82, 0xae, 0xc2, 0x35, 0xaf, 0x34, 0x57,
+	0x88, 0x9b, 0x8b, 0xdd, 0xdd, 0xc7, 0x31, 0x38, 0xd8, 0x35, 0x58, 0x80, 0x51, 0x88, 0x83, 0x8b,
+	0xc5, 0xc3, 0xd1, 0x33, 0x48, 0x80, 0xc9, 0xc9, 0x26, 0xca, 0x2a, 0x3d, 0xb3, 0x24, 0xa3, 0x34,
+	0x49, 0x2f, 0x39, 0x3f, 0x57, 0x3f, 0x3d, 0x3f, 0x27, 0x31, 0x2f, 0x5d, 0x1f, 0xec, 0x9f, 0xa4,
+	0xd2, 0x34, 0x08, 0x23, 0x59, 0x37, 0x3d, 0x35, 0x4f, 0x37, 0x3d, 0x5f, 0xbf, 0x24, 0xb5, 0xb8,
+	0x24, 0x25, 0xb1, 0x24, 0x51, 0x1f, 0xe6, 0x7b, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xcb,
+	0xbc, 0x81, 0x08, 0x01, 0x00, 0x00,
+}

+ 5 - 1
protoc-gen-go/testdata/imp/imp2.proto → protoc-gen-go/testdata/imp/imp2/imp2.proto

@@ -33,12 +33,16 @@ syntax = "proto2";
 
 
 package imp;
 package imp;
 
 
-option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imp";
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imp/imp2";
 
 
 message PubliclyImportedMessage {
 message PubliclyImportedMessage {
   optional int64 field = 1;
   optional int64 field = 1;
 }
 }
 
 
+message PubliclyImportedMessage2 {
+  optional PubliclyImportedMessage field = 1;
+}
+
 enum PubliclyImportedEnum {
 enum PubliclyImportedEnum {
   GLASSES = 1;
   GLASSES = 1;
   HAIR = 2;
   HAIR = 2;

+ 15 - 15
protoc-gen-go/testdata/imp/imp3.pb.go → protoc-gen-go/testdata/imp/imp3/imp3.pb.go

@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // Code generated by protoc-gen-go. DO NOT EDIT.
-// source: imp/imp3.proto
+// source: imp/imp3/imp3.proto
 
 
-package imp // import "github.com/golang/protobuf/protoc-gen-go/testdata/imp"
+package imp3 // import "github.com/golang/protobuf/protoc-gen-go/testdata/imp/imp3"
 
 
 import proto "github.com/golang/protobuf/proto"
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import fmt "fmt"
@@ -29,7 +29,7 @@ func (m *ForeignImportedMessage) Reset()         { *m = ForeignImportedMessage{}
 func (m *ForeignImportedMessage) String() string { return proto.CompactTextString(m) }
 func (m *ForeignImportedMessage) String() string { return proto.CompactTextString(m) }
 func (*ForeignImportedMessage) ProtoMessage()    {}
 func (*ForeignImportedMessage) ProtoMessage()    {}
 func (*ForeignImportedMessage) Descriptor() ([]byte, []int) {
 func (*ForeignImportedMessage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_imp3_dbacc1715de7e782, []int{0}
+	return fileDescriptor_imp3_4aae87d6f1c23d12, []int{0}
 }
 }
 func (m *ForeignImportedMessage) XXX_Unmarshal(b []byte) error {
 func (m *ForeignImportedMessage) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_ForeignImportedMessage.Unmarshal(m, b)
 	return xxx_messageInfo_ForeignImportedMessage.Unmarshal(m, b)
@@ -60,17 +60,17 @@ func init() {
 	proto.RegisterType((*ForeignImportedMessage)(nil), "imp.ForeignImportedMessage")
 	proto.RegisterType((*ForeignImportedMessage)(nil), "imp.ForeignImportedMessage")
 }
 }
 
 
-func init() { proto.RegisterFile("imp/imp3.proto", fileDescriptor_imp3_dbacc1715de7e782) }
+func init() { proto.RegisterFile("imp/imp3/imp3.proto", fileDescriptor_imp3_4aae87d6f1c23d12) }
 
 
-var fileDescriptor_imp3_dbacc1715de7e782 = []byte{
-	// 137 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcb, 0xcc, 0x2d, 0xd0,
-	0xcf, 0xcc, 0x2d, 0x30, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xce, 0xcc, 0x2d, 0x50,
-	0xd2, 0xe3, 0x12, 0x73, 0xcb, 0x2f, 0x4a, 0xcd, 0x4c, 0xcf, 0xf3, 0xcc, 0x2d, 0xc8, 0x2f, 0x2a,
-	0x49, 0x4d, 0xf1, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, 0x15, 0x12, 0xe1, 0x62, 0x2d, 0x29, 0x4d,
-	0x4a, 0x2d, 0x92, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x70, 0x9c, 0xcc, 0xa3, 0x4c, 0xd3,
-	0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0x73, 0x12, 0xf3, 0xd2,
-	0xf5, 0xc1, 0xe6, 0x25, 0x95, 0xa6, 0x41, 0x18, 0xc9, 0xba, 0xe9, 0xa9, 0x79, 0xba, 0xe9, 0xf9,
-	0xfa, 0x25, 0xa9, 0xc5, 0x25, 0x29, 0x89, 0x25, 0x89, 0x20, 0x4b, 0x01, 0x01, 0x00, 0x00, 0xff,
-	0xff, 0xa9, 0xbf, 0xbe, 0xdc, 0x7e, 0x00, 0x00, 0x00,
+var fileDescriptor_imp3_4aae87d6f1c23d12 = []byte{
+	// 139 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xce, 0xcc, 0x2d, 0xd0,
+	0xcf, 0xcc, 0x2d, 0x30, 0x06, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xcc, 0x99, 0xb9,
+	0x05, 0x4a, 0x7a, 0x5c, 0x62, 0x6e, 0xf9, 0x45, 0xa9, 0x99, 0xe9, 0x79, 0x9e, 0xb9, 0x05, 0xf9,
+	0x45, 0x25, 0xa9, 0x29, 0xbe, 0xa9, 0xc5, 0xc5, 0x89, 0xe9, 0xa9, 0x42, 0x22, 0x5c, 0xac, 0x25,
+	0xa5, 0x49, 0xa9, 0x45, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x10, 0x8e, 0x93, 0x4d, 0x94,
+	0x55, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62,
+	0x5e, 0xba, 0x3e, 0xd8, 0xbc, 0xa4, 0xd2, 0x34, 0x08, 0x23, 0x59, 0x37, 0x3d, 0x35, 0x4f, 0x37,
+	0x3d, 0x5f, 0xbf, 0x24, 0xb5, 0xb8, 0x24, 0x25, 0xb1, 0x24, 0x51, 0x1f, 0x66, 0x3b, 0x20, 0x00,
+	0x00, 0xff, 0xff, 0xda, 0xb9, 0x43, 0xe2, 0x88, 0x00, 0x00, 0x00,
 }
 }

+ 1 - 1
protoc-gen-go/testdata/imp/imp3.proto → protoc-gen-go/testdata/imp/imp3/imp3.proto

@@ -33,7 +33,7 @@ syntax = "proto2";
 
 
 package imp;
 package imp;
 
 
-option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imp";
+option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imp/imp3";
 
 
 message ForeignImportedMessage {
 message ForeignImportedMessage {
   optional string tuber = 1;
   optional string tuber = 1;

+ 72 - 9
protoc-gen-go/testdata/imports/test_a_1/m1.pb.go

@@ -18,6 +18,26 @@ var _ = math.Inf
 // proto package needs to be updated.
 // proto package needs to be updated.
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 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_m1_56a2598431d21e61, []int{0}
+}
+
 type M1 struct {
 type M1 struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
@@ -28,7 +48,7 @@ func (m *M1) Reset()         { *m = M1{} }
 func (m *M1) String() string { return proto.CompactTextString(m) }
 func (m *M1) String() string { return proto.CompactTextString(m) }
 func (*M1) ProtoMessage()    {}
 func (*M1) ProtoMessage()    {}
 func (*M1) Descriptor() ([]byte, []int) {
 func (*M1) Descriptor() ([]byte, []int) {
-	return fileDescriptor_m1_4abc85f8d0361bef, []int{0}
+	return fileDescriptor_m1_56a2598431d21e61, []int{0}
 }
 }
 func (m *M1) XXX_Unmarshal(b []byte) error {
 func (m *M1) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_M1.Unmarshal(m, b)
 	return xxx_messageInfo_M1.Unmarshal(m, b)
@@ -48,20 +68,63 @@ func (m *M1) XXX_DiscardUnknown() {
 
 
 var xxx_messageInfo_M1 proto.InternalMessageInfo
 var xxx_messageInfo_M1 proto.InternalMessageInfo
 
 
+type M1_1 struct {
+	M1                   *M1      `protobuf:"bytes,1,opt,name=m1" 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_m1_56a2598431d21e61, []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 (dst *M1_1) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_M1_1.Merge(dst, 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() {
 func init() {
 	proto.RegisterType((*M1)(nil), "test.a.M1")
 	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_m1_4abc85f8d0361bef) }
+func init() { proto.RegisterFile("imports/test_a_1/m1.proto", fileDescriptor_m1_56a2598431d21e61) }
 
 
-var fileDescriptor_m1_4abc85f8d0361bef = []byte{
-	// 114 bytes of a gzipped FileDescriptorProto
+var fileDescriptor_m1_56a2598431d21e61 = []byte{
+	// 165 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
 	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,
 	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,
 	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0x09, 0xe9, 0x25, 0x2a, 0xb1, 0x70, 0x31, 0xf9,
-	0x1a, 0x3a, 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, 0x17, 0x7d, 0xab, 0xd8, 0x77, 0x00,
-	0x00, 0x00,
+	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,
 }
 }

+ 9 - 0
protoc-gen-go/testdata/imports/test_a_1/m1.proto

@@ -32,4 +32,13 @@
 syntax = "proto3";
 syntax = "proto3";
 package test.a;
 package test.a;
 option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1";
 option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1";
+
 message M1 {}
 message M1 {}
+
+message M1_1 {
+  M1 m1 = 1;
+}
+
+enum E1 {
+  E1_ZERO = 0;
+}

+ 47 - 14
protoc-gen-go/testdata/imports/test_import_public.pb.go

@@ -32,8 +32,33 @@ func (m *M1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 func (m *M1) XXX_Size() int       { return (*test_a_1.M1)(m).XXX_Size() }
 func (m *M1) XXX_Size() int       { return (*test_a_1.M1)(m).XXX_Size() }
 func (m *M1) XXX_DiscardUnknown() { (*test_a_1.M1)(m).XXX_DiscardUnknown() }
 func (m *M1) XXX_DiscardUnknown() { (*test_a_1.M1)(m).XXX_DiscardUnknown() }
 
 
+// M1_1 from public import imports/test_a_1/m1.proto
+type M1_1 test_a_1.M1_1
+
+func (m *M1_1) Reset()                         { (*test_a_1.M1_1)(m).Reset() }
+func (m *M1_1) String() string                 { return (*test_a_1.M1_1)(m).String() }
+func (*M1_1) ProtoMessage()                    {}
+func (m *M1_1) XXX_Unmarshal(buf []byte) error { return (*test_a_1.M1_1)(m).XXX_Unmarshal(buf) }
+func (m *M1_1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return (*test_a_1.M1_1)(m).XXX_Marshal(b, deterministic)
+}
+func (m *M1_1) XXX_Size() int       { return (*test_a_1.M1_1)(m).XXX_Size() }
+func (m *M1_1) XXX_DiscardUnknown() { (*test_a_1.M1_1)(m).XXX_DiscardUnknown() }
+func (m *M1_1) GetM1() *M1          { return (*M1)((*test_a_1.M1_1)(m).GetM1()) }
+
+// E1 from public import imports/test_a_1/m1.proto
+type E1 test_a_1.E1
+
+var E1_name = test_a_1.E1_name
+var E1_value = test_a_1.E1_value
+
+func (x E1) String() string { return (test_a_1.E1)(x).String() }
+
+const E1_E1_ZERO = E1(test_a_1.E1_E1_ZERO)
+
 type Public struct {
 type Public struct {
-	F                    *test_a_1.M1 `protobuf:"bytes,1,opt,name=f" json:"f,omitempty"`
+	M1                   *test_a_1.M1 `protobuf:"bytes,1,opt,name=m1" json:"m1,omitempty"`
+	E1                   test_a_1.E1  `protobuf:"varint,2,opt,name=e1,enum=test.a.E1" json:"e1,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
 	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
 	XXX_unrecognized     []byte       `json:"-"`
 	XXX_unrecognized     []byte       `json:"-"`
 	XXX_sizecache        int32        `json:"-"`
 	XXX_sizecache        int32        `json:"-"`
@@ -43,7 +68,7 @@ func (m *Public) Reset()         { *m = Public{} }
 func (m *Public) String() string { return proto.CompactTextString(m) }
 func (m *Public) String() string { return proto.CompactTextString(m) }
 func (*Public) ProtoMessage()    {}
 func (*Public) ProtoMessage()    {}
 func (*Public) Descriptor() ([]byte, []int) {
 func (*Public) Descriptor() ([]byte, []int) {
-	return fileDescriptor_test_import_public_592f461eca0812f7, []int{0}
+	return fileDescriptor_test_import_public_b5b1d653c96016f3, []int{0}
 }
 }
 func (m *Public) XXX_Unmarshal(b []byte) error {
 func (m *Public) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_Public.Unmarshal(m, b)
 	return xxx_messageInfo_Public.Unmarshal(m, b)
@@ -63,31 +88,39 @@ func (m *Public) XXX_DiscardUnknown() {
 
 
 var xxx_messageInfo_Public proto.InternalMessageInfo
 var xxx_messageInfo_Public proto.InternalMessageInfo
 
 
-func (m *Public) GetF() *test_a_1.M1 {
+func (m *Public) GetM1() *test_a_1.M1 {
 	if m != nil {
 	if m != nil {
-		return m.F
+		return m.M1
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
+func (m *Public) GetE1() test_a_1.E1 {
+	if m != nil {
+		return m.E1
+	}
+	return test_a_1.E1_E1_ZERO
+}
+
 func init() {
 func init() {
 	proto.RegisterType((*Public)(nil), "test.Public")
 	proto.RegisterType((*Public)(nil), "test.Public")
 }
 }
 
 
 func init() {
 func init() {
-	proto.RegisterFile("imports/test_import_public.proto", fileDescriptor_test_import_public_592f461eca0812f7)
+	proto.RegisterFile("imports/test_import_public.proto", fileDescriptor_test_import_public_b5b1d653c96016f3)
 }
 }
 
 
-var fileDescriptor_test_import_public_592f461eca0812f7 = []byte{
-	// 154 bytes of a gzipped FileDescriptorProto
+var fileDescriptor_test_import_public_b5b1d653c96016f3 = []byte{
+	// 174 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc8, 0xcc, 0x2d, 0xc8,
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc8, 0xcc, 0x2d, 0xc8,
 	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x87, 0x70, 0xe2, 0x0b, 0x4a, 0x93, 0x72,
 	0x2f, 0x2a, 0x29, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x89, 0x87, 0x70, 0xe2, 0x0b, 0x4a, 0x93, 0x72,
 	0x32, 0x93, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x58, 0x40, 0x32, 0x52, 0x92, 0x28, 0xea,
 	0x32, 0x93, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x58, 0x40, 0x32, 0x52, 0x92, 0x28, 0xea,
-	0x12, 0xe3, 0x0d, 0xf5, 0x73, 0x0d, 0x21, 0x0a, 0x94, 0x94, 0xb8, 0xd8, 0x02, 0xc0, 0x1a, 0x84,
-	0x24, 0xb8, 0x18, 0xd3, 0x24, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0xb8, 0xf4, 0x40, 0x0a, 0xf5,
-	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, 0xda, 0x93,
-	0x4a, 0xd3, 0x20, 0x8c, 0x64, 0xdd, 0xf4, 0xd4, 0x3c, 0xdd, 0xf4, 0x7c, 0xb0, 0x0d, 0x29, 0x89,
-	0x25, 0x89, 0xfa, 0x50, 0x2b, 0x03, 0x18, 0x92, 0xd8, 0xc0, 0x2a, 0x8c, 0x01, 0x01, 0x00, 0x00,
-	0xff, 0xff, 0x2d, 0x78, 0xaa, 0x84, 0xae, 0x00, 0x00, 0x00,
+	0x12, 0xe3, 0x0d, 0xf5, 0x73, 0x0d, 0x21, 0x0a, 0x94, 0x1c, 0xb8, 0xd8, 0x02, 0xc0, 0x1a, 0x84,
+	0xa4, 0xb8, 0x98, 0x72, 0x0d, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0xb8, 0xf4, 0x40, 0x2a,
+	0xf5, 0x12, 0xf5, 0x7c, 0x0d, 0x83, 0x98, 0x72, 0x0d, 0x41, 0x72, 0xa9, 0x86, 0x12, 0x4c, 0x0a,
+	0x8c, 0x1a, 0x7c, 0x08, 0x39, 0x57, 0xc3, 0x20, 0xa6, 0x54, 0x43, 0x27, 0xeb, 0x28, 0xcb, 0xf4,
+	0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0xf4, 0xfc, 0x9c, 0xc4, 0xbc, 0x74,
+	0x7d, 0xb0, 0xe1, 0x49, 0xa5, 0x69, 0x10, 0x46, 0xb2, 0x6e, 0x7a, 0x6a, 0x9e, 0x6e, 0x7a, 0x3e,
+	0xd8, 0xfe, 0x94, 0xc4, 0x92, 0x44, 0x7d, 0xa8, 0x83, 0x02, 0x18, 0x92, 0xd8, 0xc0, 0x2a, 0x8c,
+	0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x65, 0x95, 0x6f, 0xe5, 0xcc, 0x00, 0x00, 0x00,
 }
 }

+ 2 - 1
protoc-gen-go/testdata/imports/test_import_public.proto

@@ -38,5 +38,6 @@ option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/imports";
 import public "imports/test_a_1/m1.proto";
 import public "imports/test_a_1/m1.proto";
 
 
 message Public {
 message Public {
-  test.a.M1 f = 1;
+  test.a.M1 m1 = 1;
+  test.a.E1 e1 = 2;
 }
 }

+ 2 - 0
protoc-gen-go/testdata/main_test.go

@@ -36,6 +36,7 @@ package testdata
 import (
 import (
 	"testing"
 	"testing"
 
 
+	imppb "github.com/golang/protobuf/protoc-gen-go/testdata/imp"
 	importspb "github.com/golang/protobuf/protoc-gen-go/testdata/imports"
 	importspb "github.com/golang/protobuf/protoc-gen-go/testdata/imports"
 	multipb "github.com/golang/protobuf/protoc-gen-go/testdata/multi"
 	multipb "github.com/golang/protobuf/protoc-gen-go/testdata/multi"
 	mytestpb "github.com/golang/protobuf/protoc-gen-go/testdata/my_test"
 	mytestpb "github.com/golang/protobuf/protoc-gen-go/testdata/my_test"
@@ -45,4 +46,5 @@ func TestLink(t *testing.T) {
 	_ = &multipb.Multi1{}
 	_ = &multipb.Multi1{}
 	_ = &mytestpb.Request{}
 	_ = &mytestpb.Request{}
 	_ = &importspb.All{}
 	_ = &importspb.All{}
+	_ = &imppb.ImportedMessage{}
 }
 }