Procházet zdrojové kódy

all: drop reflect/prototype package

Remove the remaining uses of the prototype package.

The most significant change is to impl.MessageInfo, which now directly
implements the MessageType interface. This involves two notable changes
to exported fields of MessageInfo:

  - PBType is now Desc.
  - GoType is now GoReflectType. (Name changed to avoid a conflict with
    the GoType method of the MessageType interface.)

Fixes golang/protobuf#911

Change-Id: Ie2aa4766d6887ceaa9cf06b1f109aa6e6e2a208f
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/189340
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Damien Neil před 6 roky
rodič
revize
16163b4f67

+ 4 - 4
internal/cmd/generate-types/impl.go

@@ -602,13 +602,13 @@ func generateImplMessage() string {
 var implMessageTemplate = template.Must(template.New("").Parse(`
 {{range . -}}
 func (m *{{.}}) Descriptor() protoreflect.MessageDescriptor {
-	return m.messageInfo().PBType.Descriptor()
+	return m.messageInfo().Desc
 }
 func (m *{{.}}) Type() protoreflect.MessageType {
-	return m.messageInfo().PBType
+	return m.messageInfo()
 }
 func (m *{{.}}) New() protoreflect.Message {
-	return m.messageInfo().PBType.New()
+	return m.messageInfo().New()
 }
 func (m *{{.}}) Interface() protoreflect.ProtoMessage {
 	{{if eq . "messageState" -}}
@@ -621,7 +621,7 @@ func (m *{{.}}) Interface() protoreflect.ProtoMessage {
 	{{- end -}}
 }
 func (m *{{.}}) ProtoUnwrap() interface{} {
-	return m.pointer().AsIfaceOf(m.messageInfo().GoType.Elem())
+	return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
 }
 func (m *{{.}}) ProtoMethods() *protoiface.Methods {
 	m.messageInfo().init()

+ 3 - 13
internal/filetype/build.go

@@ -15,7 +15,6 @@ import (
 	pimpl "google.golang.org/protobuf/internal/impl"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	preg "google.golang.org/protobuf/reflect/protoregistry"
-	ptype "google.golang.org/protobuf/reflect/prototype"
 	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
@@ -163,23 +162,18 @@ func (tb Builder) Build() (out struct {
 		panic("mismatching message lengths")
 	}
 	if len(fbOut.Messages) > 0 {
-		messages := make([]Message, len(fbOut.Messages))
 		for i := range fbOut.Messages {
 			if messageGoTypes[i] == nil {
 				continue // skip map entry
 			}
-			messages[i] = Message{
-				MessageDescriptor: &fbOut.Messages[i],
-				NewMessage:        messageMaker(reflect.TypeOf(messageGoTypes[i])),
-			}
 
 			if tb.MessageInfos != nil {
-				tb.MessageInfos[i].GoType = reflect.TypeOf(messageGoTypes[i])
-				tb.MessageInfos[i].PBType = &messages[i]
+				tb.MessageInfos[i].GoReflectType = reflect.TypeOf(messageGoTypes[i])
+				tb.MessageInfos[i].Desc = &fbOut.Messages[i]
 			}
 
 			// Register message types.
-			if err := tb.TypeRegistry.Register(&messages[i]); err != nil {
+			if err := tb.TypeRegistry.Register(&tb.MessageInfos[i]); err != nil {
 				panic(err)
 			}
 		}
@@ -335,10 +329,6 @@ func messageMaker(t reflect.Type) func() pref.Message {
 	}
 }
 
-type (
-	Message = ptype.Message
-)
-
 type Extension struct {
 	desc       pref.ExtensionDescriptor
 	tdesc      extensionTypeDescriptor

+ 3 - 14
internal/impl/api_export.go

@@ -10,7 +10,6 @@ import (
 
 	"google.golang.org/protobuf/encoding/prototext"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/prototype"
 	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
@@ -33,12 +32,7 @@ func (Export) EnumOf(e enum) pref.Enum {
 // EnumTypeOf returns the protoreflect.EnumType for e.
 func (Export) EnumTypeOf(e enum) pref.EnumType {
 	if ev, ok := e.(pref.Enum); ok {
-		return &prototype.Enum{
-			EnumDescriptor: ev.Descriptor(),
-			NewEnum: func(n pref.EnumNumber) pref.Enum {
-				return reflect.ValueOf(n).Convert(reflect.TypeOf(e)).Interface().(pref.Enum)
-			},
-		}
+		return ev.Type()
 	}
 	return legacyLoadEnumType(reflect.TypeOf(e))
 }
@@ -76,14 +70,9 @@ func (Export) MessageOf(m message) pref.Message {
 // MessageTypeOf returns the protoreflect.MessageType for m.
 func (Export) MessageTypeOf(m message) pref.MessageType {
 	if mv, ok := m.(pref.ProtoMessage); ok {
-		return &prototype.Message{
-			MessageDescriptor: mv.ProtoReflect().Descriptor(),
-			NewMessage: func() pref.Message {
-				return reflect.New(reflect.TypeOf(m).Elem()).Interface().(pref.ProtoMessage).ProtoReflect()
-			},
-		}
+		return mv.ProtoReflect().Type()
 	}
-	return legacyLoadMessageInfo(reflect.TypeOf(m)).PBType
+	return legacyLoadMessageInfo(reflect.TypeOf(m))
 }
 
 // MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.

+ 4 - 4
internal/impl/codec_field.go

@@ -138,7 +138,7 @@ func consumeMessageInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, op
 		return 0, wire.ParseError(n)
 	}
 	if p.Elem().IsNil() {
-		p.SetPointer(pointerOfValue(reflect.New(mi.GoType.Elem())))
+		p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
 	}
 	if _, err := mi.unmarshalPointer(v, p.Elem(), 0, opts); err != nil {
 		return 0, err
@@ -256,7 +256,7 @@ func consumeGroupType(b []byte, p pointer, mi *MessageInfo, num wire.Number, wty
 		return 0, errUnknown
 	}
 	if p.Elem().IsNil() {
-		p.SetPointer(pointerOfValue(reflect.New(mi.GoType.Elem())))
+		p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
 	}
 	return mi.unmarshalPointer(b, p.Elem(), num, opts)
 }
@@ -367,7 +367,7 @@ func consumeMessageSliceInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Typ
 	if n < 0 {
 		return 0, wire.ParseError(n)
 	}
-	m := reflect.New(mi.GoType.Elem()).Interface()
+	m := reflect.New(mi.GoReflectType.Elem()).Interface()
 	mp := pointerOfIface(m)
 	if _, err := mi.unmarshalPointer(v, mp, 0, opts); err != nil {
 		return 0, err
@@ -571,7 +571,7 @@ func consumeGroupSliceInfo(b []byte, p pointer, num wire.Number, wtyp wire.Type,
 	if wtyp != wire.StartGroupType {
 		return 0, errUnknown
 	}
-	m := reflect.New(mi.GoType.Elem()).Interface()
+	m := reflect.New(mi.GoReflectType.Elem()).Interface()
 	mp := pointerOfIface(m)
 	n, err := mi.unmarshalPointer(b, mp, num, opts)
 	if err != nil {

+ 4 - 4
internal/impl/codec_message.go

@@ -44,7 +44,7 @@ func (mi *MessageInfo) makeMethods(t reflect.Type, si structInfo) {
 	mi.extensionOffset = si.extensionOffset
 
 	mi.coderFields = make(map[wire.Number]*coderFieldInfo)
-	fields := mi.PBType.Descriptor().Fields()
+	fields := mi.Desc.Fields()
 	for i := 0; i < fields.Len(); i++ {
 		fd := fields.Get(i)
 
@@ -80,9 +80,9 @@ func (mi *MessageInfo) makeMethods(t reflect.Type, si structInfo) {
 		mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
 		mi.coderFields[cf.num] = cf
 	}
-	if messageset.IsMessageSet(mi.PBType.Descriptor()) {
+	if messageset.IsMessageSet(mi.Desc) {
 		if !mi.extensionOffset.IsValid() {
-			panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.PBType.Descriptor().FullName()))
+			panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
 		}
 		cf := &coderFieldInfo{
 			num:       messageset.FieldItem,
@@ -114,7 +114,7 @@ func (mi *MessageInfo) makeMethods(t reflect.Type, si structInfo) {
 		mi.denseCoderFields[cf.num] = cf
 	}
 
-	mi.needsInitCheck = needsInitCheck(mi.PBType.Descriptor())
+	mi.needsInitCheck = needsInitCheck(mi.Desc)
 	mi.methods = piface.Methods{
 		Flags:         piface.SupportMarshalDeterministic | piface.SupportUnmarshalDiscardUnknown,
 		MarshalAppend: mi.marshalAppend,

+ 1 - 1
internal/impl/decode.go

@@ -138,7 +138,7 @@ func (mi *MessageInfo) unmarshalExtension(b []byte, num wire.Number, wtyp wire.T
 	xt := x.GetType()
 	if xt == nil {
 		var err error
-		xt, err = opts.Resolver().FindExtensionByNumber(mi.PBType.Descriptor().FullName(), num)
+		xt, err = opts.Resolver().FindExtensionByNumber(mi.Desc.FullName(), num)
 		if err != nil {
 			if err == preg.NotFound {
 				return 0, errUnknown

+ 2 - 2
internal/impl/isinit.go

@@ -29,7 +29,7 @@ func (mi *MessageInfo) isInitializedPointer(p pointer) error {
 	if p.IsNil() {
 		for _, f := range mi.orderedCoderFields {
 			if f.isRequired {
-				return errors.RequiredNotSet(string(mi.PBType.Descriptor().Fields().ByNumber(f.num).FullName()))
+				return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
 			}
 		}
 		return nil
@@ -47,7 +47,7 @@ func (mi *MessageInfo) isInitializedPointer(p pointer) error {
 		fptr := p.Apply(f.offset)
 		if f.isPointer && fptr.Elem().IsNil() {
 			if f.isRequired {
-				return errors.RequiredNotSet(string(mi.PBType.Descriptor().Fields().ByNumber(f.num).FullName()))
+				return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
 			}
 			continue
 		}

+ 24 - 12
internal/impl/legacy_enum.go

@@ -13,7 +13,6 @@ import (
 	"google.golang.org/protobuf/internal/filedesc"
 	"google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/prototype"
 )
 
 // legacyWrapEnum wraps v as a protoreflect.Enum,
@@ -35,18 +34,10 @@ func legacyLoadEnumType(t reflect.Type) pref.EnumType {
 
 	// Slow-path: derive enum descriptor and initialize EnumType.
 	var et pref.EnumType
-	var m sync.Map // map[protoreflect.EnumNumber]proto.Enum
 	ed := LegacyLoadEnumDesc(t)
-	et = &prototype.Enum{
-		EnumDescriptor: ed,
-		NewEnum: func(n pref.EnumNumber) pref.Enum {
-			if e, ok := m.Load(n); ok {
-				return e.(pref.Enum)
-			}
-			e := &legacyEnumWrapper{num: n, pbTyp: et, goTyp: t}
-			m.Store(n, e)
-			return e
-		},
+	et = &legacyEnumType{
+		desc:   ed,
+		goType: t,
 	}
 	if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok {
 		return et.(pref.EnumType)
@@ -54,6 +45,27 @@ func legacyLoadEnumType(t reflect.Type) pref.EnumType {
 	return et
 }
 
+type legacyEnumType struct {
+	desc   pref.EnumDescriptor
+	goType reflect.Type
+	m      sync.Map // map[protoreflect.EnumNumber]proto.Enum
+}
+
+func (t *legacyEnumType) New(n pref.EnumNumber) pref.Enum {
+	if e, ok := t.m.Load(n); ok {
+		return e.(pref.Enum)
+	}
+	e := &legacyEnumWrapper{num: n, pbTyp: t, goTyp: t.goType}
+	t.m.Store(n, e)
+	return e
+}
+func (t *legacyEnumType) GoType() reflect.Type {
+	return t.goType
+}
+func (t *legacyEnumType) Descriptor() pref.EnumDescriptor {
+	return t.desc
+}
+
 type legacyEnumWrapper struct {
 	num   pref.EnumNumber
 	pbTyp pref.EnumType

+ 6 - 12
internal/impl/legacy_message.go

@@ -16,7 +16,6 @@ import (
 	"google.golang.org/protobuf/internal/strs"
 	"google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/prototype"
 )
 
 // legacyWrapMessage wraps v as a protoreflect.ProtoMessage,
@@ -37,19 +36,14 @@ func legacyLoadMessageInfo(t reflect.Type) *MessageInfo {
 	}
 
 	// Slow-path: derive message descriptor and initialize MessageInfo.
-	md := LegacyLoadMessageDesc(t)
-	mt := new(MessageInfo)
-	mt.GoType = t
-	mt.PBType = &prototype.Message{
-		MessageDescriptor: md,
-		NewMessage: func() pref.Message {
-			return mt.MessageOf(reflect.New(t.Elem()).Interface())
-		},
+	mi := &MessageInfo{
+		Desc:          LegacyLoadMessageDesc(t),
+		GoReflectType: t,
 	}
-	if mt, ok := legacyMessageTypeCache.LoadOrStore(t, mt); ok {
-		return mt.(*MessageInfo)
+	if mi, ok := legacyMessageTypeCache.LoadOrStore(t, mi); ok {
+		return mi.(*MessageInfo)
 	}
-	return mt
+	return mi
 }
 
 var legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor

+ 2 - 3
internal/impl/legacy_test.go

@@ -78,14 +78,13 @@ var (
 	testParentDesc    = pimpl.Export{}.MessageDescriptorOf((*LegacyTestMessage)(nil))
 	testEnumV1Desc    = pimpl.Export{}.EnumDescriptorOf(proto2_20180125.Message_ChildEnum(0))
 	testMessageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil))
-	testEnumV2Desc    = enumProto2Type.Descriptor()
-	testMessageV2Desc = enumMessagesType.PBType.Descriptor()
+	testMessageV2Desc = enumMessagesType.Desc
 
 	depReg = preg.NewFiles(
 		testParentDesc.ParentFile(),
 		testEnumV1Desc.ParentFile(),
 		testMessageV1Desc.ParentFile(),
-		testEnumV2Desc.ParentFile(),
+		enumProto2Desc.ParentFile(),
 		testMessageV2Desc.ParentFile(),
 	)
 	extensionTypes = []pref.ExtensionType{

+ 18 - 6
internal/impl/message.go

@@ -12,6 +12,7 @@ import (
 	"sync"
 	"sync/atomic"
 
+	"google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	piface "google.golang.org/protobuf/runtime/protoiface"
 )
@@ -20,13 +21,13 @@ import (
 // that represents a message. A given instance of MessageInfo is tied to
 // exactly one Go type, which must be a pointer to a struct type.
 type MessageInfo struct {
-	// GoType is the underlying message Go type and must be populated.
+	// GoReflectType is the underlying message Go type and must be populated.
 	// Once set, this field must never be mutated.
-	GoType reflect.Type // pointer to struct
+	GoReflectType reflect.Type // pointer to struct
 
-	// PBType is the underlying message descriptor type and must be populated.
+	// Desc is the underlying message descriptor type and must be populated.
 	// Once set, this field must never be mutated.
-	PBType pref.MessageType
+	Desc pref.MessageDescriptor
 
 	// Exporter must be provided in a purego environment in order to provide
 	// access to unexported fields.
@@ -95,7 +96,7 @@ func (mi *MessageInfo) initOnce() {
 		return
 	}
 
-	t := mi.GoType
+	t := mi.GoReflectType
 	if t.Kind() != reflect.Ptr && t.Elem().Kind() != reflect.Struct {
 		panic(fmt.Sprintf("got %v, want *struct kind", t))
 	}
@@ -222,7 +223,7 @@ fieldLoop:
 // any discrepancies.
 func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
 	mi.fields = map[pref.FieldNumber]*fieldInfo{}
-	md := mi.PBType.Descriptor()
+	md := mi.Desc
 	for i := 0; i < md.Fields().Len(); i++ {
 		fd := md.Fields().Get(i)
 		fs := si.fieldsByNumber[fd.Number()]
@@ -296,3 +297,14 @@ func (mi *MessageInfo) makeExtensionFieldsFunc(t reflect.Type, si structInfo) {
 		}
 	}
 }
+
+func (mi *MessageInfo) GoType() reflect.Type {
+	return mi.GoReflectType
+}
+func (mi *MessageInfo) New() protoreflect.Message {
+	return mi.MessageOf(reflect.New(mi.GoReflectType.Elem()).Interface())
+}
+func (mi *MessageInfo) Zero() protoreflect.Message {
+	return mi.MessageOf(reflect.Zero(mi.GoReflectType).Interface())
+}
+func (mi *MessageInfo) Descriptor() protoreflect.MessageDescriptor { return mi.Desc }

+ 5 - 5
internal/impl/message_reflect.go

@@ -95,8 +95,8 @@ var (
 // it must be implemented by calling this method.
 func (mi *MessageInfo) MessageOf(m interface{}) pref.Message {
 	// TODO: Switch the input to be an opaque Pointer.
-	if reflect.TypeOf(m) != mi.GoType {
-		panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoType))
+	if reflect.TypeOf(m) != mi.GoReflectType {
+		panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
 	}
 	p := pointerOfIface(m)
 	if p.IsNil() {
@@ -112,7 +112,7 @@ func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
 	return (*messageReflectWrapper)(m)
 }
 func (m *messageIfaceWrapper) ProtoUnwrap() interface{} {
-	return m.p.AsIfaceOf(m.mi.GoType.Elem())
+	return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
 }
 
 type extensionMap map[int32]ExtensionField
@@ -181,11 +181,11 @@ func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.Ext
 		return fi, nil
 	}
 	if fd.IsExtension() {
-		if fd.ContainingMessage().FullName() != mi.PBType.Descriptor().FullName() {
+		if fd.ContainingMessage().FullName() != mi.Desc.FullName() {
 			// TODO: Should this be exact containing message descriptor match?
 			panic("mismatching containing message")
 		}
-		if !mi.PBType.Descriptor().ExtensionRanges().Has(fd.Number()) {
+		if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
 			panic("invalid extension field")
 		}
 		xtd, ok := fd.(pref.ExtensionTypeDescriptor)

+ 8 - 8
internal/impl/message_reflect_gen.go

@@ -12,19 +12,19 @@ import (
 )
 
 func (m *messageState) Descriptor() protoreflect.MessageDescriptor {
-	return m.messageInfo().PBType.Descriptor()
+	return m.messageInfo().Desc
 }
 func (m *messageState) Type() protoreflect.MessageType {
-	return m.messageInfo().PBType
+	return m.messageInfo()
 }
 func (m *messageState) New() protoreflect.Message {
-	return m.messageInfo().PBType.New()
+	return m.messageInfo().New()
 }
 func (m *messageState) Interface() protoreflect.ProtoMessage {
 	return m.ProtoUnwrap().(protoreflect.ProtoMessage)
 }
 func (m *messageState) ProtoUnwrap() interface{} {
-	return m.pointer().AsIfaceOf(m.messageInfo().GoType.Elem())
+	return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
 }
 func (m *messageState) ProtoMethods() *protoiface.Methods {
 	m.messageInfo().init()
@@ -119,13 +119,13 @@ func (m *messageState) SetUnknown(b protoreflect.RawFields) {
 }
 
 func (m *messageReflectWrapper) Descriptor() protoreflect.MessageDescriptor {
-	return m.messageInfo().PBType.Descriptor()
+	return m.messageInfo().Desc
 }
 func (m *messageReflectWrapper) Type() protoreflect.MessageType {
-	return m.messageInfo().PBType
+	return m.messageInfo()
 }
 func (m *messageReflectWrapper) New() protoreflect.Message {
-	return m.messageInfo().PBType.New()
+	return m.messageInfo().New()
 }
 func (m *messageReflectWrapper) Interface() protoreflect.ProtoMessage {
 	if m, ok := m.ProtoUnwrap().(protoreflect.ProtoMessage); ok {
@@ -134,7 +134,7 @@ func (m *messageReflectWrapper) Interface() protoreflect.ProtoMessage {
 	return (*messageIfaceWrapper)(m)
 }
 func (m *messageReflectWrapper) ProtoUnwrap() interface{} {
-	return m.pointer().AsIfaceOf(m.messageInfo().GoType.Elem())
+	return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
 }
 func (m *messageReflectWrapper) ProtoMethods() *protoiface.Methods {
 	m.messageInfo().init()

+ 34 - 65
internal/impl/message_test.go

@@ -21,7 +21,6 @@ import (
 	pdesc "google.golang.org/protobuf/reflect/protodesc"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/protoregistry"
-	"google.golang.org/protobuf/reflect/prototype"
 
 	proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
 	testpb "google.golang.org/protobuf/internal/testprotos/test"
@@ -209,8 +208,7 @@ type (
 	MapBytes   map[MyString]MyBytes
 )
 
-var scalarProto2Type = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ScalarProto2)), PBType: &prototype.Message{
-	MessageDescriptor: mustMakeMessageDesc("scalar2.proto", pref.Proto2, "", `
+var scalarProto2Type = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ScalarProto2)), Desc: mustMakeMessageDesc("scalar2.proto", pref.Proto2, "", `
 		name: "ScalarProto2"
 		field: [
 			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_BOOL   default_value:"true"},
@@ -238,10 +236,7 @@ var scalarProto2Type = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ScalarProto2
 			{name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"22"}
 		]
 	`, nil),
-	NewMessage: func() pref.Message {
-		return pref.ProtoMessage(new(ScalarProto2)).ProtoReflect()
-	},
-}}
+}
 
 func (m *ScalarProto2) ProtoReflect() pref.Message { return scalarProto2Type.MessageOf(m) }
 
