| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift - JSON map encoding visitor
- //
- // Copyright (c) 2014 - 2016 Apple Inc. and the project authors
- // Licensed under Apache License v2.0 with Runtime Library Exception
- //
- // See LICENSE.txt for license information:
- // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
- //
- // -----------------------------------------------------------------------------
- ///
- /// Visitor that writes out the key/value pairs for a JSON map.
- ///
- // -----------------------------------------------------------------------------
- import Foundation
- /// Visitor that serializes a message into JSON map format.
- ///
- /// This expects to alternately visit the keys and values for a JSON
- /// map. It only accepts singular values. Keys should be identified
- /// as `fieldNumber:1`, values should be identified as `fieldNumber:2`
- ///
- internal struct JSONMapEncodingVisitor: SelectiveVisitor {
- private var separator: StaticString?
- internal var encoder: JSONEncoder
- private let options: JSONEncodingOptions
- init(encoder: JSONEncoder, options: JSONEncodingOptions) {
- self.encoder = encoder
- self.options = options
- }
- internal var bytesResult: [UInt8] {
- get {
- encoder.bytesResult
- }
- }
- private mutating func startKey() {
- if let s = separator {
- encoder.append(staticText: s)
- } else {
- separator = ","
- }
- }
- private mutating func startValue() {
- encoder.append(staticText: ":")
- }
- mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
- // Doubles/Floats can never be map keys, only values
- assert(fieldNumber == 2)
- startValue()
- encoder.putFloatValue(value: value)
- }
- mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
- // Doubles/Floats can never be map keys, only values
- assert(fieldNumber == 2)
- startValue()
- encoder.putDoubleValue(value: value)
- }
- mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
- if fieldNumber == 1 {
- startKey()
- encoder.putQuotedInt32(value: value)
- } else {
- startValue()
- encoder.putNonQuotedInt32(value: value)
- }
- }
- mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
- if fieldNumber == 1 {
- startKey()
- encoder.putQuotedInt64(value: value)
- } else {
- startValue()
- options.alwaysPrintInt64sAsNumbers
- ? encoder.putNonQuotedInt64(value: value)
- : encoder.putQuotedInt64(value: value)
- }
- }
- mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
- if fieldNumber == 1 {
- startKey()
- encoder.putQuotedUInt32(value: value)
- } else {
- startValue()
- encoder.putNonQuotedUInt32(value: value)
- }
- }
- mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
- if fieldNumber == 1 {
- startKey()
- encoder.putQuotedUInt64(value: value)
- } else {
- startValue()
- options.alwaysPrintInt64sAsNumbers
- ? encoder.putNonQuotedUInt64(value: value)
- : encoder.putQuotedUInt64(value: value)
- }
- }
- mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
- try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
- }
- mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
- try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
- }
- mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
- try visitSingularUInt32Field(value: value, fieldNumber: fieldNumber)
- }
- mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
- try visitSingularUInt64Field(value: value, fieldNumber: fieldNumber)
- }
- mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
- try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
- }
- mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
- try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
- }
- mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
- if fieldNumber == 1 {
- startKey()
- encoder.putQuotedBoolValue(value: value)
- } else {
- startValue()
- encoder.putNonQuotedBoolValue(value: value)
- }
- }
- mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
- if fieldNumber == 1 {
- startKey()
- } else {
- startValue()
- }
- encoder.putStringValue(value: value)
- }
- mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
- // Bytes can only be map values, never keys
- assert(fieldNumber == 2)
- startValue()
- encoder.putBytesValue(value: value)
- }
- mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
- // Enums can only be map values, never keys
- assert(fieldNumber == 2)
- startValue()
- if !options.alwaysPrintEnumsAsInts, let n = value.name {
- encoder.putStringValue(value: String(describing: n))
- } else {
- encoder.putEnumInt(value: value.rawValue)
- }
- }
- mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
- // Messages can only be map values, never keys
- assert(fieldNumber == 2)
- startValue()
- let json = try value.jsonString(options: options)
- encoder.append(text: json)
- }
- // SelectiveVisitor will block:
- // - single Groups
- // - everything repeated
- // - everything packed
- // - all maps
- // - unknown fields
- // - extensions
- }
|