protoc-gen-go: handle package import names per-file (#543)

Rework the handling of imported packages.

Do not add imported protobuf packages to a global registry. Instead,
maintain a per-file list of packages and names. This avoids imports
in one file affecting the generated code in a second one.

Consistently deal with imports in terms of import path, rather than
source file. This avoids imports of two .proto files in the same
Go package producing redundant import statements.

Introduce ImportPath and PackageName types to prevent confusion about
which values contain import paths ("github.com/golang/protobuf/proto")
and which contain package names ("proto").

Convert many uses of FileDescriptorProto to FileDescriptor, for
consistency and general convenience.
diff --git a/_conformance/conformance.pb.go b/_conformance/conformance.pb.go
index 2dc0bbb..b02a47f 100644
--- a/_conformance/conformance.pb.go
+++ b/_conformance/conformance.pb.go
@@ -6,12 +6,12 @@
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
-import google_protobuf1 "github.com/golang/protobuf/ptypes/duration"
-import google_protobuf2 "google.golang.org/genproto/protobuf"
-import google_protobuf3 "github.com/golang/protobuf/ptypes/struct"
-import google_protobuf4 "github.com/golang/protobuf/ptypes/timestamp"
-import google_protobuf5 "github.com/golang/protobuf/ptypes/wrappers"
+import any "github.com/golang/protobuf/ptypes/any"
+import duration "github.com/golang/protobuf/ptypes/duration"
+import _struct "github.com/golang/protobuf/ptypes/struct"
+import timestamp "github.com/golang/protobuf/ptypes/timestamp"
+import wrappers "github.com/golang/protobuf/ptypes/wrappers"
+import protobuf "google.golang.org/genproto/protobuf"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -581,36 +581,36 @@
 	//	*TestAllTypes_OneofEnum
 	OneofField isTestAllTypes_OneofField `protobuf_oneof:"oneof_field"`
 	// Well-known types
-	OptionalBoolWrapper   *google_protobuf5.BoolValue     `protobuf:"bytes,201,opt,name=optional_bool_wrapper,json=optionalBoolWrapper" json:"optional_bool_wrapper,omitempty"`
-	OptionalInt32Wrapper  *google_protobuf5.Int32Value    `protobuf:"bytes,202,opt,name=optional_int32_wrapper,json=optionalInt32Wrapper" json:"optional_int32_wrapper,omitempty"`
-	OptionalInt64Wrapper  *google_protobuf5.Int64Value    `protobuf:"bytes,203,opt,name=optional_int64_wrapper,json=optionalInt64Wrapper" json:"optional_int64_wrapper,omitempty"`
-	OptionalUint32Wrapper *google_protobuf5.UInt32Value   `protobuf:"bytes,204,opt,name=optional_uint32_wrapper,json=optionalUint32Wrapper" json:"optional_uint32_wrapper,omitempty"`
-	OptionalUint64Wrapper *google_protobuf5.UInt64Value   `protobuf:"bytes,205,opt,name=optional_uint64_wrapper,json=optionalUint64Wrapper" json:"optional_uint64_wrapper,omitempty"`
-	OptionalFloatWrapper  *google_protobuf5.FloatValue    `protobuf:"bytes,206,opt,name=optional_float_wrapper,json=optionalFloatWrapper" json:"optional_float_wrapper,omitempty"`
-	OptionalDoubleWrapper *google_protobuf5.DoubleValue   `protobuf:"bytes,207,opt,name=optional_double_wrapper,json=optionalDoubleWrapper" json:"optional_double_wrapper,omitempty"`
-	OptionalStringWrapper *google_protobuf5.StringValue   `protobuf:"bytes,208,opt,name=optional_string_wrapper,json=optionalStringWrapper" json:"optional_string_wrapper,omitempty"`
-	OptionalBytesWrapper  *google_protobuf5.BytesValue    `protobuf:"bytes,209,opt,name=optional_bytes_wrapper,json=optionalBytesWrapper" json:"optional_bytes_wrapper,omitempty"`
-	RepeatedBoolWrapper   []*google_protobuf5.BoolValue   `protobuf:"bytes,211,rep,name=repeated_bool_wrapper,json=repeatedBoolWrapper" json:"repeated_bool_wrapper,omitempty"`
-	RepeatedInt32Wrapper  []*google_protobuf5.Int32Value  `protobuf:"bytes,212,rep,name=repeated_int32_wrapper,json=repeatedInt32Wrapper" json:"repeated_int32_wrapper,omitempty"`
-	RepeatedInt64Wrapper  []*google_protobuf5.Int64Value  `protobuf:"bytes,213,rep,name=repeated_int64_wrapper,json=repeatedInt64Wrapper" json:"repeated_int64_wrapper,omitempty"`
-	RepeatedUint32Wrapper []*google_protobuf5.UInt32Value `protobuf:"bytes,214,rep,name=repeated_uint32_wrapper,json=repeatedUint32Wrapper" json:"repeated_uint32_wrapper,omitempty"`
-	RepeatedUint64Wrapper []*google_protobuf5.UInt64Value `protobuf:"bytes,215,rep,name=repeated_uint64_wrapper,json=repeatedUint64Wrapper" json:"repeated_uint64_wrapper,omitempty"`
-	RepeatedFloatWrapper  []*google_protobuf5.FloatValue  `protobuf:"bytes,216,rep,name=repeated_float_wrapper,json=repeatedFloatWrapper" json:"repeated_float_wrapper,omitempty"`
-	RepeatedDoubleWrapper []*google_protobuf5.DoubleValue `protobuf:"bytes,217,rep,name=repeated_double_wrapper,json=repeatedDoubleWrapper" json:"repeated_double_wrapper,omitempty"`
-	RepeatedStringWrapper []*google_protobuf5.StringValue `protobuf:"bytes,218,rep,name=repeated_string_wrapper,json=repeatedStringWrapper" json:"repeated_string_wrapper,omitempty"`
-	RepeatedBytesWrapper  []*google_protobuf5.BytesValue  `protobuf:"bytes,219,rep,name=repeated_bytes_wrapper,json=repeatedBytesWrapper" json:"repeated_bytes_wrapper,omitempty"`
-	OptionalDuration      *google_protobuf1.Duration      `protobuf:"bytes,301,opt,name=optional_duration,json=optionalDuration" json:"optional_duration,omitempty"`
-	OptionalTimestamp     *google_protobuf4.Timestamp     `protobuf:"bytes,302,opt,name=optional_timestamp,json=optionalTimestamp" json:"optional_timestamp,omitempty"`
-	OptionalFieldMask     *google_protobuf2.FieldMask     `protobuf:"bytes,303,opt,name=optional_field_mask,json=optionalFieldMask" json:"optional_field_mask,omitempty"`
-	OptionalStruct        *google_protobuf3.Struct        `protobuf:"bytes,304,opt,name=optional_struct,json=optionalStruct" json:"optional_struct,omitempty"`
-	OptionalAny           *google_protobuf.Any            `protobuf:"bytes,305,opt,name=optional_any,json=optionalAny" json:"optional_any,omitempty"`
-	OptionalValue         *google_protobuf3.Value         `protobuf:"bytes,306,opt,name=optional_value,json=optionalValue" json:"optional_value,omitempty"`
-	RepeatedDuration      []*google_protobuf1.Duration    `protobuf:"bytes,311,rep,name=repeated_duration,json=repeatedDuration" json:"repeated_duration,omitempty"`
-	RepeatedTimestamp     []*google_protobuf4.Timestamp   `protobuf:"bytes,312,rep,name=repeated_timestamp,json=repeatedTimestamp" json:"repeated_timestamp,omitempty"`
-	RepeatedFieldmask     []*google_protobuf2.FieldMask   `protobuf:"bytes,313,rep,name=repeated_fieldmask,json=repeatedFieldmask" json:"repeated_fieldmask,omitempty"`
-	RepeatedStruct        []*google_protobuf3.Struct      `protobuf:"bytes,324,rep,name=repeated_struct,json=repeatedStruct" json:"repeated_struct,omitempty"`
-	RepeatedAny           []*google_protobuf.Any          `protobuf:"bytes,315,rep,name=repeated_any,json=repeatedAny" json:"repeated_any,omitempty"`
-	RepeatedValue         []*google_protobuf3.Value       `protobuf:"bytes,316,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
+	OptionalBoolWrapper   *wrappers.BoolValue     `protobuf:"bytes,201,opt,name=optional_bool_wrapper,json=optionalBoolWrapper" json:"optional_bool_wrapper,omitempty"`
+	OptionalInt32Wrapper  *wrappers.Int32Value    `protobuf:"bytes,202,opt,name=optional_int32_wrapper,json=optionalInt32Wrapper" json:"optional_int32_wrapper,omitempty"`
+	OptionalInt64Wrapper  *wrappers.Int64Value    `protobuf:"bytes,203,opt,name=optional_int64_wrapper,json=optionalInt64Wrapper" json:"optional_int64_wrapper,omitempty"`
+	OptionalUint32Wrapper *wrappers.UInt32Value   `protobuf:"bytes,204,opt,name=optional_uint32_wrapper,json=optionalUint32Wrapper" json:"optional_uint32_wrapper,omitempty"`
+	OptionalUint64Wrapper *wrappers.UInt64Value   `protobuf:"bytes,205,opt,name=optional_uint64_wrapper,json=optionalUint64Wrapper" json:"optional_uint64_wrapper,omitempty"`
+	OptionalFloatWrapper  *wrappers.FloatValue    `protobuf:"bytes,206,opt,name=optional_float_wrapper,json=optionalFloatWrapper" json:"optional_float_wrapper,omitempty"`
+	OptionalDoubleWrapper *wrappers.DoubleValue   `protobuf:"bytes,207,opt,name=optional_double_wrapper,json=optionalDoubleWrapper" json:"optional_double_wrapper,omitempty"`
+	OptionalStringWrapper *wrappers.StringValue   `protobuf:"bytes,208,opt,name=optional_string_wrapper,json=optionalStringWrapper" json:"optional_string_wrapper,omitempty"`
+	OptionalBytesWrapper  *wrappers.BytesValue    `protobuf:"bytes,209,opt,name=optional_bytes_wrapper,json=optionalBytesWrapper" json:"optional_bytes_wrapper,omitempty"`
+	RepeatedBoolWrapper   []*wrappers.BoolValue   `protobuf:"bytes,211,rep,name=repeated_bool_wrapper,json=repeatedBoolWrapper" json:"repeated_bool_wrapper,omitempty"`
+	RepeatedInt32Wrapper  []*wrappers.Int32Value  `protobuf:"bytes,212,rep,name=repeated_int32_wrapper,json=repeatedInt32Wrapper" json:"repeated_int32_wrapper,omitempty"`
+	RepeatedInt64Wrapper  []*wrappers.Int64Value  `protobuf:"bytes,213,rep,name=repeated_int64_wrapper,json=repeatedInt64Wrapper" json:"repeated_int64_wrapper,omitempty"`
+	RepeatedUint32Wrapper []*wrappers.UInt32Value `protobuf:"bytes,214,rep,name=repeated_uint32_wrapper,json=repeatedUint32Wrapper" json:"repeated_uint32_wrapper,omitempty"`
+	RepeatedUint64Wrapper []*wrappers.UInt64Value `protobuf:"bytes,215,rep,name=repeated_uint64_wrapper,json=repeatedUint64Wrapper" json:"repeated_uint64_wrapper,omitempty"`
+	RepeatedFloatWrapper  []*wrappers.FloatValue  `protobuf:"bytes,216,rep,name=repeated_float_wrapper,json=repeatedFloatWrapper" json:"repeated_float_wrapper,omitempty"`
+	RepeatedDoubleWrapper []*wrappers.DoubleValue `protobuf:"bytes,217,rep,name=repeated_double_wrapper,json=repeatedDoubleWrapper" json:"repeated_double_wrapper,omitempty"`
+	RepeatedStringWrapper []*wrappers.StringValue `protobuf:"bytes,218,rep,name=repeated_string_wrapper,json=repeatedStringWrapper" json:"repeated_string_wrapper,omitempty"`
+	RepeatedBytesWrapper  []*wrappers.BytesValue  `protobuf:"bytes,219,rep,name=repeated_bytes_wrapper,json=repeatedBytesWrapper" json:"repeated_bytes_wrapper,omitempty"`
+	OptionalDuration      *duration.Duration      `protobuf:"bytes,301,opt,name=optional_duration,json=optionalDuration" json:"optional_duration,omitempty"`
+	OptionalTimestamp     *timestamp.Timestamp    `protobuf:"bytes,302,opt,name=optional_timestamp,json=optionalTimestamp" json:"optional_timestamp,omitempty"`
+	OptionalFieldMask     *protobuf.FieldMask     `protobuf:"bytes,303,opt,name=optional_field_mask,json=optionalFieldMask" json:"optional_field_mask,omitempty"`
+	OptionalStruct        *_struct.Struct         `protobuf:"bytes,304,opt,name=optional_struct,json=optionalStruct" json:"optional_struct,omitempty"`
+	OptionalAny           *any.Any                `protobuf:"bytes,305,opt,name=optional_any,json=optionalAny" json:"optional_any,omitempty"`
+	OptionalValue         *_struct.Value          `protobuf:"bytes,306,opt,name=optional_value,json=optionalValue" json:"optional_value,omitempty"`
+	RepeatedDuration      []*duration.Duration    `protobuf:"bytes,311,rep,name=repeated_duration,json=repeatedDuration" json:"repeated_duration,omitempty"`
+	RepeatedTimestamp     []*timestamp.Timestamp  `protobuf:"bytes,312,rep,name=repeated_timestamp,json=repeatedTimestamp" json:"repeated_timestamp,omitempty"`
+	RepeatedFieldmask     []*protobuf.FieldMask   `protobuf:"bytes,313,rep,name=repeated_fieldmask,json=repeatedFieldmask" json:"repeated_fieldmask,omitempty"`
+	RepeatedStruct        []*_struct.Struct       `protobuf:"bytes,324,rep,name=repeated_struct,json=repeatedStruct" json:"repeated_struct,omitempty"`
+	RepeatedAny           []*any.Any              `protobuf:"bytes,315,rep,name=repeated_any,json=repeatedAny" json:"repeated_any,omitempty"`
+	RepeatedValue         []*_struct.Value        `protobuf:"bytes,316,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
 	// Test field-name-to-JSON-name convention.
 	// (protobuf says names can be any valid C/C++ identifier.)
 	Fieldname1           int32    `protobuf:"varint,401,opt,name=fieldname1" json:"fieldname1,omitempty"`
@@ -1206,210 +1206,210 @@
 	return TestAllTypes_FOO
 }
 
