proto, runtime/protoiface: add support for fast-path marshaling

Allow message implementations to provide optimized versions of standard
operations. Generated messages now include a ProtoReflectMethods method,
returning a protoiface.Methods struct containing pointers to assorted
optional functions.

The Methods struct also includes a Flags field indicating support for
optional features such as deterministic marshaling.

Implementation of the fast paths (and tests) will come in later CLs.

Change-Id: Idd1beed0ecf43ec5e5e7b8da2ee1e08d3ce32213
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/170340
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/cmd/protoc-gen-go-grpc/testdata/grpc/grpc.pb.go b/cmd/protoc-gen-go-grpc/testdata/grpc/grpc.pb.go
index 4f84300..56a2c11 100644
--- a/cmd/protoc-gen-go-grpc/testdata/grpc/grpc.pb.go
+++ b/cmd/protoc-gen-go-grpc/testdata/grpc/grpc.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_grpc_grpc_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Request) XXX_Methods() *protoiface.Methods {
+	return xxx_File_grpc_grpc_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Request.ProtoReflect.Type instead.
 func (*Request) Descriptor() ([]byte, []int) {
 	return xxx_File_grpc_grpc_proto_rawDescGZIP(), []int{0}
@@ -57,6 +62,10 @@
 	return xxx_File_grpc_grpc_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Response) XXX_Methods() *protoiface.Methods {
+	return xxx_File_grpc_grpc_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Response.ProtoReflect.Type instead.
 func (*Response) Descriptor() ([]byte, []int) {
 	return xxx_File_grpc_grpc_proto_rawDescGZIP(), []int{1}
diff --git a/cmd/protoc-gen-go/internal_gengo/reflect.go b/cmd/protoc-gen-go/internal_gengo/reflect.go
index 2d0a9ff..129a735 100644
--- a/cmd/protoc-gen-go/internal_gengo/reflect.go
+++ b/cmd/protoc-gen-go/internal_gengo/reflect.go
@@ -265,6 +265,9 @@
 	g.P("return ", typesVar, "[", idx, "].MessageOf(x)")
 	g.P("}")
 	g.P()
+	g.P("func (m *", message.GoIdent, ") XXX_Methods() *", protoifacePackage.Ident("Methods"), " {")
+	g.P("return ", typesVar, "[", idx, "].Methods()")
+	g.P("}")
 }
 
 func rawDescVarName(f *fileInfo) string {
diff --git a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
index e4e3e06..b5e3701 100644
--- a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
+++ b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -80,6 +81,10 @@
 	return xxx_File_annotations_annotations_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *AnnotationsTestMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_annotations_annotations_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use AnnotationsTestMessage.ProtoReflect.Type instead.
 func (*AnnotationsTestMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_annotations_annotations_proto_rawDescGZIP(), []int{0}
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 a0f0199..2db1eff 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:398 end:417} annotation:{path:5 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:434 end:481} annotation:{path:4 path:0 source_file:"annotations/annotations.proto" begin:1639 end:1661} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:1672 end:1692} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:2528 end:2551}
\ No newline at end of file
+annotation:{path:5 path:0 source_file:"annotations/annotations.proto" begin:461 end:480} annotation:{path:5 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:497 end:544} annotation:{path:4 path:0 source_file:"annotations/annotations.proto" begin:1702 end:1724} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:1735 end:1755} annotation:{path:4 path:0 path:2 path:0 source_file:"annotations/annotations.proto" begin:2736 end:2759}
\ 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 48a847e..4f973b2 100644
--- a/cmd/protoc-gen-go/testdata/comments/comments.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
@@ -8,6 +8,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -43,6 +44,10 @@
 	return xxx_File_comments_comments_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Message1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_comments_comments_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Message1.ProtoReflect.Type instead.
 func (*Message1) Descriptor() ([]byte, []int) {
 	return xxx_File_comments_comments_proto_rawDescGZIP(), []int{0}
@@ -107,6 +112,10 @@
 	return xxx_File_comments_comments_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Message2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_comments_comments_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Message2.ProtoReflect.Type instead.
 func (*Message2) Descriptor() ([]byte, []int) {
 	return xxx_File_comments_comments_proto_rawDescGZIP(), []int{1}
@@ -133,6 +142,10 @@
 	return xxx_File_comments_comments_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Message1_Message1A) XXX_Methods() *protoiface.Methods {
+	return xxx_File_comments_comments_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Message1_Message1A.ProtoReflect.Type instead.
 func (*Message1_Message1A) Descriptor() ([]byte, []int) {
 	return xxx_File_comments_comments_proto_rawDescGZIP(), []int{0, 0}
@@ -159,6 +172,10 @@
 	return xxx_File_comments_comments_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *Message1_Message1B) XXX_Methods() *protoiface.Methods {
+	return xxx_File_comments_comments_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use Message1_Message1B.ProtoReflect.Type instead.
 func (*Message1_Message1B) Descriptor() ([]byte, []int) {
 	return xxx_File_comments_comments_proto_rawDescGZIP(), []int{0, 1}
@@ -185,6 +202,10 @@
 	return xxx_File_comments_comments_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *Message2_Message2A) XXX_Methods() *protoiface.Methods {
+	return xxx_File_comments_comments_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use Message2_Message2A.ProtoReflect.Type instead.
 func (*Message2_Message2A) Descriptor() ([]byte, []int) {
 	return xxx_File_comments_comments_proto_rawDescGZIP(), []int{1, 0}
@@ -211,6 +232,10 @@
 	return xxx_File_comments_comments_proto_messageTypes[5].MessageOf(x)
 }
 
+func (m *Message2_Message2B) XXX_Methods() *protoiface.Methods {
+	return xxx_File_comments_comments_proto_messageTypes[5].Methods()
+}
+
 // Deprecated: Use Message2_Message2B.ProtoReflect.Type instead.
 func (*Message2_Message2B) Descriptor() ([]byte, []int) {
 	return xxx_File_comments_comments_proto_rawDescGZIP(), []int{1, 1}
diff --git a/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go b/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
index 19721de..f30e424 100644
--- a/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -66,6 +67,10 @@
 	return xxx_File_comments_deprecated_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *DeprecatedMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_comments_deprecated_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use DeprecatedMessage.ProtoReflect.Type instead.
 func (*DeprecatedMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_comments_deprecated_proto_rawDescGZIP(), []int{0}
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 17e4bd6..b53d3dc 100644
--- a/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
@@ -35,6 +35,10 @@
 	return xxx_File_extensions_base_base_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *BaseMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_base_base_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use BaseMessage.ProtoReflect.Type instead.
 func (*BaseMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_base_base_proto_rawDescGZIP(), []int{0}
@@ -78,6 +82,10 @@
 	return xxx_File_extensions_base_base_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *MessageSetWireFormatMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_base_base_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use MessageSetWireFormatMessage.ProtoReflect.Type instead.
 func (*MessageSetWireFormatMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_base_base_proto_rawDescGZIP(), []int{1}
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 8ff2821..2267480 100644
--- a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
@@ -83,6 +83,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Message.ProtoReflect.Type instead.
 func (*Message) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{0}
@@ -116,6 +120,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *ExtensionGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use ExtensionGroup.ProtoReflect.Type instead.
 func (*ExtensionGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{1}
@@ -149,6 +157,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *ExtendingMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use ExtendingMessage.ProtoReflect.Type instead.
 func (*ExtendingMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{2}
@@ -175,6 +187,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *RepeatedGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use RepeatedGroup.ProtoReflect.Type instead.
 func (*RepeatedGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{3}
@@ -209,6 +225,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *Extendable) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use Extendable.ProtoReflect.Type instead.
 func (*Extendable) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{4}
@@ -244,6 +264,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[5].MessageOf(x)
 }
 
+func (m *MessageSetWireFormatExtension) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[5].Methods()
+}
+
 // Deprecated: Use MessageSetWireFormatExtension.ProtoReflect.Type instead.
 func (*MessageSetWireFormatExtension) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{5}
@@ -269,6 +293,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[6].MessageOf(x)
 }
 
+func (m *Message_M) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[6].Methods()
+}
+
 // Deprecated: Use Message_M.ProtoReflect.Type instead.
 func (*Message_M) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{0, 0}
@@ -294,6 +322,10 @@
 	return xxx_File_extensions_ext_ext_proto_messageTypes[7].MessageOf(x)
 }
 
+func (m *ExtendingMessage_ExtendingMessageSubmessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_ext_ext_proto_messageTypes[7].Methods()
+}
+
 // Deprecated: Use ExtendingMessage_ExtendingMessageSubmessage.ProtoReflect.Type instead.
 func (*ExtendingMessage_ExtendingMessageSubmessage) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_ext_ext_proto_rawDescGZIP(), []int{2, 0}
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 ef84692..e8367a6 100644
--- a/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -33,6 +34,10 @@
 	return xxx_File_extensions_extra_extra_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *ExtraMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_extra_extra_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use ExtraMessage.ProtoReflect.Type instead.
 func (*ExtraMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_extra_extra_proto_rawDescGZIP(), []int{0}
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 e8d218c..4aac7fb 100644
--- a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
@@ -67,6 +67,10 @@
 	return xxx_File_extensions_proto3_ext3_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_extensions_proto3_ext3_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Message.ProtoReflect.Type instead.
 func (*Message) Descriptor() ([]byte, []int) {
 	return xxx_File_extensions_proto3_ext3_proto_rawDescGZIP(), []int{0}
diff --git a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
index cf6cca5..b8832bd 100644
--- a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
+++ b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -71,6 +72,10 @@
 	return xxx_File_fieldnames_fieldnames_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_fieldnames_fieldnames_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Message.ProtoReflect.Type instead.
 func (*Message) Descriptor() ([]byte, []int) {
 	return xxx_File_fieldnames_fieldnames_proto_rawDescGZIP(), []int{0}
@@ -289,6 +294,10 @@
 	return xxx_File_fieldnames_fieldnames_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Message_OneofMessageConflict) XXX_Methods() *protoiface.Methods {
+	return xxx_File_fieldnames_fieldnames_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Message_OneofMessageConflict.ProtoReflect.Type instead.
 func (*Message_OneofMessageConflict) Descriptor() ([]byte, []int) {
 	return xxx_File_fieldnames_fieldnames_proto_rawDescGZIP(), []int{0, 0}
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 af81fce..d527901 100644
--- a/cmd/protoc-gen-go/testdata/import_public/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/a.pb.go
@@ -8,6 +8,7 @@
 	sub2 "github.com/golang/protobuf/v2/cmd/protoc-gen-go/testdata/import_public/sub2"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -79,6 +80,10 @@
 	return xxx_File_import_public_a_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Public) XXX_Methods() *protoiface.Methods {
+	return xxx_File_import_public_a_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Public.ProtoReflect.Type instead.
 func (*Public) Descriptor() ([]byte, []int) {
 	return xxx_File_import_public_a_proto_rawDescGZIP(), []int{0}
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 5dcf793..8cd06e7 100644
--- a/cmd/protoc-gen-go/testdata/import_public/b.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/b.pb.go
@@ -7,6 +7,7 @@
 	sub "github.com/golang/protobuf/v2/cmd/protoc-gen-go/testdata/import_public/sub"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -35,6 +36,10 @@
 	return xxx_File_import_public_b_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Local) XXX_Methods() *protoiface.Methods {
+	return xxx_File_import_public_b_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Local.ProtoReflect.Type instead.
 func (*Local) Descriptor() ([]byte, []int) {
 	return xxx_File_import_public_b_proto_rawDescGZIP(), []int{0}
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 1a94137..053bfb0 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
@@ -190,6 +190,10 @@
 	return xxx_File_import_public_sub_a_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M) XXX_Methods() *protoiface.Methods {
+	return xxx_File_import_public_sub_a_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M.ProtoReflect.Type instead.
 func (*M) Descriptor() ([]byte, []int) {
 	return xxx_File_import_public_sub_a_proto_rawDescGZIP(), []int{0}
@@ -306,6 +310,10 @@
 	return xxx_File_import_public_sub_a_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *M_Submessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_import_public_sub_a_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use M_Submessage.ProtoReflect.Type instead.
 func (*M_Submessage) Descriptor() ([]byte, []int) {
 	return xxx_File_import_public_sub_a_proto_rawDescGZIP(), []int{0, 0}
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 bbb09bf..da7e13f 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_import_public_sub_b_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_import_public_sub_b_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M2.ProtoReflect.Type instead.
 func (*M2) Descriptor() ([]byte, []int) {
 	return xxx_File_import_public_sub_b_proto_rawDescGZIP(), []int{0}
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 be37da4..1061cda 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_import_public_sub2_a_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Sub2Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_import_public_sub2_a_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Sub2Message.ProtoReflect.Type instead.
 func (*Sub2Message) Descriptor() ([]byte, []int) {
 	return xxx_File_import_public_sub2_a_proto_rawDescGZIP(), []int{0}
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 1ad7e8d..bcbf842 100644
--- a/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_imports_fmt_m_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_fmt_m_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M.ProtoReflect.Type instead.
 func (*M) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_fmt_m_proto_rawDescGZIP(), []int{0}
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 8f1cb2c..0a431cc 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -65,6 +66,10 @@
 	return xxx_File_imports_test_a_1_m1_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_a_1_m1_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M1.ProtoReflect.Type instead.
 func (*M1) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_a_1_m1_proto_rawDescGZIP(), []int{0}
@@ -91,6 +96,10 @@
 	return xxx_File_imports_test_a_1_m1_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *M1_1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_a_1_m1_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use M1_1.ProtoReflect.Type instead.
 func (*M1_1) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_a_1_m1_proto_rawDescGZIP(), []int{1}
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 f822333..32fd4cd 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_imports_test_a_1_m2_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_a_1_m2_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M2.ProtoReflect.Type instead.
 func (*M2) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_a_1_m2_proto_rawDescGZIP(), []int{0}
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 9eda985..42d38fc 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_imports_test_a_2_m3_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M3) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_a_2_m3_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M3.ProtoReflect.Type instead.
 func (*M3) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_a_2_m3_proto_rawDescGZIP(), []int{0}
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 d9eb9d4..4c83df3 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_imports_test_a_2_m4_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M4) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_a_2_m4_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M4.ProtoReflect.Type instead.
 func (*M4) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_a_2_m4_proto_rawDescGZIP(), []int{0}
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 4f8f37e..c5bf4d8 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_imports_test_b_1_m1_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_b_1_m1_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M1.ProtoReflect.Type instead.
 func (*M1) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_b_1_m1_proto_rawDescGZIP(), []int{0}
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 6da5dfb..bd2f632 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_imports_test_b_1_m2_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *M2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_b_1_m2_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use M2.ProtoReflect.Type instead.
 func (*M2) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_b_1_m2_proto_rawDescGZIP(), []int{0}
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 3022393..b29d33d 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
@@ -7,6 +7,7 @@
 	test_a_1 "github.com/golang/protobuf/v2/cmd/protoc-gen-go/testdata/imports/test_a_1"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -34,6 +35,10 @@
 	return xxx_File_imports_test_import_a1m1_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *A1M1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_import_a1m1_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use A1M1.ProtoReflect.Type instead.
 func (*A1M1) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_import_a1m1_proto_rawDescGZIP(), []int{0}
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 b2c5d85..a819ff1 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
@@ -7,6 +7,7 @@
 	test_a_1 "github.com/golang/protobuf/v2/cmd/protoc-gen-go/testdata/imports/test_a_1"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -34,6 +35,10 @@
 	return xxx_File_imports_test_import_a1m2_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *A1M2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_import_a1m2_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use A1M2.ProtoReflect.Type instead.
 func (*A1M2) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_import_a1m2_proto_rawDescGZIP(), []int{0}
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 ff1fd2f..e6bde82 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
@@ -10,6 +10,7 @@
 	test_b_1 "github.com/golang/protobuf/v2/cmd/protoc-gen-go/testdata/imports/test_b_1"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -41,6 +42,10 @@
 	return xxx_File_imports_test_import_all_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *All) XXX_Methods() *protoiface.Methods {
+	return xxx_File_imports_test_import_all_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use All.ProtoReflect.Type instead.
 func (*All) Descriptor() ([]byte, []int) {
 	return xxx_File_imports_test_import_all_proto_rawDescGZIP(), []int{0}
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 b2826bd..36cc583 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
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -35,6 +36,10 @@
 	return xxx_File_issue780_oneof_conflict_test_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Foo) XXX_Methods() *protoiface.Methods {
+	return xxx_File_issue780_oneof_conflict_test_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Foo.ProtoReflect.Type instead.
 func (*Foo) Descriptor() ([]byte, []int) {
 	return xxx_File_issue780_oneof_conflict_test_proto_rawDescGZIP(), []int{0}
diff --git a/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go b/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
index 829a1b6..75f0eac 100644
--- a/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
+++ b/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -81,6 +82,10 @@
 	return xxx_File_nopackage_nopackage_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_nopackage_nopackage_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Message.ProtoReflect.Type instead.
 func (*Message) Descriptor() ([]byte, []int) {
 	return xxx_File_nopackage_nopackage_proto_rawDescGZIP(), []int{0}
diff --git a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
index ca359dd..eb0e87b 100644
--- a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -329,6 +330,10 @@
 	return xxx_File_proto2_enum_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *EnumContainerMessage1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_enum_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use EnumContainerMessage1.ProtoReflect.Type instead.
 func (*EnumContainerMessage1) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_enum_proto_rawDescGZIP(), []int{0}
@@ -371,6 +376,10 @@
 	return xxx_File_proto2_enum_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *EnumContainerMessage1_EnumContainerMessage2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_enum_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use EnumContainerMessage1_EnumContainerMessage2.ProtoReflect.Type instead.
 func (*EnumContainerMessage1_EnumContainerMessage2) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_enum_proto_rawDescGZIP(), []int{0, 0}
diff --git a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
index da2f13a..6906ece 100644
--- a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	math "math"
 	sync "sync"
@@ -189,6 +190,10 @@
 	return xxx_File_proto2_fields_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *FieldTestMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_fields_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use FieldTestMessage.ProtoReflect.Type instead.
 func (*FieldTestMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_fields_proto_rawDescGZIP(), []int{0}
@@ -1132,6 +1137,10 @@
 	return xxx_File_proto2_fields_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *FieldTestMessage_OptionalGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_fields_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use FieldTestMessage_OptionalGroup.ProtoReflect.Type instead.
 func (*FieldTestMessage_OptionalGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_fields_proto_rawDescGZIP(), []int{0, 0}
@@ -1165,6 +1174,10 @@
 	return xxx_File_proto2_fields_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *FieldTestMessage_RequiredGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_fields_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use FieldTestMessage_RequiredGroup.ProtoReflect.Type instead.
 func (*FieldTestMessage_RequiredGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_fields_proto_rawDescGZIP(), []int{0, 1}
@@ -1198,6 +1211,10 @@
 	return xxx_File_proto2_fields_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *FieldTestMessage_RepeatedGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_fields_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use FieldTestMessage_RepeatedGroup.ProtoReflect.Type instead.
 func (*FieldTestMessage_RepeatedGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_fields_proto_rawDescGZIP(), []int{0, 2}
@@ -1231,6 +1248,10 @@
 	return xxx_File_proto2_fields_proto_messageTypes[7].MessageOf(x)
 }
 
+func (m *FieldTestMessage_OneofGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_fields_proto_messageTypes[7].Methods()
+}
+
 // Deprecated: Use FieldTestMessage_OneofGroup.ProtoReflect.Type instead.
 func (*FieldTestMessage_OneofGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_fields_proto_rawDescGZIP(), []int{0, 6}
@@ -1263,6 +1284,10 @@
 	return xxx_File_proto2_fields_proto_messageTypes[8].MessageOf(x)
 }
 
+func (m *FieldTestMessage_Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_fields_proto_messageTypes[8].Methods()
+}
+
 // Deprecated: Use FieldTestMessage_Message.ProtoReflect.Type instead.
 func (*FieldTestMessage_Message) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_fields_proto_rawDescGZIP(), []int{0, 7}
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 c9b2e46..6a2227a 100644
--- a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -34,6 +35,10 @@
 	return xxx_File_proto2_nested_messages_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Layer1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_nested_messages_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Layer1.ProtoReflect.Type instead.
 func (*Layer1) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_nested_messages_proto_rawDescGZIP(), []int{0}
@@ -74,6 +79,10 @@
 	return xxx_File_proto2_nested_messages_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Layer1_Layer2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_nested_messages_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Layer1_Layer2.ProtoReflect.Type instead.
 func (*Layer1_Layer2) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_nested_messages_proto_rawDescGZIP(), []int{0, 0}
@@ -106,6 +115,10 @@
 	return xxx_File_proto2_nested_messages_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Layer1_Layer2_Layer3) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_nested_messages_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Layer1_Layer2_Layer3.ProtoReflect.Type instead.
 func (*Layer1_Layer2_Layer3) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_nested_messages_proto_rawDescGZIP(), []int{0, 0, 0}
diff --git a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
index 2ac0ff1..fa6458d 100644
--- a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -34,6 +35,10 @@
 	return xxx_File_proto2_proto2_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto2_proto2_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Message.ProtoReflect.Type instead.
 func (*Message) Descriptor() ([]byte, []int) {
 	return xxx_File_proto2_proto2_proto_rawDescGZIP(), []int{0}
diff --git a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
index 8cb68f6..058ada4 100644
--- a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -102,6 +103,10 @@
 	return xxx_File_proto3_fields_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *FieldTestMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto3_fields_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use FieldTestMessage.ProtoReflect.Type instead.
 func (*FieldTestMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_proto3_fields_proto_rawDescGZIP(), []int{0}
@@ -386,6 +391,10 @@
 	return xxx_File_proto3_fields_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *FieldTestMessage_Message) XXX_Methods() *protoiface.Methods {
+	return xxx_File_proto3_fields_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use FieldTestMessage_Message.ProtoReflect.Type instead.
 func (*FieldTestMessage_Message) Descriptor() ([]byte, []int) {
 	return xxx_File_proto3_fields_proto_rawDescGZIP(), []int{0, 3}
diff --git a/encoding/testprotos/pb2/test.pb.go b/encoding/testprotos/pb2/test.pb.go
index 0ad7a9a..9c3f74e 100644
--- a/encoding/testprotos/pb2/test.pb.go
+++ b/encoding/testprotos/pb2/test.pb.go
@@ -156,6 +156,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Scalars) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Scalars.ProtoReflect.Type instead.
 func (*Scalars) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{0}
@@ -291,6 +295,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Enums) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Enums.ProtoReflect.Type instead.
 func (*Enums) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{1}
@@ -354,6 +362,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Repeats) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Repeats.ProtoReflect.Type instead.
 func (*Repeats) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{2}
@@ -445,6 +457,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *Nested) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use Nested.ProtoReflect.Type instead.
 func (*Nested) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{3}
@@ -489,6 +505,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *Nests) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use Nests.ProtoReflect.Type instead.
 func (*Nests) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{4}
@@ -549,6 +569,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[5].MessageOf(x)
 }
 
+func (m *Requireds) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[5].Methods()
+}
+
 // Deprecated: Use Requireds.ProtoReflect.Type instead.
 func (*Requireds) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{5}
@@ -619,6 +643,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[6].MessageOf(x)
 }
 
+func (m *PartialRequired) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[6].Methods()
+}
+
 // Deprecated: Use PartialRequired.ProtoReflect.Type instead.
 func (*PartialRequired) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{6}
@@ -659,6 +687,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[7].MessageOf(x)
 }
 
+func (m *NestedWithRequired) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[7].Methods()
+}
+
 // Deprecated: Use NestedWithRequired.ProtoReflect.Type instead.
 func (*NestedWithRequired) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{7}
@@ -697,6 +729,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[8].MessageOf(x)
 }
 
+func (m *IndirectRequired) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[8].Methods()
+}
+
 // Deprecated: Use IndirectRequired.ProtoReflect.Type instead.
 func (*IndirectRequired) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{8}
@@ -778,6 +814,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[9].MessageOf(x)
 }
 
+func (m *Extensions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[9].Methods()
+}
+
 // Deprecated: Use Extensions.ProtoReflect.Type instead.
 func (*Extensions) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{9}
@@ -833,6 +873,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[10].MessageOf(x)
 }
 
+func (m *ExtensionsContainer) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[10].Methods()
+}
+
 // Deprecated: Use ExtensionsContainer.ProtoReflect.Type instead.
 func (*ExtensionsContainer) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{10}
@@ -859,6 +903,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[11].MessageOf(x)
 }
 
+func (m *MessageSet) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[11].Methods()
+}
+
 // Deprecated: Use MessageSet.ProtoReflect.Type instead.
 func (*MessageSet) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{11}
@@ -894,6 +942,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[12].MessageOf(x)
 }
 
+func (m *MessageSetExtension) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[12].Methods()
+}
+
 // Deprecated: Use MessageSetExtension.ProtoReflect.Type instead.
 func (*MessageSetExtension) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{12}
@@ -927,6 +979,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[13].MessageOf(x)
 }
 
