extension.go 4.9 KB

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