xref: /aosp_15_r20/external/golang-protobuf/internal/impl/extension.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1*1c12ee1eSDan Willemsen// Copyright 2019 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	"sync"
10*1c12ee1eSDan Willemsen	"sync/atomic"
11*1c12ee1eSDan Willemsen
12*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoreflect"
13*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/runtime/protoiface"
14*1c12ee1eSDan Willemsen)
15*1c12ee1eSDan Willemsen
16*1c12ee1eSDan Willemsen// ExtensionInfo implements ExtensionType.
17*1c12ee1eSDan Willemsen//
18*1c12ee1eSDan Willemsen// This type contains a number of exported fields for legacy compatibility.
19*1c12ee1eSDan Willemsen// The only non-deprecated use of this type is through the methods of the
20*1c12ee1eSDan Willemsen// ExtensionType interface.
21*1c12ee1eSDan Willemsentype ExtensionInfo struct {
22*1c12ee1eSDan Willemsen	// An ExtensionInfo may exist in several stages of initialization.
23*1c12ee1eSDan Willemsen	//
24*1c12ee1eSDan Willemsen	// extensionInfoUninitialized: Some or all of the legacy exported
25*1c12ee1eSDan Willemsen	// fields may be set, but none of the unexported fields have been
26*1c12ee1eSDan Willemsen	// initialized. This is the starting state for an ExtensionInfo
27*1c12ee1eSDan Willemsen	// in legacy generated code.
28*1c12ee1eSDan Willemsen	//
29*1c12ee1eSDan Willemsen	// extensionInfoDescInit: The desc field is set, but other unexported fields
30*1c12ee1eSDan Willemsen	// may not be initialized. Legacy exported fields may or may not be set.
31*1c12ee1eSDan Willemsen	// This is the starting state for an ExtensionInfo in newly generated code.
32*1c12ee1eSDan Willemsen	//
33*1c12ee1eSDan Willemsen	// extensionInfoFullInit: The ExtensionInfo is fully initialized.
34*1c12ee1eSDan Willemsen	// This state is only entered after lazy initialization is complete.
35*1c12ee1eSDan Willemsen	init uint32
36*1c12ee1eSDan Willemsen	mu   sync.Mutex
37*1c12ee1eSDan Willemsen
38*1c12ee1eSDan Willemsen	goType reflect.Type
39*1c12ee1eSDan Willemsen	desc   extensionTypeDescriptor
40*1c12ee1eSDan Willemsen	conv   Converter
41*1c12ee1eSDan Willemsen	info   *extensionFieldInfo // for fast-path method implementations
42*1c12ee1eSDan Willemsen
43*1c12ee1eSDan Willemsen	// ExtendedType is a typed nil-pointer to the parent message type that
44*1c12ee1eSDan Willemsen	// is being extended. It is possible for this to be unpopulated in v2
45*1c12ee1eSDan Willemsen	// since the message may no longer implement the MessageV1 interface.
46*1c12ee1eSDan Willemsen	//
47*1c12ee1eSDan Willemsen	// Deprecated: Use the ExtendedType method instead.
48*1c12ee1eSDan Willemsen	ExtendedType protoiface.MessageV1
49*1c12ee1eSDan Willemsen
50*1c12ee1eSDan Willemsen	// ExtensionType is the zero value of the extension type.
51*1c12ee1eSDan Willemsen	//
52*1c12ee1eSDan Willemsen	// For historical reasons, reflect.TypeOf(ExtensionType) and the
53*1c12ee1eSDan Willemsen	// type returned by InterfaceOf may not be identical.
54*1c12ee1eSDan Willemsen	//
55*1c12ee1eSDan Willemsen	// Deprecated: Use InterfaceOf(xt.Zero()) instead.
56*1c12ee1eSDan Willemsen	ExtensionType interface{}
57*1c12ee1eSDan Willemsen
58*1c12ee1eSDan Willemsen	// Field is the field number of the extension.
59*1c12ee1eSDan Willemsen	//
60*1c12ee1eSDan Willemsen	// Deprecated: Use the Descriptor().Number method instead.
61*1c12ee1eSDan Willemsen	Field int32
62*1c12ee1eSDan Willemsen
63*1c12ee1eSDan Willemsen	// Name is the fully qualified name of extension.
64*1c12ee1eSDan Willemsen	//
65*1c12ee1eSDan Willemsen	// Deprecated: Use the Descriptor().FullName method instead.
66*1c12ee1eSDan Willemsen	Name string
67*1c12ee1eSDan Willemsen
68*1c12ee1eSDan Willemsen	// Tag is the protobuf struct tag used in the v1 API.
69*1c12ee1eSDan Willemsen	//
70*1c12ee1eSDan Willemsen	// Deprecated: Do not use.
71*1c12ee1eSDan Willemsen	Tag string
72*1c12ee1eSDan Willemsen
73*1c12ee1eSDan Willemsen	// Filename is the proto filename in which the extension is defined.
74*1c12ee1eSDan Willemsen	//
75*1c12ee1eSDan Willemsen	// Deprecated: Use Descriptor().ParentFile().Path() instead.
76*1c12ee1eSDan Willemsen	Filename string
77*1c12ee1eSDan Willemsen}
78*1c12ee1eSDan Willemsen
79*1c12ee1eSDan Willemsen// Stages of initialization: See the ExtensionInfo.init field.
80*1c12ee1eSDan Willemsenconst (
81*1c12ee1eSDan Willemsen	extensionInfoUninitialized = 0
82*1c12ee1eSDan Willemsen	extensionInfoDescInit      = 1
83*1c12ee1eSDan Willemsen	extensionInfoFullInit      = 2
84*1c12ee1eSDan Willemsen)
85*1c12ee1eSDan Willemsen
86*1c12ee1eSDan Willemsenfunc InitExtensionInfo(xi *ExtensionInfo, xd protoreflect.ExtensionDescriptor, goType reflect.Type) {
87*1c12ee1eSDan Willemsen	xi.goType = goType
88*1c12ee1eSDan Willemsen	xi.desc = extensionTypeDescriptor{xd, xi}
89*1c12ee1eSDan Willemsen	xi.init = extensionInfoDescInit
90*1c12ee1eSDan Willemsen}
91*1c12ee1eSDan Willemsen
92*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) New() protoreflect.Value {
93*1c12ee1eSDan Willemsen	return xi.lazyInit().New()
94*1c12ee1eSDan Willemsen}
95*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) Zero() protoreflect.Value {
96*1c12ee1eSDan Willemsen	return xi.lazyInit().Zero()
97*1c12ee1eSDan Willemsen}
98*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) ValueOf(v interface{}) protoreflect.Value {
99*1c12ee1eSDan Willemsen	return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
100*1c12ee1eSDan Willemsen}
101*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) InterfaceOf(v protoreflect.Value) interface{} {
102*1c12ee1eSDan Willemsen	return xi.lazyInit().GoValueOf(v).Interface()
103*1c12ee1eSDan Willemsen}
104*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) IsValidValue(v protoreflect.Value) bool {
105*1c12ee1eSDan Willemsen	return xi.lazyInit().IsValidPB(v)
106*1c12ee1eSDan Willemsen}
107*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
108*1c12ee1eSDan Willemsen	return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
109*1c12ee1eSDan Willemsen}
110*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) TypeDescriptor() protoreflect.ExtensionTypeDescriptor {
111*1c12ee1eSDan Willemsen	if atomic.LoadUint32(&xi.init) < extensionInfoDescInit {
112*1c12ee1eSDan Willemsen		xi.lazyInitSlow()
113*1c12ee1eSDan Willemsen	}
114*1c12ee1eSDan Willemsen	return &xi.desc
115*1c12ee1eSDan Willemsen}
116*1c12ee1eSDan Willemsen
117*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) lazyInit() Converter {
118*1c12ee1eSDan Willemsen	if atomic.LoadUint32(&xi.init) < extensionInfoFullInit {
119*1c12ee1eSDan Willemsen		xi.lazyInitSlow()
120*1c12ee1eSDan Willemsen	}
121*1c12ee1eSDan Willemsen	return xi.conv
122*1c12ee1eSDan Willemsen}
123*1c12ee1eSDan Willemsen
124*1c12ee1eSDan Willemsenfunc (xi *ExtensionInfo) lazyInitSlow() {
125*1c12ee1eSDan Willemsen	xi.mu.Lock()
126*1c12ee1eSDan Willemsen	defer xi.mu.Unlock()
127*1c12ee1eSDan Willemsen
128*1c12ee1eSDan Willemsen	if xi.init == extensionInfoFullInit {
129*1c12ee1eSDan Willemsen		return
130*1c12ee1eSDan Willemsen	}
131*1c12ee1eSDan Willemsen	defer atomic.StoreUint32(&xi.init, extensionInfoFullInit)
132*1c12ee1eSDan Willemsen
133*1c12ee1eSDan Willemsen	if xi.desc.ExtensionDescriptor == nil {
134*1c12ee1eSDan Willemsen		xi.initFromLegacy()
135*1c12ee1eSDan Willemsen	}
136*1c12ee1eSDan Willemsen	if !xi.desc.ExtensionDescriptor.IsPlaceholder() {
137*1c12ee1eSDan Willemsen		if xi.ExtensionType == nil {
138*1c12ee1eSDan Willemsen			xi.initToLegacy()
139*1c12ee1eSDan Willemsen		}
140*1c12ee1eSDan Willemsen		xi.conv = NewConverter(xi.goType, xi.desc.ExtensionDescriptor)
141*1c12ee1eSDan Willemsen		xi.info = makeExtensionFieldInfo(xi.desc.ExtensionDescriptor)
142*1c12ee1eSDan Willemsen		xi.info.validation = newValidationInfo(xi.desc.ExtensionDescriptor, xi.goType)
143*1c12ee1eSDan Willemsen	}
144*1c12ee1eSDan Willemsen}
145*1c12ee1eSDan Willemsen
146*1c12ee1eSDan Willemsentype extensionTypeDescriptor struct {
147*1c12ee1eSDan Willemsen	protoreflect.ExtensionDescriptor
148*1c12ee1eSDan Willemsen	xi *ExtensionInfo
149*1c12ee1eSDan Willemsen}
150*1c12ee1eSDan Willemsen
151*1c12ee1eSDan Willemsenfunc (xtd *extensionTypeDescriptor) Type() protoreflect.ExtensionType {
152*1c12ee1eSDan Willemsen	return xtd.xi
153*1c12ee1eSDan Willemsen}
154*1c12ee1eSDan Willemsenfunc (xtd *extensionTypeDescriptor) Descriptor() protoreflect.ExtensionDescriptor {
155*1c12ee1eSDan Willemsen	return xtd.ExtensionDescriptor
156*1c12ee1eSDan Willemsen}
157