vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
    14 	ptag "google.golang.org/protobuf/internal/encoding/tag"
    14 	ptag "google.golang.org/protobuf/internal/encoding/tag"
    15 	"google.golang.org/protobuf/internal/errors"
    15 	"google.golang.org/protobuf/internal/errors"
    16 	"google.golang.org/protobuf/internal/filedesc"
    16 	"google.golang.org/protobuf/internal/filedesc"
    17 	"google.golang.org/protobuf/internal/strs"
    17 	"google.golang.org/protobuf/internal/strs"
    18 	"google.golang.org/protobuf/reflect/protoreflect"
    18 	"google.golang.org/protobuf/reflect/protoreflect"
    19 	pref "google.golang.org/protobuf/reflect/protoreflect"
       
    20 	"google.golang.org/protobuf/runtime/protoiface"
    19 	"google.golang.org/protobuf/runtime/protoiface"
    21 	piface "google.golang.org/protobuf/runtime/protoiface"
       
    22 )
    20 )
    23 
    21 
    24 // legacyWrapMessage wraps v as a protoreflect.Message,
    22 // legacyWrapMessage wraps v as a protoreflect.Message,
    25 // where v must be a *struct kind and not implement the v2 API already.
    23 // where v must be a *struct kind and not implement the v2 API already.
    26 func legacyWrapMessage(v reflect.Value) pref.Message {
    24 func legacyWrapMessage(v reflect.Value) protoreflect.Message {
    27 	t := v.Type()
    25 	t := v.Type()
    28 	if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
    26 	if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
    29 		return aberrantMessage{v: v}
    27 		return aberrantMessage{v: v}
    30 	}
    28 	}
    31 	mt := legacyLoadMessageInfo(t, "")
    29 	mt := legacyLoadMessageInfo(t, "")
    33 }
    31 }
    34 
    32 
    35 // legacyLoadMessageType dynamically loads a protoreflect.Type for t,
    33 // legacyLoadMessageType dynamically loads a protoreflect.Type for t,
    36 // where t must be not implement the v2 API already.
    34 // where t must be not implement the v2 API already.
    37 // The provided name is used if it cannot be determined from the message.
    35 // The provided name is used if it cannot be determined from the message.
    38 func legacyLoadMessageType(t reflect.Type, name pref.FullName) protoreflect.MessageType {
    36 func legacyLoadMessageType(t reflect.Type, name protoreflect.FullName) protoreflect.MessageType {
    39 	if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
    37 	if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
    40 		return aberrantMessageType{t}
    38 		return aberrantMessageType{t}
    41 	}
    39 	}
    42 	return legacyLoadMessageInfo(t, name)
    40 	return legacyLoadMessageInfo(t, name)
    43 }
    41 }
    45 var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo
    43 var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo
    46 
    44 
    47 // legacyLoadMessageInfo dynamically loads a *MessageInfo for t,
    45 // legacyLoadMessageInfo dynamically loads a *MessageInfo for t,
    48 // where t must be a *struct kind and not implement the v2 API already.
    46 // where t must be a *struct kind and not implement the v2 API already.
    49 // The provided name is used if it cannot be determined from the message.
    47 // The provided name is used if it cannot be determined from the message.
    50 func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo {
    48 func legacyLoadMessageInfo(t reflect.Type, name protoreflect.FullName) *MessageInfo {
    51 	// Fast-path: check if a MessageInfo is cached for this concrete type.
    49 	// Fast-path: check if a MessageInfo is cached for this concrete type.
    52 	if mt, ok := legacyMessageTypeCache.Load(t); ok {
    50 	if mt, ok := legacyMessageTypeCache.Load(t); ok {
    53 		return mt.(*MessageInfo)
    51 		return mt.(*MessageInfo)
    54 	}
    52 	}
    55 
    53 
    66 
    64 
    67 		// We have no way to tell whether the type's Marshal method
    65 		// We have no way to tell whether the type's Marshal method
    68 		// supports deterministic serialization or not, but this
    66 		// supports deterministic serialization or not, but this
    69 		// preserves the v1 implementation's behavior of always
    67 		// preserves the v1 implementation's behavior of always
    70 		// calling Marshal methods when present.
    68 		// calling Marshal methods when present.
    71 		mi.methods.Flags |= piface.SupportMarshalDeterministic
    69 		mi.methods.Flags |= protoiface.SupportMarshalDeterministic
    72 	}
    70 	}
    73 	if _, hasUnmarshal = v.(legacyUnmarshaler); hasUnmarshal {
    71 	if _, hasUnmarshal = v.(legacyUnmarshaler); hasUnmarshal {
    74 		mi.methods.Unmarshal = legacyUnmarshal
    72 		mi.methods.Unmarshal = legacyUnmarshal
    75 	}
    73 	}
    76 	if _, hasMerge := v.(legacyMerger); hasMerge || (hasMarshal && hasUnmarshal) {
    74 	if _, hasMerge := v.(legacyMerger); hasMerge || (hasMarshal && hasUnmarshal) {
    87 
    85 
    88 // LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type,
    86 // LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type,
    89 // which should be a *struct kind and must not implement the v2 API already.
    87 // which should be a *struct kind and must not implement the v2 API already.
    90 //
    88 //
    91 // This is exported for testing purposes.
    89 // This is exported for testing purposes.
    92 func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor {
    90 func LegacyLoadMessageDesc(t reflect.Type) protoreflect.MessageDescriptor {
    93 	return legacyLoadMessageDesc(t, "")
    91 	return legacyLoadMessageDesc(t, "")
    94 }
    92 }
    95 func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
    93 func legacyLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor {
    96 	// Fast-path: check if a MessageDescriptor is cached for this concrete type.
    94 	// Fast-path: check if a MessageDescriptor is cached for this concrete type.
    97 	if mi, ok := legacyMessageDescCache.Load(t); ok {
    95 	if mi, ok := legacyMessageDescCache.Load(t); ok {
    98 		return mi.(pref.MessageDescriptor)
    96 		return mi.(protoreflect.MessageDescriptor)
    99 	}
    97 	}
   100 
    98 
   101 	// Slow-path: initialize MessageDescriptor from the raw descriptor.
    99 	// Slow-path: initialize MessageDescriptor from the raw descriptor.
   102 	mv := reflect.Zero(t).Interface()
   100 	mv := reflect.Zero(t).Interface()
   103 	if _, ok := mv.(pref.ProtoMessage); ok {
   101 	if _, ok := mv.(protoreflect.ProtoMessage); ok {
   104 		panic(fmt.Sprintf("%v already implements proto.Message", t))
   102 		panic(fmt.Sprintf("%v already implements proto.Message", t))
   105 	}
   103 	}
   106 	mdV1, ok := mv.(messageV1)
   104 	mdV1, ok := mv.(messageV1)
   107 	if !ok {
   105 	if !ok {
   108 		return aberrantLoadMessageDesc(t, name)
   106 		return aberrantLoadMessageDesc(t, name)
   162 // aberrantLoadMessageDesc returns an MessageDescriptor derived from the Go type,
   160 // aberrantLoadMessageDesc returns an MessageDescriptor derived from the Go type,
   163 // which must not implement protoreflect.ProtoMessage or messageV1.
   161 // which must not implement protoreflect.ProtoMessage or messageV1.
   164 //
   162 //
   165 // This is a best-effort derivation of the message descriptor using the protobuf
   163 // This is a best-effort derivation of the message descriptor using the protobuf
   166 // tags on the struct fields.
   164 // tags on the struct fields.
   167 func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
   165 func aberrantLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor {
   168 	aberrantMessageDescLock.Lock()
   166 	aberrantMessageDescLock.Lock()
   169 	defer aberrantMessageDescLock.Unlock()
   167 	defer aberrantMessageDescLock.Unlock()
   170 	if aberrantMessageDescCache == nil {
   168 	if aberrantMessageDescCache == nil {
   171 		aberrantMessageDescCache = make(map[reflect.Type]protoreflect.MessageDescriptor)
   169 		aberrantMessageDescCache = make(map[reflect.Type]protoreflect.MessageDescriptor)
   172 	}
   170 	}
   173 	return aberrantLoadMessageDescReentrant(t, name)
   171 	return aberrantLoadMessageDescReentrant(t, name)
   174 }
   172 }
   175 func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
   173 func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor {
   176 	// Fast-path: check if an MessageDescriptor is cached for this concrete type.
   174 	// Fast-path: check if an MessageDescriptor is cached for this concrete type.
   177 	if md, ok := aberrantMessageDescCache[t]; ok {
   175 	if md, ok := aberrantMessageDescCache[t]; ok {
   178 		return md
   176 		return md
   179 	}
   177 	}
   180 
   178 
   223 	// Obtain a list of the extension ranges.
   221 	// Obtain a list of the extension ranges.
   224 	if fn, ok := t.MethodByName("ExtensionRangeArray"); ok {
   222 	if fn, ok := t.MethodByName("ExtensionRangeArray"); ok {
   225 		vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
   223 		vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
   226 		for i := 0; i < vs.Len(); i++ {
   224 		for i := 0; i < vs.Len(); i++ {
   227 			v := vs.Index(i)
   225 			v := vs.Index(i)
   228 			md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]pref.FieldNumber{
   226 			md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{
   229 				pref.FieldNumber(v.FieldByName("Start").Int()),
   227 				protoreflect.FieldNumber(v.FieldByName("Start").Int()),
   230 				pref.FieldNumber(v.FieldByName("End").Int() + 1),
   228 				protoreflect.FieldNumber(v.FieldByName("End").Int() + 1),
   231 			})
   229 			})
   232 			md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil)
   230 			md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil)
   233 		}
   231 		}
   234 	}
   232 	}
   235 
   233 
   243 		}
   241 		}
   244 		if tag := f.Tag.Get("protobuf_oneof"); tag != "" {
   242 		if tag := f.Tag.Get("protobuf_oneof"); tag != "" {
   245 			n := len(md.L2.Oneofs.List)
   243 			n := len(md.L2.Oneofs.List)
   246 			md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{})
   244 			md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{})
   247 			od := &md.L2.Oneofs.List[n]
   245 			od := &md.L2.Oneofs.List[n]
   248 			od.L0.FullName = md.FullName().Append(pref.Name(tag))
   246 			od.L0.FullName = md.FullName().Append(protoreflect.Name(tag))
   249 			od.L0.ParentFile = md.L0.ParentFile
   247 			od.L0.ParentFile = md.L0.ParentFile
   250 			od.L0.Parent = md
   248 			od.L0.Parent = md
   251 			od.L0.Index = n
   249 			od.L0.Index = n
   252 
   250 
   253 			for _, t := range oneofWrappers {
   251 			for _, t := range oneofWrappers {
   265 	}
   263 	}
   266 
   264 
   267 	return md
   265 	return md
   268 }
   266 }
   269 
   267 
   270 func aberrantDeriveMessageName(t reflect.Type, name pref.FullName) pref.FullName {
   268 func aberrantDeriveMessageName(t reflect.Type, name protoreflect.FullName) protoreflect.FullName {
   271 	if name.IsValid() {
   269 	if name.IsValid() {
   272 		return name
   270 		return name
   273 	}
   271 	}
   274 	func() {
   272 	func() {
   275 		defer func() { recover() }() // swallow possible nil panics
   273 		defer func() { recover() }() // swallow possible nil panics
   276 		if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok {
   274 		if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok {
   277 			name = pref.FullName(m.XXX_MessageName())
   275 			name = protoreflect.FullName(m.XXX_MessageName())
   278 		}
   276 		}
   279 	}()
   277 	}()
   280 	if name.IsValid() {
   278 	if name.IsValid() {
   281 		return name
   279 		return name
   282 	}
   280 	}
   303 	fd.L0.ParentFile = md.L0.ParentFile
   301 	fd.L0.ParentFile = md.L0.ParentFile
   304 	fd.L0.Parent = md
   302 	fd.L0.Parent = md
   305 	fd.L0.Index = n
   303 	fd.L0.Index = n
   306 
   304 
   307 	if fd.L1.IsWeak || fd.L1.HasPacked {
   305 	if fd.L1.IsWeak || fd.L1.HasPacked {
   308 		fd.L1.Options = func() pref.ProtoMessage {
   306 		fd.L1.Options = func() protoreflect.ProtoMessage {
   309 			opts := descopts.Field.ProtoReflect().New()
   307 			opts := descopts.Field.ProtoReflect().New()
   310 			if fd.L1.IsWeak {
   308 			if fd.L1.IsWeak {
   311 				opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
   309 				opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
   312 			}
   310 			}
   313 			if fd.L1.HasPacked {
   311 			if fd.L1.HasPacked {
   316 			return opts.Interface()
   314 			return opts.Interface()
   317 		}
   315 		}
   318 	}
   316 	}
   319 
   317 
   320 	// Populate Enum and Message.
   318 	// Populate Enum and Message.
   321 	if fd.Enum() == nil && fd.Kind() == pref.EnumKind {
   319 	if fd.Enum() == nil && fd.Kind() == protoreflect.EnumKind {
   322 		switch v := reflect.Zero(t).Interface().(type) {
   320 		switch v := reflect.Zero(t).Interface().(type) {
   323 		case pref.Enum:
   321 		case protoreflect.Enum:
   324 			fd.L1.Enum = v.Descriptor()
   322 			fd.L1.Enum = v.Descriptor()
   325 		default:
   323 		default:
   326 			fd.L1.Enum = LegacyLoadEnumDesc(t)
   324 			fd.L1.Enum = LegacyLoadEnumDesc(t)
   327 		}
   325 		}
   328 	}
   326 	}
   329 	if fd.Message() == nil && (fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind) {
   327 	if fd.Message() == nil && (fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind) {
   330 		switch v := reflect.Zero(t).Interface().(type) {
   328 		switch v := reflect.Zero(t).Interface().(type) {
   331 		case pref.ProtoMessage:
   329 		case protoreflect.ProtoMessage:
   332 			fd.L1.Message = v.ProtoReflect().Descriptor()
   330 			fd.L1.Message = v.ProtoReflect().Descriptor()
   333 		case messageV1:
   331 		case messageV1:
   334 			fd.L1.Message = LegacyLoadMessageDesc(t)
   332 			fd.L1.Message = LegacyLoadMessageDesc(t)
   335 		default:
   333 		default:
   336 			if t.Kind() == reflect.Map {
   334 			if t.Kind() == reflect.Map {
   337 				n := len(md.L1.Messages.List)
   335 				n := len(md.L1.Messages.List)
   338 				md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)})
   336 				md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)})
   339 				md2 := &md.L1.Messages.List[n]
   337 				md2 := &md.L1.Messages.List[n]
   340 				md2.L0.FullName = md.FullName().Append(pref.Name(strs.MapEntryName(string(fd.Name()))))
   338 				md2.L0.FullName = md.FullName().Append(protoreflect.Name(strs.MapEntryName(string(fd.Name()))))
   341 				md2.L0.ParentFile = md.L0.ParentFile
   339 				md2.L0.ParentFile = md.L0.ParentFile
   342 				md2.L0.Parent = md
   340 				md2.L0.Parent = md
   343 				md2.L0.Index = n
   341 				md2.L0.Index = n
   344 
   342 
   345 				md2.L1.IsMapEntry = true
   343 				md2.L1.IsMapEntry = true
   346 				md2.L2.Options = func() pref.ProtoMessage {
   344 				md2.L2.Options = func() protoreflect.ProtoMessage {
   347 					opts := descopts.Message.ProtoReflect().New()
   345 					opts := descopts.Message.ProtoReflect().New()
   348 					opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true))
   346 					opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true))
   349 					return opts.Interface()
   347 					return opts.Interface()
   350 				}
   348 				}
   351 
   349 
   362 
   360 
   363 type placeholderEnumValues struct {
   361 type placeholderEnumValues struct {
   364 	protoreflect.EnumValueDescriptors
   362 	protoreflect.EnumValueDescriptors
   365 }
   363 }
   366 
   364 
   367 func (placeholderEnumValues) ByNumber(n pref.EnumNumber) pref.EnumValueDescriptor {
   365 func (placeholderEnumValues) ByNumber(n protoreflect.EnumNumber) protoreflect.EnumValueDescriptor {
   368 	return filedesc.PlaceholderEnumValue(pref.FullName(fmt.Sprintf("UNKNOWN_%d", n)))
   366 	return filedesc.PlaceholderEnumValue(protoreflect.FullName(fmt.Sprintf("UNKNOWN_%d", n)))
   369 }
   367 }
   370 
   368 
   371 // legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder.
   369 // legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder.
   372 type legacyMarshaler interface {
   370 type legacyMarshaler interface {
   373 	Marshal() ([]byte, error)
   371 	Marshal() ([]byte, error)
   381 // legacyMerger is the proto.Merger interface superseded by protoiface.Methoder.
   379 // legacyMerger is the proto.Merger interface superseded by protoiface.Methoder.
   382 type legacyMerger interface {
   380 type legacyMerger interface {
   383 	Merge(protoiface.MessageV1)
   381 	Merge(protoiface.MessageV1)
   384 }
   382 }
   385 
   383 
   386 var aberrantProtoMethods = &piface.Methods{
   384 var aberrantProtoMethods = &protoiface.Methods{
   387 	Marshal:   legacyMarshal,
   385 	Marshal:   legacyMarshal,
   388 	Unmarshal: legacyUnmarshal,
   386 	Unmarshal: legacyUnmarshal,
   389 	Merge:     legacyMerge,
   387 	Merge:     legacyMerge,
   390 
   388 
   391 	// We have no way to tell whether the type's Marshal method
   389 	// We have no way to tell whether the type's Marshal method
   392 	// supports deterministic serialization or not, but this
   390 	// supports deterministic serialization or not, but this
   393 	// preserves the v1 implementation's behavior of always
   391 	// preserves the v1 implementation's behavior of always
   394 	// calling Marshal methods when present.
   392 	// calling Marshal methods when present.
   395 	Flags: piface.SupportMarshalDeterministic,
   393 	Flags: protoiface.SupportMarshalDeterministic,
   396 }
   394 }
   397 
   395 
   398 func legacyMarshal(in piface.MarshalInput) (piface.MarshalOutput, error) {
   396 func legacyMarshal(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
   399 	v := in.Message.(unwrapper).protoUnwrap()
   397 	v := in.Message.(unwrapper).protoUnwrap()
   400 	marshaler, ok := v.(legacyMarshaler)
   398 	marshaler, ok := v.(legacyMarshaler)
   401 	if !ok {
   399 	if !ok {
   402 		return piface.MarshalOutput{}, errors.New("%T does not implement Marshal", v)
   400 		return protoiface.MarshalOutput{}, errors.New("%T does not implement Marshal", v)
   403 	}
   401 	}
   404 	out, err := marshaler.Marshal()
   402 	out, err := marshaler.Marshal()
   405 	if in.Buf != nil {
   403 	if in.Buf != nil {
   406 		out = append(in.Buf, out...)
   404 		out = append(in.Buf, out...)
   407 	}
   405 	}
   408 	return piface.MarshalOutput{
   406 	return protoiface.MarshalOutput{
   409 		Buf: out,
   407 		Buf: out,
   410 	}, err
   408 	}, err
   411 }
   409 }
   412 
   410 
   413 func legacyUnmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
   411 func legacyUnmarshal(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
   414 	v := in.Message.(unwrapper).protoUnwrap()
   412 	v := in.Message.(unwrapper).protoUnwrap()
   415 	unmarshaler, ok := v.(legacyUnmarshaler)
   413 	unmarshaler, ok := v.(legacyUnmarshaler)
   416 	if !ok {
   414 	if !ok {
   417 		return piface.UnmarshalOutput{}, errors.New("%T does not implement Unmarshal", v)
   415 		return protoiface.UnmarshalOutput{}, errors.New("%T does not implement Unmarshal", v)
   418 	}
   416 	}
   419 	return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf)
   417 	return protoiface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf)
   420 }
   418 }
   421 
   419 
   422 func legacyMerge(in piface.MergeInput) piface.MergeOutput {
   420 func legacyMerge(in protoiface.MergeInput) protoiface.MergeOutput {
   423 	// Check whether this supports the legacy merger.
   421 	// Check whether this supports the legacy merger.
   424 	dstv := in.Destination.(unwrapper).protoUnwrap()
   422 	dstv := in.Destination.(unwrapper).protoUnwrap()
   425 	merger, ok := dstv.(legacyMerger)
   423 	merger, ok := dstv.(legacyMerger)
   426 	if ok {
   424 	if ok {
   427 		merger.Merge(Export{}.ProtoMessageV1Of(in.Source))
   425 		merger.Merge(Export{}.ProtoMessageV1Of(in.Source))
   428 		return piface.MergeOutput{Flags: piface.MergeComplete}
   426 		return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
   429 	}
   427 	}
   430 
   428 
   431 	// If legacy merger is unavailable, implement merge in terms of
   429 	// If legacy merger is unavailable, implement merge in terms of
   432 	// a marshal and unmarshal operation.
   430 	// a marshal and unmarshal operation.
   433 	srcv := in.Source.(unwrapper).protoUnwrap()
   431 	srcv := in.Source.(unwrapper).protoUnwrap()
   434 	marshaler, ok := srcv.(legacyMarshaler)
   432 	marshaler, ok := srcv.(legacyMarshaler)
   435 	if !ok {
   433 	if !ok {
   436 		return piface.MergeOutput{}
   434 		return protoiface.MergeOutput{}
   437 	}
   435 	}
   438 	dstv = in.Destination.(unwrapper).protoUnwrap()
   436 	dstv = in.Destination.(unwrapper).protoUnwrap()
   439 	unmarshaler, ok := dstv.(legacyUnmarshaler)
   437 	unmarshaler, ok := dstv.(legacyUnmarshaler)
   440 	if !ok {
   438 	if !ok {
   441 		return piface.MergeOutput{}
   439 		return protoiface.MergeOutput{}
   442 	}
   440 	}
   443 	if !in.Source.IsValid() {
   441 	if !in.Source.IsValid() {
   444 		// Legacy Marshal methods may not function on nil messages.
   442 		// Legacy Marshal methods may not function on nil messages.
   445 		// Check for a typed nil source only after we confirm that
   443 		// Check for a typed nil source only after we confirm that
   446 		// legacy Marshal/Unmarshal methods are present, for
   444 		// legacy Marshal/Unmarshal methods are present, for
   447 		// consistency.
   445 		// consistency.
   448 		return piface.MergeOutput{Flags: piface.MergeComplete}
   446 		return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
   449 	}
   447 	}
   450 	b, err := marshaler.Marshal()
   448 	b, err := marshaler.Marshal()
   451 	if err != nil {
   449 	if err != nil {
   452 		return piface.MergeOutput{}
   450 		return protoiface.MergeOutput{}
   453 	}
   451 	}
   454 	err = unmarshaler.Unmarshal(b)
   452 	err = unmarshaler.Unmarshal(b)
   455 	if err != nil {
   453 	if err != nil {
   456 		return piface.MergeOutput{}
   454 		return protoiface.MergeOutput{}
   457 	}
   455 	}
   458 	return piface.MergeOutput{Flags: piface.MergeComplete}
   456 	return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
   459 }
   457 }
   460 
   458 
   461 // aberrantMessageType implements MessageType for all types other than pointer-to-struct.
   459 // aberrantMessageType implements MessageType for all types other than pointer-to-struct.
   462 type aberrantMessageType struct {
   460 type aberrantMessageType struct {
   463 	t reflect.Type
   461 	t reflect.Type
   464 }
   462 }
   465 
   463 
   466 func (mt aberrantMessageType) New() pref.Message {
   464 func (mt aberrantMessageType) New() protoreflect.Message {
   467 	if mt.t.Kind() == reflect.Ptr {
   465 	if mt.t.Kind() == reflect.Ptr {
   468 		return aberrantMessage{reflect.New(mt.t.Elem())}
   466 		return aberrantMessage{reflect.New(mt.t.Elem())}
   469 	}
   467 	}
   470 	return aberrantMessage{reflect.Zero(mt.t)}
   468 	return aberrantMessage{reflect.Zero(mt.t)}
   471 }
   469 }
   472 func (mt aberrantMessageType) Zero() pref.Message {
   470 func (mt aberrantMessageType) Zero() protoreflect.Message {
   473 	return aberrantMessage{reflect.Zero(mt.t)}
   471 	return aberrantMessage{reflect.Zero(mt.t)}
   474 }
   472 }
   475 func (mt aberrantMessageType) GoType() reflect.Type {
   473 func (mt aberrantMessageType) GoType() reflect.Type {
   476 	return mt.t
   474 	return mt.t
   477 }
   475 }
   478 func (mt aberrantMessageType) Descriptor() pref.MessageDescriptor {
   476 func (mt aberrantMessageType) Descriptor() protoreflect.MessageDescriptor {
   479 	return LegacyLoadMessageDesc(mt.t)
   477 	return LegacyLoadMessageDesc(mt.t)
   480 }
   478 }
   481 
   479 
   482 // aberrantMessage implements Message for all types other than pointer-to-struct.
   480 // aberrantMessage implements Message for all types other than pointer-to-struct.
   483 //
   481 //
   497 	if m.v.Kind() == reflect.Ptr && !m.v.IsNil() {
   495 	if m.v.Kind() == reflect.Ptr && !m.v.IsNil() {
   498 		m.v.Elem().Set(reflect.Zero(m.v.Type().Elem()))
   496 		m.v.Elem().Set(reflect.Zero(m.v.Type().Elem()))
   499 	}
   497 	}
   500 }
   498 }
   501 
   499 
   502 func (m aberrantMessage) ProtoReflect() pref.Message {
   500 func (m aberrantMessage) ProtoReflect() protoreflect.Message {
   503 	return m
   501 	return m
   504 }
   502 }
   505 
   503 
   506 func (m aberrantMessage) Descriptor() pref.MessageDescriptor {
   504 func (m aberrantMessage) Descriptor() protoreflect.MessageDescriptor {
   507 	return LegacyLoadMessageDesc(m.v.Type())
   505 	return LegacyLoadMessageDesc(m.v.Type())
   508 }
   506 }
   509 func (m aberrantMessage) Type() pref.MessageType {
   507 func (m aberrantMessage) Type() protoreflect.MessageType {
   510 	return aberrantMessageType{m.v.Type()}
   508 	return aberrantMessageType{m.v.Type()}
   511 }
   509 }
   512 func (m aberrantMessage) New() pref.Message {
   510 func (m aberrantMessage) New() protoreflect.Message {
   513 	if m.v.Type().Kind() == reflect.Ptr {
   511 	if m.v.Type().Kind() == reflect.Ptr {
   514 		return aberrantMessage{reflect.New(m.v.Type().Elem())}
   512 		return aberrantMessage{reflect.New(m.v.Type().Elem())}
   515 	}
   513 	}
   516 	return aberrantMessage{reflect.Zero(m.v.Type())}
   514 	return aberrantMessage{reflect.Zero(m.v.Type())}
   517 }
   515 }
   518 func (m aberrantMessage) Interface() pref.ProtoMessage {
   516 func (m aberrantMessage) Interface() protoreflect.ProtoMessage {
   519 	return m
   517 	return m
   520 }
   518 }
   521 func (m aberrantMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
   519 func (m aberrantMessage) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
   522 	return
   520 	return
   523 }
   521 }
   524 func (m aberrantMessage) Has(pref.FieldDescriptor) bool {
   522 func (m aberrantMessage) Has(protoreflect.FieldDescriptor) bool {
   525 	return false
   523 	return false
   526 }
   524 }
   527 func (m aberrantMessage) Clear(pref.FieldDescriptor) {
   525 func (m aberrantMessage) Clear(protoreflect.FieldDescriptor) {
   528 	panic("invalid Message.Clear on " + string(m.Descriptor().FullName()))
   526 	panic("invalid Message.Clear on " + string(m.Descriptor().FullName()))
   529 }
   527 }
   530 func (m aberrantMessage) Get(fd pref.FieldDescriptor) pref.Value {
   528 func (m aberrantMessage) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
   531 	if fd.Default().IsValid() {
   529 	if fd.Default().IsValid() {
   532 		return fd.Default()
   530 		return fd.Default()
   533 	}
   531 	}
   534 	panic("invalid Message.Get on " + string(m.Descriptor().FullName()))
   532 	panic("invalid Message.Get on " + string(m.Descriptor().FullName()))
   535 }
   533 }
   536 func (m aberrantMessage) Set(pref.FieldDescriptor, pref.Value) {
   534 func (m aberrantMessage) Set(protoreflect.FieldDescriptor, protoreflect.Value) {
   537 	panic("invalid Message.Set on " + string(m.Descriptor().FullName()))
   535 	panic("invalid Message.Set on " + string(m.Descriptor().FullName()))
   538 }
   536 }
   539 func (m aberrantMessage) Mutable(pref.FieldDescriptor) pref.Value {
   537 func (m aberrantMessage) Mutable(protoreflect.FieldDescriptor) protoreflect.Value {
   540 	panic("invalid Message.Mutable on " + string(m.Descriptor().FullName()))
   538 	panic("invalid Message.Mutable on " + string(m.Descriptor().FullName()))
   541 }
   539 }
   542 func (m aberrantMessage) NewField(pref.FieldDescriptor) pref.Value {
   540 func (m aberrantMessage) NewField(protoreflect.FieldDescriptor) protoreflect.Value {
   543 	panic("invalid Message.NewField on " + string(m.Descriptor().FullName()))
   541 	panic("invalid Message.NewField on " + string(m.Descriptor().FullName()))
   544 }
   542 }
   545 func (m aberrantMessage) WhichOneof(pref.OneofDescriptor) pref.FieldDescriptor {
   543 func (m aberrantMessage) WhichOneof(protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
   546 	panic("invalid Message.WhichOneof descriptor on " + string(m.Descriptor().FullName()))
   544 	panic("invalid Message.WhichOneof descriptor on " + string(m.Descriptor().FullName()))
   547 }
   545 }
   548 func (m aberrantMessage) GetUnknown() pref.RawFields {
   546 func (m aberrantMessage) GetUnknown() protoreflect.RawFields {
   549 	return nil
   547 	return nil
   550 }
   548 }
   551 func (m aberrantMessage) SetUnknown(pref.RawFields) {
   549 func (m aberrantMessage) SetUnknown(protoreflect.RawFields) {
   552 	// SetUnknown discards its input on messages which don't support unknown field storage.
   550 	// SetUnknown discards its input on messages which don't support unknown field storage.
   553 }
   551 }
   554 func (m aberrantMessage) IsValid() bool {
   552 func (m aberrantMessage) IsValid() bool {
   555 	if m.v.Kind() == reflect.Ptr {
   553 	if m.v.Kind() == reflect.Ptr {
   556 		return !m.v.IsNil()
   554 		return !m.v.IsNil()
   557 	}
   555 	}
   558 	return false
   556 	return false
   559 }
   557 }
   560 func (m aberrantMessage) ProtoMethods() *piface.Methods {
   558 func (m aberrantMessage) ProtoMethods() *protoiface.Methods {
   561 	return aberrantProtoMethods
   559 	return aberrantProtoMethods
   562 }
   560 }
   563 func (m aberrantMessage) protoUnwrap() interface{} {
   561 func (m aberrantMessage) protoUnwrap() interface{} {
   564 	return m.v.Interface()
   562 	return m.v.Interface()
   565 }
   563 }