+func (m *FakeMessageSet) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[13].Methods()
+}
+
 // Deprecated: Use FakeMessageSet.ProtoReflect.Type instead.
 func (*FakeMessageSet) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{13}
@@ -962,6 +1018,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[14].MessageOf(x)
 }
 
+func (m *FakeMessageSetExtension) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[14].Methods()
+}
+
 // Deprecated: Use FakeMessageSetExtension.ProtoReflect.Type instead.
 func (*FakeMessageSetExtension) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{14}
@@ -1013,6 +1073,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[15].MessageOf(x)
 }
 
+func (m *KnownTypes) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[15].Methods()
+}
+
 // Deprecated: Use KnownTypes.ProtoReflect.Type instead.
 func (*KnownTypes) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{15}
@@ -1167,6 +1231,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[16].MessageOf(x)
 }
 
+func (m *Nests_OptGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[16].Methods()
+}
+
 // Deprecated: Use Nests_OptGroup.ProtoReflect.Type instead.
 func (*Nests_OptGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{4, 0}
@@ -1214,6 +1282,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[17].MessageOf(x)
 }
 
+func (m *Nests_RptGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[17].Methods()
+}
+
 // Deprecated: Use Nests_RptGroup.ProtoReflect.Type instead.
 func (*Nests_RptGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{4, 1}
@@ -1247,6 +1319,10 @@
 	return xxx_File_pb2_test_proto_messageTypes[18].MessageOf(x)
 }
 
