Просмотр исходного кода

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>
Damien Neil 6 лет назад
Родитель
Сommit
0d3e8cc096
62 измененных файлов с 881 добавлено и 3 удалено
  1. 9 0
      cmd/protoc-gen-go-grpc/testdata/grpc/grpc.pb.go
  2. 3 0
      cmd/protoc-gen-go/internal_gengo/reflect.go
  3. 5 0
      cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
  4. 1 1
      cmd/protoc-gen-go/testdata/annotations/annotations.pb.go.meta
  5. 25 0
      cmd/protoc-gen-go/testdata/comments/comments.pb.go
  6. 5 0
      cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
  7. 8 0
      cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
  8. 32 0
      cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
  9. 5 0
      cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
  10. 4 0
      cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
  11. 9 0
      cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
  12. 5 0
      cmd/protoc-gen-go/testdata/import_public/a.pb.go
  13. 5 0
      cmd/protoc-gen-go/testdata/import_public/b.pb.go
  14. 8 0
      cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
  15. 5 0
      cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go
  16. 5 0
      cmd/protoc-gen-go/testdata/import_public/sub2/a.pb.go
  17. 5 0
      cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
  18. 9 0
      cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
  19. 5 0
      cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
  20. 5 0
      cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
  21. 5 0
      cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
  22. 5 0
      cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
  23. 5 0
      cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
  24. 5 0
      cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
  25. 5 0
      cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
  26. 5 0
      cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
  27. 5 0
      cmd/protoc-gen-go/testdata/issue780_oneof_conflict/test.pb.go
  28. 5 0
      cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
  29. 9 0
      cmd/protoc-gen-go/testdata/proto2/enum.pb.go
  30. 25 0
      cmd/protoc-gen-go/testdata/proto2/fields.pb.go
  31. 13 0
      cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
  32. 5 0
      cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
  33. 9 0
      cmd/protoc-gen-go/testdata/proto3/fields.pb.go
  34. 76 0
      encoding/testprotos/pb2/test.pb.go
  35. 29 0
      encoding/testprotos/pb3/test.pb.go
  36. 8 0
      internal/impl/message.go
  37. 17 0
      internal/testprotos/conformance/conformance.pb.go
  38. 5 0
      internal/testprotos/legacy/legacy.pb.go
  39. 52 0
      internal/testprotos/test/test.pb.go
  40. 5 0
      internal/testprotos/test/test_import.pb.go
  41. 5 0
      internal/testprotos/test/test_public.pb.go
  42. 5 0
      internal/testprotos/test/test_weak.pb.go
  43. 13 0
      internal/testprotos/test3/test.pb.go
  44. 5 0
      internal/testprotos/test3/test_import.pb.go
  45. 21 0
      proto/decode.go
  46. 32 1
      proto/encode.go
  47. 16 1
      proto/proto.go
  48. 12 0
      proto/size.go
  49. 16 0
      reflect/protoregistry/testprotos/test.pb.go
  50. 66 0
      runtime/protoiface/methods.go
  51. 108 0
      types/descriptor/descriptor.pb.go
  52. 5 0
      types/known/any.pb.go
  53. 13 0
      types/known/api.pb.go
  54. 5 0
      types/known/duration.pb.go
  55. 5 0
      types/known/empty.pb.go
  56. 5 0
      types/known/field_mask.pb.go
  57. 5 0
      types/known/source_context.pb.go
  58. 13 0
      types/known/struct.pb.go
  59. 5 0
      types/known/timestamp.pb.go
  60. 21 0
      types/known/type.pb.go
  61. 37 0
      types/known/wrappers.pb.go
  62. 17 0
      types/plugin/plugin.pb.go

+ 9 - 0
cmd/protoc-gen-go-grpc/testdata/grpc/grpc.pb.go

@@ -6,6 +6,7 @@ package grpc
 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 @@ func (x *Request) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Response) ProtoReflect() protoreflect.Message {
 	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}

+ 3 - 0
cmd/protoc-gen-go/internal_gengo/reflect.go

@@ -265,6 +265,9 @@ func genReflectMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileI
 	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 {

+ 5 - 0
cmd/protoc-gen-go/testdata/annotations/annotations.pb.go

@@ -6,6 +6,7 @@ package annotations
 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 @@ func (x *AnnotationsTestMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 1 - 1
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}
+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}

+ 25 - 0
cmd/protoc-gen-go/testdata/comments/comments.pb.go

@@ -8,6 +8,7 @@ package comments
 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 @@ func (x *Message1) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message2) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message1_Message1A) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message1_Message1B) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message2_Message2A) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message2_Message2B) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/comments/deprecated.pb.go

@@ -6,6 +6,7 @@ package comments
 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 @@ func (x *DeprecatedMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 8 - 0
cmd/protoc-gen-go/testdata/extensions/base/base.pb.go

@@ -35,6 +35,10 @@ func (x *BaseMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *MessageSetWireFormatMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 32 - 0
cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go

@@ -83,6 +83,10 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ExtensionGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ExtendingMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *RepeatedGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Extendable) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *MessageSetWireFormatExtension) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message_M) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ExtendingMessage_ExtendingMessageSubmessage) ProtoReflect() protoreflec
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go

