internal/impl: add MessageState to every generated message

We define MessageState, which is essentially an atomically set *MessageInfo.
By nesting this as the first field in every generated message, we can
implement the reflective methods on a *MessageState when obtained by
unsafe casting a concrete message pointer as a *MessageState.
The MessageInfo held by MessageState provides additional Go type information
to interpret the memory that comes after the contents of the MessageState.

Since we are nesting a MessageState in every message,
the memory use of every message instance grows by 8B.

On average, the body of ProtoReflect grows from 133B to 202B (+50%).
However, this is offset by XXX_Methods, which is 108B and
will be removed in a future CL. Taking into account the eventual removal
of XXX_Methods, this is a net reduction of 25%.

name          old time/op    new time/op    delta
Name/Value-4    70.3ns ± 2%    17.5ns ± 6%   -75.08%  (p=0.000 n=10+10)
Name/Nil-4      70.6ns ± 3%    33.4ns ± 2%   -52.66%  (p=0.000 n=10+10)

name          old alloc/op   new alloc/op   delta
Name/Value-4     16.0B ± 0%      0.0B       -100.00%  (p=0.000 n=10+10)
Name/Nil-4       16.0B ± 0%      0.0B       -100.00%  (p=0.000 n=10+10)

name          old allocs/op  new allocs/op  delta
Name/Value-4      1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)
Name/Nil-4        1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)

Change-Id: I92bd58dc681c57c92612fd5ba7fc066aea34e95a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185460
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go
index 219d79a..67f3071 100644
--- a/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/cmd/protoc-gen-go/internal_gengo/main.go
@@ -48,10 +48,14 @@
 	// ExtensionRangeArray method for messages that support extensions.
 	generateExtensionRangeMethods = true
 
-	// generateWKTMarkerMethods specifes whether to generate
+	// generateWKTMarkerMethods specifies whether to generate
 	// XXX_WellKnownType methods on well-known types.
 	generateWKTMarkerMethods = false
 
+	// generateMessateStateFields specifies whether to generate an unexported
+	// protoimpl.MessageState as the first field.
+	generateMessateStateFields = true
+
 	// generateNoUnkeyedLiteralFields specifies whether to generate
 	// the XXX_NoUnkeyedLiteral field.
 	generateNoUnkeyedLiteralFields = false
@@ -395,6 +399,10 @@
 	g.Annotate(message.GoIdent.GoName, message.Location)
 	g.P("type ", message.GoIdent, " struct {")
 	sf := f.allMessageFieldsByPtr[message]