+func (m *Nests_OptGroup_OptNestedGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb2_test_proto_messageTypes[18].Methods()
+}
+
 // Deprecated: Use Nests_OptGroup_OptNestedGroup.ProtoReflect.Type instead.
 func (*Nests_OptGroup_OptNestedGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_pb2_test_proto_rawDescGZIP(), []int{4, 0, 0}
diff --git a/encoding/testprotos/pb3/test.pb.go b/encoding/testprotos/pb3/test.pb.go
index b879929..383db64 100644
--- a/encoding/testprotos/pb3/test.pb.go
+++ b/encoding/testprotos/pb3/test.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -132,6 +133,10 @@
 	return xxx_File_pb3_test_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Scalars) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb3_test_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Scalars.ProtoReflect.Type instead.
 func (*Scalars) Descriptor() ([]byte, []int) {
 	return xxx_File_pb3_test_proto_rawDescGZIP(), []int{0}
@@ -265,6 +270,10 @@
 	return xxx_File_pb3_test_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Enums) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb3_test_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Enums.ProtoReflect.Type instead.
 func (*Enums) Descriptor() ([]byte, []int) {
 	return xxx_File_pb3_test_proto_rawDescGZIP(), []int{1}
@@ -306,6 +315,10 @@
 	return xxx_File_pb3_test_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Nests) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb3_test_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Nests.ProtoReflect.Type instead.
 func (*Nests) Descriptor() ([]byte, []int) {
 	return xxx_File_pb3_test_proto_rawDescGZIP(), []int{2}
@@ -341,6 +354,10 @@
 	return xxx_File_pb3_test_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *Nested) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb3_test_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use Nested.ProtoReflect.Type instead.
 func (*Nested) Descriptor() ([]byte, []int) {
 	return xxx_File_pb3_test_proto_rawDescGZIP(), []int{3}
@@ -386,6 +403,10 @@
 	return xxx_File_pb3_test_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *Oneofs) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb3_test_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use Oneofs.ProtoReflect.Type instead.
 func (*Oneofs) Descriptor() ([]byte, []int) {
 	return xxx_File_pb3_test_proto_rawDescGZIP(), []int{4}
@@ -476,6 +497,10 @@
 	return xxx_File_pb3_test_proto_messageTypes[5].MessageOf(x)
 }
 
