extension.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 field is set, but other unexported fields
  26. // may not be initialized. Legacy exported fields may or may not be set.
  27. // This is the starting state for an ExtensionInfo in newly generated code.
  28. //
  29. // extensionInfoFullInit: The ExtensionInfo is fully initialized.
  30. // This state is only entered after lazy initialization is complete.
  31. init uint32
  32. mu sync.Mutex
  33. goType reflect.Type
  34. desc extensionTypeDescriptor
  35. conv Converter
  36. // ExtendedType is a typed nil-pointer to the parent message type that
  37. // is being extended. It is possible for this to be unpopulated in v2
  38. // since the message may no longer implement the MessageV1 interface.
  39. //
  40. // Deprecated: Use the ExtendedType method instead.
  41. ExtendedType piface.MessageV1
  42. // ExtensionType is the zero value of the extension type.
  43. //
  44. // For historical reasons, reflect.TypeOf(ExtensionType) and the
  45. // type returned by InterfaceOf may not be identical.
  46. //
  47. // Deprecated: Use InterfaceOf(xt.Zero()) instead.
  48. ExtensionType interface{}
  49. // Field is the field number of the extension.
  50. //
  51. // Deprecated: Use the Descriptor().Number method instead.
  52. Field int32
  53. // Name is the fully qualified name of extension.
  54. //
  55. // Deprecated: Use the Descriptor().FullName method instead.
  56. Name string
  57. // Tag is the protobuf struct tag used in the v1 API.
  58. //
  59. // Deprecated: Do not use.
  60. Tag string
  61. // Filename is the proto filename in which the extension is defined.
  62. //
  63. // Deprecated: Use Descriptor().ParentFile().Path() instead.
  64. Filename string
  65. }
  66. // Stages of initialization: See the ExtensionInfo.init field.
  67. const (
  68. extensionInfoUninitialized = 0
  69. extensionInfoDescInit = 1
  70. extensionInfoFullInit = 2
  71. )
  72. func InitExtensionInfo(xi *ExtensionInfo, xd pref.ExtensionDescriptor, goType reflect.Type) {
  73. xi.goType = goType
  74. xi.desc = extensionTypeDescriptor{xd, xi}
  75. xi.init = extensionInfoDescInit
  76. }
  77. func (xi *ExtensionInfo) New() pref.Value {
  78. return xi.lazyInit().New()
  79. }
  80. func (xi *ExtensionInfo) Zero() pref.Value {
  81. return xi.lazyInit().Zero()
  82. }
  83. func (xi *ExtensionInfo) ValueOf(v interface{}) pref.Value {
  84. return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
  85. }
  86. func (xi *ExtensionInfo) InterfaceOf(v pref.Value) interface{} {
  87. return xi.lazyInit().GoValueOf(v).Interface()
  88. }
  89. func (xi *ExtensionInfo) IsValidValue(v pref.Value) bool {
  90. return xi.lazyInit().IsValidPB(v)
  91. }
  92. func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
  93. return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
  94. }
  95. func (xi *ExtensionInfo) TypeDescriptor() pref.ExtensionTypeDescriptor {
  96. if atomic.LoadUint32(&xi.init) < extensionInfoDescInit {
  97. xi.lazyInitSlow()
  98. }
  99. return &xi.desc
  100. }
  101. func (xi *ExtensionInfo) lazyInit() Converter {
  102. if atomic.LoadUint32(&xi.init) < extensionInfoFullInit {
  103. xi.lazyInitSlow()
  104. }
  105. return xi.conv
  106. }
  107. func (xi *ExtensionInfo) lazyInitSlow() {
  108. xi.mu.Lock()
  109. defer xi.mu.Unlock()
  110. if xi.init == extensionInfoFullInit {
  111. return
  112. }
  113. defer atomic.StoreUint32(&xi.init, extensionInfoFullInit)
  114. if xi.desc.ExtensionDescriptor == nil {
  115. xi.initFromLegacy()
  116. }
  117. if !xi.desc.ExtensionDescriptor.IsPlaceholder() {
  118. if xi.ExtensionType == nil {
  119. xi.initToLegacy()
  120. }
  121. xi.conv = NewConverter(xi.goType, xi.desc)
  122. }
  123. }
  124. type extensionTypeDescriptor struct {
  125. pref.ExtensionDescriptor
  126. xi *ExtensionInfo
  127. }
  128. func (xtd *extensionTypeDescriptor) Type() pref.ExtensionType {
  129. return xtd.xi
  130. }
  131. func (xtd *extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor {
  132. return xtd.ExtensionDescriptor
  133. }