gtsocial-umbx

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

extension.go (4721B)


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