+func (m *Maps) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb3_test_proto_messageTypes[5].Methods()
+}
+
 // Deprecated: Use Maps.ProtoReflect.Type instead.
 func (*Maps) Descriptor() ([]byte, []int) {
 	return xxx_File_pb3_test_proto_rawDescGZIP(), []int{5}
@@ -538,6 +563,10 @@
 	return xxx_File_pb3_test_proto_messageTypes[6].MessageOf(x)
 }
 
+func (m *JSONNames) XXX_Methods() *protoiface.Methods {
+	return xxx_File_pb3_test_proto_messageTypes[6].Methods()
+}
+
 // Deprecated: Use JSONNames.ProtoReflect.Type instead.
 func (*JSONNames) Descriptor() ([]byte, []int) {
 	return xxx_File_pb3_test_proto_rawDescGZIP(), []int{6}
diff --git a/internal/impl/message.go b/internal/impl/message.go
index dbf9816..0b2c3fc 100644
--- a/internal/impl/message.go
+++ b/internal/impl/message.go
@@ -13,6 +13,7 @@
 
 	pvalue "github.com/golang/protobuf/v2/internal/value"
 	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
+	piface "github.com/golang/protobuf/v2/runtime/protoiface"
 )
 
 // MessageType provides protobuf related functionality for a given Go type
@@ -148,6 +149,10 @@
 	return (*messageReflectWrapper)(mi.dataTypeOf(p))
 }
 
+func (mi *MessageType) Methods() *piface.Methods {
+	return nil
+}
+
 func (mi *MessageType) dataTypeOf(p interface{}) *messageDataType {
 	// TODO: Remove this check? This API is primarily used by generated code,
 	// and should not violate this assumption. Leave this check in for now to
@@ -213,6 +218,9 @@
 func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
 	return (*messageReflectWrapper)(m)
 }
+func (m *messageIfaceWrapper) XXX_Methods() *piface.Methods {
+	return m.mi.Methods()
+}
 func (m *messageIfaceWrapper) ProtoUnwrap() interface{} {
 	return m.p.AsIfaceOf(m.mi.GoType.Elem())
 }
diff --git a/internal/testprotos/conformance/conformance.pb.go b/internal/testprotos/conformance/conformance.pb.go
index 593c909..8c94d06 100644
--- a/internal/testprotos/conformance/conformance.pb.go
+++ b/internal/testprotos/conformance/conformance.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -137,6 +138,10 @@
 	return xxx_File_conformance_conformance_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *FailureSet) XXX_Methods() *protoiface.Methods {
+	return xxx_File_conformance_conformance_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use FailureSet.ProtoReflect.Type instead.
 func (*FailureSet) Descriptor() ([]byte, []int) {
 	return xxx_File_conformance_conformance_proto_rawDescGZIP(), []int{0}
@@ -201,6 +206,10 @@
 	return xxx_File_conformance_conformance_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *ConformanceRequest) XXX_Methods() *protoiface.Methods {
+	return xxx_File_conformance_conformance_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use ConformanceRequest.ProtoReflect.Type instead.
 func (*ConformanceRequest) Descriptor() ([]byte, []int) {
 	return xxx_File_conformance_conformance_proto_rawDescGZIP(), []int{1}
@@ -360,6 +369,10 @@
 	return xxx_File_conformance_conformance_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *ConformanceResponse) XXX_Methods() *protoiface.Methods {
+	return xxx_File_conformance_conformance_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use ConformanceResponse.ProtoReflect.Type instead.
 func (*ConformanceResponse) Descriptor() ([]byte, []int) {
 	return xxx_File_conformance_conformance_proto_rawDescGZIP(), []int{2}
@@ -517,6 +530,10 @@
 	return xxx_File_conformance_conformance_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *JspbEncodingConfig) XXX_Methods() *protoiface.Methods {
+	return xxx_File_conformance_conformance_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use JspbEncodingConfig.ProtoReflect.Type instead.
 func (*JspbEncodingConfig) Descriptor() ([]byte, []int) {
 	return xxx_File_conformance_conformance_proto_rawDescGZIP(), []int{3}
diff --git a/internal/testprotos/legacy/legacy.pb.go b/internal/testprotos/legacy/legacy.pb.go
index d394dc2..ab5ab0e 100644
--- a/internal/testprotos/legacy/legacy.pb.go
+++ b/internal/testprotos/legacy/legacy.pb.go
@@ -18,6 +18,7 @@
 	proto3_v1_21 "github.com/golang/protobuf/v2/internal/testprotos/legacy/proto3.v1.2.1-20181126-8d0c54c1"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -56,6 +57,10 @@
 	return xxx_File_legacy_legacy_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Legacy) XXX_Methods() *protoiface.Methods {
+	return xxx_File_legacy_legacy_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Legacy.ProtoReflect.Type instead.
 func (*Legacy) Descriptor() ([]byte, []int) {
 	return xxx_File_legacy_legacy_proto_rawDescGZIP(), []int{0}
diff --git a/internal/testprotos/test/test.pb.go b/internal/testprotos/test/test.pb.go
index c9f3fb6..4025320 100644
--- a/internal/testprotos/test/test.pb.go
+++ b/internal/testprotos/test/test.pb.go
@@ -325,6 +325,10 @@
 	return xxx_File_test_test_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *TestAllTypes) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use TestAllTypes.ProtoReflect.Type instead.
 func (*TestAllTypes) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{0}
@@ -1064,6 +1068,10 @@
 	return xxx_File_test_test_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *TestDeprecatedMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use TestDeprecatedMessage.ProtoReflect.Type instead.
 func (*TestDeprecatedMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{1}
@@ -1131,6 +1139,10 @@
 	return xxx_File_test_test_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *ForeignMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use ForeignMessage.ProtoReflect.Type instead.
 func (*ForeignMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{2}
@@ -1170,6 +1182,10 @@
 	return xxx_File_test_test_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *TestReservedFields) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use TestReservedFields.ProtoReflect.Type instead.
 func (*TestReservedFields) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{3}
@@ -1196,6 +1212,10 @@
 	return xxx_File_test_test_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *TestAllExtensions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use TestAllExtensions.ProtoReflect.Type instead.
 func (*TestAllExtensions) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{4}
@@ -1231,6 +1251,10 @@
 	return xxx_File_test_test_proto_messageTypes[5].MessageOf(x)
 }
 
+func (m *OptionalGroupExtension) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[5].Methods()
+}
+
 // Deprecated: Use OptionalGroupExtension.ProtoReflect.Type instead.
 func (*OptionalGroupExtension) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{5}
@@ -1264,6 +1288,10 @@
 	return xxx_File_test_test_proto_messageTypes[6].MessageOf(x)
 }
 
+func (m *RepeatedGroupExtension) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[6].Methods()
+}
+
 // Deprecated: Use RepeatedGroupExtension.ProtoReflect.Type instead.
 func (*RepeatedGroupExtension) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{6}
@@ -1296,6 +1324,10 @@
 	return xxx_File_test_test_proto_messageTypes[7].MessageOf(x)
 }
 
+func (m *TestNestedExtension) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[7].Methods()
+}
+
 // Deprecated: Use TestNestedExtension.ProtoReflect.Type instead.
 func (*TestNestedExtension) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{7}