@@ -6,6 +6,7 @@ package extra
 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 @@ func (x *ExtraMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 4 - 0
cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go

@@ -67,6 +67,10 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 	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}

+ 9 - 0
cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go

@@ -6,6 +6,7 @@ package fieldnames
 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 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message_OneofMessageConflict) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/import_public/a.pb.go

@@ -8,6 +8,7 @@ import (
 	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 @@ func (x *Public) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/import_public/b.pb.go

@@ -7,6 +7,7 @@ import (
 	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 @@ func (x *Local) ProtoReflect() protoreflect.Message {
 	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}

+ 8 - 0
cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go

@@ -190,6 +190,10 @@ func (x *M) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *M_Submessage) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go

@@ -6,6 +6,7 @@ package sub
 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 @@ func (x *M2) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/import_public/sub2/a.pb.go

@@ -6,6 +6,7 @@ package sub2
 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 @@ func (x *Sub2Message) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go

@@ -6,6 +6,7 @@ package fmt
 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 @@ func (x *M) ProtoReflect() protoreflect.Message {
 	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}

+ 9 - 0
cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go

@@ -6,6 +6,7 @@ package test_a_1
 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 @@ func (x *M1) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *M1_1) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go

@@ -6,6 +6,7 @@ package test_a_1
 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 @@ func (x *M2) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go

@@ -6,6 +6,7 @@ package test_a_2
 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 @@ func (x *M3) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go

@@ -6,6 +6,7 @@ package test_a_2
 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 @@ func (x *M4) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go

@@ -6,6 +6,7 @@ package beta
 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 @@ func (x *M1) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go

@@ -6,6 +6,7 @@ package beta
 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 @@ func (x *M2) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go

@@ -7,6 +7,7 @@ import (
 	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 @@ func (x *A1M1) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go

@@ -7,6 +7,7 @@ import (
 	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 @@ func (x *A1M2) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go

@@ -10,6 +10,7 @@ import (
 	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 @@ func (x *All) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/issue780_oneof_conflict/test.pb.go

@@ -6,6 +6,7 @@ package oneoftest
 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 @@ func (x *Foo) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go

@@ -6,6 +6,7 @@ package nopackage
 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 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 	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}

+ 9 - 0
cmd/protoc-gen-go/testdata/proto2/enum.pb.go

@@ -6,6 +6,7 @@ package proto2
 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 @@ func (x *EnumContainerMessage1) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *EnumContainerMessage1_EnumContainerMessage2) ProtoReflect() protoreflec
 	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}

+ 25 - 0
cmd/protoc-gen-go/testdata/proto2/fields.pb.go

@@ -6,6 +6,7 @@ package proto2
 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 @@ func (x *FieldTestMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldTestMessage_OptionalGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldTestMessage_RequiredGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldTestMessage_RepeatedGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldTestMessage_OneofGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldTestMessage_Message) ProtoReflect() protoreflect.Message {
 	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}

+ 13 - 0
cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go

@@ -6,6 +6,7 @@ package proto2
 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 @@ func (x *Layer1) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Layer1_Layer2) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Layer1_Layer2_Layer3) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
cmd/protoc-gen-go/testdata/proto2/proto2.pb.go

@@ -6,6 +6,7 @@ package proto2
 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 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 	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}

+ 9 - 0
cmd/protoc-gen-go/testdata/proto3/fields.pb.go

@@ -6,6 +6,7 @@ package proto3
 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 @@ func (x *FieldTestMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldTestMessage_Message) ProtoReflect() protoreflect.Message {
 	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}

+ 76 - 0
encoding/testprotos/pb2/test.pb.go

@@ -156,6 +156,10 @@ func (x *Scalars) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Enums) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Repeats) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Nested) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Nests) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Requireds) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *PartialRequired) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *NestedWithRequired) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *IndirectRequired) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Extensions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ExtensionsContainer) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *MessageSet) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *MessageSetExtension) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FakeMessageSet) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FakeMessageSetExtension) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *KnownTypes) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Nests_OptGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Nests_RptGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Nests_OptGroup_OptNestedGroup) ProtoReflect() protoreflect.Message {
 	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}

+ 29 - 0
encoding/testprotos/pb3/test.pb.go

@@ -6,6 +6,7 @@ package pb3
 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 @@ func (x *Scalars) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Enums) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Nests) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Nested) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Oneofs) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Maps) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *JSONNames) ProtoReflect() protoreflect.Message {
 	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}

+ 8 - 0
internal/impl/message.go

@@ -13,6 +13,7 @@ import (
 
 	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 @@ func (mi *MessageType) MessageOf(p interface{}) pref.Message {
 	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 @@ type messageIfaceWrapper messageDataType
 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())
 }

+ 17 - 0
internal/testprotos/conformance/conformance.pb.go

