You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

634 line
24 KiB

  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 filedesc
  5. import (
  6. "bytes"
  7. "fmt"
  8. "sync"
  9. "sync/atomic"
  10. "google.golang.org/protobuf/internal/descfmt"
  11. "google.golang.org/protobuf/internal/descopts"
  12. "google.golang.org/protobuf/internal/encoding/defval"
  13. "google.golang.org/protobuf/internal/encoding/messageset"
  14. "google.golang.org/protobuf/internal/genid"
  15. "google.golang.org/protobuf/internal/pragma"
  16. "google.golang.org/protobuf/internal/strs"
  17. "google.golang.org/protobuf/reflect/protoreflect"
  18. "google.golang.org/protobuf/reflect/protoregistry"
  19. )
  20. // The types in this file may have a suffix:
  21. // • L0: Contains fields common to all descriptors (except File) and
  22. // must be initialized up front.
  23. // • L1: Contains fields specific to a descriptor and
  24. // must be initialized up front.
  25. // • L2: Contains fields that are lazily initialized when constructing
  26. // from the raw file descriptor. When constructing as a literal, the L2
  27. // fields must be initialized up front.
  28. //
  29. // The types are exported so that packages like reflect/protodesc can
  30. // directly construct descriptors.
  31. type (
  32. File struct {
  33. fileRaw
  34. L1 FileL1
  35. once uint32 // atomically set if L2 is valid
  36. mu sync.Mutex // protects L2
  37. L2 *FileL2
  38. }
  39. FileL1 struct {
  40. Syntax protoreflect.Syntax
  41. Path string
  42. Package protoreflect.FullName
  43. Enums Enums
  44. Messages Messages
  45. Extensions Extensions
  46. Services Services
  47. }
  48. FileL2 struct {
  49. Options func() protoreflect.ProtoMessage
  50. Imports FileImports
  51. Locations SourceLocations
  52. }
  53. )
  54. func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd }
  55. func (fd *File) Parent() protoreflect.Descriptor { return nil }
  56. func (fd *File) Index() int { return 0 }
  57. func (fd *File) Syntax() protoreflect.Syntax { return fd.L1.Syntax }
  58. func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() }
  59. func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package }
  60. func (fd *File) IsPlaceholder() bool { return false }
  61. func (fd *File) Options() protoreflect.ProtoMessage {
  62. if f := fd.lazyInit().Options; f != nil {
  63. return f()
  64. }
  65. return descopts.File
  66. }
  67. func (fd *File) Path() string { return fd.L1.Path }
  68. func (fd *File) Package() protoreflect.FullName { return fd.L1.Package }
  69. func (fd *File) Imports() protoreflect.FileImports { return &fd.lazyInit().Imports }
  70. func (fd *File) Enums() protoreflect.EnumDescriptors { return &fd.L1.Enums }
  71. func (fd *File) Messages() protoreflect.MessageDescriptors { return &fd.L1.Messages }
  72. func (fd *File) Extensions() protoreflect.ExtensionDescriptors { return &fd.L1.Extensions }
  73. func (fd *File) Services() protoreflect.ServiceDescriptors { return &fd.L1.Services }
  74. func (fd *File) SourceLocations() protoreflect.SourceLocations { return &fd.lazyInit().Locations }
  75. func (fd *File) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
  76. func (fd *File) ProtoType(protoreflect.FileDescriptor) {}
  77. func (fd *File) ProtoInternal(pragma.DoNotImplement) {}
  78. func (fd *File) lazyInit() *FileL2 {
  79. if atomic.LoadUint32(&fd.once) == 0 {
  80. fd.lazyInitOnce()
  81. }
  82. return fd.L2
  83. }
  84. func (fd *File) lazyInitOnce() {
  85. fd.mu.Lock()
  86. if fd.L2 == nil {
  87. fd.lazyRawInit() // recursively initializes all L2 structures
  88. }
  89. atomic.StoreUint32(&fd.once, 1)
  90. fd.mu.Unlock()
  91. }
  92. // GoPackagePath is a pseudo-internal API for determining the Go package path
  93. // that this file descriptor is declared in.
  94. //
  95. // WARNING: This method is exempt from the compatibility promise and may be
  96. // removed in the future without warning.
  97. func (fd *File) GoPackagePath() string {
  98. return fd.builder.GoPackagePath
  99. }
  100. type (
  101. Enum struct {
  102. Base
  103. L1 EnumL1
  104. L2 *EnumL2 // protected by fileDesc.once
  105. }
  106. EnumL1 struct {
  107. eagerValues bool // controls whether EnumL2.Values is already populated
  108. }
  109. EnumL2 struct {
  110. Options func() protoreflect.ProtoMessage
  111. Values EnumValues
  112. ReservedNames Names
  113. ReservedRanges EnumRanges
  114. }
  115. EnumValue struct {
  116. Base
  117. L1 EnumValueL1
  118. }
  119. EnumValueL1 struct {
  120. Options func() protoreflect.ProtoMessage
  121. Number protoreflect.EnumNumber
  122. }
  123. )
  124. func (ed *Enum) Options() protoreflect.ProtoMessage {
  125. if f := ed.lazyInit().Options; f != nil {
  126. return f()
  127. }
  128. return descopts.Enum
  129. }
  130. func (ed *Enum) Values() protoreflect.EnumValueDescriptors {
  131. if ed.L1.eagerValues {
  132. return &ed.L2.Values
  133. }
  134. return &ed.lazyInit().Values
  135. }
  136. func (ed *Enum) ReservedNames() protoreflect.Names { return &ed.lazyInit().ReservedNames }
  137. func (ed *Enum) ReservedRanges() protoreflect.EnumRanges { return &ed.lazyInit().ReservedRanges }
  138. func (ed *Enum) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
  139. func (ed *Enum) ProtoType(protoreflect.EnumDescriptor) {}
  140. func (ed *Enum) lazyInit() *EnumL2 {
  141. ed.L0.ParentFile.lazyInit() // implicitly initializes L2
  142. return ed.L2
  143. }
  144. func (ed *EnumValue) Options() protoreflect.ProtoMessage {
  145. if f := ed.L1.Options; f != nil {
  146. return f()
  147. }
  148. return descopts.EnumValue
  149. }
  150. func (ed *EnumValue) Number() protoreflect.EnumNumber { return ed.L1.Number }
  151. func (ed *EnumValue) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
  152. func (ed *EnumValue) ProtoType(protoreflect.EnumValueDescriptor) {}
  153. type (
  154. Message struct {
  155. Base
  156. L1 MessageL1
  157. L2 *MessageL2 // protected by fileDesc.once
  158. }
  159. MessageL1 struct {
  160. Enums Enums
  161. Messages Messages
  162. Extensions Extensions
  163. IsMapEntry bool // promoted from google.protobuf.MessageOptions
  164. IsMessageSet bool // promoted from google.protobuf.MessageOptions
  165. }
  166. MessageL2 struct {
  167. Options func() protoreflect.ProtoMessage
  168. Fields Fields
  169. Oneofs Oneofs
  170. ReservedNames Names
  171. ReservedRanges FieldRanges
  172. RequiredNumbers FieldNumbers // must be consistent with Fields.Cardinality
  173. ExtensionRanges FieldRanges
  174. ExtensionRangeOptions []func() protoreflect.ProtoMessage // must be same length as ExtensionRanges
  175. }
  176. Field struct {
  177. Base
  178. L1 FieldL1
  179. }
  180. FieldL1 struct {
  181. Options func() protoreflect.ProtoMessage
  182. Number protoreflect.FieldNumber
  183. Cardinality protoreflect.Cardinality // must be consistent with Message.RequiredNumbers
  184. Kind protoreflect.Kind
  185. StringName stringName
  186. IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
  187. IsWeak bool // promoted from google.protobuf.FieldOptions
  188. HasPacked bool // promoted from google.protobuf.FieldOptions
  189. IsPacked bool // promoted from google.protobuf.FieldOptions
  190. HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions
  191. EnforceUTF8 bool // promoted from google.protobuf.FieldOptions
  192. Default defaultValue
  193. ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
  194. Enum protoreflect.EnumDescriptor
  195. Message protoreflect.MessageDescriptor
  196. }
  197. Oneof struct {
  198. Base
  199. L1 OneofL1
  200. }
  201. OneofL1 struct {
  202. Options func() protoreflect.ProtoMessage
  203. Fields OneofFields // must be consistent with Message.Fields.ContainingOneof
  204. }
  205. )
  206. func (md *Message) Options() protoreflect.ProtoMessage {
  207. if f := md.lazyInit().Options; f != nil {
  208. return f()
  209. }
  210. return descopts.Message
  211. }
  212. func (md *Message) IsMapEntry() bool { return md.L1.IsMapEntry }
  213. func (md *Message) Fields() protoreflect.FieldDescriptors { return &md.lazyInit().Fields }
  214. func (md *Message) Oneofs() protoreflect.OneofDescriptors { return &md.lazyInit().Oneofs }
  215. func (md *Message) ReservedNames() protoreflect.Names { return &md.lazyInit().ReservedNames }
  216. func (md *Message) ReservedRanges() protoreflect.FieldRanges { return &md.lazyInit().ReservedRanges }
  217. func (md *Message) RequiredNumbers() protoreflect.FieldNumbers { return &md.lazyInit().RequiredNumbers }
  218. func (md *Message) ExtensionRanges() protoreflect.FieldRanges { return &md.lazyInit().ExtensionRanges }
  219. func (md *Message) ExtensionRangeOptions(i int) protoreflect.ProtoMessage {
  220. if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
  221. return f()
  222. }
  223. return descopts.ExtensionRange
  224. }
  225. func (md *Message) Enums() protoreflect.EnumDescriptors { return &md.L1.Enums }
  226. func (md *Message) Messages() protoreflect.MessageDescriptors { return &md.L1.Messages }
  227. func (md *Message) Extensions() protoreflect.ExtensionDescriptors { return &md.L1.Extensions }
  228. func (md *Message) ProtoType(protoreflect.MessageDescriptor) {}
  229. func (md *Message) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
  230. func (md *Message) lazyInit() *MessageL2 {
  231. md.L0.ParentFile.lazyInit() // implicitly initializes L2
  232. return md.L2
  233. }
  234. // IsMessageSet is a pseudo-internal API for checking whether a message
  235. // should serialize in the proto1 message format.
  236. //
  237. // WARNING: This method is exempt from the compatibility promise and may be
  238. // removed in the future without warning.
  239. func (md *Message) IsMessageSet() bool {
  240. return md.L1.IsMessageSet
  241. }
  242. func (fd *Field) Options() protoreflect.ProtoMessage {
  243. if f := fd.L1.Options; f != nil {
  244. return f()
  245. }
  246. return descopts.Field
  247. }
  248. func (fd *Field) Number() protoreflect.FieldNumber { return fd.L1.Number }
  249. func (fd *Field) Cardinality() protoreflect.Cardinality { return fd.L1.Cardinality }
  250. func (fd *Field) Kind() protoreflect.Kind { return fd.L1.Kind }
  251. func (fd *Field) HasJSONName() bool { return fd.L1.StringName.hasJSON }
  252. func (fd *Field) JSONName() string { return fd.L1.StringName.getJSON(fd) }
  253. func (fd *Field) TextName() string { return fd.L1.StringName.getText(fd) }
  254. func (fd *Field) HasPresence() bool {
  255. return fd.L1.Cardinality != protoreflect.Repeated && (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil)
  256. }
  257. func (fd *Field) HasOptionalKeyword() bool {
  258. return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
  259. }
  260. func (fd *Field) IsPacked() bool {
  261. if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Repeated {
  262. switch fd.L1.Kind {
  263. case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
  264. default:
  265. return true
  266. }
  267. }
  268. return fd.L1.IsPacked
  269. }
  270. func (fd *Field) IsExtension() bool { return false }
  271. func (fd *Field) IsWeak() bool { return fd.L1.IsWeak }
  272. func (fd *Field) IsList() bool { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() }
  273. func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() }
  274. func (fd *Field) MapKey() protoreflect.FieldDescriptor {
  275. if !fd.IsMap() {
  276. return nil
  277. }
  278. return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
  279. }
  280. func (fd *Field) MapValue() protoreflect.FieldDescriptor {
  281. if !fd.IsMap() {
  282. return nil
  283. }
  284. return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
  285. }
  286. func (fd *Field) HasDefault() bool { return fd.L1.Default.has }
  287. func (fd *Field) Default() protoreflect.Value { return fd.L1.Default.get(fd) }
  288. func (fd *Field) DefaultEnumValue() protoreflect.EnumValueDescriptor { return fd.L1.Default.enum }
  289. func (fd *Field) ContainingOneof() protoreflect.OneofDescriptor { return fd.L1.ContainingOneof }
  290. func (fd *Field) ContainingMessage() protoreflect.MessageDescriptor {
  291. return fd.L0.Parent.(protoreflect.MessageDescriptor)
  292. }
  293. func (fd *Field) Enum() protoreflect.EnumDescriptor {
  294. return fd.L1.Enum
  295. }
  296. func (fd *Field) Message() protoreflect.MessageDescriptor {
  297. if fd.L1.IsWeak {
  298. if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
  299. return d.(protoreflect.MessageDescriptor)
  300. }
  301. }
  302. return fd.L1.Message
  303. }
  304. func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
  305. func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}
  306. // EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
  307. // validation for the string field. This exists for Google-internal use only
  308. // since proto3 did not enforce UTF-8 validity prior to the open-source release.
  309. // If this method does not exist, the default is to enforce valid UTF-8.
  310. //
  311. // WARNING: This method is exempt from the compatibility promise and may be
  312. // removed in the future without warning.
  313. func (fd *Field) EnforceUTF8() bool {
  314. if fd.L1.HasEnforceUTF8 {
  315. return fd.L1.EnforceUTF8
  316. }
  317. return fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3
  318. }
  319. func (od *Oneof) IsSynthetic() bool {
  320. return od.L0.ParentFile.L1.Syntax == protoreflect.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
  321. }
  322. func (od *Oneof) Options() protoreflect.ProtoMessage {
  323. if f := od.L1.Options; f != nil {
  324. return f()
  325. }
  326. return descopts.Oneof
  327. }
  328. func (od *Oneof) Fields() protoreflect.FieldDescriptors { return &od.L1.Fields }
  329. func (od *Oneof) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, od) }
  330. func (od *Oneof) ProtoType(protoreflect.OneofDescriptor) {}
  331. type (
  332. Extension struct {
  333. Base
  334. L1 ExtensionL1
  335. L2 *ExtensionL2 // protected by fileDesc.once
  336. }
  337. ExtensionL1 struct {
  338. Number protoreflect.FieldNumber
  339. Extendee protoreflect.MessageDescriptor
  340. Cardinality protoreflect.Cardinality
  341. Kind protoreflect.Kind
  342. }
  343. ExtensionL2 struct {
  344. Options func() protoreflect.ProtoMessage
  345. StringName stringName
  346. IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
  347. IsPacked bool // promoted from google.protobuf.FieldOptions
  348. Default defaultValue
  349. Enum protoreflect.EnumDescriptor
  350. Message protoreflect.MessageDescriptor
  351. }
  352. )
  353. func (xd *Extension) Options() protoreflect.ProtoMessage {
  354. if f := xd.lazyInit().Options; f != nil {
  355. return f()
  356. }
  357. return descopts.Field
  358. }
  359. func (xd *Extension) Number() protoreflect.FieldNumber { return xd.L1.Number }
  360. func (xd *Extension) Cardinality() protoreflect.Cardinality { return xd.L1.Cardinality }
  361. func (xd *Extension) Kind() protoreflect.Kind { return xd.L1.Kind }
  362. func (xd *Extension) HasJSONName() bool { return xd.lazyInit().StringName.hasJSON }
  363. func (xd *Extension) JSONName() string { return xd.lazyInit().StringName.getJSON(xd) }
  364. func (xd *Extension) TextName() string { return xd.lazyInit().StringName.getText(xd) }
  365. func (xd *Extension) HasPresence() bool { return xd.L1.Cardinality != protoreflect.Repeated }
  366. func (xd *Extension) HasOptionalKeyword() bool {
  367. return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional
  368. }
  369. func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked }
  370. func (xd *Extension) IsExtension() bool { return true }
  371. func (xd *Extension) IsWeak() bool { return false }
  372. func (xd *Extension) IsList() bool { return xd.Cardinality() == protoreflect.Repeated }
  373. func (xd *Extension) IsMap() bool { return false }
  374. func (xd *Extension) MapKey() protoreflect.FieldDescriptor { return nil }
  375. func (xd *Extension) MapValue() protoreflect.FieldDescriptor { return nil }
  376. func (xd *Extension) HasDefault() bool { return xd.lazyInit().Default.has }
  377. func (xd *Extension) Default() protoreflect.Value { return xd.lazyInit().Default.get(xd) }
  378. func (xd *Extension) DefaultEnumValue() protoreflect.EnumValueDescriptor {
  379. return xd.lazyInit().Default.enum
  380. }
  381. func (xd *Extension) ContainingOneof() protoreflect.OneofDescriptor { return nil }
  382. func (xd *Extension) ContainingMessage() protoreflect.MessageDescriptor { return xd.L1.Extendee }
  383. func (xd *Extension) Enum() protoreflect.EnumDescriptor { return xd.lazyInit().Enum }
  384. func (xd *Extension) Message() protoreflect.MessageDescriptor { return xd.lazyInit().Message }
  385. func (xd *Extension) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, xd) }
  386. func (xd *Extension) ProtoType(protoreflect.FieldDescriptor) {}
  387. func (xd *Extension) ProtoInternal(pragma.DoNotImplement) {}
  388. func (xd *Extension) lazyInit() *ExtensionL2 {
  389. xd.L0.ParentFile.lazyInit() // implicitly initializes L2
  390. return xd.L2
  391. }
  392. type (
  393. Service struct {
  394. Base
  395. L1 ServiceL1
  396. L2 *ServiceL2 // protected by fileDesc.once
  397. }
  398. ServiceL1 struct{}
  399. ServiceL2 struct {
  400. Options func() protoreflect.ProtoMessage
  401. Methods Methods
  402. }
  403. Method struct {
  404. Base
  405. L1 MethodL1
  406. }
  407. MethodL1 struct {
  408. Options func() protoreflect.ProtoMessage
  409. Input protoreflect.MessageDescriptor
  410. Output protoreflect.MessageDescriptor
  411. IsStreamingClient bool
  412. IsStreamingServer bool
  413. }
  414. )
  415. func (sd *Service) Options() protoreflect.ProtoMessage {
  416. if f := sd.lazyInit().Options; f != nil {
  417. return f()
  418. }
  419. return descopts.Service
  420. }
  421. func (sd *Service) Methods() protoreflect.MethodDescriptors { return &sd.lazyInit().Methods }
  422. func (sd *Service) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, sd) }
  423. func (sd *Service) ProtoType(protoreflect.ServiceDescriptor) {}
  424. func (sd *Service) ProtoInternal(pragma.DoNotImplement) {}
  425. func (sd *Service) lazyInit() *ServiceL2 {
  426. sd.L0.ParentFile.lazyInit() // implicitly initializes L2
  427. return sd.L2
  428. }
  429. func (md *Method) Options() protoreflect.ProtoMessage {
  430. if f := md.L1.Options; f != nil {
  431. return f()
  432. }
  433. return descopts.Method
  434. }
  435. func (md *Method) Input() protoreflect.MessageDescriptor { return md.L1.Input }
  436. func (md *Method) Output() protoreflect.MessageDescriptor { return md.L1.Output }
  437. func (md *Method) IsStreamingClient() bool { return md.L1.IsStreamingClient }
  438. func (md *Method) IsStreamingServer() bool { return md.L1.IsStreamingServer }
  439. func (md *Method) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
  440. func (md *Method) ProtoType(protoreflect.MethodDescriptor) {}
  441. func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
  442. // Surrogate files are can be used to create standalone descriptors
  443. // where the syntax is only information derived from the parent file.
  444. var (
  445. SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
  446. SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
  447. )
  448. type (
  449. Base struct {
  450. L0 BaseL0
  451. }
  452. BaseL0 struct {
  453. FullName protoreflect.FullName // must be populated
  454. ParentFile *File // must be populated
  455. Parent protoreflect.Descriptor
  456. Index int
  457. }
  458. )
  459. func (d *Base) Name() protoreflect.Name { return d.L0.FullName.Name() }
  460. func (d *Base) FullName() protoreflect.FullName { return d.L0.FullName }
  461. func (d *Base) ParentFile() protoreflect.FileDescriptor {
  462. if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
  463. return nil // surrogate files are not real parents
  464. }
  465. return d.L0.ParentFile
  466. }
  467. func (d *Base) Parent() protoreflect.Descriptor { return d.L0.Parent }
  468. func (d *Base) Index() int { return d.L0.Index }
  469. func (d *Base) Syntax() protoreflect.Syntax { return d.L0.ParentFile.Syntax() }
  470. func (d *Base) IsPlaceholder() bool { return false }
  471. func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
  472. type stringName struct {
  473. hasJSON bool
  474. once sync.Once
  475. nameJSON string
  476. nameText string
  477. }
  478. // InitJSON initializes the name. It is exported for use by other internal packages.
  479. func (s *stringName) InitJSON(name string) {
  480. s.hasJSON = true
  481. s.nameJSON = name
  482. }
  483. func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
  484. s.once.Do(func() {
  485. if fd.IsExtension() {
  486. // For extensions, JSON and text are formatted the same way.
  487. var name string
  488. if messageset.IsMessageSetExtension(fd) {
  489. name = string("[" + fd.FullName().Parent() + "]")
  490. } else {
  491. name = string("[" + fd.FullName() + "]")
  492. }
  493. s.nameJSON = name
  494. s.nameText = name
  495. } else {
  496. // Format the JSON name.
  497. if !s.hasJSON {
  498. s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
  499. }
  500. // Format the text name.
  501. s.nameText = string(fd.Name())
  502. if fd.Kind() == protoreflect.GroupKind {
  503. s.nameText = string(fd.Message().Name())
  504. }
  505. }
  506. })
  507. return s
  508. }
  509. func (s *stringName) getJSON(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
  510. func (s *stringName) getText(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameText }
  511. func DefaultValue(v protoreflect.Value, ev protoreflect.EnumValueDescriptor) defaultValue {
  512. dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
  513. if b, ok := v.Interface().([]byte); ok {
  514. // Store a copy of the default bytes, so that we can detect
  515. // accidental mutations of the original value.
  516. dv.bytes = append([]byte(nil), b...)
  517. }
  518. return dv
  519. }
  520. func unmarshalDefault(b []byte, k protoreflect.Kind, pf *File, ed protoreflect.EnumDescriptor) defaultValue {
  521. var evs protoreflect.EnumValueDescriptors
  522. if k == protoreflect.EnumKind {
  523. // If the enum is declared within the same file, be careful not to
  524. // blindly call the Values method, lest we bind ourselves in a deadlock.
  525. if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
  526. evs = &e.L2.Values
  527. } else {
  528. evs = ed.Values()
  529. }
  530. // If we are unable to resolve the enum dependency, use a placeholder
  531. // enum value since we will not be able to parse the default value.
  532. if ed.IsPlaceholder() && protoreflect.Name(b).IsValid() {
  533. v := protoreflect.ValueOfEnum(0)
  534. ev := PlaceholderEnumValue(ed.FullName().Parent().Append(protoreflect.Name(b)))
  535. return DefaultValue(v, ev)
  536. }
  537. }
  538. v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
  539. if err != nil {
  540. panic(err)
  541. }
  542. return DefaultValue(v, ev)
  543. }
  544. type defaultValue struct {
  545. has bool
  546. val protoreflect.Value
  547. enum protoreflect.EnumValueDescriptor
  548. bytes []byte
  549. }
  550. func (dv *defaultValue) get(fd protoreflect.FieldDescriptor) protoreflect.Value {
  551. // Return the zero value as the default if unpopulated.
  552. if !dv.has {
  553. if fd.Cardinality() == protoreflect.Repeated {
  554. return protoreflect.Value{}
  555. }
  556. switch fd.Kind() {
  557. case protoreflect.BoolKind:
  558. return protoreflect.ValueOfBool(false)
  559. case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
  560. return protoreflect.ValueOfInt32(0)
  561. case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
  562. return protoreflect.ValueOfInt64(0)
  563. case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
  564. return protoreflect.ValueOfUint32(0)
  565. case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
  566. return protoreflect.ValueOfUint64(0)
  567. case protoreflect.FloatKind:
  568. return protoreflect.ValueOfFloat32(0)
  569. case protoreflect.DoubleKind:
  570. return protoreflect.ValueOfFloat64(0)
  571. case protoreflect.StringKind:
  572. return protoreflect.ValueOfString("")
  573. case protoreflect.BytesKind:
  574. return protoreflect.ValueOfBytes(nil)
  575. case protoreflect.EnumKind:
  576. if evs := fd.Enum().Values(); evs.Len() > 0 {
  577. return protoreflect.ValueOfEnum(evs.Get(0).Number())
  578. }
  579. return protoreflect.ValueOfEnum(0)
  580. }
  581. }
  582. if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
  583. // TODO: Avoid panic if we're running with the race detector
  584. // and instead spawn a goroutine that periodically resets
  585. // this value back to the original to induce a race.
  586. panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
  587. }
  588. return dv.val
  589. }