@@ -1322,6 +1354,10 @@
 	return xxx_File_test_test_proto_messageTypes[8].MessageOf(x)
 }
 
+func (m *FooRequest) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[8].Methods()
+}
+
 // Deprecated: Use FooRequest.ProtoReflect.Type instead.
 func (*FooRequest) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{8}
@@ -1347,6 +1383,10 @@
 	return xxx_File_test_test_proto_messageTypes[9].MessageOf(x)
 }
 
+func (m *FooResponse) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[9].Methods()
+}
+
 // Deprecated: Use FooResponse.ProtoReflect.Type instead.
 func (*FooResponse) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{9}
@@ -1374,6 +1414,10 @@
 	return xxx_File_test_test_proto_messageTypes[10].MessageOf(x)
 }
 
+func (m *TestAllTypes_NestedMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[10].Methods()
+}
+
 // Deprecated: Use TestAllTypes_NestedMessage.ProtoReflect.Type instead.
 func (*TestAllTypes_NestedMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{0, 0}
@@ -1414,6 +1458,10 @@
 	return xxx_File_test_test_proto_messageTypes[11].MessageOf(x)
 }
 
+func (m *TestAllTypes_OptionalGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[11].Methods()
+}
+
 // Deprecated: Use TestAllTypes_OptionalGroup.ProtoReflect.Type instead.
 func (*TestAllTypes_OptionalGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{0, 1}
@@ -1447,6 +1495,10 @@
 	return xxx_File_test_test_proto_messageTypes[12].MessageOf(x)
 }
 
+func (m *TestAllTypes_RepeatedGroup) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_proto_messageTypes[12].Methods()
+}
+
 // Deprecated: Use TestAllTypes_RepeatedGroup.ProtoReflect.Type instead.
 func (*TestAllTypes_RepeatedGroup) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_proto_rawDescGZIP(), []int{0, 2}
