cmd/protoc-gen-go: import public: forward default const/vars

Generate forwarders for default value const/vars defined in public
imports:

    const Default_Message_Field = pubimport.Default_Message_Field

Change-Id: Ife09e38ae6a674b4460dd6613a8264e23f30b277
Reviewed-on: https://go-review.googlesource.com/c/140897
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go
index 4f38570..a0a65cb 100644
--- a/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/cmd/protoc-gen-go/internal_gengo/main.go
@@ -146,10 +146,35 @@
 	if !imp.IsPublic {
 		return
 	}
+	// TODO: An alternate approach to generating public imports might be
+	// to generate the imported file contents, parse it, and extract all
+	// exported identifiers from the AST to build a list of forwarding
+	// declarations.
+	//
+	// TODO: Consider whether this should generate recursive aliases. e.g.,
+	// if a.proto publicly imports b.proto publicly imports c.proto, should
+	// a.pb.go contain aliases for symbols defined in c.proto?
 	var enums []*protogen.Enum
 	enums = append(enums, impFile.Enums...)
 	walkMessages(impFile.Messages, func(message *protogen.Message) {
+		if message.Desc.IsMapEntry() {
+			return
+		}
 		enums = append(enums, message.Enums...)
+		for _, field := range message.Fields {
+			if !fieldHasDefault(field) {
+				continue
+			}
+			defVar := protogen.GoIdent{
+				GoImportPath: message.GoIdent.GoImportPath,
+				GoName:       "Default_" + message.GoIdent.GoName + "_" + field.GoName,
+			}
+			decl := "const"
+			if field.Desc.Kind() == protoreflect.BytesKind {
+				decl = "var"
+			}
+			g.P(decl, " ", defVar.GoName, " = ", defVar)
+		}
 		g.P("// ", message.GoIdent.GoName, " from public import ", imp.Path())
 		g.P("type ", message.GoIdent.GoName, " = ", message.GoIdent)
 		for _, oneof := range message.Oneofs {
@@ -170,6 +195,7 @@
 			g.P("const ", value.GoIdent.GoName, " = ", enum.GoIdent.GoName, "(", value.GoIdent, ")")
 		}
 	}
+	g.P()
 }
 
 func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) {
diff --git a/cmd/protoc-gen-go/testdata/import_public/a.pb.go b/cmd/protoc-gen-go/testdata/import_public/a.pb.go
index 75b719d..830e965 100644
--- a/cmd/protoc-gen-go/testdata/import_public/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/a.pb.go
@@ -21,6 +21,8 @@
 // proto package needs to be updated.
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
+const Default_M_S = sub.Default_M_S
+
 // M from public import import_public/sub/a.proto
 type M = sub.M
 type M_OneofInt32 = sub.M_OneofInt32
@@ -56,9 +58,9 @@
 const M_Submessage_M_SUBMESSAGE_ZERO = M_Submessage_Submessage_Subenum(sub.M_Submessage_M_SUBMESSAGE_ZERO)
 
 type Public struct {
-	M                    *sub.M   `protobuf:"bytes,1,opt,name=m,proto3" json:"m,omitempty"`
-	E                    sub.E    `protobuf:"varint,2,opt,name=e,proto3,enum=goproto.protoc.import_public.sub.E" json:"e,omitempty"`
-	Local                *Local   `protobuf:"bytes,3,opt,name=local,proto3" json:"local,omitempty"`
+	M                    *sub.M   `protobuf:"bytes,1,opt,name=m" json:"m,omitempty"`
+	E                    *sub.E   `protobuf:"varint,2,opt,name=e,enum=goproto.protoc.import_public.sub.E" json:"e,omitempty"`
+	Local                *Local   `protobuf:"bytes,3,opt,name=local" json:"local,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -97,8 +99,8 @@
 }
 
 func (m *Public) GetE() sub.E {
-	if m != nil {
-		return m.E
+	if m != nil && m.E != nil {
+		return *m.E
 	}
 	return sub.E_ZERO
 }
@@ -117,7 +119,7 @@
 func init() { proto.RegisterFile("import_public/a.proto", fileDescriptor_73b7577c95fa6b70) }
 
 var fileDescriptor_73b7577c95fa6b70 = []byte{
-	// 207 bytes of a gzipped FileDescriptorProto
+	// 202 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcd, 0xcc, 0x2d, 0xc8,
 	0x2f, 0x2a, 0x89, 0x2f, 0x28, 0x4d, 0xca, 0xc9, 0x4c, 0xd6, 0x4f, 0xd4, 0x2b, 0x28, 0xca, 0x2f,
 	0xc9, 0x17, 0x92, 0x49, 0xcf, 0x07, 0x33, 0x20, 0xdc, 0x64, 0x3d, 0x14, 0x55, 0x52, 0x92, 0xa8,
@@ -129,6 +131,6 @@
 	0xe1, 0xe4, 0x11, 0xe5, 0x96, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f,
 	0x9e, 0x9f, 0x93, 0x98, 0x97, 0xae, 0x0f, 0xd6, 0x96, 0x54, 0x9a, 0xa6, 0x5f, 0x66, 0xa4, 0x9f,
 	0x9c, 0x9b, 0x02, 0xe1, 0x27, 0xeb, 0xa6, 0xa7, 0xe6, 0xe9, 0xa6, 0xe7, 0xeb, 0x97, 0xa4, 0x16,
-	0x97, 0xa4, 0x24, 0x96, 0x24, 0xea, 0xa3, 0x18, 0x1b, 0xc0, 0x10, 0xc0, 0x98, 0xc4, 0x06, 0x56,
-	0x69, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x70, 0xe1, 0xdc, 0x69, 0x01, 0x00, 0x00,
+	0x97, 0xa4, 0x24, 0x96, 0x24, 0xea, 0xa3, 0x18, 0x1b, 0xc0, 0x10, 0xc0, 0x08, 0x08, 0x00, 0x00,
+	0xff, 0xff, 0xfa, 0x3e, 0xda, 0xad, 0x61, 0x01, 0x00, 0x00,
 }
diff --git a/cmd/protoc-gen-go/testdata/import_public/a.proto b/cmd/protoc-gen-go/testdata/import_public/a.proto
index 2722ad2..e33b758 100644
--- a/cmd/protoc-gen-go/testdata/import_public/a.proto
+++ b/cmd/protoc-gen-go/testdata/import_public/a.proto
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-syntax = "proto3";
+syntax = "proto2";
 
 package goproto.protoc.import_public;
 
@@ -12,7 +12,7 @@
 import public "import_public/b.proto";     // Same Go package.
 
 message Public {
-  goproto.protoc.import_public.sub.M m = 1;
-  goproto.protoc.import_public.sub.E e = 2;
-  Local local = 3;
+  optional goproto.protoc.import_public.sub.M m = 1;
+  optional goproto.protoc.import_public.sub.E e = 2;
+  optional Local local = 3;
 }
diff --git a/cmd/protoc-gen-go/testdata/import_public/b.pb.go b/cmd/protoc-gen-go/testdata/import_public/b.pb.go
index 0afec4b..62ff437 100644
--- a/cmd/protoc-gen-go/testdata/import_public/b.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/b.pb.go
@@ -22,8 +22,8 @@
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 type Local struct {
-	M                    *sub.M   `protobuf:"bytes,1,opt,name=m,proto3" json:"m,omitempty"`
-	E                    sub.E    `protobuf:"varint,2,opt,name=e,proto3,enum=goproto.protoc.import_public.sub.E" json:"e,omitempty"`
+	M                    *sub.M   `protobuf:"bytes,1,opt,name=m" json:"m,omitempty"`
+	E                    *sub.E   `protobuf:"varint,2,opt,name=e,enum=goproto.protoc.import_public.sub.E" json:"e,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -62,8 +62,8 @@
 }
 
 func (m *Local) GetE() sub.E {
-	if m != nil {
-		return m.E
+	if m != nil && m.E != nil {
+		return *m.E
 	}
 	return sub.E_ZERO
 }
@@ -75,17 +75,16 @@
 func init() { proto.RegisterFile("import_public/b.proto", fileDescriptor_84995586b3d09710) }
 
 var fileDescriptor_84995586b3d09710 = []byte{
-	// 180 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x8c, 0x31, 0x0b, 0xc2, 0x30,
-	0x10, 0x46, 0x89, 0xa0, 0x43, 0x05, 0x87, 0x82, 0x50, 0xc5, 0xa1, 0xe8, 0xd2, 0xa5, 0x39, 0xac,
-	0xff, 0x40, 0x50, 0x1c, 0x74, 0xe9, 0xe8, 0x22, 0xb9, 0x34, 0xc6, 0x42, 0xd3, 0x2b, 0xed, 0xc5,
-	0xdf, 0x2f, 0xb6, 0x53, 0x17, 0x71, 0xfb, 0x3e, 0x78, 0xef, 0x05, 0xcb, 0xd2, 0x35, 0xd4, 0xf2,
-	0xa3, 0xf1, 0x58, 0x95, 0x1a, 0x50, 0x36, 0x2d, 0x31, 0x85, 0x1b, 0x4b, 0xfd, 0x18, 0xae, 0x96,
-	0x23, 0x6a, 0xbd, 0x1a, 0x4b, 0x9d, 0x47, 0x50, 0x03, 0xb9, 0x75, 0xc1, 0xf4, 0x4a, 0x5a, 0x55,
-	0xe1, 0x3e, 0x10, 0x2e, 0x12, 0xb1, 0x48, 0xe6, 0xd9, 0x4e, 0xfe, 0xaa, 0xc9, 0xce, 0xa3, 0xbc,
-	0xe5, 0xc2, 0x7d, 0x15, 0x13, 0x4d, 0x62, 0x91, 0x2c, 0xfe, 0x51, 0x4e, 0xb9, 0x30, 0xc7, 0xcb,
-	0xfd, 0x6c, 0x4b, 0x7e, 0x79, 0x94, 0x9a, 0x1c, 0x58, 0xaa, 0x54, 0x6d, 0xa1, 0x57, 0xd0, 0x3f,
-	0xe1, 0x9d, 0x81, 0x76, 0xc5, 0xf0, 0x75, 0x6a, 0x4d, 0x9d, 0x5a, 0x02, 0x36, 0x1d, 0x17, 0x8a,
-	0x15, 0x8c, 0x92, 0x38, 0xeb, 0xa9, 0xc3, 0x27, 0x00, 0x00, 0xff, 0xff, 0x20, 0x34, 0xa1, 0xfe,
-	0x11, 0x01, 0x00, 0x00,
+	// 176 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcd, 0xcc, 0x2d, 0xc8,
+	0x2f, 0x2a, 0x89, 0x2f, 0x28, 0x4d, 0xca, 0xc9, 0x4c, 0xd6, 0x4f, 0xd2, 0x2b, 0x28, 0xca, 0x2f,
+	0xc9, 0x17, 0x92, 0x49, 0xcf, 0x07, 0x33, 0x20, 0xdc, 0x64, 0x3d, 0x14, 0x55, 0x52, 0x92, 0xa8,
+	0x9a, 0x8a, 0x4b, 0x93, 0xf4, 0x13, 0x21, 0x2a, 0x95, 0x72, 0xb9, 0x58, 0x7d, 0xf2, 0x93, 0x13,
+	0x73, 0x84, 0x0c, 0xb9, 0x18, 0x73, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0x94, 0xf5, 0xf0,
+	0x99, 0xa6, 0x57, 0x5c, 0x9a, 0xa4, 0xe7, 0x1b, 0xc4, 0x98, 0x0b, 0xd2, 0x92, 0x2a, 0xc1, 0xa4,
+	0xc0, 0xa8, 0xc1, 0x47, 0x8c, 0x16, 0xd7, 0x20, 0xc6, 0x54, 0x27, 0x8f, 0x28, 0xb7, 0xf4, 0xcc,
+	0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0xf4, 0xfc, 0x9c, 0xc4, 0xbc, 0x74, 0x7d,
+	0xb0, 0x96, 0xa4, 0xd2, 0x34, 0xfd, 0x32, 0x23, 0xfd, 0xe4, 0xdc, 0x14, 0x08, 0x3f, 0x59, 0x37,
+	0x3d, 0x35, 0x4f, 0x37, 0x3d, 0x5f, 0xbf, 0x24, 0xb5, 0xb8, 0x24, 0x25, 0xb1, 0x24, 0x51, 0x1f,
+	0xc5, 0x48, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x34, 0xb9, 0xda, 0x09, 0x01, 0x00, 0x00,
 }
diff --git a/cmd/protoc-gen-go/testdata/import_public/b.proto b/cmd/protoc-gen-go/testdata/import_public/b.proto
index 4632fc6..02e4abe 100644
--- a/cmd/protoc-gen-go/testdata/import_public/b.proto
+++ b/cmd/protoc-gen-go/testdata/import_public/b.proto
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-syntax = "proto3";
+syntax = "proto2";
 
 package goproto.protoc.import_public;
 
@@ -11,6 +11,6 @@
 import "import_public/sub/a.proto";
 
 message Local {
-  goproto.protoc.import_public.sub.M m = 1;
-  goproto.protoc.import_public.sub.E e = 2;
+  optional goproto.protoc.import_public.sub.M m = 1;
+  optional goproto.protoc.import_public.sub.E e = 2;
 }
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go b/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
index f1dfd60..f9d5e4b 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
@@ -34,10 +34,25 @@
 	"ZERO": 0,
 }
 
+func (x E) Enum() *E {
+	p := new(E)
+	*p = x
+	return p
+}
+
 func (x E) String() string {
 	return proto.EnumName(E_name, int32(x))
 }
 
+func (x *E) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(E_value, data, "E")
+	if err != nil {
+		return err
+	}
+	*x = E(value)
+	return nil
+}
+
 func (E) EnumDescriptor() ([]byte, []int) {
 	return fileDescriptor_382f7805394b5c4e, []int{0}
 }
