FirestoreDecoder.swift 39 KB

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