diff --git a/internal/testprotos/test/test_import.pb.go b/internal/testprotos/test/test_import.pb.go
index 8949257..6a5fc07 100644
--- a/internal/testprotos/test/test_import.pb.go
+++ b/internal/testprotos/test/test_import.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -79,6 +80,10 @@
 	return xxx_File_test_test_import_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *ImportMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_import_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use ImportMessage.ProtoReflect.Type instead.
 func (*ImportMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_import_proto_rawDescGZIP(), []int{0}
diff --git a/internal/testprotos/test/test_public.pb.go b/internal/testprotos/test/test_public.pb.go
index fde1bd6..1c76763 100644
--- a/internal/testprotos/test/test_public.pb.go
+++ b/internal/testprotos/test/test_public.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_test_test_public_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *PublicImportMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_public_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use PublicImportMessage.ProtoReflect.Type instead.
 func (*PublicImportMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_public_proto_rawDescGZIP(), []int{0}
diff --git a/internal/testprotos/test/test_weak.pb.go b/internal/testprotos/test/test_weak.pb.go
index 5f52a22..541908c 100644
--- a/internal/testprotos/test/test_weak.pb.go
+++ b/internal/testprotos/test/test_weak.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -32,6 +33,10 @@
 	return xxx_File_test_test_weak_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *WeakImportMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_test_weak_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use WeakImportMessage.ProtoReflect.Type instead.
 func (*WeakImportMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test_test_weak_proto_rawDescGZIP(), []int{0}
diff --git a/internal/testprotos/test3/test.pb.go b/internal/testprotos/test3/test.pb.go
index c76410b..ad26119 100644
--- a/internal/testprotos/test3/test.pb.go
+++ b/internal/testprotos/test3/test.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -186,6 +187,10 @@
 	return xxx_File_test3_test_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *TestAllTypes) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test3_test_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use TestAllTypes.ProtoReflect.Type instead.
 func (*TestAllTypes) Descriptor() ([]byte, []int) {
 	return xxx_File_test3_test_proto_rawDescGZIP(), []int{0}
@@ -769,6 +774,10 @@
 	return xxx_File_test3_test_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *ForeignMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test3_test_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use ForeignMessage.ProtoReflect.Type instead.
 func (*ForeignMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test3_test_proto_rawDescGZIP(), []int{1}
@@ -810,6 +819,10 @@
 	return xxx_File_test3_test_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *TestAllTypes_NestedMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test3_test_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use TestAllTypes_NestedMessage.ProtoReflect.Type instead.
 func (*TestAllTypes_NestedMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test3_test_proto_rawDescGZIP(), []int{0, 0}
diff --git a/internal/testprotos/test3/test_import.pb.go b/internal/testprotos/test3/test_import.pb.go
index 7d0b70c..8b89c52 100644
--- a/internal/testprotos/test3/test_import.pb.go
+++ b/internal/testprotos/test3/test_import.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -65,6 +66,10 @@
 	return xxx_File_test3_test_import_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *ImportMessage) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test3_test_import_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use ImportMessage.ProtoReflect.Type instead.
 func (*ImportMessage) Descriptor() ([]byte, []int) {
 	return xxx_File_test3_test_import_proto_rawDescGZIP(), []int{0}
diff --git a/proto/decode.go b/proto/decode.go
index c0934c6..4928ace 100644
--- a/proto/decode.go
+++ b/proto/decode.go
@@ -10,6 +10,7 @@
 	"github.com/golang/protobuf/v2/internal/encoding/wire"
 	"github.com/golang/protobuf/v2/internal/pragma"
 	"github.com/golang/protobuf/v2/reflect/protoreflect"
+	"github.com/golang/protobuf/v2/runtime/protoiface"
 )
 
 // UnmarshalOptions configures the unmarshaler.
@@ -20,9 +21,15 @@
 	// If DiscardUnknown is set, unknown fields are ignored.
 	DiscardUnknown bool
 
+	// Reflection forces use of the reflection-based decoder, even for
+	// messages which implement fast-path deserialization.
+	Reflection bool
+
 	pragma.NoUnkeyedLiterals
 }
 
+var _ = protoiface.UnmarshalOptions(UnmarshalOptions{})
+
 // Unmarshal parses the wire-format message in b and places the result in m.
 func Unmarshal(b []byte, m Message) error {
 	return UnmarshalOptions{}.Unmarshal(b, m)
@@ -31,9 +38,23 @@
 // Unmarshal parses the wire-format message in b and places the result in m.
 func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
 	// TODO: Reset m?
+	if err := o.unmarshalMessageFast(b, m); err != errInternalNoFast {
+		return err
+	}
 	return o.unmarshalMessage(b, m.ProtoReflect())
 }
 
+func (o UnmarshalOptions) unmarshalMessageFast(b []byte, m Message) error {
+	if o.Reflection {
+		return errInternalNoFast
+	}
+	methods := protoMethods(m)
+	if methods == nil || methods.Unmarshal == nil {
+		return errInternalNoFast
+	}
+	return methods.Unmarshal(b, m, protoiface.UnmarshalOptions(o))
+}
+
 func (o UnmarshalOptions) unmarshalMessage(b []byte, m protoreflect.Message) error {
 	messageType := m.Type()
 	fieldTypes := messageType.Fields()
diff --git a/proto/encode.go b/proto/encode.go
index 68a3448..973e53a 100644
--- a/proto/encode.go
+++ b/proto/encode.go
@@ -12,6 +12,7 @@
 	"github.com/golang/protobuf/v2/internal/mapsort"
 	"github.com/golang/protobuf/v2/internal/pragma"
 	"github.com/golang/protobuf/v2/reflect/protoreflect"
+	"github.com/golang/protobuf/v2/runtime/protoiface"
 )
 
 // MarshalOptions configures the marshaler.
@@ -40,9 +41,15 @@
 	// detail and subject to change.
 	Deterministic bool
 
+	// Reflection forces use of the reflection-based encoder, even for
+	// messages which implement fast-path serialization.
+	Reflection bool
+
 	pragma.NoUnkeyedLiterals
 }
 
+var _ = protoiface.MarshalOptions(MarshalOptions{})
+
 // Marshal returns the wire-format encoding of m.
 func Marshal(m Message) ([]byte, error) {
 	return MarshalOptions{}.MarshalAppend(nil, m)
@@ -50,15 +57,39 @@
 
 // Marshal returns the wire-format encoding of m.
 func (o MarshalOptions) Marshal(m Message) ([]byte, error) {
-	return o.marshalMessage(nil, m.ProtoReflect())
+	return o.MarshalAppend(nil, m)
 }
 
 // MarshalAppend appends the wire-format encoding of m to b,
 // returning the result.
 func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
+	if b, err := o.marshalMessageFast(b, m); err != errInternalNoFast {
+		return b, err
+	}
 	return o.marshalMessage(b, m.ProtoReflect())
 }
 
+func (o MarshalOptions) marshalMessageFast(b []byte, m Message) ([]byte, error) {
+	if o.Reflection {
+		return nil, errInternalNoFast
+	}
+	methods := protoMethods(m)
+	if methods == nil ||
+		methods.MarshalAppend == nil ||
+		(o.Deterministic && methods.Flags&protoiface.MethodFlagDeterministicMarshal == 0) {
+		return nil, errInternalNoFast
+	}
+	if methods.Size != nil {
+		sz := methods.Size(m)
+		if cap(b) < len(b)+sz {
+			x := make([]byte, len(b), len(b)+sz)
+			copy(x, b)
+			b = x
+		}
+	}
+	return methods.MarshalAppend(b, m, protoiface.MarshalOptions(o))
+}
+
 func (o MarshalOptions) marshalMessage(b []byte, m protoreflect.Message) ([]byte, error) {
 	// There are many choices for what order we visit fields in. The default one here
 	// is chosen for reasonable efficiency and simplicity given the protoreflect API.
diff --git a/proto/proto.go b/proto/proto.go
index 0f20339..6b2510e 100644
--- a/proto/proto.go
+++ b/proto/proto.go
@@ -4,7 +4,22 @@
 
 package proto
 
-import "github.com/golang/protobuf/v2/reflect/protoreflect"
+import (
+	"errors"
+
+	"github.com/golang/protobuf/v2/reflect/protoreflect"
+	"github.com/golang/protobuf/v2/runtime/protoiface"
+)
 
 // Message is the top-level interface that all messages must implement.
 type Message = protoreflect.ProtoMessage
+
+// errInternalNoFast indicates that fast-path operations are not available for a message.
+var errInternalNoFast = errors.New("proto: BUG: internal error (errInternalNoFast)")
+
+func protoMethods(m Message) *protoiface.Methods {
+	if x, ok := m.(protoiface.Methoder); ok {
+		return x.XXX_Methods()
+	}
+	return nil
+}
diff --git a/proto/size.go b/proto/size.go
index 8c9263f..a817cf7 100644
--- a/proto/size.go
+++ b/proto/size.go
@@ -13,9 +13,21 @@
 
 // Size returns the size in bytes of the wire-format encoding of m.
 func Size(m Message) int {
+	if size, err := sizeMessageFast(m); err == nil {
+		return size
+	}
 	return sizeMessage(m.ProtoReflect())
 }
 
+func sizeMessageFast(m Message) (int, error) {
+	// TODO: Pass MarshalOptions to size to permit disabling fast path?
+	methods := protoMethods(m)
+	if methods == nil || methods.Size == nil {
+		return 0, errInternalNoFast
+	}
+	return methods.Size(m), nil
+}
+
 func sizeMessage(m protoreflect.Message) (size int) {
 	fields := m.Type().Fields()
 	knownFields := m.KnownFields()
diff --git a/reflect/protoregistry/testprotos/test.pb.go b/reflect/protoregistry/testprotos/test.pb.go
index 69aeab1..44d7e4a 100644
--- a/reflect/protoregistry/testprotos/test.pb.go
+++ b/reflect/protoregistry/testprotos/test.pb.go
@@ -175,6 +175,10 @@
 	return xxx_File_test_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Message1) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Message1.ProtoReflect.Type instead.
 func (*Message1) Descriptor() ([]byte, []int) {
 	return xxx_File_test_proto_rawDescGZIP(), []int{0}
@@ -209,6 +213,10 @@
 	return xxx_File_test_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Message2) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Message2.ProtoReflect.Type instead.
 func (*Message2) Descriptor() ([]byte, []int) {
 	return xxx_File_test_proto_rawDescGZIP(), []int{1}
@@ -234,6 +242,10 @@
 	return xxx_File_test_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Message3) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Message3.ProtoReflect.Type instead.
 func (*Message3) Descriptor() ([]byte, []int) {
 	return xxx_File_test_proto_rawDescGZIP(), []int{2}
@@ -260,6 +272,10 @@
 	return xxx_File_test_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *Message4) XXX_Methods() *protoiface.Methods {
+	return xxx_File_test_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use Message4.ProtoReflect.Type instead.
 func (*Message4) Descriptor() ([]byte, []int) {
 	return xxx_File_test_proto_rawDescGZIP(), []int{3}
diff --git a/runtime/protoiface/methods.go b/runtime/protoiface/methods.go
new file mode 100644
index 0000000..9c3efa2
--- /dev/null
+++ b/runtime/protoiface/methods.go
@@ -0,0 +1,66 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protoiface
+
+import (
+	"github.com/golang/protobuf/v2/internal/pragma"
+	"github.com/golang/protobuf/v2/reflect/protoreflect"
+)
+
+// Methoder is an optional interface implemented by generated messages to
+// provide fast-path implementations of various operations.
+type Methoder interface {
+	XXX_Methods() *Methods // may return nil
+}
+
+// Methods is a set of optional fast-path implementations of various operations.
+type Methods struct {
+	// Flags indicate support for optional features.
+	Flags MethodFlag
+
+	// MarshalAppend appends the wire-format encoding of m to b, returning the result.
+	MarshalAppend func(b []byte, m protoreflect.ProtoMessage, opts MarshalOptions) ([]byte, error)
+
+	// Size returns the size in bytes of the wire-format encoding of m.
+	Size func(m protoreflect.ProtoMessage) int
+
+	// CachedSize returns the result of the last call to Size.
+	// It must not be called if the message has been changed since the last call to Size.
+	CachedSize func(m protoreflect.ProtoMessage) int
+
+	// Unmarshal parses the wire-format message in b and places the result in m.
+	// It does not reset m.
+	Unmarshal func(b []byte, m protoreflect.ProtoMessage, opts UnmarshalOptions) error
+
+	pragma.NoUnkeyedLiterals
+}
+
+// MethodFlag indicates support for optional fast-path features.
+type MethodFlag int64
+
+const (
+	// MethodFlagDeterministicMarshal indicates support for deterministic marshaling.
+	MethodFlagDeterministicMarshal MethodFlag = 1 << iota
+)
+
+// MarshalOptions configure the marshaler.
+//
+// This type is identical to the one in package proto.
+type MarshalOptions struct {
+	Deterministic bool
+	Reflection    bool
+
+	pragma.NoUnkeyedLiterals
+}
+
+// UnmarshalOptions configures the unmarshaler.
+//
+// This type is identical to the one in package proto.
+type UnmarshalOptions struct {
+	DiscardUnknown bool
+	Reflection     bool
+
+	pragma.NoUnkeyedLiterals
+}
diff --git a/types/descriptor/descriptor.pb.go b/types/descriptor/descriptor.pb.go
index e128ad5..5e436a3 100644
--- a/types/descriptor/descriptor.pb.go
+++ b/types/descriptor/descriptor.pb.go
@@ -421,6 +421,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *FileDescriptorSet) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use FileDescriptorSet.ProtoReflect.Type instead.
 func (*FileDescriptorSet) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{0}
@@ -477,6 +481,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *FileDescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use FileDescriptorProto.ProtoReflect.Type instead.
 func (*FileDescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{1}
@@ -599,6 +607,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *DescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use DescriptorProto.ProtoReflect.Type instead.
 func (*DescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{2}
@@ -697,6 +709,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *ExtensionRangeOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use ExtensionRangeOptions.ProtoReflect.Type instead.
 func (*ExtensionRangeOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{3}
@@ -769,6 +785,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *FieldDescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use FieldDescriptorProto.ProtoReflect.Type instead.
 func (*FieldDescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{4}
@@ -867,6 +887,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[5].MessageOf(x)
 }
 
+func (m *OneofDescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[5].Methods()
+}
+
 // Deprecated: Use OneofDescriptorProto.ProtoReflect.Type instead.
 func (*OneofDescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{5}
@@ -917,6 +941,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[6].MessageOf(x)
 }
 
+func (m *EnumDescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[6].Methods()
+}
+
 // Deprecated: Use EnumDescriptorProto.ProtoReflect.Type instead.
 func (*EnumDescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{6}
@@ -981,6 +1009,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[7].MessageOf(x)
 }
 
+func (m *EnumValueDescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[7].Methods()
+}
+
 // Deprecated: Use EnumValueDescriptorProto.ProtoReflect.Type instead.
 func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{7}
@@ -1031,6 +1063,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[8].MessageOf(x)
 }
 
+func (m *ServiceDescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[8].Methods()
+}
+
 // Deprecated: Use ServiceDescriptorProto.ProtoReflect.Type instead.
 func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{8}
@@ -1088,6 +1124,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[9].MessageOf(x)
 }
 
+func (m *MethodDescriptorProto) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[9].Methods()
+}
+
 // Deprecated: Use MethodDescriptorProto.ProtoReflect.Type instead.
 func (*MethodDescriptorProto) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{9}
@@ -1243,6 +1283,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[10].MessageOf(x)
 }
 
+func (m *FileOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[10].Methods()
+}
+
 // Deprecated: Use FileOptions.ProtoReflect.Type instead.
 func (*FileOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{10}
@@ -1488,6 +1532,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[11].MessageOf(x)
 }
 
+func (m *MessageOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[11].Methods()
+}
+
 // Deprecated: Use MessageOptions.ProtoReflect.Type instead.
 func (*MessageOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{11}
@@ -1623,6 +1671,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[12].MessageOf(x)
 }
 
+func (m *FieldOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[12].Methods()
+}
+
 // Deprecated: Use FieldOptions.ProtoReflect.Type instead.
 func (*FieldOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{12}
@@ -1715,6 +1767,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[13].MessageOf(x)
 }
 
+func (m *OneofOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[13].Methods()
+}
+
 // Deprecated: Use OneofOptions.ProtoReflect.Type instead.
 func (*OneofOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{13}
@@ -1767,6 +1823,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[14].MessageOf(x)
 }
 
+func (m *EnumOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[14].Methods()
+}
+
 // Deprecated: Use EnumOptions.ProtoReflect.Type instead.
 func (*EnumOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{14}
@@ -1832,6 +1892,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[15].MessageOf(x)
 }
 
+func (m *EnumValueOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[15].Methods()
+}
+
 // Deprecated: Use EnumValueOptions.ProtoReflect.Type instead.
 func (*EnumValueOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{15}
@@ -1890,6 +1954,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[16].MessageOf(x)
 }
 
+func (m *ServiceOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[16].Methods()
+}
+
 // Deprecated: Use ServiceOptions.ProtoReflect.Type instead.
 func (*ServiceOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{16}
@@ -1949,6 +2017,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[17].MessageOf(x)
 }
 
+func (m *MethodOptions) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[17].Methods()
+}
+
 // Deprecated: Use MethodOptions.ProtoReflect.Type instead.
 func (*MethodOptions) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{17}
@@ -2022,6 +2094,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[18].MessageOf(x)
 }
 
+func (m *UninterpretedOption) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[18].Methods()
+}
+
 // Deprecated: Use UninterpretedOption.ProtoReflect.Type instead.
 func (*UninterpretedOption) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{18}