+	if generateMessateStateFields {
+		g.P("state ", protoimplPackage.Ident("MessageState"))
+		sf.append("state")
+	}
 	for _, field := range message.Fields {
 		if field.Oneof != nil {
 			// It would be a bit simpler to iterate over the oneofs below,
diff --git a/cmd/protoc-gen-go/internal_gengo/reflect.go b/cmd/protoc-gen-go/internal_gengo/reflect.go
index b7c5261..43099b2 100644
--- a/cmd/protoc-gen-go/internal_gengo/reflect.go
+++ b/cmd/protoc-gen-go/internal_gengo/reflect.go
@@ -293,12 +293,25 @@
 
 	// ProtoReflect method.
 	g.P("func (x *", message.GoIdent, ") ProtoReflect() ", protoreflectPackage.Ident("Message"), " {")
-	g.P("return ", typesVar, "[", idx, "].MessageOf(x)")
+	g.P("mi := &", typesVar, "[", idx, "]")
+	if generateMessateStateFields {
+		g.P("if ", protoimplPackage.Ident("UnsafeEnabled"), " && x != nil {")
+		g.P("ms := ", protoimplPackage.Ident("X"), ".MessageStateOf(", protoimplPackage.Ident("Pointer"), "(x))")
+		g.P("if ms.LoadMessageInfo() == nil {")
+		g.P("ms.StoreMessageInfo(mi)")
+		g.P("}")
+		g.P("return ms")
+		g.P("}")
+	}
+	g.P("return mi.MessageOf(x)")
 	g.P("}")
 	g.P()
-	g.P("func (m *", message.GoIdent, ") XXX_Methods() *", protoifacePackage.Ident("Methods"), " {")
+
+	// XXX_Methods method.
+	g.P("func (x *", message.GoIdent, ") XXX_Methods() *", protoifacePackage.Ident("Methods"), " {")
 	g.P("return ", typesVar, "[", idx, "].Methods()")
 	g.P("}")
+	g.P()
 }
 
 func fileVarName(f *protogen.File, suffix string) string {
diff --git a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
index da6e752..895886f 100644
--- a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
+++ b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
@@ -66,6 +66,7 @@
 }
 
 type AnnotationsTestMessage struct {
+	state                protoimpl.MessageState
 	AnnotationsTestField *string `protobuf:"bytes,1,opt,name=AnnotationsTestField" json:"AnnotationsTestField,omitempty"`
 	sizeCache            protoimpl.SizeCache
 	unknownFields        protoimpl.UnknownFields
@@ -82,10 +83,18 @@
 func (*AnnotationsTestMessage) ProtoMessage() {}
 
 func (x *AnnotationsTestMessage) ProtoReflect() protoreflect.Message {
-	return file_annotations_annotations_proto_msgTypes[0].MessageOf(x)
+	mi := &file_annotations_annotations_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *AnnotationsTestMessage) XXX_Methods() *protoiface.Methods {
+func (x *AnnotationsTestMessage) XXX_Methods() *protoiface.Methods {
 	return file_annotations_annotations_proto_msgTypes[0].Methods()
 }
 
@@ -157,9 +166,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_annotations_annotations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AnnotationsTestMessage); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go.meta b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go.meta
index 6450f14..4debc0d 100644
--- a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go.meta
+++ b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go.meta
@@ -1 +1 @@
-annotation:{path:5 path:0 source_file:"annotations/annotations.proto" begin:631 end:650} annotation:{path:5 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:667 end:714} annotation:{path:4 path:0 source_file:"annotations/annotations.proto" begin:1821 end:1843} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:1854 end:1874} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:2796 end:2819}
\ No newline at end of file
+annotation:{path:5 path:0 source_file:"annotations/annotations.proto" begin:631 end:650} annotation:{path:5 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:667 end:714} annotation:{path:4 path:0 source_file:"annotations/annotations.proto" begin:1821 end:1843} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:1899 end:1919} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:3032 end:3055}
\ No newline at end of file
diff --git a/cmd/protoc-gen-go/testdata/comments/comments.pb.go b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
index ae1e989..b01afe9 100644
--- a/cmd/protoc-gen-go/testdata/comments/comments.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
@@ -21,6 +21,7 @@
 
 // COMMENT: Message1
 type Message1 struct {
+	state protoimpl.MessageState
 	// COMMENT: Field1A
 	Field1A *string `protobuf:"bytes,1,opt,name=Field1A" json:"Field1A,omitempty"`
 	// COMMENT: Oneof1A
@@ -44,10 +45,18 @@
 func (*Message1) ProtoMessage() {}
 
 func (x *Message1) ProtoReflect() protoreflect.Message {
-	return file_comments_comments_proto_msgTypes[0].MessageOf(x)
+	mi := &file_comments_comments_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message1) XXX_Methods() *protoiface.Methods {
+func (x *Message1) XXX_Methods() *protoiface.Methods {
 	return file_comments_comments_proto_msgTypes[0].Methods()
 }
 
@@ -89,6 +98,7 @@
 
 // COMMENT: Message2
 type Message2 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -104,10 +114,18 @@
 func (*Message2) ProtoMessage() {}
 
 func (x *Message2) ProtoReflect() protoreflect.Message {
-	return file_comments_comments_proto_msgTypes[1].MessageOf(x)
+	mi := &file_comments_comments_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message2) XXX_Methods() *protoiface.Methods {
+func (x *Message2) XXX_Methods() *protoiface.Methods {
 	return file_comments_comments_proto_msgTypes[1].Methods()
 }
 
@@ -118,6 +136,7 @@
 
 // COMMENT: Message1A
 type Message1_Message1A struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -133,10 +152,18 @@
 func (*Message1_Message1A) ProtoMessage() {}
 
 func (x *Message1_Message1A) ProtoReflect() protoreflect.Message {
-	return file_comments_comments_proto_msgTypes[2].MessageOf(x)
+	mi := &file_comments_comments_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message1_Message1A) XXX_Methods() *protoiface.Methods {
+func (x *Message1_Message1A) XXX_Methods() *protoiface.Methods {
 	return file_comments_comments_proto_msgTypes[2].Methods()
 }
 
@@ -147,6 +174,7 @@
 
 // COMMENT: Message1B
 type Message1_Message1B struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -162,10 +190,18 @@
 func (*Message1_Message1B) ProtoMessage() {}
 
 func (x *Message1_Message1B) ProtoReflect() protoreflect.Message {
-	return file_comments_comments_proto_msgTypes[3].MessageOf(x)
+	mi := &file_comments_comments_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message1_Message1B) XXX_Methods() *protoiface.Methods {
+func (x *Message1_Message1B) XXX_Methods() *protoiface.Methods {
 	return file_comments_comments_proto_msgTypes[3].Methods()
 }
 
@@ -176,6 +212,7 @@
 
 // COMMENT: Message2A
 type Message2_Message2A struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -191,10 +228,18 @@
 func (*Message2_Message2A) ProtoMessage() {}
 
 func (x *Message2_Message2A) ProtoReflect() protoreflect.Message {
-	return file_comments_comments_proto_msgTypes[4].MessageOf(x)
+	mi := &file_comments_comments_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message2_Message2A) XXX_Methods() *protoiface.Methods {
+func (x *Message2_Message2A) XXX_Methods() *protoiface.Methods {
 	return file_comments_comments_proto_msgTypes[4].Methods()
 }
 
@@ -205,6 +250,7 @@
 
 // COMMENT: Message2B
 type Message2_Message2B struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -220,10 +266,18 @@
 func (*Message2_Message2B) ProtoMessage() {}
 
 func (x *Message2_Message2B) ProtoReflect() protoreflect.Message {
-	return file_comments_comments_proto_msgTypes[5].MessageOf(x)
+	mi := &file_comments_comments_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message2_Message2B) XXX_Methods() *protoiface.Methods {
+func (x *Message2_Message2B) XXX_Methods() *protoiface.Methods {
 	return file_comments_comments_proto_msgTypes[5].Methods()
 }
 
@@ -291,9 +345,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_comments_comments_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message1); i {
-			case 2:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 3:
+				return &v.sizeCache
+			case 4:
 				return &v.unknownFields
 			default:
 				return nil
@@ -302,8 +358,10 @@
 		file_comments_comments_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message2); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -312,8 +370,10 @@
 		file_comments_comments_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message1_Message1A); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -322,8 +382,10 @@
 		file_comments_comments_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message1_Message1B); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -332,8 +394,10 @@
 		file_comments_comments_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message2_Message2A); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -342,8 +406,10 @@
 		file_comments_comments_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message2_Message2B); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go b/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
index b0d7ce9..0cb5754 100644
--- a/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
@@ -56,6 +56,7 @@
 
 // Deprecated: Do not use.
 type DeprecatedMessage struct {
+	state           protoimpl.MessageState
 	DeprecatedField string `protobuf:"bytes,1,opt,name=deprecated_field,json=deprecatedField,proto3" json:"deprecated_field,omitempty"` // Deprecated: Do not use.
 	sizeCache       protoimpl.SizeCache
 	unknownFields   protoimpl.UnknownFields
@@ -72,10 +73,18 @@
 func (*DeprecatedMessage) ProtoMessage() {}
 
 func (x *DeprecatedMessage) ProtoReflect() protoreflect.Message {
-	return file_comments_deprecated_proto_msgTypes[0].MessageOf(x)
+	mi := &file_comments_deprecated_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *DeprecatedMessage) XXX_Methods() *protoiface.Methods {
+func (x *DeprecatedMessage) XXX_Methods() *protoiface.Methods {
 	return file_comments_deprecated_proto_msgTypes[0].Methods()
 }
 
@@ -147,9 +156,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_comments_deprecated_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeprecatedMessage); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go b/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
index dde0588..dc14c4c 100644
--- a/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
@@ -18,6 +18,7 @@
 )
 
 type BaseMessage struct {
+	state           protoimpl.MessageState
 	Field           *string `protobuf:"bytes,1,opt,name=field" json:"field,omitempty"`
 	sizeCache       protoimpl.SizeCache
 	unknownFields   protoimpl.UnknownFields
@@ -35,10 +36,18 @@
 func (*BaseMessage) ProtoMessage() {}
 
 func (x *BaseMessage) ProtoReflect() protoreflect.Message {
-	return file_extensions_base_base_proto_msgTypes[0].MessageOf(x)
+	mi := &file_extensions_base_base_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *BaseMessage) XXX_Methods() *protoiface.Methods {
+func (x *BaseMessage) XXX_Methods() *protoiface.Methods {
 	return file_extensions_base_base_proto_msgTypes[0].Methods()
 }
 
@@ -65,6 +74,7 @@
 }
 
 type MessageSetWireFormatMessage struct {
+	state           protoimpl.MessageState
 	sizeCache       protoimpl.SizeCache
 	unknownFields   protoimpl.UnknownFields
 	extensionFields protoimpl.ExtensionFields
@@ -81,10 +91,18 @@
 func (*MessageSetWireFormatMessage) ProtoMessage() {}
 
 func (x *MessageSetWireFormatMessage) ProtoReflect() protoreflect.Message {
-	return file_extensions_base_base_proto_msgTypes[1].MessageOf(x)
+	mi := &file_extensions_base_base_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *MessageSetWireFormatMessage) XXX_Methods() *protoiface.Methods {
+func (x *MessageSetWireFormatMessage) XXX_Methods() *protoiface.Methods {
 	return file_extensions_base_base_proto_msgTypes[1].Methods()
 }
 
@@ -155,11 +173,13 @@
 	if !protoimpl.UnsafeEnabled {
 		file_extensions_base_base_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*BaseMessage); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
-				return &v.unknownFields
+				return &v.sizeCache
 			case 3:
+				return &v.unknownFields
+			case 4:
 				return &v.extensionFields
 			default:
 				return nil
@@ -168,10 +188,12 @@
 		file_extensions_base_base_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*MessageSetWireFormatMessage); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
-				return &v.unknownFields
+				return &v.sizeCache
 			case 2:
+				return &v.unknownFields
+			case 3:
 				return &v.extensionFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
index b989089..9a6167d 100644
--- a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
@@ -68,6 +68,7 @@
 }
 
 type Message struct {
+	state         protoimpl.MessageState
 	Data          []byte `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -84,10 +85,18 @@
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[0].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message) XXX_Methods() *protoiface.Methods {
+func (x *Message) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[0].Methods()
 }
 
@@ -104,6 +113,7 @@
 }
 
 type ExtensionGroup struct {
+	state          protoimpl.MessageState
 	ExtensionGroup *string `protobuf:"bytes,120,opt,name=extension_group,json=extensionGroup" json:"extension_group,omitempty"`
 	sizeCache      protoimpl.SizeCache
 	unknownFields  protoimpl.UnknownFields
@@ -120,10 +130,18 @@
 func (*ExtensionGroup) ProtoMessage() {}
 
 func (x *ExtensionGroup) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[1].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *ExtensionGroup) XXX_Methods() *protoiface.Methods {
+func (x *ExtensionGroup) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[1].Methods()
 }
 
@@ -141,6 +159,7 @@
 
 // Extend in the scope of another type.
 type ExtendingMessage struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -156,10 +175,18 @@
 func (*ExtendingMessage) ProtoMessage() {}
 
 func (x *ExtendingMessage) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[2].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *ExtendingMessage) XXX_Methods() *protoiface.Methods {
+func (x *ExtendingMessage) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[2].Methods()
 }
 
@@ -169,6 +196,7 @@
 }
 
 type RepeatedGroup struct {
+	state          protoimpl.MessageState
 	RepeatedXGroup []string `protobuf:"bytes,319,rep,name=repeated_x_group,json=repeatedXGroup" json:"repeated_x_group,omitempty"`
 	sizeCache      protoimpl.SizeCache
 	unknownFields  protoimpl.UnknownFields
@@ -185,10 +213,18 @@
 func (*RepeatedGroup) ProtoMessage() {}
 
 func (x *RepeatedGroup) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[3].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *RepeatedGroup) XXX_Methods() *protoiface.Methods {
+func (x *RepeatedGroup) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[3].Methods()
 }
 
@@ -206,6 +242,7 @@
 
 // An extension of an extension.
 type Extendable struct {
+	state           protoimpl.MessageState
 	sizeCache       protoimpl.SizeCache
 	unknownFields   protoimpl.UnknownFields
 	extensionFields protoimpl.ExtensionFields
@@ -222,10 +259,18 @@
 func (*Extendable) ProtoMessage() {}
 
 func (x *Extendable) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[4].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Extendable) XXX_Methods() *protoiface.Methods {
+func (x *Extendable) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[4].Methods()
 }
 
@@ -245,6 +290,7 @@
 
 // Message set wire format.
 type MessageSetWireFormatExtension struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -260,10 +306,18 @@
 func (*MessageSetWireFormatExtension) ProtoMessage() {}
 
 func (x *MessageSetWireFormatExtension) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[5].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *MessageSetWireFormatExtension) XXX_Methods() *protoiface.Methods {
+func (x *MessageSetWireFormatExtension) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[5].Methods()
 }
 
@@ -273,6 +327,7 @@
 }
 
 type Message_M struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -288,10 +343,18 @@
 func (*Message_M) ProtoMessage() {}
 
 func (x *Message_M) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[6].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message_M) XXX_Methods() *protoiface.Methods {
+func (x *Message_M) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[6].Methods()
 }
 
@@ -301,6 +364,7 @@
 }
 
 type ExtendingMessage_ExtendingMessageSubmessage struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -316,10 +380,18 @@
 func (*ExtendingMessage_ExtendingMessageSubmessage) ProtoMessage() {}
 
 func (x *ExtendingMessage_ExtendingMessageSubmessage) ProtoReflect() protoreflect.Message {
-	return file_extensions_ext_ext_proto_msgTypes[7].MessageOf(x)
+	mi := &file_extensions_ext_ext_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *ExtendingMessage_ExtendingMessageSubmessage) XXX_Methods() *protoiface.Methods {
+func (x *ExtendingMessage_ExtendingMessageSubmessage) XXX_Methods() *protoiface.Methods {
 	return file_extensions_ext_ext_proto_msgTypes[7].Methods()
 }
 
@@ -1233,9 +1305,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_extensions_ext_ext_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1243,9 +1317,11 @@
 		}
 		file_extensions_ext_ext_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ExtensionGroup); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1254,8 +1330,10 @@
 		file_extensions_ext_ext_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ExtendingMessage); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1263,9 +1341,11 @@
 		}
 		file_extensions_ext_ext_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RepeatedGroup); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1274,10 +1354,12 @@
 		file_extensions_ext_ext_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Extendable); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
-				return &v.unknownFields
+				return &v.sizeCache
 			case 2:
+				return &v.unknownFields
+			case 3:
 				return &v.extensionFields
 			default:
 				return nil
@@ -1286,8 +1368,10 @@
 		file_extensions_ext_ext_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*MessageSetWireFormatExtension); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1296,8 +1380,10 @@
 		file_extensions_ext_ext_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message_M); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1306,8 +1392,10 @@
 		file_extensions_ext_ext_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ExtendingMessage_ExtendingMessageSubmessage); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go b/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
index 639b0ab..04468fb 100644
--- a/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
@@ -18,6 +18,7 @@
 )
 
 type ExtraMessage struct {
+	state         protoimpl.MessageState
 	Data          []byte `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -34,10 +35,18 @@
 func (*ExtraMessage) ProtoMessage() {}
 
 func (x *ExtraMessage) ProtoReflect() protoreflect.Message {
-	return file_extensions_extra_extra_proto_msgTypes[0].MessageOf(x)
+	mi := &file_extensions_extra_extra_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *ExtraMessage) XXX_Methods() *protoiface.Methods {
+func (x *ExtraMessage) XXX_Methods() *protoiface.Methods {
 	return file_extensions_extra_extra_proto_msgTypes[0].Methods()
 }
 
@@ -101,9 +110,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_extensions_extra_extra_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ExtraMessage); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
index d8ec9d7..df5e65b 100644
--- a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
@@ -57,6 +57,7 @@
 }
 
 type Message struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -72,10 +73,18 @@
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	return file_extensions_proto3_ext3_proto_msgTypes[0].MessageOf(x)
+	mi := &file_extensions_proto3_ext3_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message) XXX_Methods() *protoiface.Methods {
+func (x *Message) XXX_Methods() *protoiface.Methods {
 	return file_extensions_proto3_ext3_proto_msgTypes[0].Methods()
 }
 
@@ -745,8 +754,10 @@
 		file_extensions_proto3_ext3_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
index 1aa62b7..52fc8f5 100644
--- a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
+++ b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
@@ -23,6 +23,7 @@
 // This exists to demonstrate the current behavior and catch unintended
 // changes in it.
 type Message struct {
+	state protoimpl.MessageState
 	// Various CamelCase conversions.
 	FieldOne   *string `protobuf:"bytes,1,opt,name=field_one,json=fieldOne" json:"field_one,omitempty"`
 	FieldTwo   *string `protobuf:"bytes,2,opt,name=FieldTwo" json:"FieldTwo,omitempty"`
@@ -72,10 +73,18 @@
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	return file_fieldnames_fieldnames_proto_msgTypes[0].MessageOf(x)
+	mi := &file_fieldnames_fieldnames_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message) XXX_Methods() *protoiface.Methods {
+func (x *Message) XXX_Methods() *protoiface.Methods {
 	return file_fieldnames_fieldnames_proto_msgTypes[0].Methods()
 }
 
@@ -268,6 +277,7 @@
 func (*Message_OneofMessageConflict_) isMessage_OneofConflictC() {}
 
 type Message_OneofMessageConflict struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -283,10 +293,18 @@
 func (*Message_OneofMessageConflict) ProtoMessage() {}
 
 func (x *Message_OneofMessageConflict) ProtoReflect() protoreflect.Message {
-	return file_fieldnames_fieldnames_proto_msgTypes[1].MessageOf(x)
+	mi := &file_fieldnames_fieldnames_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message_OneofMessageConflict) XXX_Methods() *protoiface.Methods {
+func (x *Message_OneofMessageConflict) XXX_Methods() *protoiface.Methods {
 	return file_fieldnames_fieldnames_proto_msgTypes[1].Methods()
 }
 
@@ -385,9 +403,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_fieldnames_fieldnames_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message); i {
-			case 17:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 18:
+				return &v.sizeCache
+			case 19:
 				return &v.unknownFields
 			default:
 				return nil
@@ -396,8 +416,10 @@
 		file_fieldnames_fieldnames_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message_OneofMessageConflict); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
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 89e81e4..28f50ba 100644
--- a/cmd/protoc-gen-go/testdata/import_public/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/a.pb.go
@@ -57,6 +57,7 @@
 var E_ExtensionField = sub.E_ExtensionField
 
 type Public struct {
+	state         protoimpl.MessageState
 	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"`
@@ -75,10 +76,18 @@
 func (*Public) ProtoMessage() {}
 
 func (x *Public) ProtoReflect() protoreflect.Message {
-	return file_import_public_a_proto_msgTypes[0].MessageOf(x)
+	mi := &file_import_public_a_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Public) XXX_Methods() *protoiface.Methods {
+func (x *Public) XXX_Methods() *protoiface.Methods {
 	return file_import_public_a_proto_msgTypes[0].Methods()
 }
 
@@ -174,9 +183,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_import_public_a_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Public); i {
-			case 3:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 4:
+				return &v.sizeCache
+			case 5:
 				return &v.unknownFields
 			default:
 				return nil
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 1cc48ea..2b26113 100644
--- a/cmd/protoc-gen-go/testdata/import_public/b.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/b.pb.go
@@ -19,6 +19,7 @@
 )
 
 type Local struct {
+	state         protoimpl.MessageState
 	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"`
 	sizeCache     protoimpl.SizeCache
@@ -36,10 +37,18 @@
 func (*Local) ProtoMessage() {}
 
 func (x *Local) ProtoReflect() protoreflect.Message {
-	return file_import_public_b_proto_msgTypes[0].MessageOf(x)
+	mi := &file_import_public_b_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Local) XXX_Methods() *protoiface.Methods {
+func (x *Local) XXX_Methods() *protoiface.Methods {
 	return file_import_public_b_proto_msgTypes[0].Methods()
 }
 
@@ -120,9 +129,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_import_public_b_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Local); i {
-			case 2:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 3:
+				return &v.sizeCache
+			case 4:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/import_public/c.pb.go b/cmd/protoc-gen-go/testdata/import_public/c.pb.go
index f863ac5..5c2b346 100644
--- a/cmd/protoc-gen-go/testdata/import_public/c.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/c.pb.go
@@ -19,6 +19,7 @@
 )
 
 type UsingPublicImport struct {
+	state protoimpl.MessageState
 	// Local is declared in b.proto, which is a public import of a.proto.
 	Local *Local `protobuf:"bytes,1,opt,name=local" json:"local,omitempty"`
 	// Sub2Message is declared in sub2/a.proto, which is a public import of
@@ -39,10 +40,18 @@
 func (*UsingPublicImport) ProtoMessage() {}
 
 func (x *UsingPublicImport) ProtoReflect() protoreflect.Message {
-	return file_import_public_c_proto_msgTypes[0].MessageOf(x)
+	mi := &file_import_public_c_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *UsingPublicImport) XXX_Methods() *protoiface.Methods {
+func (x *UsingPublicImport) XXX_Methods() *protoiface.Methods {
 	return file_import_public_c_proto_msgTypes[0].Methods()
 }
 
@@ -126,9 +135,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_import_public_c_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UsingPublicImport); i {
-			case 2:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 3:
+				return &v.sizeCache
+			case 4:
 				return &v.unknownFields
 			default:
 				return nil
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 f4e3a63..49bc41e 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
@@ -166,6 +166,7 @@
 }
 
 type M struct {
+	state protoimpl.MessageState
 	// Field using a type in the same Go package, but a different source file.
 	M2 *M2      `protobuf:"bytes,1,opt,name=m2" json:"m2,omitempty"`
 	S  *string  `protobuf:"bytes,4,opt,name=s,def=default" json:"s,omitempty"`
@@ -191,10 +192,18 @@
 func (*M) ProtoMessage() {}
 
 func (x *M) ProtoReflect() protoreflect.Message {
-	return file_import_public_sub_a_proto_msgTypes[0].MessageOf(x)
+	mi := &file_import_public_sub_a_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M) XXX_Methods() *protoiface.Methods {
+func (x *M) XXX_Methods() *protoiface.Methods {
 	return file_import_public_sub_a_proto_msgTypes[0].Methods()
 }
 
@@ -283,6 +292,7 @@
 func (*M_OneofInt64) isM_OneofField() {}
 
 type M_Submessage struct {
+	state protoimpl.MessageState
 	// Types that are valid to be assigned to SubmessageOneofField:
 	//	*M_Submessage_SubmessageOneofInt32
 	//	*M_Submessage_SubmessageOneofInt64
@@ -302,10 +312,18 @@
 func (*M_Submessage) ProtoMessage() {}
 
 func (x *M_Submessage) ProtoReflect() protoreflect.Message {
-	return file_import_public_sub_a_proto_msgTypes[1].MessageOf(x)
+	mi := &file_import_public_sub_a_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M_Submessage) XXX_Methods() *protoiface.Methods {
+func (x *M_Submessage) XXX_Methods() *protoiface.Methods {
 	return file_import_public_sub_a_proto_msgTypes[1].Methods()
 }
 
@@ -457,11 +475,13 @@
 	if !protoimpl.UnsafeEnabled {
 		file_import_public_sub_a_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M); i {
-			case 5:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 6:
-				return &v.unknownFields
+				return &v.sizeCache
 			case 7:
+				return &v.unknownFields
+			case 8:
 				return &v.extensionFields
 			default:
 				return nil
@@ -469,9 +489,11 @@
 		}
 		file_import_public_sub_a_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M_Submessage); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
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 33c51fe..32d6473 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
@@ -18,6 +18,7 @@
 )
 
 type M2 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*M2) ProtoMessage() {}
 
 func (x *M2) ProtoReflect() protoreflect.Message {
-	return file_import_public_sub_b_proto_msgTypes[0].MessageOf(x)
+	mi := &file_import_public_sub_b_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M2) XXX_Methods() *protoiface.Methods {
+func (x *M2) XXX_Methods() *protoiface.Methods {
 	return file_import_public_sub_b_proto_msgTypes[0].Methods()
 }
 
@@ -92,8 +101,10 @@
 		file_import_public_sub_b_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M2); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub2/a.pb.go b/cmd/protoc-gen-go/testdata/import_public/sub2/a.pb.go
index d5f6c72..ef605ea 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub2/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/sub2/a.pb.go
@@ -18,6 +18,7 @@
 )
 
 type Sub2Message struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*Sub2Message) ProtoMessage() {}
 
 func (x *Sub2Message) ProtoReflect() protoreflect.Message {
-	return file_import_public_sub2_a_proto_msgTypes[0].MessageOf(x)
+	mi := &file_import_public_sub2_a_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Sub2Message) XXX_Methods() *protoiface.Methods {
+func (x *Sub2Message) XXX_Methods() *protoiface.Methods {
 	return file_import_public_sub2_a_proto_msgTypes[0].Methods()
 }
 
@@ -93,8 +102,10 @@
 		file_import_public_sub2_a_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Sub2Message); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go b/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
index 9acc5d0..dc7568b 100644
--- a/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
@@ -18,6 +18,7 @@
 )
 
 type M struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*M) ProtoMessage() {}
 
 func (x *M) ProtoReflect() protoreflect.Message {
-	return file_imports_fmt_m_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_fmt_m_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M) XXX_Methods() *protoiface.Methods {
+func (x *M) XXX_Methods() *protoiface.Methods {
 	return file_imports_fmt_m_proto_msgTypes[0].Methods()
 }
 
@@ -90,8 +99,10 @@
 		file_imports_fmt_m_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
index 20dbd48..52d5391 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
@@ -56,6 +56,7 @@
 }
 
 type M1 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -71,10 +72,18 @@
 func (*M1) ProtoMessage() {}
 
 func (x *M1) ProtoReflect() protoreflect.Message {
-	return file_imports_test_a_1_m1_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_a_1_m1_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M1) XXX_Methods() *protoiface.Methods {
+func (x *M1) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_a_1_m1_proto_msgTypes[0].Methods()
 }
 
@@ -84,6 +93,7 @@
 }
 
 type M1_1 struct {
+	state         protoimpl.MessageState
 	M1            *M1 `protobuf:"bytes,1,opt,name=m1,proto3" json:"m1,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -100,10 +110,18 @@
 func (*M1_1) ProtoMessage() {}
 
 func (x *M1_1) ProtoReflect() protoreflect.Message {
-	return file_imports_test_a_1_m1_proto_msgTypes[1].MessageOf(x)
+	mi := &file_imports_test_a_1_m1_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M1_1) XXX_Methods() *protoiface.Methods {
+func (x *M1_1) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_a_1_m1_proto_msgTypes[1].Methods()
 }
 
@@ -173,8 +191,10 @@
 		file_imports_test_a_1_m1_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M1); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
@@ -182,9 +202,11 @@
 		}
 		file_imports_test_a_1_m1_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M1_1); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
index ed81393..0433505 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
@@ -18,6 +18,7 @@
 )
 
 type M2 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*M2) ProtoMessage() {}
 
 func (x *M2) ProtoReflect() protoreflect.Message {
-	return file_imports_test_a_1_m2_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_a_1_m2_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M2) XXX_Methods() *protoiface.Methods {
+func (x *M2) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_a_1_m2_proto_msgTypes[0].Methods()
 }
 
@@ -91,8 +100,10 @@
 		file_imports_test_a_1_m2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M2); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
index 2365425..6121ed4 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
@@ -18,6 +18,7 @@
 )
 
 type M3 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*M3) ProtoMessage() {}
 
 func (x *M3) ProtoReflect() protoreflect.Message {
-	return file_imports_test_a_2_m3_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_a_2_m3_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M3) XXX_Methods() *protoiface.Methods {
+func (x *M3) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_a_2_m3_proto_msgTypes[0].Methods()
 }
 
@@ -91,8 +100,10 @@
 		file_imports_test_a_2_m3_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M3); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
index 356427b..eda832a 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
@@ -18,6 +18,7 @@
 )
 
 type M4 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*M4) ProtoMessage() {}
 
 func (x *M4) ProtoReflect() protoreflect.Message {
-	return file_imports_test_a_2_m4_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_a_2_m4_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M4) XXX_Methods() *protoiface.Methods {
+func (x *M4) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_a_2_m4_proto_msgTypes[0].Methods()
 }
 
@@ -91,8 +100,10 @@
 		file_imports_test_a_2_m4_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M4); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
index f8485df..3a4677e 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
@@ -18,6 +18,7 @@
 )
 
 type M1 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*M1) ProtoMessage() {}
 
 func (x *M1) ProtoReflect() protoreflect.Message {
-	return file_imports_test_b_1_m1_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_b_1_m1_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M1) XXX_Methods() *protoiface.Methods {
+func (x *M1) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_b_1_m1_proto_msgTypes[0].Methods()
 }
 
@@ -92,8 +101,10 @@
 		file_imports_test_b_1_m1_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M1); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
index 0c4a73c..c2558c9 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
@@ -18,6 +18,7 @@
 )
 
 type M2 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -33,10 +34,18 @@
 func (*M2) ProtoMessage() {}
 
 func (x *M2) ProtoReflect() protoreflect.Message {
-	return file_imports_test_b_1_m2_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_b_1_m2_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *M2) XXX_Methods() *protoiface.Methods {
+func (x *M2) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_b_1_m2_proto_msgTypes[0].Methods()
 }
 
@@ -92,8 +101,10 @@
 		file_imports_test_b_1_m2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*M2); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
index 8d790d3..c310d52 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
@@ -19,6 +19,7 @@
 )
 
 type A1M1 struct {
+	state         protoimpl.MessageState
 	F             *test_a_1.M1 `protobuf:"bytes,1,opt,name=f,proto3" json:"f,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -35,10 +36,18 @@
 func (*A1M1) ProtoMessage() {}
 
 func (x *A1M1) ProtoReflect() protoreflect.Message {
-	return file_imports_test_import_a1m1_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_import_a1m1_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *A1M1) XXX_Methods() *protoiface.Methods {
+func (x *A1M1) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_import_a1m1_proto_msgTypes[0].Methods()
 }
 
@@ -104,9 +113,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_imports_test_import_a1m1_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*A1M1); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
index 0483904..c07111b 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
@@ -19,6 +19,7 @@
 )
 
 type A1M2 struct {
+	state         protoimpl.MessageState
 	F             *test_a_1.M2 `protobuf:"bytes,1,opt,name=f,proto3" json:"f,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -35,10 +36,18 @@
 func (*A1M2) ProtoMessage() {}
 
 func (x *A1M2) ProtoReflect() protoreflect.Message {
-	return file_imports_test_import_a1m2_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_import_a1m2_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *A1M2) XXX_Methods() *protoiface.Methods {
+func (x *A1M2) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_import_a1m2_proto_msgTypes[0].Methods()
 }
 
@@ -104,9 +113,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_imports_test_import_a1m2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*A1M2); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
index 0475375..a872359 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
@@ -22,6 +22,7 @@
 )
 
 type All struct {
+	state         protoimpl.MessageState
 	Am1           *test_a_1.M1 `protobuf:"bytes,1,opt,name=am1,proto3" json:"am1,omitempty"`
 	Am2           *test_a_1.M2 `protobuf:"bytes,2,opt,name=am2,proto3" json:"am2,omitempty"`
 	Bm1           *test_b_1.M1 `protobuf:"bytes,5,opt,name=bm1,proto3" json:"bm1,omitempty"`
@@ -42,10 +43,18 @@
 func (*All) ProtoMessage() {}
 
 func (x *All) ProtoReflect() protoreflect.Message {
-	return file_imports_test_import_all_proto_msgTypes[0].MessageOf(x)
+	mi := &file_imports_test_import_all_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *All) XXX_Methods() *protoiface.Methods {
+func (x *All) XXX_Methods() *protoiface.Methods {
 	return file_imports_test_import_all_proto_msgTypes[0].Methods()
 }
 
@@ -165,9 +174,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_imports_test_import_all_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*All); i {
-			case 5:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 6:
+				return &v.sizeCache
+			case 7:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/test.pb.go b/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/test.pb.go
index 5d9bd7d..47a2f03 100644
--- a/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/test.pb.go
+++ b/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/test.pb.go
@@ -18,6 +18,7 @@
 )
 
 type Foo struct {
+	state protoimpl.MessageState
 	// Types that are valid to be assigned to Bar:
 	//	*Foo_GetBar
 	Bar           isFoo_Bar `protobuf_oneof:"bar"`
@@ -36,10 +37,18 @@
 func (*Foo) ProtoMessage() {}
 
 func (x *Foo) ProtoReflect() protoreflect.Message {
-	return file_issue780_oneof_conflict_test_proto_msgTypes[0].MessageOf(x)
+	mi := &file_issue780_oneof_conflict_test_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Foo) XXX_Methods() *protoiface.Methods {
+func (x *Foo) XXX_Methods() *protoiface.Methods {
 	return file_issue780_oneof_conflict_test_proto_msgTypes[0].Methods()
 }
 
@@ -115,9 +124,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_issue780_oneof_conflict_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Foo); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go b/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
index 0026f3e..c1fb2a0 100644
--- a/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
+++ b/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
@@ -66,6 +66,7 @@
 }
 
 type Message struct {
+	state         protoimpl.MessageState
 	StringField   *string `protobuf:"bytes,1,opt,name=string_field,json=stringField" json:"string_field,omitempty"`
 	EnumField     *Enum   `protobuf:"varint,2,opt,name=enum_field,json=enumField,enum=Enum,def=0" json:"enum_field,omitempty"`
 	sizeCache     protoimpl.SizeCache
@@ -83,10 +84,18 @@
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	return file_nopackage_nopackage_proto_msgTypes[0].MessageOf(x)
+	mi := &file_nopackage_nopackage_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message) XXX_Methods() *protoiface.Methods {
+func (x *Message) XXX_Methods() *protoiface.Methods {
 	return file_nopackage_nopackage_proto_msgTypes[0].Methods()
 }
 
@@ -160,9 +169,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_nopackage_nopackage_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message); i {
-			case 2:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 3:
+				return &v.sizeCache
+			case 4:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
index 8f92f17..8df45bc 100644
--- a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
@@ -314,6 +314,7 @@
 }
 
 type EnumContainerMessage1 struct {
+	state             protoimpl.MessageState
 	DefaultDuplicate1 *EnumType2 `protobuf:"varint,1,opt,name=default_duplicate1,json=defaultDuplicate1,enum=goproto.protoc.proto2.EnumType2,def=1" json:"default_duplicate1,omitempty"`
 	DefaultDuplicate2 *EnumType2 `protobuf:"varint,2,opt,name=default_duplicate2,json=defaultDuplicate2,enum=goproto.protoc.proto2.EnumType2,def=1" json:"default_duplicate2,omitempty"`
 	sizeCache         protoimpl.SizeCache
@@ -331,10 +332,18 @@
 func (*EnumContainerMessage1) ProtoMessage() {}
 
 func (x *EnumContainerMessage1) ProtoReflect() protoreflect.Message {
-	return file_proto2_enum_proto_msgTypes[0].MessageOf(x)
+	mi := &file_proto2_enum_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *EnumContainerMessage1) XXX_Methods() *protoiface.Methods {
+func (x *EnumContainerMessage1) XXX_Methods() *protoiface.Methods {
 	return file_proto2_enum_proto_msgTypes[0].Methods()
 }
 
@@ -361,6 +370,7 @@
 }
 
 type EnumContainerMessage1_EnumContainerMessage2 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -376,10 +386,18 @@
 func (*EnumContainerMessage1_EnumContainerMessage2) ProtoMessage() {}
 
 func (x *EnumContainerMessage1_EnumContainerMessage2) ProtoReflect() protoreflect.Message {
-	return file_proto2_enum_proto_msgTypes[1].MessageOf(x)
+	mi := &file_proto2_enum_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *EnumContainerMessage1_EnumContainerMessage2) XXX_Methods() *protoiface.Methods {
+func (x *EnumContainerMessage1_EnumContainerMessage2) XXX_Methods() *protoiface.Methods {
 	return file_proto2_enum_proto_msgTypes[1].Methods()
 }
 
@@ -474,9 +492,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_proto2_enum_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*EnumContainerMessage1); i {
-			case 2:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 3:
+				return &v.sizeCache
+			case 4:
 				return &v.unknownFields
 			default:
 				return nil
@@ -485,8 +505,10 @@
 		file_proto2_enum_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*EnumContainerMessage1_EnumContainerMessage2); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
index 054e264..794e33e 100644
--- a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
@@ -70,6 +70,7 @@
 }
 
 type FieldTestMessage struct {
+	state               protoimpl.MessageState
 	OptionalBool        *bool                                `protobuf:"varint,1,opt,name=optional_bool,json=optionalBool" json:"optional_bool,omitempty"`
 	OptionalEnum        *FieldTestMessage_Enum               `protobuf:"varint,2,opt,name=optional_enum,json=optionalEnum,enum=goproto.protoc.proto2.FieldTestMessage_Enum" json:"optional_enum,omitempty"`
 	OptionalInt32       *int32                               `protobuf:"varint,3,opt,name=optional_int32,json=optionalInt32" json:"optional_int32,omitempty"`
@@ -191,10 +192,18 @@
 func (*FieldTestMessage) ProtoMessage() {}
 
 func (x *FieldTestMessage) ProtoReflect() protoreflect.Message {
-	return file_proto2_fields_proto_msgTypes[0].MessageOf(x)
+	mi := &file_proto2_fields_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage) XXX_Methods() *protoiface.Methods {
 	return file_proto2_fields_proto_msgTypes[0].Methods()
 }
 
@@ -1094,6 +1103,7 @@
 func (*FieldTestMessage_OneofTwo_2) isFieldTestMessage_OneofTwo() {}
 
 type FieldTestMessage_OptionalGroup struct {
+	state         protoimpl.MessageState
 	OptionalGroup *string `protobuf:"bytes,19,opt,name=optional_group,json=optionalGroup" json:"optional_group,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -1110,10 +1120,18 @@
 func (*FieldTestMessage_OptionalGroup) ProtoMessage() {}
 
 func (x *FieldTestMessage_OptionalGroup) ProtoReflect() protoreflect.Message {
-	return file_proto2_fields_proto_msgTypes[1].MessageOf(x)
+	mi := &file_proto2_fields_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage_OptionalGroup) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage_OptionalGroup) XXX_Methods() *protoiface.Methods {
 	return file_proto2_fields_proto_msgTypes[1].Methods()
 }
 
@@ -1130,6 +1148,7 @@
 }
 
 type FieldTestMessage_RequiredGroup struct {
+	state         protoimpl.MessageState
 	RequiredGroup *string `protobuf:"bytes,119,req,name=required_group,json=requiredGroup" json:"required_group,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -1146,10 +1165,18 @@
 func (*FieldTestMessage_RequiredGroup) ProtoMessage() {}
 
 func (x *FieldTestMessage_RequiredGroup) ProtoReflect() protoreflect.Message {
-	return file_proto2_fields_proto_msgTypes[2].MessageOf(x)
+	mi := &file_proto2_fields_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage_RequiredGroup) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage_RequiredGroup) XXX_Methods() *protoiface.Methods {
 	return file_proto2_fields_proto_msgTypes[2].Methods()
 }
 
@@ -1166,6 +1193,7 @@
 }
 
 type FieldTestMessage_RepeatedGroup struct {
+	state         protoimpl.MessageState
 	RepeatedGroup []string `protobuf:"bytes,219,rep,name=repeated_group,json=repeatedGroup" json:"repeated_group,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -1182,10 +1210,18 @@
 func (*FieldTestMessage_RepeatedGroup) ProtoMessage() {}
 
 func (x *FieldTestMessage_RepeatedGroup) ProtoReflect() protoreflect.Message {
-	return file_proto2_fields_proto_msgTypes[3].MessageOf(x)
+	mi := &file_proto2_fields_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage_RepeatedGroup) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage_RepeatedGroup) XXX_Methods() *protoiface.Methods {
 	return file_proto2_fields_proto_msgTypes[3].Methods()
 }
 
@@ -1202,6 +1238,7 @@
 }
 
 type FieldTestMessage_OneofGroup struct {
+	state           protoimpl.MessageState
 	OneofGroupField *string `protobuf:"bytes,619,opt,name=oneof_group_field,json=oneofGroupField" json:"oneof_group_field,omitempty"`
 	sizeCache       protoimpl.SizeCache
 	unknownFields   protoimpl.UnknownFields
@@ -1218,10 +1255,18 @@
 func (*FieldTestMessage_OneofGroup) ProtoMessage() {}
 
 func (x *FieldTestMessage_OneofGroup) ProtoReflect() protoreflect.Message {
-	return file_proto2_fields_proto_msgTypes[7].MessageOf(x)
+	mi := &file_proto2_fields_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage_OneofGroup) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage_OneofGroup) XXX_Methods() *protoiface.Methods {
 	return file_proto2_fields_proto_msgTypes[7].Methods()
 }
 
