desc.go 25 KB

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