@@ -2142,6 +2218,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[19].MessageOf(x)
 }
 
+func (m *SourceCodeInfo) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[19].Methods()
+}
+
 // Deprecated: Use SourceCodeInfo.ProtoReflect.Type instead.
 func (*SourceCodeInfo) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19}
@@ -2180,6 +2260,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[20].MessageOf(x)
 }
 
+func (m *GeneratedCodeInfo) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[20].Methods()
+}
+
 // Deprecated: Use GeneratedCodeInfo.ProtoReflect.Type instead.
 func (*GeneratedCodeInfo) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{20}
@@ -2215,6 +2299,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[21].MessageOf(x)
 }
 
+func (m *DescriptorProto_ExtensionRange) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[21].Methods()
+}
+
 // Deprecated: Use DescriptorProto_ExtensionRange.ProtoReflect.Type instead.
 func (*DescriptorProto_ExtensionRange) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{2, 0}
@@ -2266,6 +2354,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[22].MessageOf(x)
 }
 
+func (m *DescriptorProto_ReservedRange) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[22].Methods()
+}
+
 // Deprecated: Use DescriptorProto_ReservedRange.ProtoReflect.Type instead.
 func (*DescriptorProto_ReservedRange) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{2, 1}
@@ -2313,6 +2405,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[23].MessageOf(x)
 }
 
+func (m *EnumDescriptorProto_EnumReservedRange) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[23].Methods()
+}
+
 // Deprecated: Use EnumDescriptorProto_EnumReservedRange.ProtoReflect.Type instead.
 func (*EnumDescriptorProto_EnumReservedRange) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{6, 0}
@@ -2359,6 +2455,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[24].MessageOf(x)
 }
 
+func (m *UninterpretedOption_NamePart) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[24].Methods()
+}
+
 // Deprecated: Use UninterpretedOption_NamePart.ProtoReflect.Type instead.
 func (*UninterpretedOption_NamePart) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{18, 0}
@@ -2478,6 +2578,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[25].MessageOf(x)
 }
 
+func (m *SourceCodeInfo_Location) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[25].Methods()
+}
+
 // Deprecated: Use SourceCodeInfo_Location.ProtoReflect.Type instead.
 func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19, 0}
@@ -2550,6 +2654,10 @@
 	return xxx_File_google_protobuf_descriptor_proto_messageTypes[26].MessageOf(x)
 }
 
+func (m *GeneratedCodeInfo_Annotation) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_descriptor_proto_messageTypes[26].Methods()
+}
+
 // Deprecated: Use GeneratedCodeInfo_Annotation.ProtoReflect.Type instead.
 func (*GeneratedCodeInfo_Annotation) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_descriptor_proto_rawDescGZIP(), []int{20, 0}
diff --git a/types/known/any.pb.go b/types/known/any.pb.go
index 4fa309b..f9cbcf3 100644
--- a/types/known/any.pb.go
+++ b/types/known/any.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -143,6 +144,10 @@
 	return xxx_File_google_protobuf_any_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Any) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_any_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Any.ProtoReflect.Type instead.
 func (*Any) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_any_proto_rawDescGZIP(), []int{0}
diff --git a/types/known/api.pb.go b/types/known/api.pb.go
index b1162cc..770e892 100644
--- a/types/known/api.pb.go
+++ b/types/known/api.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -77,6 +78,10 @@
 	return xxx_File_google_protobuf_api_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Api) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_api_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Api.ProtoReflect.Type instead.
 func (*Api) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_api_proto_rawDescGZIP(), []int{0}
@@ -166,6 +171,10 @@
 	return xxx_File_google_protobuf_api_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Method) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_api_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Method.ProtoReflect.Type instead.
 func (*Method) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_api_proto_rawDescGZIP(), []int{1}