-func (m *TestAllTypes) GetOptionalBoolWrapper() *google_protobuf5.BoolValue {
+func (m *TestAllTypes) GetOptionalBoolWrapper() *wrappers.BoolValue {
 	if m != nil {
 		return m.OptionalBoolWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalInt32Wrapper() *google_protobuf5.Int32Value {
+func (m *TestAllTypes) GetOptionalInt32Wrapper() *wrappers.Int32Value {
 	if m != nil {
 		return m.OptionalInt32Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalInt64Wrapper() *google_protobuf5.Int64Value {
+func (m *TestAllTypes) GetOptionalInt64Wrapper() *wrappers.Int64Value {
 	if m != nil {
 		return m.OptionalInt64Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalUint32Wrapper() *google_protobuf5.UInt32Value {
+func (m *TestAllTypes) GetOptionalUint32Wrapper() *wrappers.UInt32Value {
 	if m != nil {
 		return m.OptionalUint32Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalUint64Wrapper() *google_protobuf5.UInt64Value {
+func (m *TestAllTypes) GetOptionalUint64Wrapper() *wrappers.UInt64Value {
 	if m != nil {
 		return m.OptionalUint64Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalFloatWrapper() *google_protobuf5.FloatValue {
+func (m *TestAllTypes) GetOptionalFloatWrapper() *wrappers.FloatValue {
 	if m != nil {
 		return m.OptionalFloatWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalDoubleWrapper() *google_protobuf5.DoubleValue {
+func (m *TestAllTypes) GetOptionalDoubleWrapper() *wrappers.DoubleValue {
 	if m != nil {
 		return m.OptionalDoubleWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalStringWrapper() *google_protobuf5.StringValue {
+func (m *TestAllTypes) GetOptionalStringWrapper() *wrappers.StringValue {
 	if m != nil {
 		return m.OptionalStringWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalBytesWrapper() *google_protobuf5.BytesValue {
+func (m *TestAllTypes) GetOptionalBytesWrapper() *wrappers.BytesValue {
 	if m != nil {
 		return m.OptionalBytesWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedBoolWrapper() []*google_protobuf5.BoolValue {
+func (m *TestAllTypes) GetRepeatedBoolWrapper() []*wrappers.BoolValue {
 	if m != nil {
 		return m.RepeatedBoolWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedInt32Wrapper() []*google_protobuf5.Int32Value {
+func (m *TestAllTypes) GetRepeatedInt32Wrapper() []*wrappers.Int32Value {
 	if m != nil {
 		return m.RepeatedInt32Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedInt64Wrapper() []*google_protobuf5.Int64Value {
+func (m *TestAllTypes) GetRepeatedInt64Wrapper() []*wrappers.Int64Value {
 	if m != nil {
 		return m.RepeatedInt64Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedUint32Wrapper() []*google_protobuf5.UInt32Value {
+func (m *TestAllTypes) GetRepeatedUint32Wrapper() []*wrappers.UInt32Value {
 	if m != nil {
 		return m.RepeatedUint32Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedUint64Wrapper() []*google_protobuf5.UInt64Value {
+func (m *TestAllTypes) GetRepeatedUint64Wrapper() []*wrappers.UInt64Value {
 	if m != nil {
 		return m.RepeatedUint64Wrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedFloatWrapper() []*google_protobuf5.FloatValue {
+func (m *TestAllTypes) GetRepeatedFloatWrapper() []*wrappers.FloatValue {
 	if m != nil {
 		return m.RepeatedFloatWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedDoubleWrapper() []*google_protobuf5.DoubleValue {
+func (m *TestAllTypes) GetRepeatedDoubleWrapper() []*wrappers.DoubleValue {
 	if m != nil {
 		return m.RepeatedDoubleWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedStringWrapper() []*google_protobuf5.StringValue {
+func (m *TestAllTypes) GetRepeatedStringWrapper() []*wrappers.StringValue {
 	if m != nil {
 		return m.RepeatedStringWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedBytesWrapper() []*google_protobuf5.BytesValue {
+func (m *TestAllTypes) GetRepeatedBytesWrapper() []*wrappers.BytesValue {
 	if m != nil {
 		return m.RepeatedBytesWrapper
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalDuration() *google_protobuf1.Duration {
+func (m *TestAllTypes) GetOptionalDuration() *duration.Duration {
 	if m != nil {
 		return m.OptionalDuration
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalTimestamp() *google_protobuf4.Timestamp {
+func (m *TestAllTypes) GetOptionalTimestamp() *timestamp.Timestamp {
 	if m != nil {
 		return m.OptionalTimestamp
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalFieldMask() *google_protobuf2.FieldMask {
+func (m *TestAllTypes) GetOptionalFieldMask() *protobuf.FieldMask {
 	if m != nil {
 		return m.OptionalFieldMask
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalStruct() *google_protobuf3.Struct {
+func (m *TestAllTypes) GetOptionalStruct() *_struct.Struct {
 	if m != nil {
 		return m.OptionalStruct
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalAny() *google_protobuf.Any {
+func (m *TestAllTypes) GetOptionalAny() *any.Any {
 	if m != nil {
 		return m.OptionalAny
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetOptionalValue() *google_protobuf3.Value {
+func (m *TestAllTypes) GetOptionalValue() *_struct.Value {
 	if m != nil {
 		return m.OptionalValue
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedDuration() []*google_protobuf1.Duration {
+func (m *TestAllTypes) GetRepeatedDuration() []*duration.Duration {
 	if m != nil {
 		return m.RepeatedDuration
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedTimestamp() []*google_protobuf4.Timestamp {
+func (m *TestAllTypes) GetRepeatedTimestamp() []*timestamp.Timestamp {
 	if m != nil {
 		return m.RepeatedTimestamp
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedFieldmask() []*google_protobuf2.FieldMask {
+func (m *TestAllTypes) GetRepeatedFieldmask() []*protobuf.FieldMask {
 	if m != nil {
 		return m.RepeatedFieldmask
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedStruct() []*google_protobuf3.Struct {
+func (m *TestAllTypes) GetRepeatedStruct() []*_struct.Struct {
 	if m != nil {
 		return m.RepeatedStruct
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedAny() []*google_protobuf.Any {
+func (m *TestAllTypes) GetRepeatedAny() []*any.Any {
 	if m != nil {
 		return m.RepeatedAny
 	}
 	return nil
 }
 
-func (m *TestAllTypes) GetRepeatedValue() []*google_protobuf3.Value {
+func (m *TestAllTypes) GetRepeatedValue() []*_struct.Value {
 	if m != nil {
 		return m.RepeatedValue
 	}
diff --git a/jsonpb/jsonpb_test_proto/test_objects.pb.go b/jsonpb/jsonpb_test_proto/test_objects.pb.go
index 282a866..5809d01 100644
--- a/jsonpb/jsonpb_test_proto/test_objects.pb.go
+++ b/jsonpb/jsonpb_test_proto/test_objects.pb.go
@@ -6,11 +6,11 @@
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
-import google_protobuf1 "github.com/golang/protobuf/ptypes/duration"
-import google_protobuf2 "github.com/golang/protobuf/ptypes/struct"
-import google_protobuf3 "github.com/golang/protobuf/ptypes/timestamp"
-import google_protobuf4 "github.com/golang/protobuf/ptypes/wrappers"
+import any "github.com/golang/protobuf/ptypes/any"
+import duration "github.com/golang/protobuf/ptypes/duration"
+import _struct "github.com/golang/protobuf/ptypes/struct"
+import timestamp "github.com/golang/protobuf/ptypes/timestamp"
+import wrappers "github.com/golang/protobuf/ptypes/wrappers"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -827,24 +827,24 @@
 }
 
 type KnownTypes struct {
-	An                   *google_protobuf.Any          `protobuf:"bytes,14,opt,name=an" json:"an,omitempty"`
-	Dur                  *google_protobuf1.Duration    `protobuf:"bytes,1,opt,name=dur" json:"dur,omitempty"`
-	St                   *google_protobuf2.Struct      `protobuf:"bytes,12,opt,name=st" json:"st,omitempty"`
-	Ts                   *google_protobuf3.Timestamp   `protobuf:"bytes,2,opt,name=ts" json:"ts,omitempty"`
-	Lv                   *google_protobuf2.ListValue   `protobuf:"bytes,15,opt,name=lv" json:"lv,omitempty"`
-	Val                  *google_protobuf2.Value       `protobuf:"bytes,16,opt,name=val" json:"val,omitempty"`
-	Dbl                  *google_protobuf4.DoubleValue `protobuf:"bytes,3,opt,name=dbl" json:"dbl,omitempty"`
-	Flt                  *google_protobuf4.FloatValue  `protobuf:"bytes,4,opt,name=flt" json:"flt,omitempty"`
-	I64                  *google_protobuf4.Int64Value  `protobuf:"bytes,5,opt,name=i64" json:"i64,omitempty"`
-	U64                  *google_protobuf4.UInt64Value `protobuf:"bytes,6,opt,name=u64" json:"u64,omitempty"`
-	I32                  *google_protobuf4.Int32Value  `protobuf:"bytes,7,opt,name=i32" json:"i32,omitempty"`
-	U32                  *google_protobuf4.UInt32Value `protobuf:"bytes,8,opt,name=u32" json:"u32,omitempty"`
-	Bool                 *google_protobuf4.BoolValue   `protobuf:"bytes,9,opt,name=bool" json:"bool,omitempty"`
-	Str                  *google_protobuf4.StringValue `protobuf:"bytes,10,opt,name=str" json:"str,omitempty"`
-	Bytes                *google_protobuf4.BytesValue  `protobuf:"bytes,11,opt,name=bytes" json:"bytes,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                      `json:"-"`
-	XXX_unrecognized     []byte                        `json:"-"`
-	XXX_sizecache        int32                         `json:"-"`
+	An                   *any.Any              `protobuf:"bytes,14,opt,name=an" json:"an,omitempty"`
+	Dur                  *duration.Duration    `protobuf:"bytes,1,opt,name=dur" json:"dur,omitempty"`
+	St                   *_struct.Struct       `protobuf:"bytes,12,opt,name=st" json:"st,omitempty"`
+	Ts                   *timestamp.Timestamp  `protobuf:"bytes,2,opt,name=ts" json:"ts,omitempty"`
+	Lv                   *_struct.ListValue    `protobuf:"bytes,15,opt,name=lv" json:"lv,omitempty"`
+	Val                  *_struct.Value        `protobuf:"bytes,16,opt,name=val" json:"val,omitempty"`
+	Dbl                  *wrappers.DoubleValue `protobuf:"bytes,3,opt,name=dbl" json:"dbl,omitempty"`
+	Flt                  *wrappers.FloatValue  `protobuf:"bytes,4,opt,name=flt" json:"flt,omitempty"`
+	I64                  *wrappers.Int64Value  `protobuf:"bytes,5,opt,name=i64" json:"i64,omitempty"`
+	U64                  *wrappers.UInt64Value `protobuf:"bytes,6,opt,name=u64" json:"u64,omitempty"`
+	I32                  *wrappers.Int32Value  `protobuf:"bytes,7,opt,name=i32" json:"i32,omitempty"`
+	U32                  *wrappers.UInt32Value `protobuf:"bytes,8,opt,name=u32" json:"u32,omitempty"`
+	Bool                 *wrappers.BoolValue   `protobuf:"bytes,9,opt,name=bool" json:"bool,omitempty"`
+	Str                  *wrappers.StringValue `protobuf:"bytes,10,opt,name=str" json:"str,omitempty"`
+	Bytes                *wrappers.BytesValue  `protobuf:"bytes,11,opt,name=bytes" json:"bytes,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
+	XXX_unrecognized     []byte                `json:"-"`
+	XXX_sizecache        int32                 `json:"-"`
 }
 
 func (m *KnownTypes) Reset()         { *m = KnownTypes{} }
@@ -871,105 +871,105 @@
 
 var xxx_messageInfo_KnownTypes proto.InternalMessageInfo
 
-func (m *KnownTypes) GetAn() *google_protobuf.Any {
+func (m *KnownTypes) GetAn() *any.Any {
 	if m != nil {
 		return m.An
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetDur() *google_protobuf1.Duration {
+func (m *KnownTypes) GetDur() *duration.Duration {
 	if m != nil {
 		return m.Dur
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetSt() *google_protobuf2.Struct {
+func (m *KnownTypes) GetSt() *_struct.Struct {
 	if m != nil {
 		return m.St
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetTs() *google_protobuf3.Timestamp {
+func (m *KnownTypes) GetTs() *timestamp.Timestamp {
 	if m != nil {
 		return m.Ts
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetLv() *google_protobuf2.ListValue {
+func (m *KnownTypes) GetLv() *_struct.ListValue {
 	if m != nil {
 		return m.Lv
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetVal() *google_protobuf2.Value {
+func (m *KnownTypes) GetVal() *_struct.Value {
 	if m != nil {
 		return m.Val
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetDbl() *google_protobuf4.DoubleValue {
+func (m *KnownTypes) GetDbl() *wrappers.DoubleValue {
 	if m != nil {
 		return m.Dbl
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetFlt() *google_protobuf4.FloatValue {
+func (m *KnownTypes) GetFlt() *wrappers.FloatValue {
 	if m != nil {
 		return m.Flt
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetI64() *google_protobuf4.Int64Value {
+func (m *KnownTypes) GetI64() *wrappers.Int64Value {
 	if m != nil {
 		return m.I64
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetU64() *google_protobuf4.UInt64Value {
+func (m *KnownTypes) GetU64() *wrappers.UInt64Value {
 	if m != nil {
 		return m.U64
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetI32() *google_protobuf4.Int32Value {
+func (m *KnownTypes) GetI32() *wrappers.Int32Value {
 	if m != nil {
 		return m.I32
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetU32() *google_protobuf4.UInt32Value {
+func (m *KnownTypes) GetU32() *wrappers.UInt32Value {
 	if m != nil {
 		return m.U32
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetBool() *google_protobuf4.BoolValue {
+func (m *KnownTypes) GetBool() *wrappers.BoolValue {
 	if m != nil {
 		return m.Bool
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetStr() *google_protobuf4.StringValue {
+func (m *KnownTypes) GetStr() *wrappers.StringValue {
 	if m != nil {
 		return m.Str
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetBytes() *google_protobuf4.BytesValue {
+func (m *KnownTypes) GetBytes() *wrappers.BytesValue {
 	if m != nil {
 		return m.Bytes
 	}
@@ -1108,10 +1108,10 @@
 }
 
 type MsgWithRequiredWKT struct {
-	Str                  *google_protobuf4.StringValue `protobuf:"bytes,1,req,name=str" json:"str,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                      `json:"-"`
-	XXX_unrecognized     []byte                        `json:"-"`
-	XXX_sizecache        int32                         `json:"-"`
+	Str                  *wrappers.StringValue `protobuf:"bytes,1,req,name=str" json:"str,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
+	XXX_unrecognized     []byte                `json:"-"`
+	XXX_sizecache        int32                 `json:"-"`
 }
 
 func (m *MsgWithRequiredWKT) Reset()         { *m = MsgWithRequiredWKT{} }
@@ -1138,7 +1138,7 @@
 
 var xxx_messageInfo_MsgWithRequiredWKT proto.InternalMessageInfo
 
-func (m *MsgWithRequiredWKT) GetStr() *google_protobuf4.StringValue {
+func (m *MsgWithRequiredWKT) GetStr() *wrappers.StringValue {
 	if m != nil {
 		return m.Str
 	}
diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go
index a27b7c6..89c1cde 100644
--- a/protoc-gen-go/generator/generator.go
+++ b/protoc-gen-go/generator/generator.go
@@ -92,6 +92,12 @@
 	plugins = append(plugins, p)
 }
 
+// A GoImportPath is the import path of a Go package. e.g., "google.golang.org/genproto/protobuf".
+type GoImportPath string
+
+// A GoPackageName is the name of a Go package. e.g., "protobuf".
+type GoPackageName string
+
 // Each type we import as a protocol buffer (other than FileDescriptorProto) needs
 // a pointer to the FileDescriptorProto that represents it.  These types achieve that
 // wrapping by placing each Proto inside a struct with the pointer to its File. The
@@ -100,19 +106,21 @@
 
 // The file and package name method are common to messages and enums.
 type common struct {
-	file *descriptor.FileDescriptorProto // File this object comes from.
+	file *FileDescriptor // File this object comes from.
 }
 
-// PackageName is name in the package clause in the generated file.
-func (c *common) PackageName() string { return uniquePackageOf(c.file) }
+// GoImportPath is the import path of the Go package containing the type.
+func (c *common) GoImportPath() GoImportPath {
+	return c.file.importPath
+}
 
-func (c *common) File() *descriptor.FileDescriptorProto { return c.file }
+func (c *common) File() *FileDescriptor { return c.file }
 
 func fileIsProto3(file *descriptor.FileDescriptorProto) bool {
 	return file.GetSyntax() == "proto3"
 }
 
-func (c *common) proto3() bool { return fileIsProto3(c.file) }
+func (c *common) proto3() bool { return fileIsProto3(c.file.FileDescriptorProto) }
 
 // Descriptor represents a protocol buffer message.
 type Descriptor struct {
@@ -260,14 +268,12 @@
 	// This is used for supporting public imports.
 	exported map[Object][]symbol
 
-	fingerprint string // Fingerprint of this file's contents.
+	fingerprint string       // Fingerprint of this file's contents.
+	importPath  GoImportPath // Import path of this file's package.
 
 	proto3 bool // whether to generate proto3 code for this file
 }
 
-// PackageName is the package name we'll use in the generated code to refer to this file.
-func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDescriptorProto) }
-
 // VarName is the variable name we'll use in the generated code to refer
 // to the compressed bytes of this descriptor. It is not exported, so
 // it is only valid inside the generated package.
@@ -280,25 +286,22 @@
 // If there is no go_package, it returns ("", "", false).
 // If there's a simple name, it returns ("", pkg, true).
 // If the option implies an import path, it returns (impPath, pkg, true).
-func (d *FileDescriptor) goPackageOption() (impPath, pkg string, ok bool) {
-	pkg = d.GetOptions().GetGoPackage()
-	if pkg == "" {
-		return
+func (d *FileDescriptor) goPackageOption() (impPath GoImportPath, pkg GoPackageName, ok bool) {
+	opt := d.GetOptions().GetGoPackage()
+	if opt == "" {
+		return "", "", false
 	}
-	ok = true
 	// The presence of a slash implies there's an import path.
-	slash := strings.LastIndex(pkg, "/")
+	slash := strings.LastIndex(opt, "/")
 	if slash < 0 {
-		return
+		return "", GoPackageName(opt), true
 	}
-	impPath, pkg = pkg, pkg[slash+1:]
 	// A semicolon-delimited suffix overrides the package name.
-	sc := strings.IndexByte(impPath, ';')
+	sc := strings.Index(opt, ";")
 	if sc < 0 {
-		return
+		return GoImportPath(opt), cleanPackageName(opt[slash+1:]), true
 	}
-	impPath, pkg = impPath[:sc], impPath[sc+1:]
-	return
+	return GoImportPath(opt[:sc]), cleanPackageName(opt[sc+1:]), true
 }
 
 // goPackageName returns the Go package name to use in the
@@ -306,18 +309,18 @@
 // came from an option go_package statement.  If explicit is false,
 // the name was derived from the protocol buffer's package statement
 // or the input file name.
-func (d *FileDescriptor) goPackageName() (name string, explicit bool) {
+func (d *FileDescriptor) goPackageName() (name GoPackageName, explicit bool) {
 	// Does the file have a "go_package" option?
 	if _, pkg, ok := d.goPackageOption(); ok {
 		return pkg, true
 	}
 
 	// Does the file have a package clause?
-	if pkg := d.GetPackage(); pkg != "" {
-		return pkg, false
+	if p := d.GetPackage(); p != "" {
+		return cleanPackageName(p), false
 	}
 	// Use the file base name.
-	return baseName(d.GetName()), false
+	return cleanPackageName(baseName(d.GetName())), false
 }
 
 // goFileName returns the output name for the generated Go file.
@@ -333,7 +336,7 @@
 	if impPath, _, ok := d.goPackageOption(); ok && impPath != "" {
 		// Replace the existing dirname with the declared import path.
 		_, name = path.Split(name)
-		name = path.Join(impPath, name)
+		name = path.Join(string(impPath), name)
 		return name
 	}
 
@@ -348,7 +351,7 @@
 type symbol interface {
 	// GenerateAlias should generate an appropriate alias
 	// for the symbol from the named package.
-	GenerateAlias(g *Generator, pkg string)
+	GenerateAlias(g *Generator, pkg GoPackageName)
 }
 
 type messageSymbol struct {
@@ -365,8 +368,8 @@
 	genType  bool   // whether typ contains a generated type (message/group/enum)
 }
 
-func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) {
-	remoteSym := pkg + "." + ms.sym
+func (ms *messageSymbol) GenerateAlias(g *Generator, pkg GoPackageName) {
+	remoteSym := string(pkg) + "." + ms.sym
 
 	g.P("type ", ms.sym, " ", remoteSym)
 	g.P("func (m *", ms.sym, ") Reset() { (*", remoteSym, ")(m).Reset() }")
@@ -513,7 +516,7 @@
 	proto3 bool // Whether this came from a proto3 file.
 }
 
-func (es enumSymbol) GenerateAlias(g *Generator, pkg string) {
+func (es enumSymbol) GenerateAlias(g *Generator, pkg GoPackageName) {
 	s := es.name
 	g.P("type ", s, " ", pkg, ".", s)
 	g.P("var ", s, "_name = ", pkg, ".", s, "_name")
@@ -531,8 +534,8 @@
 	cast string // if non-empty, a type cast is required (used for enums)
 }
 
-func (cs constOrVarSymbol) GenerateAlias(g *Generator, pkg string) {
-	v := pkg + "." + cs.sym
+func (cs constOrVarSymbol) GenerateAlias(g *Generator, pkg GoPackageName) {
+	v := string(pkg) + "." + cs.sym
 	if cs.cast != "" {
 		v = cs.cast + "(" + v + ")"
 	}
@@ -541,21 +544,9 @@
 
 // Object is an interface abstracting the abilities shared by enums, messages, extensions and imported objects.
 type Object interface {
-	PackageName() string // The name we use in our output (a_b_c), possibly renamed for uniqueness.
+	GoImportPath() GoImportPath
 	TypeName() []string
-	File() *descriptor.FileDescriptorProto
-}
-
-// Each package name we generate must be unique. The package we're generating
-// gets its own name but every other package must have a unique name that does
-// not conflict in the code we generate.  These names are chosen globally (although
-// they don't have to be, it simplifies things to do them globally).
-func uniquePackageOf(fd *descriptor.FileDescriptorProto) string {
-	s, ok := uniquePackageName[fd]
-	if !ok {
-		log.Fatal("internal error: no package name defined for " + fd.GetName())
-	}
-	return s
+	File() *FileDescriptor
 }
 
 // Generator is the type whose methods generate the output, stored in the associated response structure.
@@ -565,21 +556,23 @@
 	Request  *plugin.CodeGeneratorRequest  // The input.
 	Response *plugin.CodeGeneratorResponse // The output.
 
-	Param             map[string]string // Command-line parameters.
-	PackageImportPath string            // Go import path of the package we're generating code for
-	ImportPrefix      string            // String to prefix to imported package file names.
-	ImportMap         map[string]string // Mapping from .proto file name to import path
+	Param             map[string]string       // Command-line parameters.
+	PackageImportPath string                  // Go import path of the package we're generating code for
+	ImportPrefix      GoImportPath            // String to prefix to imported package file names.
+	ImportMap         map[string]GoImportPath // Mapping from .proto file name to import path
 
 	Pkg map[string]string // The names under which we import support packages
 
-	packageName      string                     // What we're calling ourselves.
-	allFiles         []*FileDescriptor          // All files in the tree
-	allFilesByName   map[string]*FileDescriptor // All files by filename.
-	genFiles         []*FileDescriptor          // Those files we will generate output for.
-	file             *FileDescriptor            // The file we are compiling now.
-	usedPackages     map[string]bool            // Names of packages used in current file.
-	typeNameToObject map[string]Object          // Key is a fully-qualified name in input syntax.
-	init             []string                   // Lines to emit in the init function.
+	packageName      GoPackageName                  // What we're calling ourselves.
+	allFiles         []*FileDescriptor              // All files in the tree
+	allFilesByName   map[string]*FileDescriptor     // All files by filename.
+	genFiles         []*FileDescriptor              // Those files we will generate output for.
+	file             *FileDescriptor                // The file we are compiling now.
+	packageNames     map[GoImportPath]GoPackageName // Imported package names in the current file.
+	usedPackages     map[GoImportPath]bool          // Packages used in current file.
+	usedPackageNames map[GoPackageName]bool         // Package names used in the current file.
+	typeNameToObject map[string]Object              // Key is a fully-qualified name in input syntax.
+	init             []string                       // Lines to emit in the init function.
 	indent           string
 	writeOutput      bool
 	annotateCode     bool                                       // whether to store annotations
@@ -622,12 +615,12 @@
 		}
 	}
 
-	g.ImportMap = make(map[string]string)
+	g.ImportMap = make(map[string]GoImportPath)
 	pluginList := "none" // Default list of plugin names to enable (empty means all).
 	for k, v := range g.Param {
 		switch k {
 		case "import_prefix":
-			g.ImportPrefix = v
+			g.ImportPrefix = GoImportPath(v)
 		case "import_path":
 			g.PackageImportPath = v
 		case "plugins":
@@ -638,7 +631,7 @@
 			}
 		default:
 			if len(k) > 0 && k[0] == 'M' {
-				g.ImportMap[k[1:]] = v
+				g.ImportMap[k[1:]] = GoImportPath(v)
 			}
 		}
 	}
@@ -662,37 +655,42 @@
 // If its file is in a different package, it returns the package name we're using for this file, plus ".".
 // Otherwise it returns the empty string.
 func (g *Generator) DefaultPackageName(obj Object) string {
-	pkg := obj.PackageName()
-	if pkg == g.packageName {
+	importPath := obj.GoImportPath()
+	if importPath == g.file.importPath {
 		return ""
 	}
-	return pkg + "."
+	return string(g.GoPackageName(importPath)) + "."
 }
 
-// For each input file, the unique package name to use, underscored.
-var uniquePackageName = make(map[*descriptor.FileDescriptorProto]string)
+// GoPackageName returns the name used for a package.
+func (g *Generator) GoPackageName(importPath GoImportPath) GoPackageName {
+	if name, ok := g.packageNames[importPath]; ok {
+		return name
+	}
+	name := cleanPackageName(baseName(string(importPath)))
+	for i, orig := 1, name; g.usedPackageNames[name]; i++ {
+		name = orig + GoPackageName(strconv.Itoa(i))
+	}
+	g.packageNames[importPath] = name
+	g.usedPackageNames[name] = true
+	return name
+}
 
-// Package names already registered.  Key is the name from the .proto file;
-// value is the name that appears in the generated code.
-var pkgNamesInUse = make(map[string]bool)
+var globalPackageNames = map[GoPackageName]bool{
+	"fmt":   true,
+	"math":  true,
+	"proto": true,
+}
 
-// Create and remember a guaranteed unique package name for this file descriptor.
-// Pkg is the candidate name.  If f is nil, it's a builtin package like "proto" and
-// has no file descriptor.
+// Create and remember a guaranteed unique package name. Pkg is the candidate name.
+// The FileDescriptor parameter is unused.
 func RegisterUniquePackageName(pkg string, f *FileDescriptor) string {
-	// Convert dots to underscores before finding a unique alias.
-	pkg = strings.Map(badToUnderscore, pkg)
-
-	for i, orig := 1, pkg; pkgNamesInUse[pkg]; i++ {
-		// It's a duplicate; must rename.
-		pkg = orig + strconv.Itoa(i)
+	name := cleanPackageName(pkg)
+	for i, orig := 1, name; globalPackageNames[name]; i++ {
+		name = orig + GoPackageName(strconv.Itoa(i))
 	}
-	// Install it.
-	pkgNamesInUse[pkg] = true
-	if f != nil {
-		uniquePackageName[f.FileDescriptorProto] = pkg
-	}
-	return pkg
+	globalPackageNames[name] = true
+	return string(name)
 }
 
 var isGoKeyword = map[string]bool{
@@ -723,27 +721,27 @@
 	"var":         true,
 }
 
+func cleanPackageName(name string) GoPackageName {
+	name = strings.Map(badToUnderscore, name)
+	// Identifier must not be keyword: insert _.
+	if isGoKeyword[name] {
+		name = "_" + name
+	}
+	// Identifier must not begin with digit: insert _.
+	if r, _ := utf8.DecodeRuneInString(name); unicode.IsDigit(r) {
+		name = "_" + name
+	}
+	return GoPackageName(name)
+}
+
 // defaultGoPackage returns the package name to use,
 // derived from the import path of the package we're building code for.
-func (g *Generator) defaultGoPackage() string {
+func (g *Generator) defaultGoPackage() GoPackageName {
 	p := g.PackageImportPath
 	if i := strings.LastIndex(p, "/"); i >= 0 {
 		p = p[i+1:]
 	}
-	if p == "" {
-		return ""
-	}
-
-	p = strings.Map(badToUnderscore, p)
-	// Identifier must not be keyword: insert _.
-	if isGoKeyword[p] {
-		p = "_" + p
-	}
-	// Identifier must not begin with digit: insert _.
-	if r, _ := utf8.DecodeRuneInString(p); unicode.IsDigit(r) {
-		p = "_" + p
-	}
-	return p
+	return cleanPackageName(p)
 }
 
 // SetPackageNames sets the package name for this run.
@@ -762,7 +760,7 @@
 				// 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:", thisPkg, pkg)
+				g.Fail("inconsistent package names:", string(thisPkg), string(pkg))
 			}
 		}
 	}
@@ -783,37 +781,19 @@
 		for _, f := range g.genFiles {
 			thisPkg, _ := f.goPackageName()
 			if thisPkg != pkg {
-				g.Fail("inconsistent package names:", thisPkg, pkg)
+				g.Fail("inconsistent package names:", string(thisPkg), string(pkg))
 			}
 		}
 	}
 
-	g.packageName = RegisterUniquePackageName(pkg, g.genFiles[0])
+	g.packageName = pkg
 
-	// Register the support package names. They might collide with the
-	// name of a package we import.
+	// Names of support packages. These never vary (if there are conflicts,
+	// we rename the conflicting package), so this could be removed someday.
 	g.Pkg = map[string]string{
-		"fmt":   RegisterUniquePackageName("fmt", nil),
-		"math":  RegisterUniquePackageName("math", nil),
-		"proto": RegisterUniquePackageName("proto", nil),
-	}
-
-AllFiles:
-	for _, f := range g.allFiles {
-		for _, genf := range g.genFiles {
-			if f == genf {
-				// In this package already.
-				uniquePackageName[f.FileDescriptorProto] = g.packageName
-				continue AllFiles
-			}
-		}
-		// The file is a dependency, so we want to ignore its go_package option
-		// because that is only relevant for its specific generated output.
-		pkg := f.GetPackage()
-		if pkg == "" {
-			pkg = baseName(*f.Name)
-		}
-		RegisterUniquePackageName(pkg, f)
+		"fmt":   "fmt",
+		"math":  "math",
+		"proto": "proto",
 	}
 }
 
@@ -824,26 +804,30 @@
 	g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile))
 	g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles))
 	for _, f := range g.Request.ProtoFile {
-		// We must wrap the descriptors before we wrap the enums
-		descs := wrapDescriptors(f)
-		g.buildNestedDescriptors(descs)
-		enums := wrapEnumDescriptors(f, descs)
-		g.buildNestedEnums(descs, enums)
-		exts := wrapExtensions(f)
 		fd := &FileDescriptor{
 			FileDescriptorProto: f,
-			desc:                descs,
-			enum:                enums,
-			ext:                 exts,
 			exported:            make(map[Object][]symbol),
 			proto3:              fileIsProto3(f),
 		}
+		if substitution, ok := g.ImportMap[f.GetName()]; ok {
+			fd.importPath = substitution
+		} else if p, _, _ := fd.goPackageOption(); p != "" {
+			fd.importPath = p
+		} else {
+			fd.importPath = GoImportPath(path.Dir(f.GetName()))
+		}
+		// We must wrap the descriptors before we wrap the enums
+		fd.desc = wrapDescriptors(fd)
+		g.buildNestedDescriptors(fd.desc)
+		fd.enum = wrapEnumDescriptors(fd, fd.desc)
+		g.buildNestedEnums(fd.desc, fd.enum)
+		fd.ext = wrapExtensions(fd)
 		extractComments(fd)
 		g.allFiles = append(g.allFiles, fd)
 		g.allFilesByName[f.GetName()] = fd
 	}
 	for _, fd := range g.allFiles {
-		fd.imp = wrapImported(fd.FileDescriptorProto, g)
+		fd.imp = wrapImported(fd, g)
 	}
 
 	g.genFiles = make([]*FileDescriptor, 0, len(g.Request.FileToGenerate))
@@ -905,7 +889,7 @@
 }
 
 // Construct the Descriptor
-func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) *Descriptor {
+func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *Descriptor {
 	d := &Descriptor{
 		common:          common{file},
 		DescriptorProto: desc,
@@ -942,7 +926,7 @@
 }
 
 // Return a slice of all the Descriptors defined within this file
-func wrapDescriptors(file *descriptor.FileDescriptorProto) []*Descriptor {
+func wrapDescriptors(file *FileDescriptor) []*Descriptor {
 	sl := make([]*Descriptor, 0, len(file.MessageType)+10)
 	for i, desc := range file.MessageType {
 		sl = wrapThisDescriptor(sl, desc, nil, file, i)
@@ -951,7 +935,7 @@
 }
 
 // Wrap this Descriptor, recursively
-func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) []*Descriptor {
+func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) []*Descriptor {
 	sl = append(sl, newDescriptor(desc, parent, file, index))
 	me := sl[len(sl)-1]
 	for i, nested := range desc.NestedType {
@@ -961,7 +945,7 @@
 }
 
 // Construct the EnumDescriptor
-func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) *EnumDescriptor {
+func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *EnumDescriptor {
 	ed := &EnumDescriptor{
 		common:              common{file},
 		EnumDescriptorProto: desc,
@@ -977,7 +961,7 @@
 }
 
 // Return a slice of all the EnumDescriptors defined within this file
-func wrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descriptor) []*EnumDescriptor {
+func wrapEnumDescriptors(file *FileDescriptor, descs []*Descriptor) []*EnumDescriptor {
 	sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10)
 	// Top-level enums.
 	for i, enum := range file.EnumType {
@@ -993,7 +977,7 @@
 }
 
 // Return a slice of all the top-level ExtensionDescriptors defined within this file.
-func wrapExtensions(file *descriptor.FileDescriptorProto) []*ExtensionDescriptor {
+func wrapExtensions(file *FileDescriptor) []*ExtensionDescriptor {
 	var sl []*ExtensionDescriptor
 	for _, field := range file.Extension {
 		sl = append(sl, &ExtensionDescriptor{common{file}, field, nil})
@@ -1002,7 +986,7 @@
 }
 
 // Return a slice of all the types that are publicly imported into this file.
-func wrapImported(file *descriptor.FileDescriptorProto, g *Generator) (sl []*ImportedDescriptor) {
+func wrapImported(file *FileDescriptor, g *Generator) (sl []*ImportedDescriptor) {
 	for _, index := range file.PublicDependency {
 		df := g.fileByName(file.Dependency[index])
 		for _, d := range df.desc {
@@ -1111,7 +1095,7 @@
 
 // Annotate records the file name and proto AST path of a list of atoms
 // so that a later call to P can emit a link from each atom to its origin.
-func Annotate(file *descriptor.FileDescriptorProto, path string, atoms ...interface{}) *AnnotatedAtoms {
+func Annotate(file *FileDescriptor, path string, atoms ...interface{}) *AnnotatedAtoms {
 	return &AnnotatedAtoms{source: *file.Name, path: path, atoms: atoms}
 }
 
@@ -1136,6 +1120,10 @@
 		fmt.Fprint(g, v)
 	case *float64:
 		fmt.Fprint(g, *v)
+	case GoPackageName:
+		g.WriteString(string(v))
+	case GoImportPath:
+		g.WriteString(strconv.Quote(string(v)))
 	default:
 		g.Fail(fmt.Sprintf("unknown type in printer: %T", v))
 	}
@@ -1241,22 +1229,16 @@
 	}
 }
 
-// FileOf return the FileDescriptor for this FileDescriptorProto.
-func (g *Generator) FileOf(fd *descriptor.FileDescriptorProto) *FileDescriptor {
-	for _, file := range g.allFiles {
-		if file.FileDescriptorProto == fd {
-			return file
-		}
-	}
-	g.Fail("could not find file in table:", fd.GetName())
-	return nil
-}
-
 // Fill the response protocol buffer with the generated output for all the files we're
 // supposed to generate.
 func (g *Generator) generate(file *FileDescriptor) {
-	g.file = g.FileOf(file.FileDescriptorProto)
-	g.usedPackages = make(map[string]bool)
+	g.file = file
+	g.usedPackages = make(map[GoImportPath]bool)
+	g.packageNames = make(map[GoImportPath]GoPackageName)
+	g.usedPackageNames = make(map[GoPackageName]bool)
+	for name := range globalPackageNames {
+		g.usedPackageNames[name] = true
+	}
 
 	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.")
@@ -1356,12 +1338,12 @@
 	}
 	g.P()
 
-	name := g.file.PackageName()
+	name, _ := g.file.goPackageName()
 	importPath, _, haveImportPath := g.file.goPackageOption()
 	if !haveImportPath {
 		g.P("package ", name)
 	} else {
-		g.P("package ", name, " // import ", strconv.Quote(g.ImportPrefix+importPath))
+		g.P("package ", name, " // import ", g.ImportPrefix+importPath)
 	}
 	g.P()
 
@@ -1421,35 +1403,46 @@
 	// We almost always need a proto import.  Rather than computing when we
 	// do, which is tricky when there's a plugin, just import it and
 	// reference it later. The same argument applies to the fmt and math packages.
-	g.P("import " + g.Pkg["proto"] + " " + strconv.Quote(g.ImportPrefix+"github.com/golang/protobuf/proto"))
+	g.P("import "+g.Pkg["proto"]+" ", g.ImportPrefix+"github.com/golang/protobuf/proto")
 	g.P("import " + g.Pkg["fmt"] + ` "fmt"`)
 	g.P("import " + g.Pkg["math"] + ` "math"`)
+	var (
+		imports       = make(map[GoImportPath]bool)
+		strongImports = make(map[GoImportPath]bool)
+		importPaths   []string
+	)
 	for i, s := range g.file.Dependency {
 		fd := g.fileByName(s)
+		importPath := fd.importPath
 		// Do not import our own package.
-		if fd.PackageName() == g.packageName {
+		if importPath == g.file.importPath {
 			continue
 		}
-		filename := fd.goFileName()
-		// By default, import path is the dirname of the Go filename.
-		importPath := path.Dir(filename)
-		if substitution, ok := g.ImportMap[s]; ok {
-			importPath = substitution
+		if !imports[importPath] {
+			importPaths = append(importPaths, string(importPath))
 		}
-		importPath = g.ImportPrefix + importPath
+		imports[importPath] = true
+		if !g.weak(int32(i)) {
+			strongImports[importPath] = true
+		}
+	}
+	sort.Strings(importPaths)
+	for i := range importPaths {
+		importPath := GoImportPath(importPaths[i])
+		packageName := g.GoPackageName(importPath)
+		fullPath := g.ImportPrefix + importPath
 		// Skip weak imports.
-		if g.weak(int32(i)) {
-			g.P("// skipping weak import ", fd.PackageName(), " ", strconv.Quote(importPath))
+		if !strongImports[importPath] {
+			g.P("// skipping weak import ", packageName, " ", fullPath)
 			continue
 		}
 		// We need to import all the dependencies, even if we don't reference them,
 		// because other code and tools depend on having the full transitive closure
 		// of protocol buffer types in the binary.
-		pname := fd.PackageName()
-		if _, ok := g.usedPackages[pname]; !ok {
-			pname = "_"
+		if _, ok := g.usedPackages[importPath]; !ok {
+			packageName = "_"
 		}
-		g.P("import ", pname, " ", strconv.Quote(importPath))
+		g.P("import ", packageName, " ", fullPath)
 	}
 	g.P()
 	// TODO: may need to worry about uniqueness across plugins
@@ -1471,7 +1464,7 @@
 	// because g.genFiles isn't populated at that stage.
 	tn := id.TypeName()
 	sn := tn[len(tn)-1]
-	df := g.FileOf(id.o.File())
+	df := id.o.File()
 	filename := *df.Name
 	for _, fd := range g.genFiles {
 		if *fd.Name == filename {
@@ -1481,10 +1474,10 @@
 		}
 	}
 	g.P("// ", sn, " from public import ", filename)
-	g.usedPackages[df.PackageName()] = true
+	g.usedPackages[df.importPath] = true
 
 	for _, sym := range df.exported[id.o] {
-		sym.GenerateAlias(g, df.PackageName())
+		sym.GenerateAlias(g, g.GoPackageName(df.importPath))
 	}
 
 	g.P()
@@ -1651,7 +1644,7 @@
 	}
 	enum := ""
 	if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
-		// We avoid using obj.PackageName(), because we want to use the
+		// We avoid using obj.GoPackageName(), because we want to use the
 		// original (proto-world) package name.
 		obj := g.ObjectNamed(field.GetTypeName())
 		if id, ok := obj.(*ImportedDescriptor); ok {
@@ -1733,12 +1726,6 @@
 	return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName())
 }
 
-// TypeNameWithPackage is like TypeName, but always includes the package
-// name even if the object is in our own package.
-func (g *Generator) TypeNameWithPackage(obj Object) string {
-	return obj.PackageName() + CamelCaseSlice(obj.TypeName())
-}
-
 // GoType returns a string representing the type name, and the wire type
 func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) {
 	// TODO: Options.
@@ -1801,7 +1788,7 @@
 	if _, ok := g.typeNameToObject[t]; ok {
 		// Call ObjectNamed to get the true object to record the use.
 		obj := g.ObjectNamed(t)
-		g.usedPackages[obj.PackageName()] = true
+		g.usedPackages[obj.GoImportPath()] = true
 	}
 }
 
@@ -2279,7 +2266,7 @@
 			getter = false
 		case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_ENUM:
 			// Only export getter if its return type is in this package.
-			getter = g.ObjectNamed(field.GetTypeName()).PackageName() == message.PackageName()
+			getter = g.ObjectNamed(field.GetTypeName()).GoImportPath() == message.GoImportPath()
 			genType = true
 		default:
 			getter = true
diff --git a/protoc-gen-go/grpc/grpc.go b/protoc-gen-go/grpc/grpc.go
index f11aa1b..1723680 100644
--- a/protoc-gen-go/grpc/grpc.go
+++ b/protoc-gen-go/grpc/grpc.go
@@ -130,8 +130,8 @@
 		return
 	}
 	g.P("import (")
-	g.P(contextPkg, " ", strconv.Quote(path.Join(g.gen.ImportPrefix, contextPkgPath)))
-	g.P(grpcPkg, " ", strconv.Quote(path.Join(g.gen.ImportPrefix, grpcPkgPath)))
+	g.P(contextPkg, " ", generator.GoImportPath(path.Join(string(g.gen.ImportPrefix), contextPkgPath)))
+	g.P(grpcPkg, " ", generator.GoImportPath(path.Join(string(g.gen.ImportPrefix), grpcPkgPath)))
 	g.P(")")
 	g.P()
 }
diff --git a/protoc-gen-go/testdata/imports/fmt/m.pb.go b/protoc-gen-go/testdata/imports/fmt/m.pb.go
index 59ccce0..ca312d6 100644
--- a/protoc-gen-go/testdata/imports/fmt/m.pb.go
+++ b/protoc-gen-go/testdata/imports/fmt/m.pb.go
@@ -4,12 +4,12 @@
 package fmt // import "github.com/golang/protobuf/protoc-gen-go/testdata/imports/fmt"
 
 import proto "github.com/golang/protobuf/proto"
-import fmt1 "fmt"
+import fmt "fmt"
 import math "math"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
-var _ = fmt1.Errorf
+var _ = fmt.Errorf
 var _ = math.Inf
 
 // This is a compile-time assertion to ensure that this generated file
diff --git a/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go b/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
index c299a61..72daffd 100644
--- a/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
+++ b/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
@@ -6,7 +6,7 @@
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import test_a "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
+import test_a_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -20,10 +20,10 @@
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 type A1M1 struct {
-	F                    *test_a.M1 `protobuf:"bytes,1,opt,name=f" json:"f,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
-	XXX_unrecognized     []byte     `json:"-"`
-	XXX_sizecache        int32      `json:"-"`
+	F                    *test_a_1.M1 `protobuf:"bytes,1,opt,name=f" json:"f,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
+	XXX_unrecognized     []byte       `json:"-"`
+	XXX_sizecache        int32        `json:"-"`
 }
 
 func (m *A1M1) Reset()         { *m = A1M1{} }
@@ -50,7 +50,7 @@
 
 var xxx_messageInfo_A1M1 proto.InternalMessageInfo
 
-func (m *A1M1) GetF() *test_a.M1 {
+func (m *A1M1) GetF() *test_a_1.M1 {
 	if m != nil {
 		return m.F
 	}
diff --git a/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go b/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
index 6b81678..9e36ebd 100644
--- a/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
+++ b/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
@@ -6,7 +6,7 @@
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import test_a1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
+import test_a_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -20,10 +20,10 @@
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 type A1M2 struct {
-	F                    *test_a1.M2 `protobuf:"bytes,1,opt,name=f" json:"f,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
-	XXX_unrecognized     []byte      `json:"-"`
-	XXX_sizecache        int32       `json:"-"`
+	F                    *test_a_1.M2 `protobuf:"bytes,1,opt,name=f" json:"f,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
+	XXX_unrecognized     []byte       `json:"-"`
+	XXX_sizecache        int32        `json:"-"`
 }
 
 func (m *A1M2) Reset()         { *m = A1M2{} }
@@ -50,7 +50,7 @@
 
 var xxx_messageInfo_A1M2 proto.InternalMessageInfo
 
-func (m *A1M2) GetF() *test_a1.M2 {
+func (m *A1M2) GetF() *test_a_1.M2 {
 	if m != nil {
 		return m.F
 	}
diff --git a/protoc-gen-go/testdata/imports/test_import_all.pb.go b/protoc-gen-go/testdata/imports/test_import_all.pb.go
index 88abdfd..f40e0b7 100644
--- a/protoc-gen-go/testdata/imports/test_import_all.pb.go
+++ b/protoc-gen-go/testdata/imports/test_import_all.pb.go
@@ -6,13 +6,10 @@
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import test_a "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
-import test_a1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
-import test_a2 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_2"
-import test_a3 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_2"
-import test_b_part1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_b_1"
-import test_b_part2 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_b_1"
 import fmt1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/fmt"
+import test_a_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
+import test_a_2 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_2"
+import test_b_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_b_1"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -26,16 +23,16 @@
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 type All struct {
-	Am1                  *test_a.M1       `protobuf:"bytes,1,opt,name=am1" json:"am1,omitempty"`
-	Am2                  *test_a1.M2      `protobuf:"bytes,2,opt,name=am2" json:"am2,omitempty"`
-	Am3                  *test_a2.M3      `protobuf:"bytes,3,opt,name=am3" json:"am3,omitempty"`
-	Am4                  *test_a3.M4      `protobuf:"bytes,4,opt,name=am4" json:"am4,omitempty"`
-	Bm1                  *test_b_part1.M1 `protobuf:"bytes,5,opt,name=bm1" json:"bm1,omitempty"`
-	Bm2                  *test_b_part2.M2 `protobuf:"bytes,6,opt,name=bm2" json:"bm2,omitempty"`
-	Fmt                  *fmt1.M          `protobuf:"bytes,7,opt,name=fmt" json:"fmt,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
-	XXX_unrecognized     []byte           `json:"-"`
-	XXX_sizecache        int32            `json:"-"`
+	Am1                  *test_a_1.M1 `protobuf:"bytes,1,opt,name=am1" json:"am1,omitempty"`
+	Am2                  *test_a_1.M2 `protobuf:"bytes,2,opt,name=am2" json:"am2,omitempty"`
+	Am3                  *test_a_2.M3 `protobuf:"bytes,3,opt,name=am3" json:"am3,omitempty"`
+	Am4                  *test_a_2.M4 `protobuf:"bytes,4,opt,name=am4" json:"am4,omitempty"`
+	Bm1                  *test_b_1.M1 `protobuf:"bytes,5,opt,name=bm1" json:"bm1,omitempty"`
+	Bm2                  *test_b_1.M2 `protobuf:"bytes,6,opt,name=bm2" json:"bm2,omitempty"`
+	Fmt                  *fmt1.M      `protobuf:"bytes,7,opt,name=fmt" json:"fmt,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
+	XXX_unrecognized     []byte       `json:"-"`
+	XXX_sizecache        int32        `json:"-"`
 }
 
 func (m *All) Reset()         { *m = All{} }
@@ -62,42 +59,42 @@
 
 var xxx_messageInfo_All proto.InternalMessageInfo
 
-func (m *All) GetAm1() *test_a.M1 {
+func (m *All) GetAm1() *test_a_1.M1 {
 	if m != nil {
 		return m.Am1
 	}
 	return nil
 }
 
-func (m *All) GetAm2() *test_a1.M2 {
+func (m *All) GetAm2() *test_a_1.M2 {
 	if m != nil {
 		return m.Am2
 	}
 	return nil
 }
 
-func (m *All) GetAm3() *test_a2.M3 {
+func (m *All) GetAm3() *test_a_2.M3 {
 	if m != nil {
 		return m.Am3
 	}
 	return nil
 }
 
-func (m *All) GetAm4() *test_a3.M4 {
+func (m *All) GetAm4() *test_a_2.M4 {
 	if m != nil {
 		return m.Am4
 	}
 	return nil
 }
 
-func (m *All) GetBm1() *test_b_part1.M1 {
+func (m *All) GetBm1() *test_b_1.M1 {
 	if m != nil {
 		return m.Bm1
 	}
 	return nil
 }
 
-func (m *All) GetBm2() *test_b_part2.M2 {
+func (m *All) GetBm2() *test_b_1.M2 {
 	if m != nil {
 		return m.Bm2
 	}
diff --git a/protoc-gen-go/testdata/imports/test_import_public.pb.go b/protoc-gen-go/testdata/imports/test_import_public.pb.go
index e42e47a..2349b1a 100644
--- a/protoc-gen-go/testdata/imports/test_import_public.pb.go
+++ b/protoc-gen-go/testdata/imports/test_import_public.pb.go
@@ -6,7 +6,7 @@
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import test_a "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
+import test_a_1 "github.com/golang/protobuf/protoc-gen-go/testdata/imports/test_a_1"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -20,23 +20,23 @@
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 // M1 from public import imports/test_a_1/m1.proto
-type M1 test_a.M1
+type M1 test_a_1.M1
 
-func (m *M1) Reset()                         { (*test_a.M1)(m).Reset() }
-func (m *M1) String() string                 { return (*test_a.M1)(m).String() }
+func (m *M1) Reset()                         { (*test_a_1.M1)(m).Reset() }
+func (m *M1) String() string                 { return (*test_a_1.M1)(m).String() }
 func (*M1) ProtoMessage()                    {}
-func (m *M1) XXX_Unmarshal(buf []byte) error { return (*test_a.M1)(m).XXX_Unmarshal(buf) }
+func (m *M1) XXX_Unmarshal(buf []byte) error { return (*test_a_1.M1)(m).XXX_Unmarshal(buf) }
 func (m *M1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return (*test_a.M1)(m).XXX_Marshal(b, deterministic)
+	return (*test_a_1.M1)(m).XXX_Marshal(b, deterministic)
 }
-func (m *M1) XXX_Size() int       { return (*test_a.M1)(m).XXX_Size() }
-func (m *M1) XXX_DiscardUnknown() { (*test_a.M1)(m).XXX_DiscardUnknown() }
+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() }
 
 type Public struct {
-	F                    *test_a.M1 `protobuf:"bytes,1,opt,name=f" json:"f,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
-	XXX_unrecognized     []byte     `json:"-"`
-	XXX_sizecache        int32      `json:"-"`
+	F                    *test_a_1.M1 `protobuf:"bytes,1,opt,name=f" json:"f,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
+	XXX_unrecognized     []byte       `json:"-"`
+	XXX_sizecache        int32        `json:"-"`
 }
 
 func (m *Public) Reset()         { *m = Public{} }
@@ -63,7 +63,7 @@
 
 var xxx_messageInfo_Public proto.InternalMessageInfo
 
-func (m *Public) GetF() *test_a.M1 {
+func (m *Public) GetF() *test_a_1.M1 {
 	if m != nil {
 		return m.F
 	}