@@ -6,6 +6,7 @@ package conformance_proto
 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 @@ func (x *FailureSet) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ConformanceRequest) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ConformanceResponse) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *JspbEncodingConfig) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
internal/testprotos/legacy/legacy.pb.go

@@ -18,6 +18,7 @@ import (
 	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 @@ func (x *Legacy) ProtoReflect() protoreflect.Message {
 	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}

+ 52 - 0
internal/testprotos/test/test.pb.go

@@ -325,6 +325,10 @@ func (x *TestAllTypes) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestDeprecatedMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ForeignMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestReservedFields) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestAllExtensions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *OptionalGroupExtension) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *RepeatedGroupExtension) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestNestedExtension) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FooRequest) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FooResponse) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestAllTypes_NestedMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestAllTypes_OptionalGroup) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestAllTypes_RepeatedGroup) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
internal/testprotos/test/test_import.pb.go

@@ -6,6 +6,7 @@ package test
 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 @@ func (x *ImportMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
internal/testprotos/test/test_public.pb.go

@@ -6,6 +6,7 @@ package test
 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 @@ func (x *PublicImportMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
internal/testprotos/test/test_weak.pb.go

@@ -6,6 +6,7 @@ package test
 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 @@ func (x *WeakImportMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 13 - 0
internal/testprotos/test3/test.pb.go

@@ -6,6 +6,7 @@ package test3
 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 @@ func (x *TestAllTypes) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ForeignMessage) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *TestAllTypes_NestedMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
internal/testprotos/test3/test_import.pb.go

@@ -6,6 +6,7 @@ package test3
 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 @@ func (x *ImportMessage) ProtoReflect() protoreflect.Message {
 	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}

+ 21 - 0
proto/decode.go

@@ -10,6 +10,7 @@ import (
 	"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 @@ type UnmarshalOptions struct {
 	// 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 @@ func Unmarshal(b []byte, m Message) error {
 // 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()

+ 32 - 1
proto/encode.go

@@ -12,6 +12,7 @@ import (
 	"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 @@ type MarshalOptions struct {
 	// 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 @@ func Marshal(m Message) ([]byte, error) {
 
 // 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.

+ 16 - 1
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
+}

+ 12 - 0
proto/size.go

@@ -13,9 +13,21 @@ import (
 
 // 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()

+ 16 - 0
reflect/protoregistry/testprotos/test.pb.go

@@ -175,6 +175,10 @@ func (x *Message1) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message2) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message3) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Message4) ProtoReflect() protoreflect.Message {
 	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}

+ 66 - 0
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
+}

+ 108 - 0
types/descriptor/descriptor.pb.go

@@ -421,6 +421,10 @@ func (x *FileDescriptorSet) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FileDescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *DescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ExtensionRangeOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldDescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *OneofDescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *EnumDescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *EnumValueDescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ServiceDescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *MethodDescriptorProto) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FileOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *MessageOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FieldOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *OneofOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *EnumOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *EnumValueOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ServiceOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *MethodOptions) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *UninterpretedOption) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *SourceCodeInfo) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *GeneratedCodeInfo) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *DescriptorProto_ExtensionRange) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *DescriptorProto_ReservedRange) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *EnumDescriptorProto_EnumReservedRange) ProtoReflect() protoreflect.Mess
 	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 @@ func (x *UninterpretedOption_NamePart) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *SourceCodeInfo_Location) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *GeneratedCodeInfo_Annotation) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
types/known/any.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *Any) ProtoReflect() protoreflect.Message {
 	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}

+ 13 - 0
types/known/api.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *Api) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Method) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Mixin) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
types/known/duration.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *Duration) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
types/known/empty.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *Empty) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
types/known/field_mask.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *FieldMask) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
types/known/source_context.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *SourceContext) ProtoReflect() protoreflect.Message {
 	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}

+ 13 - 0
types/known/struct.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *Struct) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Value) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *ListValue) ProtoReflect() protoreflect.Message {
 	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}

+ 5 - 0
types/known/timestamp.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *Timestamp) ProtoReflect() protoreflect.Message {
 	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}

+ 21 - 0
types/known/type.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *Type) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Field) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Enum) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *EnumValue) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Option) ProtoReflect() protoreflect.Message {
 	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}

+ 37 - 0
types/known/wrappers.pb.go

@@ -6,6 +6,7 @@ package known_proto
 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 @@ func (x *DoubleValue) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *FloatValue) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Int64Value) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *UInt64Value) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *Int32Value) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *UInt32Value) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *BoolValue) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *StringValue) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *BytesValue) ProtoReflect() protoreflect.Message {
 	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}

+ 17 - 0
types/plugin/plugin.pb.go

@@ -6,6 +6,7 @@ package plugin_proto
 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 @@ func (x *Version) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *CodeGeneratorRequest) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *CodeGeneratorResponse) ProtoReflect() protoreflect.Message {
 	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 @@ func (x *CodeGeneratorResponse_File) ProtoReflect() protoreflect.Message {
 	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}