FirestoreDecoder.swift 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101
  1. // This file is derived from swift/stdlib/public/SDK/Foundation/JSONEncoder.swift
  2. // and swift/stdlib/public/SDK/Foundation/PlistEncoder.swift
  3. //===----------------------------------------------------------------------===//
  4. //
  5. // This source file is part of the Swift.org open source project
  6. //
  7. // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
  8. // Licensed under Apache License v2.0 with Runtime Library Exception
  9. //
  10. // See https://swift.org/LICENSE.txt for license information
  11. // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  12. //
  13. //===----------------------------------------------------------------------===//
  14. import FirebaseFirestore
  15. import Foundation
  16. extension Firestore {
  17. public struct Decoder {
  18. fileprivate static let documentRefUserInfoKey = CodingUserInfoKey(rawValue: "DocumentRefUserInfoKey")
  19. public init() {}
  20. /// Returns an instance of specified type from a Firestore document.
  21. ///
  22. /// If exists in `container`, Firestore specific types are recognized, and
  23. /// passed through to `Decodable` implementations. This means types below
  24. /// in `container` are directly supported:
  25. /// - GeoPoint
  26. /// - Timestamp
  27. /// - DocumentReference
  28. ///
  29. /// - Parameters:
  30. /// - A type to decode a document to.
  31. /// - container: A Map keyed of String representing a Firestore document.
  32. /// - document: A reference to the Firestore Document that is being
  33. /// decoded.
  34. /// - Returns: An instance of specified type by the first parameter.
  35. public func decode<T: Decodable>(_: T.Type,
  36. from container: [String: Any],
  37. in document: DocumentReference? = nil) throws -> T {
  38. let decoder = _FirestoreDecoder(referencing: container)
  39. if let doc = document {
  40. decoder.userInfo[Firestore.Decoder.documentRefUserInfoKey!] = doc
  41. }
  42. guard let value = try decoder.unbox(container, as: T.self) else {
  43. throw DecodingError.valueNotFound(
  44. T.self,
  45. DecodingError.Context(codingPath: [],
  46. debugDescription: "The given dictionary was invalid")
  47. )
  48. }
  49. return value
  50. }
  51. }
  52. }
  53. class _FirestoreDecoder: Decoder {
  54. // `_FirestoreDecoder`
  55. // MARK: Properties
  56. /// A stack of data containers storing data containers to decode. When a new data
  57. /// container is being decoded, a corresponding storage is pushed to the stack;
  58. /// and when that container (and all of its children containers) has been decoded,
  59. /// it is popped out such that the decoding can proceed with new top storage.
  60. fileprivate var storage: _FirestoreDecodingStorage
  61. /// The path to the current point in the container tree. Given the root container, one could
  62. /// conceptually reconstruct `storage` by following `codingPath` from the root container.
  63. public fileprivate(set) var codingPath: [CodingKey]
  64. /// Contextual user-provided information for use during encoding.
  65. public var userInfo: [CodingUserInfoKey: Any] = [:]
  66. // MARK: - Initialization
  67. /// Initializes `self` with the given top-level container and options.
  68. init(referencing container: Any, at codingPath: [CodingKey] = []) {
  69. storage = _FirestoreDecodingStorage()
  70. storage.push(container: container)
  71. self.codingPath = codingPath
  72. }
  73. // MARK: - Decoder Methods
  74. public func container<Key>(keyedBy _: Key.Type) throws -> KeyedDecodingContainer<Key> {
  75. guard !(storage.topContainer is NSNull) else {
  76. throw DecodingError.valueNotFound(KeyedDecodingContainer<Key>.self,
  77. DecodingError.Context(codingPath: codingPath,
  78. debugDescription: "Cannot get keyed decoding container -- found null value instead."))
  79. }
  80. guard let topContainer = storage.topContainer as? [String: Any] else {
  81. let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not a dictionary")
  82. throw DecodingError.typeMismatch([String: Any].self, context)
  83. }
  84. let container = _FirestoreKeyedDecodingContainer<Key>(referencing: self, wrapping: topContainer)
  85. return KeyedDecodingContainer(container)
  86. }
  87. public func unkeyedContainer() throws -> UnkeyedDecodingContainer {
  88. guard !(storage.topContainer is NSNull) else {
  89. throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self,
  90. DecodingError.Context(codingPath: codingPath,
  91. debugDescription: "Cannot get unkeyed decoding container -- found null value instead."))
  92. }
  93. guard let topContainer = storage.topContainer as? [Any] else {
  94. let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not an array")
  95. throw DecodingError.typeMismatch([Any].self, context)
  96. }
  97. return _FirestoreUnkeyedDecodingContainer(referencing: self, wrapping: topContainer)
  98. }
  99. public func singleValueContainer() throws -> SingleValueDecodingContainer {
  100. return self
  101. }
  102. }
  103. private struct _FirestoreDecodingStorage {
  104. // MARK: Properties
  105. /// The container stack.
  106. /// Elements may be any one of the plist types (NSNumber, Date, String, Array, [String : Any]).
  107. fileprivate private(set) var containers: [Any] = []
  108. // MARK: - Initialization
  109. /// Initializes `self` with no containers.
  110. fileprivate init() {}
  111. // MARK: - Modifying the Stack
  112. fileprivate var count: Int {
  113. return containers.count
  114. }
  115. fileprivate var topContainer: Any {
  116. precondition(containers.count > 0, "Empty container stack.")
  117. return containers.last!
  118. }
  119. fileprivate mutating func push(container: Any) {
  120. containers.append(container)
  121. }
  122. fileprivate mutating func popContainer() {
  123. precondition(containers.count > 0, "Empty container stack.")
  124. containers.removeLast()
  125. }
  126. }
  127. private struct _FirestoreKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtocol {
  128. typealias Key = K
  129. // MARK: Properties
  130. /// A reference to the decoder we're reading from.
  131. private let decoder: _FirestoreDecoder
  132. /// A reference to the container we're reading from.
  133. private let container: [String: Any]
  134. /// The path of coding keys taken to get to this point in decoding.
  135. public private(set) var codingPath: [CodingKey]
  136. // MARK: - Initialization
  137. /// Initializes `self` by referencing the given decoder and container.
  138. fileprivate init(referencing decoder: _FirestoreDecoder, wrapping container: [String: Any]) {
  139. self.decoder = decoder
  140. self.container = container
  141. codingPath = decoder.codingPath
  142. }
  143. // MARK: - KeyedDecodingContainerProtocol Methods
  144. public var allKeys: [Key] {
  145. return container.keys.compactMap { Key(stringValue: $0) }
  146. }
  147. public func contains(_ key: Key) -> Bool {
  148. return container[key.stringValue] != nil
  149. }
  150. public func decodeNil(forKey key: Key) throws -> Bool {
  151. let entry = try require(key: key)
  152. return entry is NSNull
  153. }
  154. public func decode(_: Bool.Type, forKey key: Key) throws -> Bool {
  155. let entry = try require(key: key)
  156. decoder.codingPath.append(key)
  157. defer { self.decoder.codingPath.removeLast() }
  158. let value = try decoder.unbox(entry, as: Bool.self)
  159. return try require(value: value)
  160. }
  161. public func decode(_: Int.Type, forKey key: Key) throws -> Int {
  162. let entry = try require(key: key)
  163. decoder.codingPath.append(key)
  164. defer { self.decoder.codingPath.removeLast() }
  165. let value = try decoder.unbox(entry, as: Int.self)
  166. return try require(value: value)
  167. }
  168. public func decode(_: Int8.Type, forKey key: Key) throws -> Int8 {
  169. let entry = try require(key: key)
  170. decoder.codingPath.append(key)
  171. defer { self.decoder.codingPath.removeLast() }
  172. let value = try decoder.unbox(entry, as: Int8.self)
  173. return try require(value: value)
  174. }
  175. public func decode(_: Int16.Type, forKey key: Key) throws -> Int16 {
  176. let entry = try require(key: key)
  177. decoder.codingPath.append(key)
  178. defer { self.decoder.codingPath.removeLast() }
  179. let value = try decoder.unbox(entry, as: Int16.self)
  180. return try require(value: value)
  181. }
  182. public func decode(_: Int32.Type, forKey key: Key) throws -> Int32 {
  183. let entry = try require(key: key)
  184. decoder.codingPath.append(key)
  185. defer { self.decoder.codingPath.removeLast() }
  186. let value = try decoder.unbox(entry, as: Int32.self)
  187. return try require(value: value)
  188. }
  189. public func decode(_: Int64.Type, forKey key: Key) throws -> Int64 {
  190. let entry = try require(key: key)
  191. decoder.codingPath.append(key)
  192. defer { self.decoder.codingPath.removeLast() }
  193. let value = try decoder.unbox(entry, as: Int64.self)
  194. return try require(value: value)
  195. }
  196. public func decode(_: UInt.Type, forKey key: Key) throws -> UInt {
  197. let entry = try require(key: key)
  198. decoder.codingPath.append(key)
  199. defer { self.decoder.codingPath.removeLast() }
  200. let value = try decoder.unbox(entry, as: UInt.self)
  201. return try require(value: value)
  202. }
  203. public func decode(_: UInt8.Type, forKey key: Key) throws -> UInt8 {
  204. let entry = try require(key: key)
  205. decoder.codingPath.append(key)
  206. defer { self.decoder.codingPath.removeLast() }
  207. let value = try decoder.unbox(entry, as: UInt8.self)
  208. return try require(value: value)
  209. }
  210. public func decode(_: UInt16.Type, forKey key: Key) throws -> UInt16 {
  211. let entry = try require(key: key)
  212. decoder.codingPath.append(key)
  213. defer { self.decoder.codingPath.removeLast() }
  214. let value = try decoder.unbox(entry, as: UInt16.self)
  215. return try require(value: value)
  216. }
  217. public func decode(_: UInt32.Type, forKey key: Key) throws -> UInt32 {
  218. let entry = try require(key: key)
  219. decoder.codingPath.append(key)
  220. defer { self.decoder.codingPath.removeLast() }
  221. let value = try decoder.unbox(entry, as: UInt32.self)
  222. return try require(value: value)
  223. }
  224. public func decode(_: UInt64.Type, forKey key: Key) throws -> UInt64 {
  225. let entry = try require(key: key)
  226. decoder.codingPath.append(key)
  227. defer { self.decoder.codingPath.removeLast() }
  228. let value = try decoder.unbox(entry, as: UInt64.self)
  229. return try require(value: value)
  230. }
  231. public func decode(_: Float.Type, forKey key: Key) throws -> Float {
  232. let entry = try require(key: key)
  233. decoder.codingPath.append(key)
  234. defer { self.decoder.codingPath.removeLast() }
  235. let value = try decoder.unbox(entry, as: Float.self)
  236. return try require(value: value)
  237. }
  238. public func decode(_: Double.Type, forKey key: Key) throws -> Double {
  239. let entry = try require(key: key)
  240. decoder.codingPath.append(key)
  241. defer { self.decoder.codingPath.removeLast() }
  242. let value = try decoder.unbox(entry, as: Double.self)
  243. return try require(value: value)
  244. }
  245. public func decode(_: String.Type, forKey key: Key) throws -> String {
  246. let entry = try require(key: key)
  247. decoder.codingPath.append(key)
  248. defer { self.decoder.codingPath.removeLast() }
  249. let value = try decoder.unbox(entry, as: String.self)
  250. return try require(value: value)
  251. }
  252. public func decode<T: Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
  253. #if compiler(>=5.1)
  254. if let type = type as? DocumentIDProtocol.Type {
  255. let docRef = decoder.userInfo[
  256. Firestore.Decoder.documentRefUserInfoKey!
  257. ] as! DocumentReference?
  258. if contains(key) {
  259. let docPath = (docRef != nil) ? docRef!.path : "nil"
  260. var codingPathCopy = codingPath.map { key in key.stringValue }
  261. codingPathCopy.append(key.stringValue)
  262. throw FirestoreDecodingError.fieldNameConfict("Field name " +
  263. "\(codingPathCopy) was found from document \"\(docPath)\", " +
  264. "cannot assign the document reference to this field.")
  265. }
  266. return try type.init(from: docRef) as! T
  267. }
  268. #endif // compiler(>=5.1)
  269. let entry = try require(key: key)
  270. decoder.codingPath.append(key)
  271. defer { self.decoder.codingPath.removeLast() }
  272. let value = try decoder.unbox(entry, as: T.self)
  273. return try require(value: value)
  274. }
  275. private func require(key: Key) throws -> Any {
  276. if let entry = container[key.stringValue] {
  277. return entry
  278. }
  279. let description = "No value associated with key \(key) (\"\(key.stringValue)\")."
  280. let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: description)
  281. throw DecodingError.keyNotFound(key, context)
  282. }
  283. private func require<T>(value: T?) throws -> T {
  284. if let value = value {
  285. return value
  286. }
  287. let message = "Expected \(T.self) value but found null instead."
  288. let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: message)
  289. throw DecodingError.valueNotFound(T.self, context)
  290. }
  291. public func nestedContainer<NestedKey>(keyedBy _: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer<NestedKey> {
  292. decoder.codingPath.append(key)
  293. defer { self.decoder.codingPath.removeLast() }
  294. guard let value = self.container[key.stringValue] else {
  295. throw DecodingError.valueNotFound(KeyedDecodingContainer<NestedKey>.self,
  296. DecodingError.Context(codingPath: codingPath,
  297. debugDescription: "Cannot get nested keyed container -- no value found for key \"\(key.stringValue)\""))
  298. }
  299. guard let dictionary = value as? [String: Any] else {
  300. throw DecodingError._typeMismatch(at: codingPath, expectation: [String: Any].self, reality: value)
  301. }
  302. let container = _FirestoreKeyedDecodingContainer<NestedKey>(referencing: decoder, wrapping: dictionary)
  303. return KeyedDecodingContainer(container)
  304. }
  305. public func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer {
  306. decoder.codingPath.append(key)
  307. defer { self.decoder.codingPath.removeLast() }
  308. guard let value = container[key.stringValue] else {
  309. throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self,
  310. DecodingError.Context(codingPath: codingPath,
  311. debugDescription: "Cannot get nested unkeyed container -- no value found for key \"\(key.stringValue)\""))
  312. }
  313. guard let array = value as? [Any] else {
  314. let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not an array")
  315. throw DecodingError.typeMismatch([Any].self, context)
  316. }
  317. return _FirestoreUnkeyedDecodingContainer(referencing: decoder, wrapping: array)
  318. }
  319. private func _superDecoder(forKey key: CodingKey) throws -> Decoder {
  320. decoder.codingPath.append(key)
  321. defer { self.decoder.codingPath.removeLast() }
  322. let value: Any = container[key.stringValue] ?? NSNull()
  323. return _FirestoreDecoder(referencing: value, at: decoder.codingPath)
  324. }
  325. public func superDecoder() throws -> Decoder {
  326. return try _superDecoder(forKey: _FirestoreKey.super)
  327. }
  328. public func superDecoder(forKey key: Key) throws -> Decoder {
  329. return try _superDecoder(forKey: key)
  330. }
  331. }
  332. private struct _FirestoreUnkeyedDecodingContainer: UnkeyedDecodingContainer {
  333. // MARK: Properties
  334. /// A reference to the decoder we're reading from.
  335. private let decoder: _FirestoreDecoder
  336. /// A reference to the container we're reading from.
  337. private let container: [Any]
  338. /// The path of coding keys taken to get to this point in decoding.
  339. public private(set) var codingPath: [CodingKey]
  340. /// The index of the element we're about to decode.
  341. public private(set) var currentIndex: Int
  342. // MARK: - Initialization
  343. /// Initializes `self` by referencing the given decoder and container.
  344. fileprivate init(referencing decoder: _FirestoreDecoder, wrapping container: [Any]) {
  345. self.decoder = decoder
  346. self.container = container
  347. codingPath = decoder.codingPath
  348. currentIndex = 0
  349. }
  350. // MARK: - UnkeyedDecodingContainer Methods
  351. public var count: Int? {
  352. return container.count
  353. }
  354. public var isAtEnd: Bool {
  355. return currentIndex >= count!
  356. }
  357. public mutating func decodeNil() throws -> Bool {
  358. try expectNotAtEnd()
  359. if container[currentIndex] is NSNull {
  360. currentIndex += 1
  361. return true
  362. } else {
  363. return false
  364. }
  365. }
  366. public mutating func decode(_: Bool.Type) throws -> Bool {
  367. try expectNotAtEnd()
  368. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  369. defer { decoder.codingPath.removeLast() }
  370. let decoded = try decoder.unbox(container[currentIndex], as: Bool.self)
  371. return try require(value: decoded)
  372. }
  373. public mutating func decode(_: Int.Type) throws -> Int {
  374. try expectNotAtEnd()
  375. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  376. defer { decoder.codingPath.removeLast() }
  377. let decoded = try decoder.unbox(container[currentIndex], as: Int.self)
  378. return try require(value: decoded)
  379. }
  380. public mutating func decode(_: Int8.Type) throws -> Int8 {
  381. try expectNotAtEnd()
  382. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  383. defer { decoder.codingPath.removeLast() }
  384. let decoded = try decoder.unbox(container[currentIndex], as: Int8.self)
  385. return try require(value: decoded)
  386. }
  387. public mutating func decode(_: Int16.Type) throws -> Int16 {
  388. try expectNotAtEnd()
  389. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  390. defer { decoder.codingPath.removeLast() }
  391. let decoded = try decoder.unbox(container[currentIndex], as: Int16.self)
  392. return try require(value: decoded)
  393. }
  394. public mutating func decode(_: Int32.Type) throws -> Int32 {
  395. try expectNotAtEnd()
  396. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  397. defer { decoder.codingPath.removeLast() }
  398. let decoded = try decoder.unbox(container[currentIndex], as: Int32.self)
  399. return try require(value: decoded)
  400. }
  401. public mutating func decode(_: Int64.Type) throws -> Int64 {
  402. try expectNotAtEnd()
  403. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  404. defer { decoder.codingPath.removeLast() }
  405. let decoded = try decoder.unbox(container[currentIndex], as: Int64.self)
  406. return try require(value: decoded)
  407. }
  408. public mutating func decode(_: UInt.Type) throws -> UInt {
  409. try expectNotAtEnd()
  410. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  411. defer { decoder.codingPath.removeLast() }
  412. let decoded = try decoder.unbox(container[currentIndex], as: UInt.self)
  413. return try require(value: decoded)
  414. }
  415. public mutating func decode(_: UInt8.Type) throws -> UInt8 {
  416. try expectNotAtEnd()
  417. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  418. defer { decoder.codingPath.removeLast() }
  419. let decoded = try decoder.unbox(container[currentIndex], as: UInt8.self)
  420. return try require(value: decoded)
  421. }
  422. public mutating func decode(_: UInt16.Type) throws -> UInt16 {
  423. try expectNotAtEnd()
  424. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  425. defer { self.decoder.codingPath.removeLast() }
  426. let decoded = try decoder.unbox(container[currentIndex], as: UInt16.self)
  427. return try require(value: decoded)
  428. }
  429. public mutating func decode(_: UInt32.Type) throws -> UInt32 {
  430. try expectNotAtEnd()
  431. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  432. defer { decoder.codingPath.removeLast() }
  433. let decoded = try decoder.unbox(container[currentIndex], as: UInt32.self)
  434. return try require(value: decoded)
  435. }
  436. public mutating func decode(_: UInt64.Type) throws -> UInt64 {
  437. try expectNotAtEnd()
  438. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  439. defer { decoder.codingPath.removeLast() }
  440. let decoded = try decoder.unbox(container[currentIndex], as: UInt64.self)
  441. return try require(value: decoded)
  442. }
  443. public mutating func decode(_: Float.Type) throws -> Float {
  444. try expectNotAtEnd()
  445. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  446. defer { self.decoder.codingPath.removeLast() }
  447. let decoded = try decoder.unbox(container[currentIndex], as: Float.self)
  448. return try require(value: decoded)
  449. }
  450. public mutating func decode(_: Double.Type) throws -> Double {
  451. try expectNotAtEnd()
  452. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  453. defer { self.decoder.codingPath.removeLast() }
  454. let decoded = try decoder.unbox(container[currentIndex], as: Double.self)
  455. return try require(value: decoded)
  456. }
  457. public mutating func decode(_: String.Type) throws -> String {
  458. try expectNotAtEnd()
  459. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  460. defer { self.decoder.codingPath.removeLast() }
  461. let decoded = try decoder.unbox(container[currentIndex], as: String.self)
  462. return try require(value: decoded)
  463. }
  464. public mutating func decode<T: Decodable>(_: T.Type) throws -> T {
  465. try expectNotAtEnd()
  466. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  467. defer { self.decoder.codingPath.removeLast() }
  468. let decoded = try decoder.unbox(container[currentIndex], as: T.self)
  469. return try require(value: decoded)
  470. }
  471. public mutating func nestedContainer<NestedKey>(keyedBy _: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> {
  472. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  473. defer { self.decoder.codingPath.removeLast() }
  474. try expectNotAtEnd()
  475. let value = self.container[currentIndex]
  476. try requireNotNSNull(value)
  477. guard let dictionary = value as? [String: Any] else {
  478. throw DecodingError._typeMismatch(at: codingPath, expectation: [String: Any].self, reality: value)
  479. }
  480. currentIndex += 1
  481. let container = _FirestoreKeyedDecodingContainer<NestedKey>(referencing: decoder, wrapping: dictionary)
  482. return KeyedDecodingContainer(container)
  483. }
  484. public mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer {
  485. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  486. defer { self.decoder.codingPath.removeLast() }
  487. try expectNotAtEnd()
  488. let value = container[currentIndex]
  489. try requireNotNSNull(value)
  490. guard let array = value as? [Any] else {
  491. throw DecodingError._typeMismatch(at: codingPath, expectation: [Any].self, reality: value)
  492. }
  493. currentIndex += 1
  494. return _FirestoreUnkeyedDecodingContainer(referencing: decoder, wrapping: array)
  495. }
  496. public mutating func superDecoder() throws -> Decoder {
  497. decoder.codingPath.append(_FirestoreKey(index: currentIndex))
  498. defer { self.decoder.codingPath.removeLast() }
  499. try expectNotAtEnd()
  500. let value = container[currentIndex]
  501. currentIndex += 1
  502. return _FirestoreDecoder(referencing: value, at: decoder.codingPath)
  503. }
  504. private func expectNotAtEnd() throws {
  505. guard !isAtEnd else {
  506. throw DecodingError.valueNotFound(Any?.self, DecodingError.Context(codingPath: decoder.codingPath + [_FirestoreKey(index: currentIndex)], debugDescription: "Unkeyed container is at end."))
  507. }
  508. }
  509. private func requireNotNSNull(_ value: Any) throws {
  510. if !(value is NSNull) {
  511. return
  512. }
  513. let description = "Cannot get keyed decoding container -- found null value instead."
  514. let context = DecodingError.Context(codingPath: codingPath, debugDescription: description)
  515. throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, context)
  516. }
  517. private mutating func require<T>(value: T?) throws -> T {
  518. guard let value = value else {
  519. let message = "Expected \(T.self) value but found null instead."
  520. let context = DecodingError.Context(codingPath: decoder.codingPath + [_FirestoreKey(index: currentIndex)], debugDescription: message)
  521. throw DecodingError.valueNotFound(T.self, context)
  522. }
  523. currentIndex += 1
  524. return value
  525. }
  526. }
  527. extension _FirestoreDecoder: SingleValueDecodingContainer {
  528. // MARK: SingleValueDecodingContainer Methods
  529. private func expectNonNull<T>(_ type: T.Type) throws {
  530. guard !decodeNil() else {
  531. throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Expected \(type) but found null value instead."))
  532. }
  533. }
  534. public func decodeNil() -> Bool {
  535. return storage.topContainer is NSNull
  536. }
  537. public func decode(_: Bool.Type) throws -> Bool {
  538. try expectNonNull(Bool.self)
  539. return try unbox(storage.topContainer, as: Bool.self)!
  540. }
  541. public func decode(_: Int.Type) throws -> Int {
  542. try expectNonNull(Int.self)
  543. return try unbox(storage.topContainer, as: Int.self)!
  544. }
  545. public func decode(_: Int8.Type) throws -> Int8 {
  546. try expectNonNull(Int8.self)
  547. return try unbox(storage.topContainer, as: Int8.self)!
  548. }
  549. public func decode(_: Int16.Type) throws -> Int16 {
  550. try expectNonNull(Int16.self)
  551. return try unbox(storage.topContainer, as: Int16.self)!
  552. }
  553. public func decode(_: Int32.Type) throws -> Int32 {
  554. try expectNonNull(Int32.self)
  555. return try unbox(storage.topContainer, as: Int32.self)!
  556. }
  557. public func decode(_: Int64.Type) throws -> Int64 {
  558. try expectNonNull(Int64.self)
  559. return try unbox(storage.topContainer, as: Int64.self)!
  560. }
  561. public func decode(_: UInt.Type) throws -> UInt {
  562. try expectNonNull(UInt.self)
  563. return try unbox(storage.topContainer, as: UInt.self)!
  564. }
  565. public func decode(_: UInt8.Type) throws -> UInt8 {
  566. try expectNonNull(UInt8.self)
  567. return try unbox(storage.topContainer, as: UInt8.self)!
  568. }
  569. public func decode(_: UInt16.Type) throws -> UInt16 {
  570. try expectNonNull(UInt16.self)
  571. return try unbox(storage.topContainer, as: UInt16.self)!
  572. }
  573. public func decode(_: UInt32.Type) throws -> UInt32 {
  574. try expectNonNull(UInt32.self)
  575. return try unbox(storage.topContainer, as: UInt32.self)!
  576. }
  577. public func decode(_: UInt64.Type) throws -> UInt64 {
  578. try expectNonNull(UInt64.self)
  579. return try unbox(storage.topContainer, as: UInt64.self)!
  580. }
  581. public func decode(_: Float.Type) throws -> Float {
  582. try expectNonNull(Float.self)
  583. return try unbox(storage.topContainer, as: Float.self)!
  584. }
  585. public func decode(_: Double.Type) throws -> Double {
  586. try expectNonNull(Double.self)
  587. return try unbox(storage.topContainer, as: Double.self)!
  588. }
  589. public func decode(_: String.Type) throws -> String {
  590. try expectNonNull(String.self)
  591. return try unbox(storage.topContainer, as: String.self)!
  592. }
  593. public func decode<T: Decodable>(_: T.Type) throws -> T {
  594. try expectNonNull(T.self)
  595. return try unbox(storage.topContainer, as: T.self)!
  596. }
  597. }
  598. extension _FirestoreDecoder {
  599. /// Returns the given value unboxed from a container.
  600. func unbox(_ value: Any, as type: Bool.Type) throws -> Bool? {
  601. guard !(value is NSNull) else { return nil }
  602. if let number = value as? NSNumber {
  603. // TODO: Add a flag to coerce non-boolean numbers into Bools?
  604. if number === kCFBooleanTrue as NSNumber {
  605. return true
  606. } else if number === kCFBooleanFalse as NSNumber {
  607. return false
  608. }
  609. }
  610. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  611. }
  612. func unbox(_ value: Any, as type: Int.Type) throws -> Int? {
  613. guard !(value is NSNull) else { return nil }
  614. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  615. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  616. }
  617. let int = number.intValue
  618. guard NSNumber(value: int) == number else {
  619. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  620. }
  621. return int
  622. }
  623. func unbox(_ value: Any, as type: Int8.Type) throws -> Int8? {
  624. guard !(value is NSNull) else { return nil }
  625. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  626. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  627. }
  628. let int8 = number.int8Value
  629. guard NSNumber(value: int8) == number else {
  630. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  631. }
  632. return int8
  633. }
  634. func unbox(_ value: Any, as type: Int16.Type) throws -> Int16? {
  635. guard !(value is NSNull) else { return nil }
  636. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  637. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  638. }
  639. let int16 = number.int16Value
  640. guard NSNumber(value: int16) == number else {
  641. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  642. }
  643. return int16
  644. }
  645. func unbox(_ value: Any, as type: Int32.Type) throws -> Int32? {
  646. guard !(value is NSNull) else { return nil }
  647. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  648. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  649. }
  650. let int32 = number.int32Value
  651. guard NSNumber(value: int32) == number else {
  652. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  653. }
  654. return int32
  655. }
  656. func unbox(_ value: Any, as type: Int64.Type) throws -> Int64? {
  657. guard !(value is NSNull) else { return nil }
  658. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  659. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  660. }
  661. let int64 = number.int64Value
  662. guard NSNumber(value: int64) == number else {
  663. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  664. }
  665. return int64
  666. }
  667. func unbox(_ value: Any, as type: UInt.Type) throws -> UInt? {
  668. guard !(value is NSNull) else { return nil }
  669. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  670. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  671. }
  672. let uint = number.uintValue
  673. guard NSNumber(value: uint) == number else {
  674. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  675. }
  676. return uint
  677. }
  678. func unbox(_ value: Any, as type: UInt8.Type) throws -> UInt8? {
  679. guard !(value is NSNull) else { return nil }
  680. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  681. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  682. }
  683. let uint8 = number.uint8Value
  684. guard NSNumber(value: uint8) == number else {
  685. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  686. }
  687. return uint8
  688. }
  689. func unbox(_ value: Any, as type: UInt16.Type) throws -> UInt16? {
  690. guard !(value is NSNull) else { return nil }
  691. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  692. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  693. }
  694. let uint16 = number.uint16Value
  695. guard NSNumber(value: uint16) == number else {
  696. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  697. }
  698. return uint16
  699. }
  700. func unbox(_ value: Any, as type: UInt32.Type) throws -> UInt32? {
  701. guard !(value is NSNull) else { return nil }
  702. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  703. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  704. }
  705. let uint32 = number.uint32Value
  706. guard NSNumber(value: uint32) == number else {
  707. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  708. }
  709. return uint32
  710. }
  711. func unbox(_ value: Any, as type: UInt64.Type) throws -> UInt64? {
  712. guard !(value is NSNull) else { return nil }
  713. guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
  714. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  715. }
  716. let uint64 = number.uint64Value
  717. guard NSNumber(value: uint64) == number else {
  718. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number <\(number)> does not fit in \(type)."))
  719. }
  720. return uint64
  721. }
  722. func unbox(_ value: Any, as type: Float.Type) throws -> Float? {
  723. guard !(value is NSNull) else { return nil }
  724. if let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse {
  725. // We are willing to return a Float by losing precision:
  726. // * If the original value was integral,
  727. // * and the integral value was > Float.greatestFiniteMagnitude, we will fail
  728. // * and the integral value was <= Float.greatestFiniteMagnitude, we are willing to lose precision past 2^24
  729. // * If it was a Float, you will get back the precise value
  730. // * If it was a Double or Decimal, you will get back the nearest approximation if it will fit
  731. let double = number.doubleValue
  732. guard abs(double) <= Double(Float.greatestFiniteMagnitude) else {
  733. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded number \(number) does not fit in \(type)."))
  734. }
  735. return Float(double)
  736. }
  737. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  738. }
  739. func unbox(_ value: Any, as type: Double.Type) throws -> Double? {
  740. guard !(value is NSNull) else { return nil }
  741. if let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse {
  742. // We are always willing to return the number as a Double:
  743. // * If the original value was integral, it is guaranteed to fit in a Double; we are willing to lose precision past 2^53 if you encoded a UInt64 but requested a Double
  744. // * If it was a Float or Double, you will get back the precise value
  745. // * If it was Decimal, you will get back the nearest approximation
  746. return number.doubleValue
  747. }
  748. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  749. }
  750. func unbox(_ value: Any, as type: String.Type) throws -> String? {
  751. guard !(value is NSNull) else { return nil }
  752. guard let string = value as? String else {
  753. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  754. }
  755. return string
  756. }
  757. func unbox(_ value: Any, as type: Date.Type) throws -> Date? {
  758. guard !(value is NSNull) else { return nil }
  759. // Firestore returns all dates as Timestamp, converting it to Date so it can be used in custom objects.
  760. if let timestamp = value as? Timestamp {
  761. return timestamp.dateValue()
  762. }
  763. guard let date = value as? Date else {
  764. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  765. }
  766. return date
  767. }
  768. func unbox(_ value: Any, as type: Data.Type) throws -> Data? {
  769. guard !(value is NSNull) else { return nil }
  770. guard let data = value as? Data else {
  771. throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value)
  772. }
  773. return data
  774. }
  775. func unbox(_ value: Any, as _: Decimal.Type) throws -> Decimal? {
  776. guard !(value is NSNull) else { return nil }
  777. // Attempt to bridge from NSDecimalNumber.
  778. if let decimal = value as? Decimal {
  779. return decimal
  780. } else {
  781. let doubleValue = try unbox(value, as: Double.self)!
  782. return Decimal(doubleValue)
  783. }
  784. }
  785. func unbox<T: Decodable>(_ value: Any, as _: T.Type) throws -> T? {
  786. if T.self == Date.self || T.self == NSDate.self {
  787. guard let date = try unbox(value, as: Date.self) else { return nil }
  788. return (date as! T)
  789. }
  790. if T.self == Data.self || T.self == NSData.self {
  791. guard let data = try unbox(value, as: Data.self) else { return nil }
  792. return (data as! T)
  793. }
  794. if T.self == URL.self || T.self == NSURL.self {
  795. guard let urlString = try unbox(value, as: String.self) else {
  796. return nil
  797. }
  798. guard let url = URL(string: urlString) else {
  799. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath,
  800. debugDescription: "Invalid URL string."))
  801. }
  802. return (url as! T)
  803. }
  804. if T.self == Decimal.self || T.self == NSDecimalNumber.self {
  805. guard let decimal = try unbox(value, as: Decimal.self) else { return nil }
  806. return (decimal as! T)
  807. }
  808. if let v = value as? T {
  809. if isFirestorePassthroughType(v) {
  810. // All the native Firestore types that should not be encoded
  811. return (value as! T)
  812. }
  813. }
  814. // Decoding an embedded container, this requires expanding the storage stack and
  815. // then restore after decoding.
  816. storage.push(container: value)
  817. let decoded = try T(from: self)
  818. storage.popContainer()
  819. return decoded
  820. }
  821. }
  822. extension DecodingError {
  823. static func _typeMismatch(at path: [CodingKey], expectation: Any.Type, reality: Any) -> DecodingError {
  824. let description = "Expected to decode \(expectation) but found \(_typeDescription(of: reality)) instead."
  825. return .typeMismatch(expectation, Context(codingPath: path, debugDescription: description))
  826. }
  827. fileprivate static func _typeDescription(of value: Any) -> String {
  828. if value is NSNull {
  829. return "a null value"
  830. } else if value is NSNumber /* FIXME: If swift-corelibs-foundation isn't updated to use NSNumber, this check will be necessary: || value is Int || value is Double */ {
  831. return "a number"
  832. } else if value is String {
  833. return "a string/data"
  834. } else if value is [Any] {
  835. return "an array"
  836. } else if value is [String: Any] {
  837. return "a dictionary"
  838. } else {
  839. return "\(type(of: value))"
  840. }
  841. }
  842. }