gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

legacy_extension.go (7691B)


      1 // Copyright 2018 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package impl
      6 
      7 import (
      8 	"reflect"
      9 
     10 	"google.golang.org/protobuf/internal/descopts"
     11 	"google.golang.org/protobuf/internal/encoding/messageset"
     12 	ptag "google.golang.org/protobuf/internal/encoding/tag"
     13 	"google.golang.org/protobuf/internal/filedesc"
     14 	"google.golang.org/protobuf/internal/pragma"
     15 	"google.golang.org/protobuf/reflect/protoreflect"
     16 	"google.golang.org/protobuf/reflect/protoregistry"
     17 	"google.golang.org/protobuf/runtime/protoiface"
     18 )
     19 
     20 func (xi *ExtensionInfo) initToLegacy() {
     21 	xd := xi.desc
     22 	var parent protoiface.MessageV1
     23 	messageName := xd.ContainingMessage().FullName()
     24 	if mt, _ := protoregistry.GlobalTypes.FindMessageByName(messageName); mt != nil {
     25 		// Create a new parent message and unwrap it if possible.
     26 		mv := mt.New().Interface()
     27 		t := reflect.TypeOf(mv)
     28 		if mv, ok := mv.(unwrapper); ok {
     29 			t = reflect.TypeOf(mv.protoUnwrap())
     30 		}
     31 
     32 		// Check whether the message implements the legacy v1 Message interface.
     33 		mz := reflect.Zero(t).Interface()
     34 		if mz, ok := mz.(protoiface.MessageV1); ok {
     35 			parent = mz
     36 		}
     37 	}
     38 
     39 	// Determine the v1 extension type, which is unfortunately not the same as
     40 	// the v2 ExtensionType.GoType.
     41 	extType := xi.goType
     42 	switch extType.Kind() {
     43 	case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
     44 		extType = reflect.PtrTo(extType) // T -> *T for singular scalar fields
     45 	}
     46 
     47 	// Reconstruct the legacy enum full name.
     48 	var enumName string
     49 	if xd.Kind() == protoreflect.EnumKind {
     50 		enumName = legacyEnumName(xd.Enum())
     51 	}
     52 
     53 	// Derive the proto file that the extension was declared within.
     54 	var filename string
     55 	if fd := xd.ParentFile(); fd != nil {
     56 		filename = fd.Path()
     57 	}
     58 
     59 	// For MessageSet extensions, the name used is the parent message.
     60 	name := xd.FullName()
     61 	if messageset.IsMessageSetExtension(xd) {
     62 		name = name.Parent()
     63 	}
     64 
     65 	xi.ExtendedType = parent
     66 	xi.ExtensionType = reflect.Zero(extType).Interface()
     67 	xi.Field = int32(xd.Number())
     68 	xi.Name = string(name)
     69 	xi.Tag = ptag.Marshal(xd, enumName)
     70 	xi.Filename = filename
     71 }
     72 
     73 // initFromLegacy initializes an ExtensionInfo from
     74 // the contents of the deprecated exported fields of the type.
     75 func (xi *ExtensionInfo) initFromLegacy() {
     76 	// The v1 API returns "type incomplete" descriptors where only the
     77 	// field number is specified. In such a case, use a placeholder.
     78 	if xi.ExtendedType == nil || xi.ExtensionType == nil {
     79 		xd := placeholderExtension{
     80 			name:   protoreflect.FullName(xi.Name),
     81 			number: protoreflect.FieldNumber(xi.Field),
     82 		}
     83 		xi.desc = extensionTypeDescriptor{xd, xi}
     84 		return
     85 	}
     86 
     87 	// Resolve enum or message dependencies.
     88 	var ed protoreflect.EnumDescriptor
     89 	var md protoreflect.MessageDescriptor
     90 	t := reflect.TypeOf(xi.ExtensionType)
     91 	isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
     92 	isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
     93 	if isOptional || isRepeated {
     94 		t = t.Elem()
     95 	}
     96 	switch v := reflect.Zero(t).Interface().(type) {
     97 	case protoreflect.Enum:
     98 		ed = v.Descriptor()
     99 	case enumV1:
    100 		ed = LegacyLoadEnumDesc(t)
    101 	case protoreflect.ProtoMessage:
    102 		md = v.ProtoReflect().Descriptor()
    103 	case messageV1:
    104 		md = LegacyLoadMessageDesc(t)
    105 	}
    106 
    107 	// Derive basic field information from the struct tag.
    108 	var evs protoreflect.EnumValueDescriptors
    109 	if ed != nil {
    110 		evs = ed.Values()
    111 	}
    112 	fd := ptag.Unmarshal(xi.Tag, t, evs).(*filedesc.Field)
    113 
    114 	// Construct a v2 ExtensionType.
    115 	xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)}
    116 	xd.L0.ParentFile = filedesc.SurrogateProto2
    117 	xd.L0.FullName = protoreflect.FullName(xi.Name)
    118 	xd.L1.Number = protoreflect.FieldNumber(xi.Field)
    119 	xd.L1.Cardinality = fd.L1.Cardinality
    120 	xd.L1.Kind = fd.L1.Kind
    121 	xd.L2.IsPacked = fd.L1.IsPacked
    122 	xd.L2.Default = fd.L1.Default
    123 	xd.L1.Extendee = Export{}.MessageDescriptorOf(xi.ExtendedType)
    124 	xd.L2.Enum = ed
    125 	xd.L2.Message = md
    126 
    127 	// Derive real extension field name for MessageSets.
    128 	if messageset.IsMessageSet(xd.L1.Extendee) && md.FullName() == xd.L0.FullName {
    129 		xd.L0.FullName = xd.L0.FullName.Append(messageset.ExtensionName)
    130 	}
    131 
    132 	tt := reflect.TypeOf(xi.ExtensionType)
    133 	if isOptional {
    134 		tt = tt.Elem()
    135 	}
    136 	xi.goType = tt
    137 	xi.desc = extensionTypeDescriptor{xd, xi}
    138 }
    139 
    140 type placeholderExtension struct {
    141 	name   protoreflect.FullName
    142 	number protoreflect.FieldNumber
    143 }
    144 
    145 func (x placeholderExtension) ParentFile() protoreflect.FileDescriptor            { return nil }
    146 func (x placeholderExtension) Parent() protoreflect.Descriptor                    { return nil }
    147 func (x placeholderExtension) Index() int                                         { return 0 }
    148 func (x placeholderExtension) Syntax() protoreflect.Syntax                        { return 0 }
    149 func (x placeholderExtension) Name() protoreflect.Name                            { return x.name.Name() }
    150 func (x placeholderExtension) FullName() protoreflect.FullName                    { return x.name }
    151 func (x placeholderExtension) IsPlaceholder() bool                                { return true }
    152 func (x placeholderExtension) Options() protoreflect.ProtoMessage                 { return descopts.Field }
    153 func (x placeholderExtension) Number() protoreflect.FieldNumber                   { return x.number }
    154 func (x placeholderExtension) Cardinality() protoreflect.Cardinality              { return 0 }
    155 func (x placeholderExtension) Kind() protoreflect.Kind                            { return 0 }
    156 func (x placeholderExtension) HasJSONName() bool                                  { return false }
    157 func (x placeholderExtension) JSONName() string                                   { return "[" + string(x.name) + "]" }
    158 func (x placeholderExtension) TextName() string                                   { return "[" + string(x.name) + "]" }
    159 func (x placeholderExtension) HasPresence() bool                                  { return false }
    160 func (x placeholderExtension) HasOptionalKeyword() bool                           { return false }
    161 func (x placeholderExtension) IsExtension() bool                                  { return true }
    162 func (x placeholderExtension) IsWeak() bool                                       { return false }
    163 func (x placeholderExtension) IsPacked() bool                                     { return false }
    164 func (x placeholderExtension) IsList() bool                                       { return false }
    165 func (x placeholderExtension) IsMap() bool                                        { return false }
    166 func (x placeholderExtension) MapKey() protoreflect.FieldDescriptor               { return nil }
    167 func (x placeholderExtension) MapValue() protoreflect.FieldDescriptor             { return nil }
    168 func (x placeholderExtension) HasDefault() bool                                   { return false }
    169 func (x placeholderExtension) Default() protoreflect.Value                        { return protoreflect.Value{} }
    170 func (x placeholderExtension) DefaultEnumValue() protoreflect.EnumValueDescriptor { return nil }
    171 func (x placeholderExtension) ContainingOneof() protoreflect.OneofDescriptor      { return nil }
    172 func (x placeholderExtension) ContainingMessage() protoreflect.MessageDescriptor  { return nil }
    173 func (x placeholderExtension) Enum() protoreflect.EnumDescriptor                  { return nil }
    174 func (x placeholderExtension) Message() protoreflect.MessageDescriptor            { return nil }
    175 func (x placeholderExtension) ProtoType(protoreflect.FieldDescriptor)             { return }
    176 func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement)                { return }