@@ -315,8 +310,7 @@ type ScalarProto3 struct {
 	MyBytesA  MyString  `protobuf:"22"`
 }
 
-var scalarProto3Type = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ScalarProto3)), PBType: &prototype.Message{
-	MessageDescriptor: mustMakeMessageDesc("scalar3.proto", pref.Proto3, "", `
+var scalarProto3Type = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ScalarProto3)), Desc: mustMakeMessageDesc("scalar3.proto", pref.Proto3, "", `
 		name: "ScalarProto3"
 		field: [
 			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_BOOL},
@@ -344,10 +338,7 @@ var scalarProto3Type = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ScalarProto3
 			{name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES}
 		]
 	`, nil),
-	NewMessage: func() pref.Message {
-		return pref.ProtoMessage(new(ScalarProto3)).ProtoReflect()
-	},
-}}
+}
 
 func (m *ScalarProto3) ProtoReflect() pref.Message { return scalarProto3Type.MessageOf(m) }
 
@@ -439,8 +430,7 @@ type ListScalars struct {
 	MyBytes4   ListStrings `protobuf:"19"`
 }
 
-var listScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ListScalars)), PBType: &prototype.Message{
-	MessageDescriptor: mustMakeMessageDesc("list-scalars.proto", pref.Proto2, "", `
+var listScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ListScalars)), Desc: mustMakeMessageDesc("list-scalars.proto", pref.Proto2, "", `
 		name: "ListScalars"
 		field: [
 			{name:"f1"  number:1  label:LABEL_REPEATED type:TYPE_BOOL},
@@ -466,10 +456,7 @@ var listScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ListScalars))
 			{name:"f19" number:19 label:LABEL_REPEATED type:TYPE_BYTES}
 		]
 	`, nil),
