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>
This commit is contained in:
Damien Neil 2019-08-06 15:43:25 -07:00
parent 4401a0de4b
commit 16163b4f67
19 changed files with 154 additions and 313 deletions

View File

@ -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()

View File

@ -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

View File

@ -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.

View File

@ -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 {

View File

@ -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,

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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{

View File

@ -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 }

View File

@ -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)

View File

@ -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()

View File

@ -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) }

View File

@ -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

View File

@ -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)

View File

@ -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),

View File

@ -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)
)

View File

@ -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
}