PathDecoder.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. // Sources/SwiftProtobuf/PathDecoder.swift - Path decoder
  2. //
  3. // Copyright (c) 2014 - 2023 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. /// Decoder which sets value of a field by its path.
  12. ///
  13. // -----------------------------------------------------------------------------
  14. import Foundation
  15. /// Describes errors can occure during decoding a proto by path.
  16. public enum PathDecodingError: Error {
  17. /// Describes a mismatch in type of the fields.
  18. ///
  19. /// If a value of type A is applied to a path with type B.
  20. /// this error will be thrown.
  21. case typeMismatch
  22. /// Describes path is not found in message type.
  23. ///
  24. /// If a message has no field with the given path this
  25. /// error will be thrown.
  26. case pathNotFound
  27. }
  28. extension Message {
  29. static func number(for field: String) -> Int? {
  30. guard let type = Self.self as? any _ProtoNameProviding.Type else {
  31. return nil
  32. }
  33. guard
  34. let number = Array(field.utf8).withUnsafeBytes({ bytes in
  35. type._protobuf_nameMap.number(forProtoName: bytes)
  36. })
  37. else {
  38. return nil
  39. }
  40. if type._protobuf_nameMap.names(for: number)?.proto.description != field {
  41. return nil
  42. }
  43. return number
  44. }
  45. static func name(for field: Int) -> String? {
  46. guard let type = Self.self as? any _ProtoNameProviding.Type else {
  47. return nil
  48. }
  49. return type._protobuf_nameMap.names(for: field)?.proto.description
  50. }
  51. }
  52. // Decoder that set value of a message field by the given path
  53. struct PathDecoder<T: Message>: Decoder {
  54. // The value should be set to the path
  55. private let value: Any?
  56. // Field number should be overriden by decoder
  57. private var number: Int?
  58. // The path only including sub-paths
  59. private let nextPath: [String]
  60. // Merge options to be concidered while setting value
  61. private let mergeOption: Google_Protobuf_FieldMask.MergeOptions
  62. private var replaceRepeatedFields: Bool {
  63. mergeOption.replaceRepeatedFields
  64. }
  65. init(
  66. path: [String],
  67. value: Any?,
  68. mergeOption: Google_Protobuf_FieldMask.MergeOptions
  69. ) throws {
  70. if let firstComponent = path.first,
  71. let number = T.number(for: firstComponent)
  72. {
  73. self.number = number
  74. self.nextPath = .init(path.dropFirst())
  75. } else {
  76. throw PathDecodingError.pathNotFound
  77. }
  78. self.value = value
  79. self.mergeOption = mergeOption
  80. }
  81. private func setValue<V>(_ value: inout V, defaultValue: V) throws {
  82. if !nextPath.isEmpty {
  83. throw PathDecodingError.pathNotFound
  84. }
  85. if self.value == nil {
  86. value = defaultValue
  87. return
  88. }
  89. guard let castedValue = self.value as? V else {
  90. throw PathDecodingError.typeMismatch
  91. }
  92. value = castedValue
  93. }
  94. private func setRepeatedValue<V>(_ value: inout [V]) throws {
  95. if !nextPath.isEmpty {
  96. throw PathDecodingError.pathNotFound
  97. }
  98. var castedValue: [V] = []
  99. if self.value != nil {
  100. guard let v = self.value as? [V] else {
  101. throw PathDecodingError.typeMismatch
  102. }
  103. castedValue = v
  104. }
  105. if replaceRepeatedFields {
  106. value = castedValue
  107. } else {
  108. value.append(contentsOf: castedValue)
  109. }
  110. }
  111. private func setMapValue<K, V>(
  112. _ value: inout [K: V]
  113. ) throws {
  114. if !nextPath.isEmpty {
  115. throw PathDecodingError.pathNotFound
  116. }
  117. var castedValue: [K: V] = [:]
  118. if self.value != nil {
  119. guard let v = self.value as? [K: V] else {
  120. throw PathDecodingError.typeMismatch
  121. }
  122. castedValue = v
  123. }
  124. if replaceRepeatedFields {
  125. value = castedValue
  126. } else {
  127. value.merge(castedValue) { _, new in
  128. new
  129. }
  130. }
  131. }
  132. private func setMessageValue<M: Message>(
  133. _ value: inout M?
  134. ) throws {
  135. if nextPath.isEmpty {
  136. try setValue(&value, defaultValue: nil)
  137. return
  138. }
  139. var decoder = try PathDecoder<M>(
  140. path: nextPath,
  141. value: self.value,
  142. mergeOption: mergeOption
  143. )
  144. if value == nil {
  145. value = .init()
  146. }
  147. try value?.decodeMessage(decoder: &decoder)
  148. }
  149. mutating func handleConflictingOneOf() throws {}
  150. mutating func nextFieldNumber() throws -> Int? {
  151. defer { number = nil }
  152. return number
  153. }
  154. mutating func decodeSingularFloatField(value: inout Float) throws {
  155. try setValue(&value, defaultValue: .init())
  156. }
  157. mutating func decodeSingularFloatField(value: inout Float?) throws {
  158. try setValue(&value, defaultValue: nil)
  159. }
  160. mutating func decodeRepeatedFloatField(value: inout [Float]) throws {
  161. try setRepeatedValue(&value)
  162. }
  163. mutating func decodeSingularDoubleField(value: inout Double) throws {
  164. try setValue(&value, defaultValue: .init())
  165. }
  166. mutating func decodeSingularDoubleField(value: inout Double?) throws {
  167. try setValue(&value, defaultValue: nil)
  168. }
  169. mutating func decodeRepeatedDoubleField(value: inout [Double]) throws {
  170. try setRepeatedValue(&value)
  171. }
  172. mutating func decodeSingularInt32Field(value: inout Int32) throws {
  173. try setValue(&value, defaultValue: .init())
  174. }
  175. mutating func decodeSingularInt32Field(value: inout Int32?) throws {
  176. try setValue(&value, defaultValue: nil)
  177. }
  178. mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws {
  179. try setRepeatedValue(&value)
  180. }
  181. mutating func decodeSingularInt64Field(value: inout Int64) throws {
  182. try setValue(&value, defaultValue: .init())
  183. }
  184. mutating func decodeSingularInt64Field(value: inout Int64?) throws {
  185. try setValue(&value, defaultValue: nil)
  186. }
  187. mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws {
  188. try setRepeatedValue(&value)
  189. }
  190. mutating func decodeSingularUInt32Field(value: inout UInt32) throws {
  191. try setValue(&value, defaultValue: .init())
  192. }
  193. mutating func decodeSingularUInt32Field(value: inout UInt32?) throws {
  194. try setValue(&value, defaultValue: nil)
  195. }
  196. mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws {
  197. try setRepeatedValue(&value)
  198. }
  199. mutating func decodeSingularUInt64Field(value: inout UInt64) throws {
  200. try setValue(&value, defaultValue: .init())
  201. }
  202. mutating func decodeSingularUInt64Field(value: inout UInt64?) throws {
  203. try setValue(&value, defaultValue: nil)
  204. }
  205. mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws {
  206. try setRepeatedValue(&value)
  207. }
  208. mutating func decodeSingularSInt32Field(value: inout Int32) throws {
  209. try setValue(&value, defaultValue: .init())
  210. }
  211. mutating func decodeSingularSInt32Field(value: inout Int32?) throws {
  212. try setValue(&value, defaultValue: nil)
  213. }
  214. mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws {
  215. try setRepeatedValue(&value)
  216. }
  217. mutating func decodeSingularSInt64Field(value: inout Int64) throws {
  218. try setValue(&value, defaultValue: .init())
  219. }
  220. mutating func decodeSingularSInt64Field(value: inout Int64?) throws {
  221. try setValue(&value, defaultValue: nil)
  222. }
  223. mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws {
  224. try setRepeatedValue(&value)
  225. }
  226. mutating func decodeSingularFixed32Field(value: inout UInt32) throws {
  227. try setValue(&value, defaultValue: .init())
  228. }
  229. mutating func decodeSingularFixed32Field(value: inout UInt32?) throws {
  230. try setValue(&value, defaultValue: nil)
  231. }
  232. mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws {
  233. try setRepeatedValue(&value)
  234. }
  235. mutating func decodeSingularFixed64Field(value: inout UInt64) throws {
  236. try setValue(&value, defaultValue: .init())
  237. }
  238. mutating func decodeSingularFixed64Field(value: inout UInt64?) throws {
  239. try setValue(&value, defaultValue: nil)
  240. }
  241. mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws {
  242. try setRepeatedValue(&value)
  243. }
  244. mutating func decodeSingularSFixed32Field(value: inout Int32) throws {
  245. try setValue(&value, defaultValue: .init())
  246. }
  247. mutating func decodeSingularSFixed32Field(value: inout Int32?) throws {
  248. try setValue(&value, defaultValue: nil)
  249. }
  250. mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws {
  251. try setRepeatedValue(&value)
  252. }
  253. mutating func decodeSingularSFixed64Field(value: inout Int64) throws {
  254. try setValue(&value, defaultValue: .init())
  255. }
  256. mutating func decodeSingularSFixed64Field(value: inout Int64?) throws {
  257. try setValue(&value, defaultValue: nil)
  258. }
  259. mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws {
  260. try setRepeatedValue(&value)
  261. }
  262. mutating func decodeSingularBoolField(value: inout Bool) throws {
  263. try setValue(&value, defaultValue: .init())
  264. }
  265. mutating func decodeSingularBoolField(value: inout Bool?) throws {
  266. try setValue(&value, defaultValue: nil)
  267. }
  268. mutating func decodeRepeatedBoolField(value: inout [Bool]) throws {
  269. try setRepeatedValue(&value)
  270. }
  271. mutating func decodeSingularStringField(value: inout String) throws {
  272. try setValue(&value, defaultValue: .init())
  273. }
  274. mutating func decodeSingularStringField(value: inout String?) throws {
  275. try setValue(&value, defaultValue: nil)
  276. }
  277. mutating func decodeRepeatedStringField(value: inout [String]) throws {
  278. try setRepeatedValue(&value)
  279. }
  280. mutating func decodeSingularBytesField(value: inout Data) throws {
  281. try setValue(&value, defaultValue: .init())
  282. }
  283. mutating func decodeSingularBytesField(value: inout Data?) throws {
  284. try setValue(&value, defaultValue: nil)
  285. }
  286. mutating func decodeRepeatedBytesField(value: inout [Data]) throws {
  287. try setRepeatedValue(&value)
  288. }
  289. mutating func decodeSingularEnumField<E>(
  290. value: inout E
  291. ) throws where E: Enum, E.RawValue == Int {
  292. try setValue(&value, defaultValue: .init())
  293. }
  294. mutating func decodeSingularEnumField<E>(
  295. value: inout E?
  296. ) throws where E: Enum, E.RawValue == Int {
  297. try setValue(&value, defaultValue: nil)
  298. }
  299. mutating func decodeRepeatedEnumField<E>(
  300. value: inout [E]
  301. ) throws where E: Enum, E.RawValue == Int {
  302. try setRepeatedValue(&value)
  303. }
  304. mutating func decodeSingularMessageField<M>(
  305. value: inout M?
  306. ) throws where M: Message {
  307. try setMessageValue(&value)
  308. }
  309. mutating func decodeRepeatedMessageField<M>(
  310. value: inout [M]
  311. ) throws where M: Message {
  312. try setRepeatedValue(&value)
  313. }
  314. mutating func decodeSingularGroupField<G>(
  315. value: inout G?
  316. ) throws where G: Message {
  317. try setMessageValue(&value)
  318. }
  319. mutating func decodeRepeatedGroupField<G>(
  320. value: inout [G]
  321. ) throws where G: Message {
  322. try setRepeatedValue(&value)
  323. }
  324. mutating func decodeMapField<KeyType, ValueType>(
  325. fieldType: _ProtobufMap<KeyType, ValueType>.Type,
  326. value: inout _ProtobufMap<KeyType, ValueType>.BaseType
  327. ) throws where KeyType: MapKeyType, ValueType: MapValueType {
  328. try setMapValue(&value)
  329. }
  330. mutating func decodeMapField<KeyType, ValueType>(
  331. fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
  332. value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType
  333. ) throws where KeyType: MapKeyType, ValueType: Enum, ValueType.RawValue == Int {
  334. try setMapValue(&value)
  335. }
  336. mutating func decodeMapField<KeyType, ValueType>(
  337. fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
  338. value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType
  339. ) throws where KeyType: MapKeyType, ValueType: Hashable, ValueType: Message {
  340. try setMapValue(&value)
  341. }
  342. mutating func decodeExtensionField(
  343. values: inout ExtensionFieldValueSet,
  344. messageType: any Message.Type,
  345. fieldNumber: Int
  346. ) throws {
  347. preconditionFailure(
  348. "Internal Error: Path decoder should never decode an extension field"
  349. )
  350. }
  351. }
  352. extension Message {
  353. mutating func `set`(
  354. path: String,
  355. value: Any?,
  356. mergeOption: Google_Protobuf_FieldMask.MergeOptions
  357. ) throws {
  358. let _path = path.components(separatedBy: ".")
  359. var decoder = try PathDecoder<Self>(
  360. path: _path,
  361. value: value,
  362. mergeOption: mergeOption
  363. )
  364. try decodeMessage(decoder: &decoder)
  365. }
  366. }