JSONMapEncodingVisitor.swift 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift - JSON map encoding visitor
  2. //
  3. // Copyright (c) 2014 - 2016 Apple Inc. and the project authors
  4. // Licensed under Apache License v2.0 with Runtime Library Exception
  5. //
  6. // See LICENSE.txt for license information:
  7. // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
  8. //
  9. // -----------------------------------------------------------------------------
  10. ///
  11. /// Visitor that writes out the key/value pairs for a JSON map.
  12. ///
  13. // -----------------------------------------------------------------------------
  14. import Foundation
  15. /// Visitor that serializes a message into JSON map format.
  16. ///
  17. /// This expects to alternately visit the keys and values for a JSON
  18. /// map. It only accepts singular values. Keys should be identified
  19. /// as `fieldNumber:1`, values should be identified as `fieldNumber:2`
  20. ///
  21. internal struct JSONMapEncodingVisitor: SelectiveVisitor {
  22. private var separator: StaticString?
  23. internal var encoder: JSONEncoder
  24. private let options: JSONEncodingOptions
  25. init(encoder: JSONEncoder, options: JSONEncodingOptions) {
  26. self.encoder = encoder
  27. self.options = options
  28. }
  29. internal var bytesResult: [UInt8] {
  30. get {
  31. encoder.bytesResult
  32. }
  33. }
  34. private mutating func startKey() {
  35. if let s = separator {
  36. encoder.append(staticText: s)
  37. } else {
  38. separator = ","
  39. }
  40. }
  41. private mutating func startValue() {
  42. encoder.append(staticText: ":")
  43. }
  44. mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
  45. // Doubles/Floats can never be map keys, only values
  46. assert(fieldNumber == 2)
  47. startValue()
  48. encoder.putFloatValue(value: value)
  49. }
  50. mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
  51. // Doubles/Floats can never be map keys, only values
  52. assert(fieldNumber == 2)
  53. startValue()
  54. encoder.putDoubleValue(value: value)
  55. }
  56. mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
  57. if fieldNumber == 1 {
  58. startKey()
  59. encoder.putQuotedInt32(value: value)
  60. } else {
  61. startValue()
  62. encoder.putNonQuotedInt32(value: value)
  63. }
  64. }
  65. mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
  66. if fieldNumber == 1 {
  67. startKey()
  68. encoder.putQuotedInt64(value: value)
  69. } else {
  70. startValue()
  71. options.alwaysPrintInt64sAsNumbers
  72. ? encoder.putNonQuotedInt64(value: value)
  73. : encoder.putQuotedInt64(value: value)
  74. }
  75. }
  76. mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
  77. if fieldNumber == 1 {
  78. startKey()
  79. encoder.putQuotedUInt32(value: value)
  80. } else {
  81. startValue()
  82. encoder.putNonQuotedUInt32(value: value)
  83. }
  84. }
  85. mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
  86. if fieldNumber == 1 {
  87. startKey()
  88. encoder.putQuotedUInt64(value: value)
  89. } else {
  90. startValue()
  91. options.alwaysPrintInt64sAsNumbers
  92. ? encoder.putNonQuotedUInt64(value: value)
  93. : encoder.putQuotedUInt64(value: value)
  94. }
  95. }
  96. mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
  97. try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
  98. }
  99. mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
  100. try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
  101. }
  102. mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
  103. try visitSingularUInt32Field(value: value, fieldNumber: fieldNumber)
  104. }
  105. mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
  106. try visitSingularUInt64Field(value: value, fieldNumber: fieldNumber)
  107. }
  108. mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
  109. try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
  110. }
  111. mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
  112. try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
  113. }
  114. mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
  115. if fieldNumber == 1 {
  116. startKey()
  117. encoder.putQuotedBoolValue(value: value)
  118. } else {
  119. startValue()
  120. encoder.putNonQuotedBoolValue(value: value)
  121. }
  122. }
  123. mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
  124. if fieldNumber == 1 {
  125. startKey()
  126. } else {
  127. startValue()
  128. }
  129. encoder.putStringValue(value: value)
  130. }
  131. mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
  132. // Bytes can only be map values, never keys
  133. assert(fieldNumber == 2)
  134. startValue()
  135. encoder.putBytesValue(value: value)
  136. }
  137. mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
  138. // Enums can only be map values, never keys
  139. assert(fieldNumber == 2)
  140. startValue()
  141. if !options.alwaysPrintEnumsAsInts, let n = value.name {
  142. encoder.putStringValue(value: String(describing: n))
  143. } else {
  144. encoder.putEnumInt(value: value.rawValue)
  145. }
  146. }
  147. mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
  148. // Messages can only be map values, never keys
  149. assert(fieldNumber == 2)
  150. startValue()
  151. let json = try value.jsonString(options: options)
  152. encoder.append(text: json)
  153. }
  154. // SelectiveVisitor will block:
  155. // - single Groups
  156. // - everything repeated
  157. // - everything packed
  158. // - all maps
  159. // - unknown fields
  160. // - extensions
  161. }