@@ -323,6 +332,10 @@
 	return xxx_File_google_protobuf_api_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Mixin) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_api_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Mixin.ProtoReflect.Type instead.
 func (*Mixin) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_api_proto_rawDescGZIP(), []int{2}
diff --git a/types/known/duration.pb.go b/types/known/duration.pb.go
index 736c9a9..dfb0692 100644
--- a/types/known/duration.pb.go
+++ b/types/known/duration.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -103,6 +104,10 @@
 	return xxx_File_google_protobuf_duration_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Duration) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_duration_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Duration.ProtoReflect.Type instead.
 func (*Duration) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_duration_proto_rawDescGZIP(), []int{0}
diff --git a/types/known/empty.pb.go b/types/known/empty.pb.go
index db7ee9e..3bed109 100644
--- a/types/known/empty.pb.go
+++ b/types/known/empty.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -41,6 +42,10 @@
 	return xxx_File_google_protobuf_empty_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Empty) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_empty_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Empty.ProtoReflect.Type instead.
 func (*Empty) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_empty_proto_rawDescGZIP(), []int{0}
diff --git a/types/known/field_mask.pb.go b/types/known/field_mask.pb.go
index dbeee7f..9e0c729 100644
--- a/types/known/field_mask.pb.go
+++ b/types/known/field_mask.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -233,6 +234,10 @@
 	return xxx_File_google_protobuf_field_mask_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *FieldMask) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_field_mask_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use FieldMask.ProtoReflect.Type instead.
 func (*FieldMask) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_field_mask_proto_rawDescGZIP(), []int{0}
diff --git a/types/known/source_context.pb.go b/types/known/source_context.pb.go
index 9a875ee..7257925 100644
--- a/types/known/source_context.pb.go
+++ b/types/known/source_context.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -37,6 +38,10 @@
 	return xxx_File_google_protobuf_source_context_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *SourceContext) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_source_context_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use SourceContext.ProtoReflect.Type instead.
 func (*SourceContext) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_source_context_proto_rawDescGZIP(), []int{0}
diff --git a/types/known/struct.pb.go b/types/known/struct.pb.go
index 9d4a208..8facc31 100644
--- a/types/known/struct.pb.go
+++ b/types/known/struct.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -82,6 +83,10 @@
 	return xxx_File_google_protobuf_struct_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Struct) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_struct_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Struct.ProtoReflect.Type instead.
 func (*Struct) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_struct_proto_rawDescGZIP(), []int{0}
@@ -138,6 +143,10 @@
 	return xxx_File_google_protobuf_struct_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Value) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_struct_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Value.ProtoReflect.Type instead.
 func (*Value) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_struct_proto_rawDescGZIP(), []int{1}
@@ -271,6 +280,10 @@
 	return xxx_File_google_protobuf_struct_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *ListValue) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_struct_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use ListValue.ProtoReflect.Type instead.
 func (*ListValue) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_struct_proto_rawDescGZIP(), []int{2}
diff --git a/types/known/timestamp.pb.go b/types/known/timestamp.pb.go
index a4a1307..a3ca7a3 100644
--- a/types/known/timestamp.pb.go
+++ b/types/known/timestamp.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -123,6 +124,10 @@
 	return xxx_File_google_protobuf_timestamp_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Timestamp) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_timestamp_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Timestamp.ProtoReflect.Type instead.
 func (*Timestamp) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_timestamp_proto_rawDescGZIP(), []int{0}
diff --git a/types/known/type.pb.go b/types/known/type.pb.go
index 12b5617..5f44d39 100644
--- a/types/known/type.pb.go
+++ b/types/known/type.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -238,6 +239,10 @@
 	return xxx_File_google_protobuf_type_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Type) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_type_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Type.ProtoReflect.Type instead.
 func (*Type) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_type_proto_rawDescGZIP(), []int{0}
@@ -328,6 +333,10 @@
 	return xxx_File_google_protobuf_type_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *Field) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_type_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use Field.ProtoReflect.Type instead.
 func (*Field) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_type_proto_rawDescGZIP(), []int{1}
@@ -434,6 +443,10 @@
 	return xxx_File_google_protobuf_type_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Enum) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_type_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Enum.ProtoReflect.Type instead.
 func (*Enum) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_type_proto_rawDescGZIP(), []int{2}
@@ -501,6 +514,10 @@
 	return xxx_File_google_protobuf_type_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *EnumValue) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_type_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use EnumValue.ProtoReflect.Type instead.
 func (*EnumValue) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_type_proto_rawDescGZIP(), []int{3}
@@ -559,6 +576,10 @@
 	return xxx_File_google_protobuf_type_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *Option) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_type_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use Option.ProtoReflect.Type instead.
 func (*Option) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_type_proto_rawDescGZIP(), []int{4}
diff --git a/types/known/wrappers.pb.go b/types/known/wrappers.pb.go
index 08ce6d8..a1ee28a 100644
--- a/types/known/wrappers.pb.go
+++ b/types/known/wrappers.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	sync "sync"
 )
@@ -37,6 +38,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *DoubleValue) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use DoubleValue.ProtoReflect.Type instead.
 func (*DoubleValue) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{0}
@@ -76,6 +81,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *FloatValue) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use FloatValue.ProtoReflect.Type instead.
 func (*FloatValue) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{1}
@@ -115,6 +124,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *Int64Value) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use Int64Value.ProtoReflect.Type instead.
 func (*Int64Value) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{2}
@@ -154,6 +167,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *UInt64Value) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use UInt64Value.ProtoReflect.Type instead.
 func (*UInt64Value) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{3}
@@ -193,6 +210,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[4].MessageOf(x)
 }
 
+func (m *Int32Value) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[4].Methods()
+}
+
 // Deprecated: Use Int32Value.ProtoReflect.Type instead.
 func (*Int32Value) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{4}
@@ -232,6 +253,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[5].MessageOf(x)
 }
 
+func (m *UInt32Value) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[5].Methods()
+}
+
 // Deprecated: Use UInt32Value.ProtoReflect.Type instead.
 func (*UInt32Value) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{5}
@@ -271,6 +296,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[6].MessageOf(x)
 }
 
+func (m *BoolValue) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[6].Methods()
+}
+
 // Deprecated: Use BoolValue.ProtoReflect.Type instead.
 func (*BoolValue) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{6}
@@ -310,6 +339,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[7].MessageOf(x)
 }
 
+func (m *StringValue) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[7].Methods()
+}
+
 // Deprecated: Use StringValue.ProtoReflect.Type instead.
 func (*StringValue) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{7}
@@ -349,6 +382,10 @@
 	return xxx_File_google_protobuf_wrappers_proto_messageTypes[8].MessageOf(x)
 }
 
+func (m *BytesValue) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_wrappers_proto_messageTypes[8].Methods()
+}
+
 // Deprecated: Use BytesValue.ProtoReflect.Type instead.
 func (*BytesValue) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_wrappers_proto_rawDescGZIP(), []int{8}
diff --git a/types/plugin/plugin.pb.go b/types/plugin/plugin.pb.go
index 639634c..dc65859 100644
--- a/types/plugin/plugin.pb.go
+++ b/types/plugin/plugin.pb.go
@@ -6,6 +6,7 @@
 import (
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
+	protoiface "github.com/golang/protobuf/v2/runtime/protoiface"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	descriptor "github.com/golang/protobuf/v2/types/descriptor"
 	sync "sync"
@@ -40,6 +41,10 @@
 	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[0].MessageOf(x)
 }
 
+func (m *Version) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[0].Methods()
+}
+
 // Deprecated: Use Version.ProtoReflect.Type instead.
 func (*Version) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{0}
@@ -117,6 +122,10 @@
 	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[1].MessageOf(x)
 }
 
+func (m *CodeGeneratorRequest) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[1].Methods()
+}
+
 // Deprecated: Use CodeGeneratorRequest.ProtoReflect.Type instead.
 func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{1}
@@ -181,6 +190,10 @@
 	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[2].MessageOf(x)
 }
 
+func (m *CodeGeneratorResponse) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[2].Methods()
+}
+
 // Deprecated: Use CodeGeneratorResponse.ProtoReflect.Type instead.
 func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{2}
@@ -273,6 +286,10 @@
 	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[3].MessageOf(x)
 }
 
+func (m *CodeGeneratorResponse_File) XXX_Methods() *protoiface.Methods {
+	return xxx_File_google_protobuf_compiler_plugin_proto_messageTypes[3].Methods()
+}
+
 // Deprecated: Use CodeGeneratorResponse_File.ProtoReflect.Type instead.
 func (*CodeGeneratorResponse_File) Descriptor() ([]byte, []int) {
 	return xxx_File_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{2, 0}