JSONMapEncodingVisitor.swift 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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/master/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. private mutating func startKey() {
  30. if let s = separator {
  31. encoder.append(staticText: s)
  32. } else {
  33. separator = ","
  34. }
  35. }
  36. private mutating func startValue() {
  37. encoder.append(staticText: ":")
  38. }
  39. mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
  40. // Doubles/Floats can never be map keys, only values
  41. assert(fieldNumber == 2)
  42. startValue()
  43. encoder.putFloatValue(value: value)
  44. }
  45. mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
  46. // Doubles/Floats can never be map keys, only values
  47. assert(fieldNumber == 2)
  48. startValue()
  49. encoder.putDoubleValue(value: value)
  50. }
  51. mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
  52. if fieldNumber == 1 {
  53. startKey()
  54. encoder.putQuotedInt32(value: value)
  55. } else {
  56. startValue()
  57. encoder.putInt32(value: value)
  58. }
  59. }
  60. mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
  61. if fieldNumber == 1 {
  62. startKey()
  63. } else {
  64. startValue()
  65. }
  66. // Int64 fields are always quoted anyway
  67. encoder.putInt64(value: value)
  68. }
  69. mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
  70. if fieldNumber == 1 {
  71. startKey()
  72. encoder.putQuotedUInt32(value: value)
  73. } else {
  74. startValue()
  75. encoder.putUInt32(value: value)
  76. }
  77. }
  78. mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
  79. if fieldNumber == 1 {
  80. startKey()
  81. } else {
  82. startValue()
  83. }
  84. encoder.putUInt64(value: value)
  85. }
  86. mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
  87. try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
  88. }
  89. mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
  90. try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
  91. }
  92. mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
  93. try visitSingularUInt32Field(value: value, fieldNumber: fieldNumber)
  94. }
  95. mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
  96. try visitSingularUInt64Field(value: value, fieldNumber: fieldNumber)
  97. }
  98. mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
  99. try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
  100. }
  101. mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
  102. try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
  103. }
  104. mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
  105. if fieldNumber == 1 {
  106. startKey()
  107. encoder.putQuotedBoolValue(value: value)
  108. } else {
  109. startValue()
  110. encoder.putBoolValue(value: value)
  111. }
  112. }
  113. mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
  114. if fieldNumber == 1 {
  115. startKey()
  116. } else {
  117. startValue()
  118. }
  119. encoder.putStringValue(value: value)
  120. }
  121. mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
  122. // Bytes can only be map values, never keys
  123. assert(fieldNumber == 2)
  124. startValue()
  125. encoder.putBytesValue(value: value)
  126. }
  127. mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
  128. // Enums can only be map values, never keys
  129. assert(fieldNumber == 2)
  130. startValue()
  131. if !options.alwaysPrintEnumsAsInts, let n = value.name {
  132. encoder.putStringValue(value: String(describing: n))
  133. } else {
  134. encoder.putEnumInt(value: value.rawValue)
  135. }
  136. }
  137. mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
  138. // Messages can only be map values, never keys
  139. assert(fieldNumber == 2)
  140. startValue()
  141. let json = try value.jsonString(options: options)
  142. encoder.append(text: json)
  143. }
  144. // SelectiveVisitor will block:
  145. // - single Groups
  146. // - everything repeated
  147. // - everything packed
  148. // - all maps
  149. // - unknown fields
  150. // - extensions
  151. }