@@ -1238,6 +1283,7 @@
 }
 
 type FieldTestMessage_Message struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -1253,10 +1299,18 @@
 func (*FieldTestMessage_Message) ProtoMessage() {}
 
 func (x *FieldTestMessage_Message) ProtoReflect() protoreflect.Message {
-	return file_proto2_fields_proto_msgTypes[8].MessageOf(x)
+	mi := &file_proto2_fields_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage_Message) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage_Message) XXX_Methods() *protoiface.Methods {
 	return file_proto2_fields_proto_msgTypes[8].Methods()
 }
 
@@ -1700,9 +1754,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_proto2_fields_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage); i {
-			case 83:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 84:
+				return &v.sizeCache
+			case 85:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1710,9 +1766,11 @@
 		}
 		file_proto2_fields_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage_OptionalGroup); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1720,9 +1778,11 @@
 		}
 		file_proto2_fields_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage_RequiredGroup); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1730,9 +1790,11 @@
 		}
 		file_proto2_fields_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage_RepeatedGroup); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1740,9 +1802,11 @@
 		}
 		file_proto2_fields_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage_OneofGroup); i {
-			case 1:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 2:
+				return &v.sizeCache
+			case 3:
 				return &v.unknownFields
 			default:
 				return nil
@@ -1751,8 +1815,10 @@
 		file_proto2_fields_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage_Message); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
