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