ExtensionFields.swift 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. // Sources/SwiftProtobuf/ExtensionFields.swift - Extension support
  2. //
  3. // Copyright (c) 2014 - 2016 Apple Inc. and the project authors
  4. // Licensed under Apache License v2.0 with Runtime Library Exception
  5. //
  6. // See LICENSE.txt for license information:
  7. // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
  8. //
  9. // -----------------------------------------------------------------------------
  10. ///
  11. /// Core protocols implemented by generated extensions.
  12. ///
  13. // -----------------------------------------------------------------------------
  14. //
  15. // Type-erased Extension field implementation.
  16. // Note that it has no "self or associated type" references, so can
  17. // be used as a protocol type. (In particular, although it does have
  18. // a hashValue property, it cannot be Hashable.)
  19. //
  20. // This can encode, decode, return a hashValue and test for
  21. // equality with some other extension field; but it's type-sealed
  22. // so you can't actually access the contained value itself.
  23. //
  24. @preconcurrency
  25. public protocol AnyExtensionField: Sendable, CustomDebugStringConvertible {
  26. func hash(into hasher: inout Hasher)
  27. var protobufExtension: any AnyMessageExtension { get }
  28. func isEqual(other: any AnyExtensionField) -> Bool
  29. /// Merging field decoding
  30. mutating func decodeExtensionField<T: Decoder>(decoder: inout T) throws
  31. /// Fields know their own type, so can dispatch to a visitor
  32. func traverse<V: Visitor>(visitor: inout V) throws
  33. /// Check if the field is initialized.
  34. var isInitialized: Bool { get }
  35. }
  36. extension AnyExtensionField {
  37. // Default implementation for extensions fields. The message types below provide
  38. // custom versions.
  39. public var isInitialized: Bool { true }
  40. }
  41. ///
  42. /// The regular ExtensionField type exposes the value directly.
  43. ///
  44. @preconcurrency
  45. public protocol ExtensionField: AnyExtensionField, Hashable {
  46. associatedtype ValueType
  47. var value: ValueType { get set }
  48. init(protobufExtension: any AnyMessageExtension, value: ValueType)
  49. init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws
  50. }
  51. ///
  52. /// Singular field
  53. ///
  54. public struct OptionalExtensionField<T: FieldType>: ExtensionField {
  55. public typealias BaseType = T.BaseType
  56. public typealias ValueType = BaseType
  57. public var value: ValueType
  58. public var protobufExtension: any AnyMessageExtension
  59. public static func == (
  60. lhs: OptionalExtensionField,
  61. rhs: OptionalExtensionField
  62. ) -> Bool {
  63. lhs.value == rhs.value
  64. }
  65. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  66. self.protobufExtension = protobufExtension
  67. self.value = value
  68. }
  69. public var debugDescription: String {
  70. #if DEBUG
  71. return String(reflecting: value)
  72. #else
  73. return String(reflecting: type(of: self))
  74. #endif
  75. }
  76. public func hash(into hasher: inout Hasher) {
  77. hasher.combine(value)
  78. }
  79. public func isEqual(other: any AnyExtensionField) -> Bool {
  80. let o = other as! OptionalExtensionField<T>
  81. return self == o
  82. }
  83. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  84. var v: ValueType?
  85. try T.decodeSingular(value: &v, from: &decoder)
  86. if let v = v {
  87. value = v
  88. }
  89. }
  90. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  91. var v: ValueType?
  92. try T.decodeSingular(value: &v, from: &decoder)
  93. if let v = v {
  94. self.init(protobufExtension: protobufExtension, value: v)
  95. } else {
  96. return nil
  97. }
  98. }
  99. public func traverse<V: Visitor>(visitor: inout V) throws {
  100. try T.visitSingular(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
  101. }
  102. }
  103. ///
  104. /// Repeated fields
  105. ///
  106. public struct RepeatedExtensionField<T: FieldType>: ExtensionField {
  107. public typealias BaseType = T.BaseType
  108. public typealias ValueType = [BaseType]
  109. public var value: ValueType
  110. public var protobufExtension: any AnyMessageExtension
  111. public static func == (
  112. lhs: RepeatedExtensionField,
  113. rhs: RepeatedExtensionField
  114. ) -> Bool {
  115. lhs.value == rhs.value
  116. }
  117. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  118. self.protobufExtension = protobufExtension
  119. self.value = value
  120. }
  121. public var debugDescription: String {
  122. #if DEBUG
  123. return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
  124. #else
  125. return String(reflecting: type(of: self))
  126. #endif
  127. }
  128. public func hash(into hasher: inout Hasher) {
  129. hasher.combine(value)
  130. }
  131. public func isEqual(other: any AnyExtensionField) -> Bool {
  132. let o = other as! RepeatedExtensionField<T>
  133. return self == o
  134. }
  135. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  136. try T.decodeRepeated(value: &value, from: &decoder)
  137. }
  138. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  139. var v: ValueType = []
  140. try T.decodeRepeated(value: &v, from: &decoder)
  141. self.init(protobufExtension: protobufExtension, value: v)
  142. }
  143. public func traverse<V: Visitor>(visitor: inout V) throws {
  144. if value.count > 0 {
  145. try T.visitRepeated(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
  146. }
  147. }
  148. }
  149. ///
  150. /// Packed Repeated fields
  151. ///
  152. /// TODO: This is almost (but not quite) identical to RepeatedFields;
  153. /// find a way to collapse the implementations.
  154. ///
  155. public struct PackedExtensionField<T: FieldType>: ExtensionField {
  156. public typealias BaseType = T.BaseType
  157. public typealias ValueType = [BaseType]
  158. public var value: ValueType
  159. public var protobufExtension: any AnyMessageExtension
  160. public static func == (
  161. lhs: PackedExtensionField,
  162. rhs: PackedExtensionField
  163. ) -> Bool {
  164. lhs.value == rhs.value
  165. }
  166. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  167. self.protobufExtension = protobufExtension
  168. self.value = value
  169. }
  170. public var debugDescription: String {
  171. #if DEBUG
  172. return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
  173. #else
  174. return String(reflecting: type(of: self))
  175. #endif
  176. }
  177. public func hash(into hasher: inout Hasher) {
  178. hasher.combine(value)
  179. }
  180. public func isEqual(other: any AnyExtensionField) -> Bool {
  181. let o = other as! PackedExtensionField<T>
  182. return self == o
  183. }
  184. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  185. try T.decodeRepeated(value: &value, from: &decoder)
  186. }
  187. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  188. var v: ValueType = []
  189. try T.decodeRepeated(value: &v, from: &decoder)
  190. self.init(protobufExtension: protobufExtension, value: v)
  191. }
  192. public func traverse<V: Visitor>(visitor: inout V) throws {
  193. if value.count > 0 {
  194. try T.visitPacked(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
  195. }
  196. }
  197. }
  198. ///
  199. /// Enum extensions
  200. ///
  201. public struct OptionalEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
  202. public typealias BaseType = E
  203. public typealias ValueType = E
  204. public var value: ValueType
  205. public var protobufExtension: any AnyMessageExtension
  206. public static func == (
  207. lhs: OptionalEnumExtensionField,
  208. rhs: OptionalEnumExtensionField
  209. ) -> Bool {
  210. lhs.value == rhs.value
  211. }
  212. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  213. self.protobufExtension = protobufExtension
  214. self.value = value
  215. }
  216. public var debugDescription: String {
  217. #if DEBUG
  218. return String(reflecting: value)
  219. #else
  220. return String(reflecting: type(of: self))
  221. #endif
  222. }
  223. public func hash(into hasher: inout Hasher) {
  224. hasher.combine(value)
  225. }
  226. public func isEqual(other: any AnyExtensionField) -> Bool {
  227. let o = other as! OptionalEnumExtensionField<E>
  228. return self == o
  229. }
  230. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  231. var v: ValueType?
  232. try decoder.decodeSingularEnumField(value: &v)
  233. if let v = v {
  234. value = v
  235. }
  236. }
  237. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  238. var v: ValueType?
  239. try decoder.decodeSingularEnumField(value: &v)
  240. if let v = v {
  241. self.init(protobufExtension: protobufExtension, value: v)
  242. } else {
  243. return nil
  244. }
  245. }
  246. public func traverse<V: Visitor>(visitor: inout V) throws {
  247. try visitor.visitSingularEnumField(
  248. value: value,
  249. fieldNumber: protobufExtension.fieldNumber
  250. )
  251. }
  252. }
  253. ///
  254. /// Repeated Enum fields
  255. ///
  256. public struct RepeatedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
  257. public typealias BaseType = E
  258. public typealias ValueType = [E]
  259. public var value: ValueType
  260. public var protobufExtension: any AnyMessageExtension
  261. public static func == (
  262. lhs: RepeatedEnumExtensionField,
  263. rhs: RepeatedEnumExtensionField
  264. ) -> Bool {
  265. lhs.value == rhs.value
  266. }
  267. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  268. self.protobufExtension = protobufExtension
  269. self.value = value
  270. }
  271. public var debugDescription: String {
  272. #if DEBUG
  273. return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
  274. #else
  275. return String(reflecting: type(of: self))
  276. #endif
  277. }
  278. public func hash(into hasher: inout Hasher) {
  279. hasher.combine(value)
  280. }
  281. public func isEqual(other: any AnyExtensionField) -> Bool {
  282. let o = other as! RepeatedEnumExtensionField<E>
  283. return self == o
  284. }
  285. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  286. try decoder.decodeRepeatedEnumField(value: &value)
  287. }
  288. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  289. var v: ValueType = []
  290. try decoder.decodeRepeatedEnumField(value: &v)
  291. self.init(protobufExtension: protobufExtension, value: v)
  292. }
  293. public func traverse<V: Visitor>(visitor: inout V) throws {
  294. if value.count > 0 {
  295. try visitor.visitRepeatedEnumField(
  296. value: value,
  297. fieldNumber: protobufExtension.fieldNumber
  298. )
  299. }
  300. }
  301. }
  302. ///
  303. /// Packed Repeated Enum fields
  304. ///
  305. /// TODO: This is almost (but not quite) identical to RepeatedEnumFields;
  306. /// find a way to collapse the implementations.
  307. ///
  308. public struct PackedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
  309. public typealias BaseType = E
  310. public typealias ValueType = [E]
  311. public var value: ValueType
  312. public var protobufExtension: any AnyMessageExtension
  313. public static func == (
  314. lhs: PackedEnumExtensionField,
  315. rhs: PackedEnumExtensionField
  316. ) -> Bool {
  317. lhs.value == rhs.value
  318. }
  319. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  320. self.protobufExtension = protobufExtension
  321. self.value = value
  322. }
  323. public var debugDescription: String {
  324. #if DEBUG
  325. return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
  326. #else
  327. return String(reflecting: type(of: self))
  328. #endif
  329. }
  330. public func hash(into hasher: inout Hasher) {
  331. hasher.combine(value)
  332. }
  333. public func isEqual(other: any AnyExtensionField) -> Bool {
  334. let o = other as! PackedEnumExtensionField<E>
  335. return self == o
  336. }
  337. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  338. try decoder.decodeRepeatedEnumField(value: &value)
  339. }
  340. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  341. var v: ValueType = []
  342. try decoder.decodeRepeatedEnumField(value: &v)
  343. self.init(protobufExtension: protobufExtension, value: v)
  344. }
  345. public func traverse<V: Visitor>(visitor: inout V) throws {
  346. if value.count > 0 {
  347. try visitor.visitPackedEnumField(
  348. value: value,
  349. fieldNumber: protobufExtension.fieldNumber
  350. )
  351. }
  352. }
  353. }
  354. //
  355. // ========== Message ==========
  356. //
  357. public struct OptionalMessageExtensionField<M: Message & Equatable>:
  358. ExtensionField
  359. {
  360. public typealias BaseType = M
  361. public typealias ValueType = BaseType
  362. public var value: ValueType
  363. public var protobufExtension: any AnyMessageExtension
  364. public static func == (
  365. lhs: OptionalMessageExtensionField,
  366. rhs: OptionalMessageExtensionField
  367. ) -> Bool {
  368. lhs.value == rhs.value
  369. }
  370. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  371. self.protobufExtension = protobufExtension
  372. self.value = value
  373. }
  374. public var debugDescription: String {
  375. #if DEBUG
  376. return String(reflecting: value)
  377. #else
  378. return String(reflecting: type(of: self))
  379. #endif
  380. }
  381. public func hash(into hasher: inout Hasher) {
  382. value.hash(into: &hasher)
  383. }
  384. public func isEqual(other: any AnyExtensionField) -> Bool {
  385. let o = other as! OptionalMessageExtensionField<M>
  386. return self == o
  387. }
  388. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  389. var v: ValueType? = value
  390. try decoder.decodeSingularMessageField(value: &v)
  391. if let v = v {
  392. self.value = v
  393. }
  394. }
  395. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  396. var v: ValueType?
  397. try decoder.decodeSingularMessageField(value: &v)
  398. if let v = v {
  399. self.init(protobufExtension: protobufExtension, value: v)
  400. } else {
  401. return nil
  402. }
  403. }
  404. public func traverse<V: Visitor>(visitor: inout V) throws {
  405. try visitor.visitSingularMessageField(
  406. value: value,
  407. fieldNumber: protobufExtension.fieldNumber
  408. )
  409. }
  410. public var isInitialized: Bool {
  411. value.isInitialized
  412. }
  413. }
  414. public struct RepeatedMessageExtensionField<M: Message & Equatable>:
  415. ExtensionField
  416. {
  417. public typealias BaseType = M
  418. public typealias ValueType = [BaseType]
  419. public var value: ValueType
  420. public var protobufExtension: any AnyMessageExtension
  421. public static func == (
  422. lhs: RepeatedMessageExtensionField,
  423. rhs: RepeatedMessageExtensionField
  424. ) -> Bool {
  425. lhs.value == rhs.value
  426. }
  427. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  428. self.protobufExtension = protobufExtension
  429. self.value = value
  430. }
  431. public var debugDescription: String {
  432. #if DEBUG
  433. return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
  434. #else
  435. return String(reflecting: type(of: self))
  436. #endif
  437. }
  438. public func hash(into hasher: inout Hasher) {
  439. for e in value {
  440. e.hash(into: &hasher)
  441. }
  442. }
  443. public func isEqual(other: any AnyExtensionField) -> Bool {
  444. let o = other as! RepeatedMessageExtensionField<M>
  445. return self == o
  446. }
  447. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  448. try decoder.decodeRepeatedMessageField(value: &value)
  449. }
  450. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  451. var v: ValueType = []
  452. try decoder.decodeRepeatedMessageField(value: &v)
  453. self.init(protobufExtension: protobufExtension, value: v)
  454. }
  455. public func traverse<V: Visitor>(visitor: inout V) throws {
  456. if value.count > 0 {
  457. try visitor.visitRepeatedMessageField(
  458. value: value,
  459. fieldNumber: protobufExtension.fieldNumber
  460. )
  461. }
  462. }
  463. public var isInitialized: Bool {
  464. Internal.areAllInitialized(value)
  465. }
  466. }
  467. //
  468. // ======== Groups within Messages ========
  469. //
  470. // Protoc internally treats groups the same as messages, but
  471. // they serialize very differently, so we have separate serialization
  472. // handling here...
  473. public struct OptionalGroupExtensionField<G: Message & Hashable>:
  474. ExtensionField
  475. {
  476. public typealias BaseType = G
  477. public typealias ValueType = BaseType
  478. public var value: G
  479. public var protobufExtension: any AnyMessageExtension
  480. public static func == (
  481. lhs: OptionalGroupExtensionField,
  482. rhs: OptionalGroupExtensionField
  483. ) -> Bool {
  484. lhs.value == rhs.value
  485. }
  486. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  487. self.protobufExtension = protobufExtension
  488. self.value = value
  489. }
  490. public var debugDescription: String {
  491. #if DEBUG
  492. return value.debugDescription
  493. #else
  494. return String(reflecting: type(of: self))
  495. #endif
  496. }
  497. public func hash(into hasher: inout Hasher) {
  498. hasher.combine(value)
  499. }
  500. public func isEqual(other: any AnyExtensionField) -> Bool {
  501. let o = other as! OptionalGroupExtensionField<G>
  502. return self == o
  503. }
  504. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  505. var v: ValueType? = value
  506. try decoder.decodeSingularGroupField(value: &v)
  507. if let v = v {
  508. value = v
  509. }
  510. }
  511. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  512. var v: ValueType?
  513. try decoder.decodeSingularGroupField(value: &v)
  514. if let v = v {
  515. self.init(protobufExtension: protobufExtension, value: v)
  516. } else {
  517. return nil
  518. }
  519. }
  520. public func traverse<V: Visitor>(visitor: inout V) throws {
  521. try visitor.visitSingularGroupField(
  522. value: value,
  523. fieldNumber: protobufExtension.fieldNumber
  524. )
  525. }
  526. public var isInitialized: Bool {
  527. value.isInitialized
  528. }
  529. }
  530. public struct RepeatedGroupExtensionField<G: Message & Hashable>:
  531. ExtensionField
  532. {
  533. public typealias BaseType = G
  534. public typealias ValueType = [BaseType]
  535. public var value: ValueType
  536. public var protobufExtension: any AnyMessageExtension
  537. public static func == (
  538. lhs: RepeatedGroupExtensionField,
  539. rhs: RepeatedGroupExtensionField
  540. ) -> Bool {
  541. lhs.value == rhs.value
  542. }
  543. public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
  544. self.protobufExtension = protobufExtension
  545. self.value = value
  546. }
  547. public var debugDescription: String {
  548. #if DEBUG
  549. return "[" + value.map { $0.debugDescription }.joined(separator: ",") + "]"
  550. #else
  551. return String(reflecting: type(of: self))
  552. #endif
  553. }
  554. public func hash(into hasher: inout Hasher) {
  555. hasher.combine(value)
  556. }
  557. public func isEqual(other: any AnyExtensionField) -> Bool {
  558. let o = other as! RepeatedGroupExtensionField<G>
  559. return self == o
  560. }
  561. public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
  562. try decoder.decodeRepeatedGroupField(value: &value)
  563. }
  564. public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
  565. var v: ValueType = []
  566. try decoder.decodeRepeatedGroupField(value: &v)
  567. self.init(protobufExtension: protobufExtension, value: v)
  568. }
  569. public func traverse<V: Visitor>(visitor: inout V) throws {
  570. if value.count > 0 {
  571. try visitor.visitRepeatedGroupField(
  572. value: value,
  573. fieldNumber: protobufExtension.fieldNumber
  574. )
  575. }
  576. }
  577. public var isInitialized: Bool {
  578. Internal.areAllInitialized(value)
  579. }
  580. }