cmd/protoc-gen-go: unexport implementation-specific XXX fields

We modify protoc-gen-go to stop generating exported XXX fields.
The unsafe implementation is unaffected by this change since unsafe
can access fields regardless of visibility. However, for the purego
implementation, we need to respect Go visibility rules as enforced
by the reflect package.

We work around this by generating a exporter function that given
a reference to the message and the field to export, returns a reference
to the unexported field value. This exporter function is protected by
a constant such that it is not linked into the final binary in non-purego
build environment.

Updates golang/protobuf#276

Change-Id: Idf5c1f158973fa1c61187ff41440acb21c5dac94
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185141
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/testprotos/pb2/test.pb.go b/encoding/testprotos/pb2/test.pb.go
index a286391..38670db 100644
--- a/encoding/testprotos/pb2/test.pb.go
+++ b/encoding/testprotos/pb2/test.pb.go
@@ -133,24 +133,23 @@
 
 // Scalars contains optional scalar fields.
 type Scalars struct {
-	OptBool              *bool                   `protobuf:"varint,1,opt,name=opt_bool,json=optBool" json:"opt_bool,omitempty"`
-	OptInt32             *int32                  `protobuf:"varint,2,opt,name=opt_int32,json=optInt32" json:"opt_int32,omitempty"`
-	OptInt64             *int64                  `protobuf:"varint,3,opt,name=opt_int64,json=optInt64" json:"opt_int64,omitempty"`
-	OptUint32            *uint32                 `protobuf:"varint,4,opt,name=opt_uint32,json=optUint32" json:"opt_uint32,omitempty"`
-	OptUint64            *uint64                 `protobuf:"varint,5,opt,name=opt_uint64,json=optUint64" json:"opt_uint64,omitempty"`
-	OptSint32            *int32                  `protobuf:"zigzag32,6,opt,name=opt_sint32,json=optSint32" json:"opt_sint32,omitempty"`
-	OptSint64            *int64                  `protobuf:"zigzag64,7,opt,name=opt_sint64,json=optSint64" json:"opt_sint64,omitempty"`
-	OptFixed32           *uint32                 `protobuf:"fixed32,8,opt,name=opt_fixed32,json=optFixed32" json:"opt_fixed32,omitempty"`
-	OptFixed64           *uint64                 `protobuf:"fixed64,9,opt,name=opt_fixed64,json=optFixed64" json:"opt_fixed64,omitempty"`
-	OptSfixed32          *int32                  `protobuf:"fixed32,10,opt,name=opt_sfixed32,json=optSfixed32" json:"opt_sfixed32,omitempty"`
-	OptSfixed64          *int64                  `protobuf:"fixed64,11,opt,name=opt_sfixed64,json=optSfixed64" json:"opt_sfixed64,omitempty"`
-	OptFloat             *float32                `protobuf:"fixed32,20,opt,name=opt_float,json=optFloat" json:"opt_float,omitempty"`
-	OptDouble            *float64                `protobuf:"fixed64,21,opt,name=opt_double,json=optDouble" json:"opt_double,omitempty"`
-	OptBytes             []byte                  `protobuf:"bytes,14,opt,name=opt_bytes,json=optBytes" json:"opt_bytes,omitempty"`
-	OptString            *string                 `protobuf:"bytes,13,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptBool       *bool    `protobuf:"varint,1,opt,name=opt_bool,json=optBool" json:"opt_bool,omitempty"`
+	OptInt32      *int32   `protobuf:"varint,2,opt,name=opt_int32,json=optInt32" json:"opt_int32,omitempty"`
+	OptInt64      *int64   `protobuf:"varint,3,opt,name=opt_int64,json=optInt64" json:"opt_int64,omitempty"`
+	OptUint32     *uint32  `protobuf:"varint,4,opt,name=opt_uint32,json=optUint32" json:"opt_uint32,omitempty"`
+	OptUint64     *uint64  `protobuf:"varint,5,opt,name=opt_uint64,json=optUint64" json:"opt_uint64,omitempty"`
+	OptSint32     *int32   `protobuf:"zigzag32,6,opt,name=opt_sint32,json=optSint32" json:"opt_sint32,omitempty"`
+	OptSint64     *int64   `protobuf:"zigzag64,7,opt,name=opt_sint64,json=optSint64" json:"opt_sint64,omitempty"`
+	OptFixed32    *uint32  `protobuf:"fixed32,8,opt,name=opt_fixed32,json=optFixed32" json:"opt_fixed32,omitempty"`
+	OptFixed64    *uint64  `protobuf:"fixed64,9,opt,name=opt_fixed64,json=optFixed64" json:"opt_fixed64,omitempty"`
+	OptSfixed32   *int32   `protobuf:"fixed32,10,opt,name=opt_sfixed32,json=optSfixed32" json:"opt_sfixed32,omitempty"`
+	OptSfixed64   *int64   `protobuf:"fixed64,11,opt,name=opt_sfixed64,json=optSfixed64" json:"opt_sfixed64,omitempty"`
+	OptFloat      *float32 `protobuf:"fixed32,20,opt,name=opt_float,json=optFloat" json:"opt_float,omitempty"`
+	OptDouble     *float64 `protobuf:"fixed64,21,opt,name=opt_double,json=optDouble" json:"opt_double,omitempty"`
+	OptBytes      []byte   `protobuf:"bytes,14,opt,name=opt_bytes,json=optBytes" json:"opt_bytes,omitempty"`
+	OptString     *string  `protobuf:"bytes,13,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Scalars) Reset() {
@@ -283,13 +282,12 @@
 
 // Message contains enum fields.
 type Enums struct {
-	OptEnum              *Enum                   `protobuf:"varint,1,opt,name=opt_enum,json=optEnum,enum=pb2.Enum" json:"opt_enum,omitempty"`
-	RptEnum              []Enum                  `protobuf:"varint,2,rep,name=rpt_enum,json=rptEnum,enum=pb2.Enum" json:"rpt_enum,omitempty"`
-	OptNestedEnum        *Enums_NestedEnum       `protobuf:"varint,3,opt,name=opt_nested_enum,json=optNestedEnum,enum=pb2.Enums_NestedEnum" json:"opt_nested_enum,omitempty"`
-	RptNestedEnum        []Enums_NestedEnum      `protobuf:"varint,4,rep,name=rpt_nested_enum,json=rptNestedEnum,enum=pb2.Enums_NestedEnum" json:"rpt_nested_enum,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptEnum       *Enum              `protobuf:"varint,1,opt,name=opt_enum,json=optEnum,enum=pb2.Enum" json:"opt_enum,omitempty"`
+	RptEnum       []Enum             `protobuf:"varint,2,rep,name=rpt_enum,json=rptEnum,enum=pb2.Enum" json:"rpt_enum,omitempty"`
+	OptNestedEnum *Enums_NestedEnum  `protobuf:"varint,3,opt,name=opt_nested_enum,json=optNestedEnum,enum=pb2.Enums_NestedEnum" json:"opt_nested_enum,omitempty"`
+	RptNestedEnum []Enums_NestedEnum `protobuf:"varint,4,rep,name=rpt_nested_enum,json=rptNestedEnum,enum=pb2.Enums_NestedEnum" json:"rpt_nested_enum,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Enums) Reset() {
@@ -345,18 +343,17 @@
 
 // Message contains repeated fields.
 type Repeats struct {
-	RptBool              []bool                  `protobuf:"varint,1,rep,name=rpt_bool,json=rptBool" json:"rpt_bool,omitempty"`
-	RptInt32             []int32                 `protobuf:"varint,2,rep,name=rpt_int32,json=rptInt32" json:"rpt_int32,omitempty"`
-	RptInt64             []int64                 `protobuf:"varint,3,rep,name=rpt_int64,json=rptInt64" json:"rpt_int64,omitempty"`
-	RptUint32            []uint32                `protobuf:"varint,4,rep,name=rpt_uint32,json=rptUint32" json:"rpt_uint32,omitempty"`
-	RptUint64            []uint64                `protobuf:"varint,5,rep,name=rpt_uint64,json=rptUint64" json:"rpt_uint64,omitempty"`
-	RptFloat             []float32               `protobuf:"fixed32,6,rep,name=rpt_float,json=rptFloat" json:"rpt_float,omitempty"`
-	RptDouble            []float64               `protobuf:"fixed64,7,rep,name=rpt_double,json=rptDouble" json:"rpt_double,omitempty"`
-	RptString            []string                `protobuf:"bytes,8,rep,name=rpt_string,json=rptString" json:"rpt_string,omitempty"`
-	RptBytes             [][]byte                `protobuf:"bytes,9,rep,name=rpt_bytes,json=rptBytes" json:"rpt_bytes,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	RptBool       []bool    `protobuf:"varint,1,rep,name=rpt_bool,json=rptBool" json:"rpt_bool,omitempty"`
+	RptInt32      []int32   `protobuf:"varint,2,rep,name=rpt_int32,json=rptInt32" json:"rpt_int32,omitempty"`
+	RptInt64      []int64   `protobuf:"varint,3,rep,name=rpt_int64,json=rptInt64" json:"rpt_int64,omitempty"`
+	RptUint32     []uint32  `protobuf:"varint,4,rep,name=rpt_uint32,json=rptUint32" json:"rpt_uint32,omitempty"`
+	RptUint64     []uint64  `protobuf:"varint,5,rep,name=rpt_uint64,json=rptUint64" json:"rpt_uint64,omitempty"`
+	RptFloat      []float32 `protobuf:"fixed32,6,rep,name=rpt_float,json=rptFloat" json:"rpt_float,omitempty"`
+	RptDouble     []float64 `protobuf:"fixed64,7,rep,name=rpt_double,json=rptDouble" json:"rpt_double,omitempty"`
+	RptString     []string  `protobuf:"bytes,8,rep,name=rpt_string,json=rptString" json:"rpt_string,omitempty"`
+	RptBytes      [][]byte  `protobuf:"bytes,9,rep,name=rpt_bytes,json=rptBytes" json:"rpt_bytes,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Repeats) Reset() {
@@ -447,11 +444,10 @@
 
 // Message type used as submessage.
 type Nested struct {
-	OptString            *string                 `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	OptNested            *Nested                 `protobuf:"bytes,2,opt,name=opt_nested,json=optNested" json:"opt_nested,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptString     *string `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	OptNested     *Nested `protobuf:"bytes,2,opt,name=opt_nested,json=optNested" json:"opt_nested,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Nested) Reset() {
@@ -493,13 +489,12 @@
 
 // Message contains message and group fields.
 type Nests struct {
-	OptNested            *Nested                 `protobuf:"bytes,1,opt,name=opt_nested,json=optNested" json:"opt_nested,omitempty"`
-	Optgroup             *Nests_OptGroup         `protobuf:"group,2,opt,name=OptGroup,json=optgroup" json:"optgroup,omitempty"`
-	RptNested            []*Nested               `protobuf:"bytes,4,rep,name=rpt_nested,json=rptNested" json:"rpt_nested,omitempty"`
-	Rptgroup             []*Nests_RptGroup       `protobuf:"group,5,rep,name=RptGroup,json=rptgroup" json:"rptgroup,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptNested     *Nested           `protobuf:"bytes,1,opt,name=opt_nested,json=optNested" json:"opt_nested,omitempty"`
+	Optgroup      *Nests_OptGroup   `protobuf:"group,2,opt,name=OptGroup,json=optgroup" json:"optgroup,omitempty"`
+	RptNested     []*Nested         `protobuf:"bytes,4,rep,name=rpt_nested,json=rptNested" json:"rpt_nested,omitempty"`
+	Rptgroup      []*Nests_RptGroup `protobuf:"group,5,rep,name=RptGroup,json=rptgroup" json:"rptgroup,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Nests) Reset() {
@@ -555,15 +550,14 @@
 
 // Message contains required fields.
 type Requireds struct {
-	ReqBool              *bool                   `protobuf:"varint,1,req,name=req_bool,json=reqBool" json:"req_bool,omitempty"`
-	ReqSfixed64          *int64                  `protobuf:"fixed64,2,req,name=req_sfixed64,json=reqSfixed64" json:"req_sfixed64,omitempty"`
-	ReqDouble            *float64                `protobuf:"fixed64,3,req,name=req_double,json=reqDouble" json:"req_double,omitempty"`
-	ReqString            *string                 `protobuf:"bytes,4,req,name=req_string,json=reqString" json:"req_string,omitempty"`
-	ReqEnum              *Enum                   `protobuf:"varint,5,req,name=req_enum,json=reqEnum,enum=pb2.Enum" json:"req_enum,omitempty"`
-	ReqNested            *Nested                 `protobuf:"bytes,6,req,name=req_nested,json=reqNested" json:"req_nested,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	ReqBool       *bool    `protobuf:"varint,1,req,name=req_bool,json=reqBool" json:"req_bool,omitempty"`
+	ReqSfixed64   *int64   `protobuf:"fixed64,2,req,name=req_sfixed64,json=reqSfixed64" json:"req_sfixed64,omitempty"`
+	ReqDouble     *float64 `protobuf:"fixed64,3,req,name=req_double,json=reqDouble" json:"req_double,omitempty"`
+	ReqString     *string  `protobuf:"bytes,4,req,name=req_string,json=reqString" json:"req_string,omitempty"`
+	ReqEnum       *Enum    `protobuf:"varint,5,req,name=req_enum,json=reqEnum,enum=pb2.Enum" json:"req_enum,omitempty"`
+	ReqNested     *Nested  `protobuf:"bytes,6,req,name=req_nested,json=reqNested" json:"req_nested,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Requireds) Reset() {
@@ -633,11 +627,10 @@
 
 // Message contains both required and optional fields.
 type PartialRequired struct {
-	ReqString            *string                 `protobuf:"bytes,1,req,name=req_string,json=reqString" json:"req_string,omitempty"`
-	OptString            *string                 `protobuf:"bytes,2,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	ReqString     *string `protobuf:"bytes,1,req,name=req_string,json=reqString" json:"req_string,omitempty"`
+	OptString     *string `protobuf:"bytes,2,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *PartialRequired) Reset() {
@@ -678,10 +671,9 @@
 }
 
 type NestedWithRequired struct {
-	ReqString            *string                 `protobuf:"bytes,1,req,name=req_string,json=reqString" json:"req_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	ReqString     *string `protobuf:"bytes,1,req,name=req_string,json=reqString" json:"req_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *NestedWithRequired) Reset() {
@@ -720,10 +712,9 @@
 	StrToNested map[string]*NestedWithRequired `protobuf:"bytes,3,rep,name=str_to_nested,json=strToNested" json:"str_to_nested,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 	// Types that are valid to be assigned to Union:
 	//	*IndirectRequired_OneofNested
-	Union                isIndirectRequired_Union `protobuf_oneof:"union"`
-	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields  `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache      `json:"-"`
+	Union         isIndirectRequired_Union `protobuf_oneof:"union"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *IndirectRequired) Reset() {
@@ -795,13 +786,12 @@
 func (*IndirectRequired_OneofNested) isIndirectRequired_Union() {}
 
 type Extensions struct {
-	OptString              *string                   `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	OptBool                *bool                     `protobuf:"varint,101,opt,name=opt_bool,json=optBool" json:"opt_bool,omitempty"`
-	OptInt32               *int32                    `protobuf:"varint,2,opt,name=opt_int32,json=optInt32" json:"opt_int32,omitempty"`
-	XXX_NoUnkeyedLiteral   struct{}                  `json:"-"`
-	XXX_InternalExtensions protoimpl.ExtensionFields `json:"-"`
-	XXX_unrecognized       protoimpl.UnknownFields   `json:"-"`
-	XXX_sizecache          protoimpl.SizeCache       `json:"-"`
+	OptString       *string `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	OptBool         *bool   `protobuf:"varint,101,opt,name=opt_bool,json=optBool" json:"opt_bool,omitempty"`
+	OptInt32        *int32  `protobuf:"varint,2,opt,name=opt_int32,json=optInt32" json:"opt_int32,omitempty"`
+	sizeCache       protoimpl.SizeCache
+	unknownFields   protoimpl.UnknownFields
+	extensionFields protoimpl.ExtensionFields ``
 }
 
 func (x *Extensions) Reset() {
@@ -858,9 +848,8 @@
 }
 
 type ExtensionsContainer struct {
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *ExtensionsContainer) Reset() {
@@ -887,10 +876,9 @@
 }
 
 type MessageSet struct {
-	XXX_NoUnkeyedLiteral   struct{}                  `json:"-"`
-	XXX_InternalExtensions protoimpl.ExtensionFields `protobuf_messageset:"1" json:"-"`
-	XXX_unrecognized       protoimpl.UnknownFields   `json:"-"`
-	XXX_sizecache          protoimpl.SizeCache       `json:"-"`
+	sizeCache       protoimpl.SizeCache
+	unknownFields   protoimpl.UnknownFields
+	extensionFields protoimpl.ExtensionFields `protobuf_messageset:"1"`
 }
 
 func (x *MessageSet) Reset() {
@@ -926,10 +914,9 @@
 }
 
 type MessageSetExtension struct {
-	OptString            *string                 `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptString     *string `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *MessageSetExtension) Reset() {
@@ -963,10 +950,9 @@
 }
 
 type FakeMessageSet struct {
-	XXX_NoUnkeyedLiteral   struct{}                  `json:"-"`
-	XXX_InternalExtensions protoimpl.ExtensionFields `json:"-"`
-	XXX_unrecognized       protoimpl.UnknownFields   `json:"-"`
-	XXX_sizecache          protoimpl.SizeCache       `json:"-"`
+	sizeCache       protoimpl.SizeCache
+	unknownFields   protoimpl.UnknownFields
+	extensionFields protoimpl.ExtensionFields ``
 }
 
 func (x *FakeMessageSet) Reset() {
@@ -1002,10 +988,9 @@
 }
 
 type FakeMessageSetExtension struct {
-	OptString            *string                 `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptString     *string `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *FakeMessageSetExtension) Reset() {
@@ -1040,27 +1025,26 @@
 
 // Message contains well-known type fields.
 type KnownTypes struct {
-	OptBool              *wrapperspb.BoolValue   `protobuf:"bytes,1,opt,name=opt_bool,json=optBool" json:"opt_bool,omitempty"`
-	OptInt32             *wrapperspb.Int32Value  `protobuf:"bytes,2,opt,name=opt_int32,json=optInt32" json:"opt_int32,omitempty"`
-	OptInt64             *wrapperspb.Int64Value  `protobuf:"bytes,3,opt,name=opt_int64,json=optInt64" json:"opt_int64,omitempty"`
-	OptUint32            *wrapperspb.UInt32Value `protobuf:"bytes,4,opt,name=opt_uint32,json=optUint32" json:"opt_uint32,omitempty"`
-	OptUint64            *wrapperspb.UInt64Value `protobuf:"bytes,5,opt,name=opt_uint64,json=optUint64" json:"opt_uint64,omitempty"`
-	OptFloat             *wrapperspb.FloatValue  `protobuf:"bytes,6,opt,name=opt_float,json=optFloat" json:"opt_float,omitempty"`
-	OptDouble            *wrapperspb.DoubleValue `protobuf:"bytes,7,opt,name=opt_double,json=optDouble" json:"opt_double,omitempty"`
-	OptString            *wrapperspb.StringValue `protobuf:"bytes,8,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	OptBytes             *wrapperspb.BytesValue  `protobuf:"bytes,9,opt,name=opt_bytes,json=optBytes" json:"opt_bytes,omitempty"`
-	OptDuration          *durationpb.Duration    `protobuf:"bytes,20,opt,name=opt_duration,json=optDuration" json:"opt_duration,omitempty"`
-	OptTimestamp         *timestamppb.Timestamp  `protobuf:"bytes,21,opt,name=opt_timestamp,json=optTimestamp" json:"opt_timestamp,omitempty"`
-	OptStruct            *structpb.Struct        `protobuf:"bytes,25,opt,name=opt_struct,json=optStruct" json:"opt_struct,omitempty"`
-	OptList              *structpb.ListValue     `protobuf:"bytes,26,opt,name=opt_list,json=optList" json:"opt_list,omitempty"`
-	OptValue             *structpb.Value         `protobuf:"bytes,27,opt,name=opt_value,json=optValue" json:"opt_value,omitempty"`
-	OptNull              *structpb.NullValue     `protobuf:"varint,28,opt,name=opt_null,json=optNull,enum=google.protobuf.NullValue" json:"opt_null,omitempty"`
-	OptEmpty             *emptypb.Empty          `protobuf:"bytes,30,opt,name=opt_empty,json=optEmpty" json:"opt_empty,omitempty"`
-	OptAny               *anypb.Any              `protobuf:"bytes,32,opt,name=opt_any,json=optAny" json:"opt_any,omitempty"`
-	OptFieldmask         *fieldmaskpb.FieldMask  `protobuf:"bytes,40,opt,name=opt_fieldmask,json=optFieldmask" json:"opt_fieldmask,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptBool       *wrapperspb.BoolValue   `protobuf:"bytes,1,opt,name=opt_bool,json=optBool" json:"opt_bool,omitempty"`
+	OptInt32      *wrapperspb.Int32Value  `protobuf:"bytes,2,opt,name=opt_int32,json=optInt32" json:"opt_int32,omitempty"`
+	OptInt64      *wrapperspb.Int64Value  `protobuf:"bytes,3,opt,name=opt_int64,json=optInt64" json:"opt_int64,omitempty"`
+	OptUint32     *wrapperspb.UInt32Value `protobuf:"bytes,4,opt,name=opt_uint32,json=optUint32" json:"opt_uint32,omitempty"`
+	OptUint64     *wrapperspb.UInt64Value `protobuf:"bytes,5,opt,name=opt_uint64,json=optUint64" json:"opt_uint64,omitempty"`
+	OptFloat      *wrapperspb.FloatValue  `protobuf:"bytes,6,opt,name=opt_float,json=optFloat" json:"opt_float,omitempty"`
+	OptDouble     *wrapperspb.DoubleValue `protobuf:"bytes,7,opt,name=opt_double,json=optDouble" json:"opt_double,omitempty"`
+	OptString     *wrapperspb.StringValue `protobuf:"bytes,8,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	OptBytes      *wrapperspb.BytesValue  `protobuf:"bytes,9,opt,name=opt_bytes,json=optBytes" json:"opt_bytes,omitempty"`
+	OptDuration   *durationpb.Duration    `protobuf:"bytes,20,opt,name=opt_duration,json=optDuration" json:"opt_duration,omitempty"`
+	OptTimestamp  *timestamppb.Timestamp  `protobuf:"bytes,21,opt,name=opt_timestamp,json=optTimestamp" json:"opt_timestamp,omitempty"`
+	OptStruct     *structpb.Struct        `protobuf:"bytes,25,opt,name=opt_struct,json=optStruct" json:"opt_struct,omitempty"`
+	OptList       *structpb.ListValue     `protobuf:"bytes,26,opt,name=opt_list,json=optList" json:"opt_list,omitempty"`
+	OptValue      *structpb.Value         `protobuf:"bytes,27,opt,name=opt_value,json=optValue" json:"opt_value,omitempty"`
+	OptNull       *structpb.NullValue     `protobuf:"varint,28,opt,name=opt_null,json=optNull,enum=google.protobuf.NullValue" json:"opt_null,omitempty"`
+	OptEmpty      *emptypb.Empty          `protobuf:"bytes,30,opt,name=opt_empty,json=optEmpty" json:"opt_empty,omitempty"`
+	OptAny        *anypb.Any              `protobuf:"bytes,32,opt,name=opt_any,json=optAny" json:"opt_any,omitempty"`
+	OptFieldmask  *fieldmaskpb.FieldMask  `protobuf:"bytes,40,opt,name=opt_fieldmask,json=optFieldmask" json:"opt_fieldmask,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *KnownTypes) Reset() {
@@ -1213,12 +1197,11 @@
 }
 
 type Nests_OptGroup struct {
-	OptString            *string                        `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
-	OptNested            *Nested                        `protobuf:"bytes,2,opt,name=opt_nested,json=optNested" json:"opt_nested,omitempty"`
-	Optnestedgroup       *Nests_OptGroup_OptNestedGroup `protobuf:"group,3,opt,name=OptNestedGroup,json=optnestedgroup" json:"optnestedgroup,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                       `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields        `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache            `json:"-"`
+	OptString      *string                        `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	OptNested      *Nested                        `protobuf:"bytes,2,opt,name=opt_nested,json=optNested" json:"opt_nested,omitempty"`
+	Optnestedgroup *Nests_OptGroup_OptNestedGroup `protobuf:"group,3,opt,name=OptNestedGroup,json=optnestedgroup" json:"optnestedgroup,omitempty"`
+	sizeCache      protoimpl.SizeCache
+	unknownFields  protoimpl.UnknownFields
 }
 
 func (x *Nests_OptGroup) Reset() {
@@ -1266,10 +1249,9 @@
 }
 
 type Nests_RptGroup struct {
-	RptString            []string                `protobuf:"bytes,1,rep,name=rpt_string,json=rptString" json:"rpt_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	RptString     []string `protobuf:"bytes,1,rep,name=rpt_string,json=rptString" json:"rpt_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Nests_RptGroup) Reset() {
@@ -1303,10 +1285,9 @@
 }
 
 type Nests_OptGroup_OptNestedGroup struct {
-	OptFixed32           *uint32                 `protobuf:"fixed32,1,opt,name=opt_fixed32,json=optFixed32" json:"opt_fixed32,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	OptFixed32    *uint32 `protobuf:"fixed32,1,opt,name=opt_fixed32,json=optFixed32" json:"opt_fixed32,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Nests_OptGroup_OptNestedGroup) Reset() {
@@ -2059,6 +2040,204 @@
 	if File_pb2_test_proto != nil {
 		return
 	}
+	if !protoimpl.UnsafeEnabled {
+		file_pb2_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Scalars); i {
+			case 15:
+				return &v.sizeCache
+			case 16:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Enums); i {
+			case 4:
+				return &v.sizeCache
+			case 5:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Repeats); i {
+			case 9:
+				return &v.sizeCache
+			case 10:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Nested); i {
+			case 2:
+				return &v.sizeCache
+			case 3:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Nests); i {
+			case 4:
+				return &v.sizeCache
+			case 5:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Requireds); i {
+			case 6:
+				return &v.sizeCache
+			case 7:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PartialRequired); i {
+			case 2:
+				return &v.sizeCache
+			case 3:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*NestedWithRequired); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*IndirectRequired); i {
+			case 4:
+				return &v.sizeCache
+			case 5:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Extensions); i {
+			case 3:
+				return &v.sizeCache
+			case 4:
+				return &v.unknownFields
+			case 5:
+				return &v.extensionFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ExtensionsContainer); i {
+			case 0:
+				return &v.sizeCache
+			case 1:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MessageSet); i {
+			case 0:
+				return &v.sizeCache
+			case 1:
+				return &v.unknownFields
+			case 2:
+				return &v.extensionFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MessageSetExtension); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FakeMessageSet); i {
+			case 0:
+				return &v.sizeCache
+			case 1:
+				return &v.unknownFields
+			case 2:
+				return &v.extensionFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FakeMessageSetExtension); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*KnownTypes); i {
+			case 18:
+				return &v.sizeCache
+			case 19:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Nests_OptGroup); i {
+			case 3:
+				return &v.sizeCache
+			case 4:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Nests_RptGroup); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb2_test_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Nests_OptGroup_OptNestedGroup); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
 	file_pb2_test_proto_msgTypes[8].OneofWrappers = []interface{}{
 		(*IndirectRequired_OneofNested)(nil),
 	}
diff --git a/encoding/testprotos/pb3/test.pb.go b/encoding/testprotos/pb3/test.pb.go
index 26fbe79..50ecdcc 100644
--- a/encoding/testprotos/pb3/test.pb.go
+++ b/encoding/testprotos/pb3/test.pb.go
@@ -112,24 +112,23 @@
 
 // Scalars contains scalar field types.
 type Scalars struct {
-	SBool                bool                    `protobuf:"varint,1,opt,name=s_bool,json=sBool,proto3" json:"s_bool,omitempty"`
-	SInt32               int32                   `protobuf:"varint,2,opt,name=s_int32,json=sInt32,proto3" json:"s_int32,omitempty"`
-	SInt64               int64                   `protobuf:"varint,3,opt,name=s_int64,json=sInt64,proto3" json:"s_int64,omitempty"`
-	SUint32              uint32                  `protobuf:"varint,4,opt,name=s_uint32,json=sUint32,proto3" json:"s_uint32,omitempty"`
-	SUint64              uint64                  `protobuf:"varint,5,opt,name=s_uint64,json=sUint64,proto3" json:"s_uint64,omitempty"`
-	SSint32              int32                   `protobuf:"zigzag32,6,opt,name=s_sint32,json=sSint32,proto3" json:"s_sint32,omitempty"`
-	SSint64              int64                   `protobuf:"zigzag64,7,opt,name=s_sint64,json=sSint64,proto3" json:"s_sint64,omitempty"`
-	SFixed32             uint32                  `protobuf:"fixed32,8,opt,name=s_fixed32,json=sFixed32,proto3" json:"s_fixed32,omitempty"`
-	SFixed64             uint64                  `protobuf:"fixed64,9,opt,name=s_fixed64,json=sFixed64,proto3" json:"s_fixed64,omitempty"`
-	SSfixed32            int32                   `protobuf:"fixed32,10,opt,name=s_sfixed32,json=sSfixed32,proto3" json:"s_sfixed32,omitempty"`
-	SSfixed64            int64                   `protobuf:"fixed64,11,opt,name=s_sfixed64,json=sSfixed64,proto3" json:"s_sfixed64,omitempty"`
-	SFloat               float32                 `protobuf:"fixed32,20,opt,name=s_float,json=sFloat,proto3" json:"s_float,omitempty"`
-	SDouble              float64                 `protobuf:"fixed64,21,opt,name=s_double,json=sDouble,proto3" json:"s_double,omitempty"`
-	SBytes               []byte                  `protobuf:"bytes,14,opt,name=s_bytes,json=sBytes,proto3" json:"s_bytes,omitempty"`
-	SString              string                  `protobuf:"bytes,13,opt,name=s_string,json=sString,proto3" json:"s_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	SBool         bool    `protobuf:"varint,1,opt,name=s_bool,json=sBool,proto3" json:"s_bool,omitempty"`
+	SInt32        int32   `protobuf:"varint,2,opt,name=s_int32,json=sInt32,proto3" json:"s_int32,omitempty"`
+	SInt64        int64   `protobuf:"varint,3,opt,name=s_int64,json=sInt64,proto3" json:"s_int64,omitempty"`
+	SUint32       uint32  `protobuf:"varint,4,opt,name=s_uint32,json=sUint32,proto3" json:"s_uint32,omitempty"`
+	SUint64       uint64  `protobuf:"varint,5,opt,name=s_uint64,json=sUint64,proto3" json:"s_uint64,omitempty"`
+	SSint32       int32   `protobuf:"zigzag32,6,opt,name=s_sint32,json=sSint32,proto3" json:"s_sint32,omitempty"`
+	SSint64       int64   `protobuf:"zigzag64,7,opt,name=s_sint64,json=sSint64,proto3" json:"s_sint64,omitempty"`
+	SFixed32      uint32  `protobuf:"fixed32,8,opt,name=s_fixed32,json=sFixed32,proto3" json:"s_fixed32,omitempty"`
+	SFixed64      uint64  `protobuf:"fixed64,9,opt,name=s_fixed64,json=sFixed64,proto3" json:"s_fixed64,omitempty"`
+	SSfixed32     int32   `protobuf:"fixed32,10,opt,name=s_sfixed32,json=sSfixed32,proto3" json:"s_sfixed32,omitempty"`
+	SSfixed64     int64   `protobuf:"fixed64,11,opt,name=s_sfixed64,json=sSfixed64,proto3" json:"s_sfixed64,omitempty"`
+	SFloat        float32 `protobuf:"fixed32,20,opt,name=s_float,json=sFloat,proto3" json:"s_float,omitempty"`
+	SDouble       float64 `protobuf:"fixed64,21,opt,name=s_double,json=sDouble,proto3" json:"s_double,omitempty"`
+	SBytes        []byte  `protobuf:"bytes,14,opt,name=s_bytes,json=sBytes,proto3" json:"s_bytes,omitempty"`
+	SString       string  `protobuf:"bytes,13,opt,name=s_string,json=sString,proto3" json:"s_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Scalars) Reset() {
@@ -262,11 +261,10 @@
 
 // Message contains enum fields.
 type Enums struct {
-	SEnum                Enum                    `protobuf:"varint,1,opt,name=s_enum,json=sEnum,proto3,enum=pb3.Enum" json:"s_enum,omitempty"`
-	SNestedEnum          Enums_NestedEnum        `protobuf:"varint,3,opt,name=s_nested_enum,json=sNestedEnum,proto3,enum=pb3.Enums_NestedEnum" json:"s_nested_enum,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	SEnum         Enum             `protobuf:"varint,1,opt,name=s_enum,json=sEnum,proto3,enum=pb3.Enum" json:"s_enum,omitempty"`
+	SNestedEnum   Enums_NestedEnum `protobuf:"varint,3,opt,name=s_nested_enum,json=sNestedEnum,proto3,enum=pb3.Enums_NestedEnum" json:"s_nested_enum,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Enums) Reset() {
@@ -308,10 +306,9 @@
 
 // Message contains nested message field.
 type Nests struct {
-	SNested              *Nested                 `protobuf:"bytes,2,opt,name=s_nested,json=sNested,proto3" json:"s_nested,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	SNested       *Nested `protobuf:"bytes,2,opt,name=s_nested,json=sNested,proto3" json:"s_nested,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Nests) Reset() {
@@ -346,11 +343,10 @@
 
 // Message type used as submessage.
 type Nested struct {
-	SString              string                  `protobuf:"bytes,1,opt,name=s_string,json=sString,proto3" json:"s_string,omitempty"`
-	SNested              *Nested                 `protobuf:"bytes,2,opt,name=s_nested,json=sNested,proto3" json:"s_nested,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	SString       string  `protobuf:"bytes,1,opt,name=s_string,json=sString,proto3" json:"s_string,omitempty"`
+	SNested       *Nested `protobuf:"bytes,2,opt,name=s_nested,json=sNested,proto3" json:"s_nested,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Nested) Reset() {
@@ -396,10 +392,9 @@
 	//	*Oneofs_OneofEnum
 	//	*Oneofs_OneofString
 	//	*Oneofs_OneofNested
-	Union                isOneofs_Union          `protobuf_oneof:"union"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	Union         isOneofs_Union `protobuf_oneof:"union"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Oneofs) Reset() {
@@ -477,14 +472,13 @@
 
 // Message contains map fields.
 type Maps struct {
-	Int32ToStr           map[int32]string        `protobuf:"bytes,1,rep,name=int32_to_str,json=int32ToStr,proto3" json:"int32_to_str,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	BoolToUint32         map[bool]uint32         `protobuf:"bytes,2,rep,name=bool_to_uint32,json=boolToUint32,proto3" json:"bool_to_uint32,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
-	Uint64ToEnum         map[uint64]Enum         `protobuf:"bytes,3,rep,name=uint64_to_enum,json=uint64ToEnum,proto3" json:"uint64_to_enum,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3,enum=pb3.Enum"`
-	StrToNested          map[string]*Nested      `protobuf:"bytes,4,rep,name=str_to_nested,json=strToNested,proto3" json:"str_to_nested,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	StrToOneofs          map[string]*Oneofs      `protobuf:"bytes,5,rep,name=str_to_oneofs,json=strToOneofs,proto3" json:"str_to_oneofs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	Int32ToStr    map[int32]string   `protobuf:"bytes,1,rep,name=int32_to_str,json=int32ToStr,proto3" json:"int32_to_str,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	BoolToUint32  map[bool]uint32    `protobuf:"bytes,2,rep,name=bool_to_uint32,json=boolToUint32,proto3" json:"bool_to_uint32,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+	Uint64ToEnum  map[uint64]Enum    `protobuf:"bytes,3,rep,name=uint64_to_enum,json=uint64ToEnum,proto3" json:"uint64_to_enum,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3,enum=pb3.Enum"`
+	StrToNested   map[string]*Nested `protobuf:"bytes,4,rep,name=str_to_nested,json=strToNested,proto3" json:"str_to_nested,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	StrToOneofs   map[string]*Oneofs `protobuf:"bytes,5,rep,name=str_to_oneofs,json=strToOneofs,proto3" json:"str_to_oneofs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *Maps) Reset() {
@@ -547,10 +541,9 @@
 
 // Message for testing json_name option.
 type JSONNames struct {
-	SString              string                  `protobuf:"bytes,1,opt,name=s_string,json=foo_bar,proto3" json:"s_string,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
-	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
-	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
+	SString       string `protobuf:"bytes,1,opt,name=s_string,json=foo_bar,proto3" json:"s_string,omitempty"`
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
 func (x *JSONNames) Reset() {
@@ -752,6 +745,78 @@
 	if File_pb3_test_proto != nil {
 		return
 	}
+	if !protoimpl.UnsafeEnabled {
+		file_pb3_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Scalars); i {
+			case 15:
+				return &v.sizeCache
+			case 16:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb3_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Enums); i {
+			case 2:
+				return &v.sizeCache
+			case 3:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb3_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Nests); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb3_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Nested); i {
+			case 2:
+				return &v.sizeCache
+			case 3:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb3_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Oneofs); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb3_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Maps); i {
+			case 5:
+				return &v.sizeCache
+			case 6:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb3_test_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*JSONNames); i {
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
 	file_pb3_test_proto_msgTypes[4].OneofWrappers = []interface{}{
 		(*Oneofs_OneofEnum)(nil),
 		(*Oneofs_OneofString)(nil),