extension.go 4.6 KB

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