-	NewMessage: func() pref.Message {
-		return pref.ProtoMessage(new(ListScalars)).ProtoReflect()
-	},
-}}
+}
 
 func (m *ListScalars) ProtoReflect() pref.Message { return listScalarsType.MessageOf(m) }
 
@@ -596,8 +583,7 @@ type MapScalars struct {
 	MyBytes4   MapStrings `protobuf:"25"`
 }
 
-var mapScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(MapScalars)), PBType: &prototype.Message{
-	MessageDescriptor: mustMakeMessageDesc("map-scalars.proto", pref.Proto2, "", `
+var mapScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(MapScalars)), Desc: mustMakeMessageDesc("map-scalars.proto", pref.Proto2, "", `
 		name: "MapScalars"
 		field: [
 			{name:"f1"  number:1  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F1Entry"},
@@ -660,10 +646,7 @@ var mapScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(MapScalars)),
 			{name:"F25Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}]  options:{map_entry:true}}
 		]
 	`, nil),
-	NewMessage: func() pref.Message {
-		return pref.ProtoMessage(new(MapScalars)).ProtoReflect()
-	},
-}}
+}
 
 func (m *MapScalars) ProtoReflect() pref.Message { return mapScalarsType.MessageOf(m) }
 
@@ -790,8 +773,7 @@ type OneofScalars struct {
 	Union isOneofScalars_Union `protobuf_oneof:"union"`
 }
 
-var oneofScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(OneofScalars)), PBType: &prototype.Message{
-	MessageDescriptor: mustMakeMessageDesc("oneof-scalars.proto", pref.Proto2, "", `
+var oneofScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(OneofScalars)), Desc: mustMakeMessageDesc("oneof-scalars.proto", pref.Proto2, "", `
 		name: "OneofScalars"
 		field: [
 			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_BOOL   default_value:"true" oneof_index:0},
@@ -810,10 +792,7 @@ var oneofScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(OneofScalars
 		]
 		oneof_decl: [{name:"union"}]
 	`, nil),
-	NewMessage: func() pref.Message {
-		return pref.ProtoMessage(new(OneofScalars)).ProtoReflect()
-	},
-}}
+}
 
 func (m *OneofScalars) ProtoReflect() pref.Message { return oneofScalarsType.MessageOf(m) }
 