index 8d2b452..fe60801 100644
--- a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
@@ -18,6 +18,7 @@
 )
 
 type Layer1 struct {
+	state         protoimpl.MessageState
 	L2            *Layer1_Layer2        `protobuf:"bytes,1,opt,name=l2" json:"l2,omitempty"`
 	L3            *Layer1_Layer2_Layer3 `protobuf:"bytes,2,opt,name=l3" json:"l3,omitempty"`
 	sizeCache     protoimpl.SizeCache
@@ -35,10 +36,18 @@
 func (*Layer1) ProtoMessage() {}
 
 func (x *Layer1) ProtoReflect() protoreflect.Message {
-	return file_proto2_nested_messages_proto_msgTypes[0].MessageOf(x)
+	mi := &file_proto2_nested_messages_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Layer1) XXX_Methods() *protoiface.Methods {
+func (x *Layer1) XXX_Methods() *protoiface.Methods {
 	return file_proto2_nested_messages_proto_msgTypes[0].Methods()
 }
 
@@ -62,6 +71,7 @@
 }
 
 type Layer1_Layer2 struct {
+	state         protoimpl.MessageState
 	L3            *Layer1_Layer2_Layer3 `protobuf:"bytes,1,opt,name=l3" json:"l3,omitempty"`
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -78,10 +88,18 @@
 func (*Layer1_Layer2) ProtoMessage() {}
 
 func (x *Layer1_Layer2) ProtoReflect() protoreflect.Message {
-	return file_proto2_nested_messages_proto_msgTypes[1].MessageOf(x)
+	mi := &file_proto2_nested_messages_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Layer1_Layer2) XXX_Methods() *protoiface.Methods {
+func (x *Layer1_Layer2) XXX_Methods() *protoiface.Methods {
 	return file_proto2_nested_messages_proto_msgTypes[1].Methods()
 }
 
@@ -98,6 +116,7 @@
 }
 
 type Layer1_Layer2_Layer3 struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -113,10 +132,18 @@
 func (*Layer1_Layer2_Layer3) ProtoMessage() {}
 
 func (x *Layer1_Layer2_Layer3) ProtoReflect() protoreflect.Message {
-	return file_proto2_nested_messages_proto_msgTypes[2].MessageOf(x)
+	mi := &file_proto2_nested_messages_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Layer1_Layer2_Layer3) XXX_Methods() *protoiface.Methods {
+func (x *Layer1_Layer2_Layer3) XXX_Methods() *protoiface.Methods {
 	return file_proto2_nested_messages_proto_msgTypes[2].Methods()
 }
 
@@ -188,6 +215,20 @@
 	if !protoimpl.UnsafeEnabled {
 		file_proto2_nested_messages_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Layer1); i {
+			case 0:
+				return &v.state
+			case 3:
+				return &v.sizeCache
+			case 4:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_proto2_nested_messages_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Layer1_Layer2); i {
+			case 0:
+				return &v.state
 			case 2:
 				return &v.sizeCache
 			case 3:
@@ -196,21 +237,13 @@
 				return nil
 			}
 		}
-		file_proto2_nested_messages_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Layer1_Layer2); i {
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
 		file_proto2_nested_messages_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Layer1_Layer2_Layer3); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
index 0fe3fcb..57ac220 100644
--- a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
@@ -18,6 +18,7 @@
 )
 
 type Message struct {
+	state         protoimpl.MessageState
 	I32           *int32   `protobuf:"varint,1,opt,name=i32" json:"i32,omitempty"`
 	M             *Message `protobuf:"bytes,2,opt,name=m" json:"m,omitempty"`
 	sizeCache     protoimpl.SizeCache
@@ -35,10 +36,18 @@
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	return file_proto2_proto2_proto_msgTypes[0].MessageOf(x)
+	mi := &file_proto2_proto2_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *Message) XXX_Methods() *protoiface.Methods {
+func (x *Message) XXX_Methods() *protoiface.Methods {
 	return file_proto2_proto2_proto_msgTypes[0].Methods()
 }
 
@@ -111,9 +120,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_proto2_proto2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message); i {
-			case 2:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 3:
+				return &v.sizeCache
+			case 4:
 				return &v.unknownFields
 			default:
 				return nil
diff --git a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
index 7333421..7646822 100644
--- a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
@@ -56,6 +56,7 @@
 }
 
 type FieldTestMessage struct {
+	state            protoimpl.MessageState
 	OptionalBool     string                               `protobuf:"bytes,1,opt,name=optional_bool,json=optionalBool,proto3" json:"optional_bool,omitempty"`
 	OptionalEnum     FieldTestMessage_Enum                `protobuf:"varint,2,opt,name=optional_enum,json=optionalEnum,proto3,enum=goproto.protoc.proto3.FieldTestMessage_Enum" json:"optional_enum,omitempty"`
 	OptionalInt32    int32                                `protobuf:"varint,3,opt,name=optional_int32,json=optionalInt32,proto3" json:"optional_int32,omitempty"`
@@ -108,10 +109,18 @@
 func (*FieldTestMessage) ProtoMessage() {}
 
 func (x *FieldTestMessage) ProtoReflect() protoreflect.Message {
-	return file_proto3_fields_proto_msgTypes[0].MessageOf(x)
+	mi := &file_proto3_fields_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage) XXX_Methods() *protoiface.Methods {
 	return file_proto3_fields_proto_msgTypes[0].Methods()
 }
 
@@ -380,6 +389,7 @@
 }
 
 type FieldTestMessage_Message struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
@@ -395,10 +405,18 @@
 func (*FieldTestMessage_Message) ProtoMessage() {}
 
 func (x *FieldTestMessage_Message) ProtoReflect() protoreflect.Message {
-	return file_proto3_fields_proto_msgTypes[4].MessageOf(x)
+	mi := &file_proto3_fields_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (m *FieldTestMessage_Message) XXX_Methods() *protoiface.Methods {
+func (x *FieldTestMessage_Message) XXX_Methods() *protoiface.Methods {
 	return file_proto3_fields_proto_msgTypes[4].Methods()
 }
 
@@ -608,9 +626,11 @@
 	if !protoimpl.UnsafeEnabled {
 		file_proto3_fields_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage); i {
-			case 37:
-				return &v.sizeCache
+			case 0:
+				return &v.state
 			case 38:
+				return &v.sizeCache
+			case 39:
 				return &v.unknownFields
 			default:
 				return nil
@@ -619,8 +639,10 @@
 		file_proto3_fields_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FieldTestMessage_Message); i {
 			case 0:
-				return &v.sizeCache
+				return &v.state
 			case 1:
+				return &v.sizeCache
+			case 2:
 				return &v.unknownFields
 			default:
 				return nil