PathVisitor.swift 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // Sources/SwiftProtobuf/PathVisitor.swift - Path visitor
  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. /// Visitor which captures a pair of paths and their values.
  12. ///
  13. // -----------------------------------------------------------------------------
  14. import Foundation
  15. // Visitor captures all values of message with their paths
  16. struct PathVisitor<T: Message>: Visitor {
  17. // The path contains parent components
  18. private let prevPath: String?
  19. // Captured values after visiting will be stored in this property
  20. private(set) var values: [String: Any] = [:]
  21. internal init(prevPath: String? = nil) {
  22. self.prevPath = prevPath
  23. }
  24. mutating private func visit(_ value: Any, fieldNumber: Int) {
  25. guard let name = T.name(for: fieldNumber) else {
  26. return
  27. }
  28. if let prevPath {
  29. values["\(prevPath).\(name)"] = value
  30. } else {
  31. values[name] = value
  32. }
  33. }
  34. mutating private func visitMessageField<M: Message>(
  35. _ value: M,
  36. fieldNumber: Int
  37. ) {
  38. guard var path = T.name(for: fieldNumber) else {
  39. return
  40. }
  41. if let prevPath {
  42. path = "\(prevPath).\(path)"
  43. }
  44. values[path] = value
  45. var visitor = PathVisitor<M>(prevPath: path)
  46. try? value.traverse(visitor: &visitor)
  47. values.merge(visitor.values) { _, new in
  48. new
  49. }
  50. }
  51. mutating func visitUnknown(bytes: Data) throws {}
  52. mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
  53. visit(value, fieldNumber: fieldNumber)
  54. }
  55. mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
  56. visit(value, fieldNumber: fieldNumber)
  57. }
  58. mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
  59. visit(value, fieldNumber: fieldNumber)
  60. }
  61. mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
  62. visit(value, fieldNumber: fieldNumber)
  63. }
  64. mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
  65. visit(value, fieldNumber: fieldNumber)
  66. }
  67. mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
  68. visit(value, fieldNumber: fieldNumber)
  69. }
  70. mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
  71. visit(value, fieldNumber: fieldNumber)
  72. }
  73. mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
  74. visit(value, fieldNumber: fieldNumber)
  75. }
  76. mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
  77. visit(value, fieldNumber: fieldNumber)
  78. }
  79. mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
  80. visit(value, fieldNumber: fieldNumber)
  81. }
  82. mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
  83. visit(value, fieldNumber: fieldNumber)
  84. }
  85. mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
  86. visit(value, fieldNumber: fieldNumber)
  87. }
  88. mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
  89. visit(value, fieldNumber: fieldNumber)
  90. }
  91. mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
  92. visit(value, fieldNumber: fieldNumber)
  93. }
  94. mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
  95. visit(value, fieldNumber: fieldNumber)
  96. }
  97. mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
  98. visit(value, fieldNumber: fieldNumber)
  99. }
  100. mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
  101. visitMessageField(value, fieldNumber: fieldNumber)
  102. }
  103. mutating func visitSingularGroupField<G: Message>(value: G, fieldNumber: Int) throws {
  104. visitMessageField(value, fieldNumber: fieldNumber)
  105. }
  106. mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
  107. visit(value, fieldNumber: fieldNumber)
  108. }
  109. mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
  110. visit(value, fieldNumber: fieldNumber)
  111. }
  112. mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
  113. visit(value, fieldNumber: fieldNumber)
  114. }
  115. mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
  116. visit(value, fieldNumber: fieldNumber)
  117. }
  118. mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
  119. visit(value, fieldNumber: fieldNumber)
  120. }
  121. mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
  122. visit(value, fieldNumber: fieldNumber)
  123. }
  124. mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
  125. visit(value, fieldNumber: fieldNumber)
  126. }
  127. mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
  128. visit(value, fieldNumber: fieldNumber)
  129. }
  130. mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
  131. visit(value, fieldNumber: fieldNumber)
  132. }
  133. mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
  134. visit(value, fieldNumber: fieldNumber)
  135. }
  136. mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
  137. visit(value, fieldNumber: fieldNumber)
  138. }
  139. mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
  140. visit(value, fieldNumber: fieldNumber)
  141. }
  142. mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
  143. visit(value, fieldNumber: fieldNumber)
  144. }
  145. mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
  146. visit(value, fieldNumber: fieldNumber)
  147. }
  148. mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
  149. visit(value, fieldNumber: fieldNumber)
  150. }
  151. mutating func visitRepeatedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
  152. visit(value, fieldNumber: fieldNumber)
  153. }
  154. mutating func visitRepeatedMessageField<M>(value: [M], fieldNumber: Int) throws where M: Message {
  155. visit(value, fieldNumber: fieldNumber)
  156. }
  157. mutating func visitRepeatedGroupField<G: Message>(value: [G], fieldNumber: Int) throws {
  158. visit(value, fieldNumber: fieldNumber)
  159. }
  160. mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws {
  161. visit(value, fieldNumber: fieldNumber)
  162. }
  163. mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws {
  164. visit(value, fieldNumber: fieldNumber)
  165. }
  166. mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws {
  167. visit(value, fieldNumber: fieldNumber)
  168. }
  169. mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws {
  170. visit(value, fieldNumber: fieldNumber)
  171. }
  172. mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
  173. visit(value, fieldNumber: fieldNumber)
  174. }
  175. mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
  176. visit(value, fieldNumber: fieldNumber)
  177. }
  178. mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws {
  179. visit(value, fieldNumber: fieldNumber)
  180. }
  181. mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws {
  182. visit(value, fieldNumber: fieldNumber)
  183. }
  184. mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
  185. visit(value, fieldNumber: fieldNumber)
  186. }
  187. mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
  188. visit(value, fieldNumber: fieldNumber)
  189. }
  190. mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
  191. visit(value, fieldNumber: fieldNumber)
  192. }
  193. mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
  194. visit(value, fieldNumber: fieldNumber)
  195. }
  196. mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws {
  197. visit(value, fieldNumber: fieldNumber)
  198. }
  199. mutating func visitPackedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
  200. visit(value, fieldNumber: fieldNumber)
  201. }
  202. mutating func visitMapField<KeyType, ValueType>(
  203. fieldType: _ProtobufMap<KeyType, ValueType>.Type,
  204. value: _ProtobufMap<KeyType, ValueType>.BaseType,
  205. fieldNumber: Int
  206. ) throws where KeyType: MapKeyType, ValueType: MapValueType {
  207. visit(value, fieldNumber: fieldNumber)
  208. }
  209. mutating func visitMapField<KeyType, ValueType>(
  210. fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
  211. value: _ProtobufEnumMap<KeyType, ValueType>.BaseType,
  212. fieldNumber: Int
  213. ) throws where KeyType: MapKeyType, ValueType: Enum, ValueType.RawValue == Int {
  214. visit(value, fieldNumber: fieldNumber)
  215. }
  216. mutating func visitMapField<KeyType, ValueType>(
  217. fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
  218. value: _ProtobufMessageMap<KeyType, ValueType>.BaseType,
  219. fieldNumber: Int
  220. ) throws where KeyType: MapKeyType, ValueType: Hashable, ValueType: Message {
  221. visit(value, fieldNumber: fieldNumber)
  222. }
  223. }