@@ -952,37 +931,31 @@ func TestOneofs(t *testing.T) {
 
 type EnumProto2 int32
 
-var enumProto2Type = &prototype.Enum{
-	EnumDescriptor: mustMakeEnumDesc("enum2.proto", pref.Proto2, `
-		name:  "EnumProto2"
-		value: [{name:"DEAD" number:0xdead}, {name:"BEEF" number:0xbeef}]
-	`),
-	NewEnum: func(n pref.EnumNumber) pref.Enum {
-		return EnumProto2(n)
-	},
-}
+var enumProto2Desc = mustMakeEnumDesc("enum2.proto", pref.Proto2, `
+	name:  "EnumProto2"
+	value: [{name:"DEAD" number:0xdead}, {name:"BEEF" number:0xbeef}]
+`)
 
-func (e EnumProto2) Descriptor() pref.EnumDescriptor { return enumProto2Type.Descriptor() }
-func (e EnumProto2) Type() pref.EnumType             { return enumProto2Type }
+func (e EnumProto2) Descriptor() pref.EnumDescriptor { return enumProto2Desc }
+func (e EnumProto2) Type() pref.EnumType             { return e }
 func (e EnumProto2) Enum() *EnumProto2               { return &e }
 func (e EnumProto2) Number() pref.EnumNumber         { return pref.EnumNumber(e) }
+func (t EnumProto2) GoType() reflect.Type            { return reflect.TypeOf(t) }
+func (t EnumProto2) New(n pref.EnumNumber) pref.Enum { return EnumProto2(n) }
 
 type EnumProto3 int32
 
-var enumProto3Type = &prototype.Enum{
-	EnumDescriptor: mustMakeEnumDesc("enum3.proto", pref.Proto3, `
-		name:  "EnumProto3",
-		value: [{name:"ALPHA" number:0}, {name:"BRAVO" number:1}]
-	`),
-	NewEnum: func(n pref.EnumNumber) pref.Enum {
-		return EnumProto3(n)
-	},
-}
+var enumProto3Desc = mustMakeEnumDesc("enum3.proto", pref.Proto3, `
+	name:  "EnumProto3",
+	value: [{name:"ALPHA" number:0}, {name:"BRAVO" number:1}]
+`)
 
-func (e EnumProto3) Descriptor() pref.EnumDescriptor { return enumProto3Type.Descriptor() }
-func (e EnumProto3) Type() pref.EnumType             { return enumProto3Type }
+func (e EnumProto3) Descriptor() pref.EnumDescriptor { return enumProto3Desc }
+func (e EnumProto3) Type() pref.EnumType             { return e }
 func (e EnumProto3) Enum() *EnumProto3               { return &e }
 func (e EnumProto3) Number() pref.EnumNumber         { return pref.EnumNumber(e) }
+func (t EnumProto3) GoType() reflect.Type            { return reflect.TypeOf(t) }
+func (t EnumProto3) New(n pref.EnumNumber) pref.Enum { return EnumProto3(n) }
 
 type EnumMessages struct {
 	EnumP2        *EnumProto2              `protobuf:"1"`
@@ -996,8 +969,7 @@ type EnumMessages struct {
 	Union         isEnumMessages_Union     `protobuf_oneof:"union"`
 }
 
-var enumMessagesType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(EnumMessages)), PBType: &prototype.Message{
-	MessageDescriptor: mustMakeMessageDesc("enum-messages.proto", pref.Proto2, `
+var enumMessagesType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(EnumMessages)), Desc: mustMakeMessageDesc("enum-messages.proto", pref.Proto2, `
 		dependency: ["enum2.proto", "enum3.proto", "scalar2.proto", "scalar3.proto", "proto2.v1.0.0-20180125-92554152/test.proto"]
 	`, `
 		name: "EnumMessages"
@@ -1021,16 +993,13 @@ var enumMessagesType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(EnumMessages
 			{name:"F8Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto3"}] options:{map_entry:true}}
 		]
 	`, protoregistry.NewFiles(
-		EnumProto2(0).Descriptor().ParentFile(),
-		EnumProto3(0).Descriptor().ParentFile(),
-		((*ScalarProto2)(nil)).ProtoReflect().Descriptor().ParentFile(),
-		((*ScalarProto3)(nil)).ProtoReflect().Descriptor().ParentFile(),
-		pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message)(nil)).ParentFile(),
-	)),
-	NewMessage: func() pref.Message {
-		return pref.ProtoMessage(new(EnumMessages)).ProtoReflect()
-	},
-}}
+	EnumProto2(0).Descriptor().ParentFile(),
+	EnumProto3(0).Descriptor().ParentFile(),
+	((*ScalarProto2)(nil)).ProtoReflect().Descriptor().ParentFile(),
+	((*ScalarProto3)(nil)).ProtoReflect().Descriptor().ParentFile(),
+	pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message)(nil)).ParentFile(),
+)),
+}
 
 func (m *EnumMessages) ProtoReflect() pref.Message { return enumMessagesType.MessageOf(m) }
 

+ 1 - 1
internal/impl/pointer_reflect.go

@@ -170,7 +170,7 @@ type atomicNilMessage struct {
 
 func (m *atomicNilMessage) Init(mi *MessageInfo) *messageReflectWrapper {
 	m.once.Do(func() {
-		m.m.p = pointerOfIface(reflect.Zero(mi.GoType).Interface())
+		m.m.p = pointerOfIface(reflect.Zero(mi.GoReflectType).Interface())
 		m.m.mi = mi
 	})
 	return &m.m

+ 6 - 10
internal/testprotos/irregular/irregular.go

@@ -5,10 +5,11 @@
 package irregular
 
 import (
+	"reflect"
+
 	"google.golang.org/protobuf/encoding/prototext"
 	"google.golang.org/protobuf/reflect/protodesc"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/prototype"
 
 	"google.golang.org/protobuf/types/descriptorpb"
 )
@@ -22,16 +23,11 @@ func (m *IrregularMessage) ProtoReflect() pref.Message { return (*message)(m) }
 
 type message IrregularMessage
 
-var messageType = &prototype.Message{
-	MessageDescriptor: fileDesc.Messages().Get(0),
-	NewMessage: func() pref.Message {
-		return &message{}
-	},
-}
-
-func (m *message) Descriptor() pref.MessageDescriptor { return messageType.Descriptor() }
-func (m *message) Type() pref.MessageType             { return messageType }
+func (m *message) Descriptor() pref.MessageDescriptor { return fileDesc.Messages().Get(0) }
+func (m *message) Type() pref.MessageType             { return m }
 func (m *message) New() pref.Message                  { return &message{} }
+func (m *message) Zero() pref.Message                 { return (*message)(nil) }
+func (m *message) GoType() reflect.Type               { return reflect.TypeOf(&message{}) }
 func (m *message) Interface() pref.ProtoMessage       { return (*IrregularMessage)(m) }
 
 var fieldDescS = fileDesc.Messages().Get(0).Fields().Get(0)

+ 17 - 23
proto/decode_test.go

@@ -16,7 +16,6 @@ import (
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/reflect/protodesc"
 	"google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/prototype"
 	"google.golang.org/protobuf/runtime/protoiface"
 	"google.golang.org/protobuf/runtime/protoimpl"
 
@@ -1614,11 +1613,10 @@ func (m *TestNoEnforceUTF8) ProtoReflect() protoreflect.Message {
 }
 
 var messageInfo_TestNoEnforceUTF8 = protoimpl.MessageInfo{
-	GoType: reflect.TypeOf((*TestNoEnforceUTF8)(nil)),
-	PBType: &prototype.Message{
-		MessageDescriptor: func() protoreflect.MessageDescriptor {
-			pb := new(descriptorpb.FileDescriptorProto)
-			if err := prototext.Unmarshal([]byte(`
+	GoReflectType: reflect.TypeOf((*TestNoEnforceUTF8)(nil)),
+	Desc: func() protoreflect.MessageDescriptor {
+		pb := new(descriptorpb.FileDescriptorProto)
+		if err := prototext.Unmarshal([]byte(`
 				syntax:  "proto3"
 				name:    "test.proto"
 				message_type: [{
@@ -1634,23 +1632,19 @@ var messageInfo_TestNoEnforceUTF8 = protoimpl.MessageInfo{
 					oneof_decl: [{name:"oneof_field"}]
 				}]
 			`), pb); err != nil {
-				panic(err)
-			}
-			fd, err := protodesc.NewFile(pb, nil)
-			if err != nil {
-				panic(err)
-			}
-			md := fd.Messages().Get(0)
-			for i := 0; i < md.Fields().Len(); i++ {
-				md.Fields().Get(i).(*filedesc.Field).L1.HasEnforceUTF8 = true
-				md.Fields().Get(i).(*filedesc.Field).L1.EnforceUTF8 = false
-			}
-			return md
-		}(),
-		NewMessage: func() protoreflect.Message {
-			return protoreflect.ProtoMessage(new(TestNoEnforceUTF8)).ProtoReflect()
-		},
-	},
+			panic(err)
+		}
+		fd, err := protodesc.NewFile(pb, nil)
+		if err != nil {
+			panic(err)
+		}
+		md := fd.Messages().Get(0)
+		for i := 0; i < md.Fields().Len(); i++ {
+			md.Fields().Get(i).(*filedesc.Field).L1.HasEnforceUTF8 = true
+			md.Fields().Get(i).(*filedesc.Field).L1.EnforceUTF8 = false
+		}
+		return md
+	}(),
 	OneofWrappers: []interface{}{
 		(*TestNoEnforceUTF8_OneofString)(nil),
 		(*TestNoEnforceUTF8_OneofBytes)(nil),

+ 0 - 118
reflect/prototype/type.go

@@ -1,118 +0,0 @@
-// 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 prototype provides constructors for protoreflect.EnumType,
-// protoreflect.MessageType, and protoreflect.ExtensionType.
-package prototype
-
-import (
-	"fmt"
-	"reflect"
-	"sync"
-
-	"google.golang.org/protobuf/internal/descfmt"
-	"google.golang.org/protobuf/reflect/protoreflect"
-)
-
-// Enum is a protoreflect.EnumType which combines a
-// protoreflect.EnumDescriptor with a constructor function.
-//
-// Both EnumDescriptor and NewEnum must be populated.
-// Once constructed, the exported fields must not be modified.
-type Enum struct {
-	protoreflect.EnumDescriptor
-
-	// NewEnum constructs a new protoreflect.Enum representing the provided
-	// enum number. The returned Go type must be identical for every call.
-	NewEnum func(protoreflect.EnumNumber) protoreflect.Enum
-
-	once   sync.Once
-	goType reflect.Type
-}
-
-func (t *Enum) New(n protoreflect.EnumNumber) protoreflect.Enum {
-	e := t.NewEnum(n)
-	t.once.Do(func() {
-		t.goType = reflect.TypeOf(e)
-		if e.Descriptor() != t.Descriptor() {
-			panic(fmt.Sprintf("mismatching enum descriptor: got %v, want %v", e.Descriptor(), t.Descriptor()))
-		}
-		if e.Descriptor().IsPlaceholder() {
-			panic("enum descriptor must not be a placeholder")
-		}
-	})
-	if t.goType != reflect.TypeOf(e) {
-		panic(fmt.Sprintf("mismatching types for enum: got %T, want %v", e, t.goType))
-	}
-	return e
-}
-
-func (t *Enum) GoType() reflect.Type {
-	t.New(0) // initialize t.typ
-	return t.goType
-}
-
-func (t *Enum) Descriptor() protoreflect.EnumDescriptor {
-	return t.EnumDescriptor
-}
-
-func (t *Enum) Format(s fmt.State, r rune) {
-	descfmt.FormatDesc(s, r, t)
-}
-
-// Message is a protoreflect.MessageType which combines a
-// protoreflect.MessageDescriptor with a constructor function.
-//
-// Both MessageDescriptor and NewMessage must be populated.
-// Once constructed, the exported fields must not be modified.
-type Message struct {
-	protoreflect.MessageDescriptor
-
-	// NewMessage constructs an empty, newly allocated protoreflect.Message.
-	// The returned Go type must be identical for every call.
-	NewMessage func() protoreflect.Message
-
-	once   sync.Once
-	goType reflect.Type
-}
-
-func (t *Message) New() protoreflect.Message {
-	m := t.NewMessage()
-	mi := m.Interface()
-	t.once.Do(func() {
-		t.goType = reflect.TypeOf(mi)
-		if m.Descriptor() != t.Descriptor() {
-			panic(fmt.Sprintf("mismatching message descriptor: got %v, want %v", m.Descriptor(), t.Descriptor()))
-		}
-		if m.Descriptor().IsPlaceholder() {
-			panic("message descriptor must not be a placeholder")
-		}
-	})
-	if t.goType != reflect.TypeOf(mi) {
-		panic(fmt.Sprintf("mismatching types for message: got %T, want %v", mi, t.goType))
-	}
-	return m
-}
-
-func (t *Message) Zero() protoreflect.Message {
-	return t.New() // TODO: return a read-only message instead
-}
-
-func (t *Message) GoType() reflect.Type {
-	t.New() // initialize t.goType
-	return t.goType
-}
-
-func (t *Message) Descriptor() protoreflect.MessageDescriptor {
-	return t.MessageDescriptor
-}
-
-func (t *Message) Format(s fmt.State, r rune) {
-	descfmt.FormatDesc(s, r, t)
-}
-
-var (
-	_ protoreflect.EnumType    = (*Enum)(nil)
-	_ protoreflect.MessageType = (*Message)(nil)
-)

+ 12 - 8
types/dynamicpb/dynamic.go

@@ -7,10 +7,10 @@ package dynamicpb
 
 import (
 	"math"
+	"reflect"
 
 	"google.golang.org/protobuf/internal/errors"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/prototype"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 )
 
@@ -30,7 +30,7 @@ import (
 //
 // Operations which modify a Message are not safe for concurrent use.
 type Message struct {
-	typ     prototype.Message
+	desc    pref.MessageDescriptor
 	known   map[pref.FieldNumber]pref.Value
 	ext     map[pref.FieldNumber]pref.FieldDescriptor
 	unknown pref.RawFields
@@ -39,10 +39,7 @@ type Message struct {
 // New creates a new message with the provided descriptor.
 func New(desc pref.MessageDescriptor) *Message {
 	return &Message{
-		typ: prototype.Message{
-			MessageDescriptor: desc,
-			NewMessage:        func() pref.Message { return New(desc) },
-		},
+		desc:  desc,
 		known: make(map[pref.FieldNumber]pref.Value),
 		ext:   make(map[pref.FieldNumber]pref.FieldDescriptor),
 	}
@@ -60,12 +57,12 @@ func (m *Message) String() string {
 
 // Descriptor returns the message descriptor.
 func (m *Message) Descriptor() pref.MessageDescriptor {
-	return m.typ.Descriptor()
+	return m.desc
 }
 
 // Type returns the message type.
 func (m *Message) Type() pref.MessageType {
-	return &m.typ
+	return (*messageType)(m)
 }
 
 // New returns a newly allocated empty message with the same descriptor.
@@ -273,6 +270,13 @@ func (m *Message) checkField(fd pref.FieldDescriptor) {
 	}
 }
 
+type messageType Message
+
+func (mt *messageType) New() pref.Message                  { return New(mt.desc) }
+func (mt *messageType) Zero() pref.Message                 { return New(mt.desc) }
+func (mt *messageType) GoType() reflect.Type               { return reflect.TypeOf((*Message)(nil)) }
+func (mt *messageType) Descriptor() pref.MessageDescriptor { return mt.desc }
+
 type emptyList struct {
 	desc pref.FieldDescriptor
 }