desc.go 28 KB

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