@@ -56,10 +71,25 @@
 	"M_ZERO": 0,
 }
 
+func (x M_Subenum) Enum() *M_Subenum {
+	p := new(M_Subenum)
+	*p = x
+	return p
+}
+
 func (x M_Subenum) String() string {
 	return proto.EnumName(M_Subenum_name, int32(x))
 }
 
+func (x *M_Subenum) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(M_Subenum_value, data, "M_Subenum")
+	if err != nil {
+		return err
+	}
+	*x = M_Subenum(value)
+	return nil
+}
+
 func (M_Subenum) EnumDescriptor() ([]byte, []int) {
 	return fileDescriptor_382f7805394b5c4e, []int{0, 0}
 }
@@ -78,17 +108,33 @@
 	"M_SUBMESSAGE_ZERO": 0,
 }
 
+func (x M_Submessage_Submessage_Subenum) Enum() *M_Submessage_Submessage_Subenum {
+	p := new(M_Submessage_Submessage_Subenum)
+	*p = x
+	return p
+}
+
 func (x M_Submessage_Submessage_Subenum) String() string {
 	return proto.EnumName(M_Submessage_Submessage_Subenum_name, int32(x))
 }
 
+func (x *M_Submessage_Submessage_Subenum) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(M_Submessage_Submessage_Subenum_value, data, "M_Submessage_Submessage_Subenum")
+	if err != nil {
+		return err
+	}
+	*x = M_Submessage_Submessage_Subenum(value)
+	return nil
+}
+
 func (M_Submessage_Submessage_Subenum) EnumDescriptor() ([]byte, []int) {
 	return fileDescriptor_382f7805394b5c4e, []int{0, 0, 0}
 }
 
 type M struct {
 	// Field using a type in the same Go package, but a different source file.
-	M2 *M2 `protobuf:"bytes,1,opt,name=m2,proto3" json:"m2,omitempty"`
+	M2 *M2     `protobuf:"bytes,1,opt,name=m2" json:"m2,omitempty"`
+	S  *string `protobuf:"bytes,4,opt,name=s,def=default" json:"s,omitempty"`
 	// Types that are valid to be assigned to OneofField:
 	//	*M_OneofInt32
 	//	*M_OneofInt64
@@ -123,6 +169,8 @@
 
 var xxx_messageInfo_M proto.InternalMessageInfo
 
+const Default_M_S string = "default"
+
 func (m *M) GetM2() *M2 {
 	if m != nil {
 		return m.M2
@@ -130,16 +178,23 @@
 	return nil
 }
 
+func (m *M) GetS() string {
+	if m != nil && m.S != nil {
+		return *m.S
+	}
+	return Default_M_S
+}
+
 type isM_OneofField interface {
 	isM_OneofField()
 }
 
 type M_OneofInt32 struct {
-	OneofInt32 int32 `protobuf:"varint,2,opt,name=oneof_int32,json=oneofInt32,proto3,oneof"`
+	OneofInt32 int32 `protobuf:"varint,2,opt,name=oneof_int32,json=oneofInt32,oneof"`
 }
 
 type M_OneofInt64 struct {
-	OneofInt64 int64 `protobuf:"varint,3,opt,name=oneof_int64,json=oneofInt64,proto3,oneof"`
+	OneofInt64 int64 `protobuf:"varint,3,opt,name=oneof_int64,json=oneofInt64,oneof"`
 }
 
 func (*M_OneofInt32) isM_OneofField() {}
@@ -271,11 +326,11 @@
 }
 
 type M_Submessage_SubmessageOneofInt32 struct {
-	SubmessageOneofInt32 int32 `protobuf:"varint,1,opt,name=submessage_oneof_int32,json=submessageOneofInt32,proto3,oneof"`
+	SubmessageOneofInt32 int32 `protobuf:"varint,1,opt,name=submessage_oneof_int32,json=submessageOneofInt32,oneof"`
 }
 
 type M_Submessage_SubmessageOneofInt64 struct {
-	SubmessageOneofInt64 int64 `protobuf:"varint,2,opt,name=submessage_oneof_int64,json=submessageOneofInt64,proto3,oneof"`
+	SubmessageOneofInt64 int64 `protobuf:"varint,2,opt,name=submessage_oneof_int64,json=submessageOneofInt64,oneof"`
 }
 
 func (*M_Submessage_SubmessageOneofInt32) isM_Submessage_SubmessageOneofField() {}
@@ -378,25 +433,26 @@
 func init() { proto.RegisterFile("import_public/sub/a.proto", fileDescriptor_382f7805394b5c4e) }
 
 var fileDescriptor_382f7805394b5c4e = []byte{
-	// 319 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0xdf, 0x4e, 0xc2, 0x30,
-	0x18, 0xc5, 0xe9, 0x50, 0x34, 0x1f, 0x21, 0xd1, 0x46, 0xcc, 0xe4, 0x6a, 0x12, 0x2f, 0x88, 0x86,
-	0x35, 0x19, 0xcb, 0xee, 0x25, 0x59, 0xfc, 0x13, 0x17, 0x12, 0x16, 0x6f, 0xb8, 0x59, 0xd6, 0x51,
-	0xea, 0x12, 0xba, 0x12, 0xda, 0xfa, 0x82, 0x3e, 0x8e, 0x2f, 0x61, 0x2c, 0x20, 0x10, 0x31, 0xde,
-	0xed, 0x7c, 0xdf, 0xef, 0x9c, 0xb3, 0xb6, 0x70, 0x55, 0x8a, 0x85, 0x5c, 0xea, 0x6c, 0x61, 0xe8,
-	0xbc, 0x2c, 0x88, 0x32, 0x94, 0xe4, 0xfe, 0x62, 0x29, 0xb5, 0xc4, 0x1e, 0x97, 0xf6, 0x63, 0x25,
-	0x0b, 0x7f, 0x8f, 0xf4, 0x95, 0xa1, 0x9d, 0x03, 0x66, 0xba, 0xa2, 0xbb, 0x9f, 0x0e, 0xa0, 0x04,
-	0x87, 0xe0, 0x88, 0xc0, 0x45, 0x1e, 0xea, 0x35, 0x83, 0x1b, 0xff, 0xbf, 0x3c, 0x3f, 0x09, 0xc6,
-	0x8e, 0x08, 0xf0, 0x35, 0x34, 0x65, 0xc5, 0xe4, 0x2c, 0x2b, 0x2b, 0x3d, 0x08, 0x5c, 0xc7, 0x43,
-	0xbd, 0xe3, 0xc7, 0xda, 0x18, 0xec, 0xf0, 0xe9, 0x7b, 0xb6, 0x87, 0x44, 0xa1, 0x5b, 0xf7, 0x50,
-	0xaf, 0xbe, 0x8b, 0x44, 0x61, 0xe7, 0x03, 0x01, 0xa4, 0x86, 0x0a, 0xa6, 0x54, 0xce, 0x19, 0x8e,
-	0xe0, 0x52, 0xfd, 0xa8, 0x6c, 0x37, 0x1f, 0xad, 0xf3, 0x2f, 0xb6, 0xfb, 0xd1, 0xb6, 0xe9, 0x0f,
-	0x5f, 0x14, 0xda, 0xff, 0xaa, 0x1f, 0xf6, 0x45, 0x61, 0xf7, 0x0e, 0xf0, 0xb6, 0x3d, 0x4b, 0x0d,
-	0x65, 0x95, 0x11, 0xb8, 0x0d, 0xe7, 0x49, 0x96, 0xbe, 0x0e, 0x93, 0x38, 0x4d, 0xef, 0x1f, 0xe2,
-	0x6c, 0x12, 0x8f, 0x47, 0x67, 0xb5, 0xa1, 0x7b, 0xa0, 0x64, 0x56, 0xb2, 0xf9, 0xb4, 0xdb, 0x86,
-	0x93, 0x8d, 0x17, 0xa0, 0x91, 0x6c, 0x0c, 0xad, 0xcd, 0xf9, 0x2d, 0x75, 0xdb, 0x02, 0x14, 0xe3,
-	0x53, 0x38, 0x5a, 0x6f, 0x5f, 0x26, 0xcf, 0xbc, 0xd4, 0x6f, 0x86, 0xfa, 0x85, 0x14, 0x84, 0xcb,
-	0x79, 0x5e, 0x71, 0x62, 0x6f, 0x9d, 0x9a, 0x19, 0x79, 0x0f, 0x48, 0x21, 0xa6, 0x2b, 0x5d, 0xf4,
-	0x39, 0xab, 0xfa, 0x5c, 0x12, 0xcd, 0x94, 0x9e, 0xe6, 0x3a, 0x27, 0xbf, 0x9e, 0x94, 0x36, 0x2c,
-	0x39, 0xf8, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x77, 0x38, 0x44, 0x2b, 0x02, 0x00, 0x00,
+	// 334 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0xcd, 0x4a, 0xc3, 0x40,
+	0x14, 0x85, 0x3b, 0x4d, 0xb5, 0x7a, 0x4b, 0x41, 0x07, 0x2b, 0xb1, 0xab, 0x58, 0x5c, 0x04, 0xa5,
+	0x19, 0x88, 0x21, 0x0b, 0x77, 0x16, 0x82, 0x3f, 0x18, 0x0a, 0x09, 0x6e, 0xba, 0x09, 0x99, 0x64,
+	0x12, 0x03, 0x49, 0xa6, 0x74, 0x66, 0x7c, 0x00, 0x5f, 0xcd, 0x17, 0x13, 0xd3, 0xd6, 0xb6, 0x58,
+	0x71, 0x97, 0x73, 0xef, 0xf9, 0xce, 0xc9, 0x70, 0xe1, 0xa2, 0xa8, 0xe6, 0x7c, 0x21, 0xa3, 0xb9,
+	0xa2, 0x65, 0x91, 0x10, 0xa1, 0x28, 0x89, 0xad, 0xf9, 0x82, 0x4b, 0x8e, 0x8d, 0x9c, 0x37, 0x1f,
+	0x4b, 0x99, 0x58, 0x3b, 0x4e, 0x4b, 0x28, 0x3a, 0xdc, 0x03, 0xd3, 0xa5, 0x7b, 0xf4, 0xa1, 0x01,
+	0xf2, 0xb1, 0x03, 0xed, 0xca, 0xd6, 0x91, 0x81, 0xcc, 0x9e, 0x7d, 0x65, 0xfd, 0x97, 0x67, 0xf9,
+	0x76, 0xd0, 0xae, 0x6c, 0x3c, 0x00, 0x24, 0xf4, 0x8e, 0x81, 0xcc, 0xe3, 0xbb, 0x6e, 0xca, 0xb2,
+	0x58, 0x95, 0x32, 0x40, 0x02, 0x5f, 0x42, 0x8f, 0xd7, 0x8c, 0x67, 0x51, 0x51, 0xcb, 0x5b, 0x5b,
+	0x6f, 0x1b, 0xc8, 0x3c, 0x78, 0x6c, 0x05, 0xd0, 0x0c, 0x9f, 0xbe, 0x67, 0x3b, 0x16, 0xd7, 0xd1,
+	0x35, 0x03, 0x99, 0xda, 0xb6, 0xc5, 0x75, 0x86, 0x9f, 0x08, 0x20, 0x54, 0xb4, 0x62, 0x42, 0xc4,
+	0x39, 0xc3, 0x2e, 0x9c, 0x8b, 0x1f, 0x15, 0x6d, 0xe7, 0xa3, 0x55, 0xfe, 0xd9, 0x66, 0x3f, 0xdd,
+	0x34, 0xfd, 0xc1, 0xb9, 0x4e, 0xf3, 0x5f, 0xda, 0x7e, 0xce, 0x75, 0x46, 0x37, 0x80, 0x37, 0xed,
+	0x51, 0xa8, 0x28, 0xab, 0x55, 0x85, 0x07, 0x70, 0xea, 0x47, 0xe1, 0xeb, 0xc4, 0xf7, 0xc2, 0xf0,
+	0xfe, 0xc1, 0x8b, 0x66, 0x5e, 0x30, 0x3d, 0x69, 0x4d, 0xf4, 0x3d, 0x25, 0x59, 0xc1, 0xca, 0x74,
+	0x34, 0x80, 0xee, 0x9a, 0x05, 0x38, 0xf4, 0xd7, 0x40, 0x7f, 0xfd, 0xfe, 0xc6, 0x75, 0xdd, 0x07,
+	0xe4, 0xe1, 0x23, 0xe8, 0xac, 0xb6, 0x2f, 0xb3, 0xe7, 0xbc, 0x90, 0x6f, 0x8a, 0x5a, 0x09, 0xaf,
+	0x48, 0xce, 0xcb, 0xb8, 0xce, 0x49, 0x73, 0x0c, 0xaa, 0x32, 0xf2, 0x6e, 0x93, 0xa4, 0x4a, 0x97,
+	0x3a, 0x19, 0xe7, 0xac, 0x1e, 0xe7, 0x9c, 0x48, 0x26, 0x64, 0x1a, 0xcb, 0x98, 0xfc, 0xba, 0xf4,
+	0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x85, 0xd9, 0xf7, 0xbf, 0x3a, 0x02, 0x00, 0x00,
 }
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub/a.proto b/cmd/protoc-gen-go/testdata/import_public/sub/a.proto
index 13bc0b3..3771366 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub/a.proto
+++ b/cmd/protoc-gen-go/testdata/import_public/sub/a.proto
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-syntax = "proto3";
+syntax = "proto2";
 
 package goproto.protoc.import_public.sub;
 
@@ -12,7 +12,8 @@
 
 message M {
   // Field using a type in the same Go package, but a different source file.
-  M2 m2 = 1;
+  optional M2 m2 = 1;
+  optional string s = 4 [default="default"];
 
   oneof oneof_field {
     int32 oneof_int32 = 2;
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go b/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go
index cf468ff..0baad37 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go
@@ -58,7 +58,7 @@
 func init() { proto.RegisterFile("import_public/sub/b.proto", fileDescriptor_fc66afda3d7c2232) }
 
 var fileDescriptor_fc66afda3d7c2232 = []byte{
-	// 134 bytes of a gzipped FileDescriptorProto
+	// 129 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xcc, 0x2d, 0xc8,
 	0x2f, 0x2a, 0x89, 0x2f, 0x28, 0x4d, 0xca, 0xc9, 0x4c, 0xd6, 0x2f, 0x2e, 0x4d, 0xd2, 0x4f, 0xd2,
 	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x48, 0xcf, 0x07, 0x33, 0x20, 0xdc, 0x64, 0x3d, 0x14,
@@ -66,6 +66,6 @@
 	0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xe9, 0xf9, 0x39, 0x89, 0x79, 0xe9,
 	0xfa, 0x60, 0x3d, 0x49, 0xa5, 0x69, 0xfa, 0x65, 0x46, 0xfa, 0xc9, 0xb9, 0x29, 0x10, 0x7e, 0xb2,
 	0x6e, 0x7a, 0x6a, 0x9e, 0x6e, 0x7a, 0xbe, 0x7e, 0x49, 0x6a, 0x71, 0x49, 0x4a, 0x62, 0x49, 0xa2,
-	0x3e, 0x86, 0xed, 0x49, 0x6c, 0x60, 0x95, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x46, 0xb8,
-	0x19, 0x87, 0x99, 0x00, 0x00, 0x00,
+	0x3e, 0x86, 0xed, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc7, 0x2d, 0x0b, 0x52, 0x91, 0x00, 0x00,
+	0x00,
 }
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub/b.proto b/cmd/protoc-gen-go/testdata/import_public/sub/b.proto
index fd643d6..017ae18 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub/b.proto
+++ b/cmd/protoc-gen-go/testdata/import_public/sub/b.proto
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-syntax = "proto3";
+syntax = "proto2";
 
 package goproto.protoc.import_public.sub;