| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756 |
- // Sources/SwiftProtobuf/JSONDecoder.swift - JSON format decoding
- //
- // 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
- //
- // -----------------------------------------------------------------------------
- ///
- /// JSON format decoding engine.
- ///
- // -----------------------------------------------------------------------------
- import Foundation
- internal struct JSONDecoder: Decoder {
- internal var scanner: JSONScanner
- internal var messageType: any Message.Type
- private var fieldCount = 0
- private var isMapKey = false
- private var fieldNameMap: _NameMap?
- internal var options: JSONDecodingOptions {
- scanner.options
- }
- mutating func handleConflictingOneOf() throws {
- throw JSONDecodingError.conflictingOneOf
- }
- internal init(
- source: UnsafeRawBufferPointer,
- options: JSONDecodingOptions,
- messageType: any Message.Type,
- extensions: (any ExtensionMap)?
- ) {
- let scanner = JSONScanner(
- source: source,
- options: options,
- extensions: extensions
- )
- self.init(scanner: scanner, messageType: messageType)
- }
- private init(scanner: JSONScanner, messageType: any Message.Type) {
- self.scanner = scanner
- self.messageType = messageType
- }
- mutating func nextFieldNumber() throws -> Int? {
- if scanner.skipOptionalObjectEnd() {
- return nil
- }
- if fieldCount > 0 {
- try scanner.skipRequiredComma()
- }
- let fieldNumber = try scanner.nextFieldNumber(
- names: fieldNameMap!,
- messageType: messageType
- )
- if let fieldNumber = fieldNumber {
- fieldCount += 1
- return fieldNumber
- }
- return nil
- }
- mutating func decodeSingularFloatField(value: inout Float) throws {
- if scanner.skipOptionalNull() {
- value = 0
- return
- }
- value = try scanner.nextFloat()
- }
- mutating func decodeSingularFloatField(value: inout Float?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- value = try scanner.nextFloat()
- }
- mutating func decodeRepeatedFloatField(value: inout [Float]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextFloat()
- value.append(n)
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularDoubleField(value: inout Double) throws {
- if scanner.skipOptionalNull() {
- value = 0
- return
- }
- value = try scanner.nextDouble()
- }
- mutating func decodeSingularDoubleField(value: inout Double?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- value = try scanner.nextDouble()
- }
- mutating func decodeRepeatedDoubleField(value: inout [Double]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextDouble()
- value.append(n)
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularInt32Field(value: inout Int32) throws {
- if scanner.skipOptionalNull() {
- value = 0
- return
- }
- let n = try scanner.nextSInt()
- if n > Int64(Int32.max) || n < Int64(Int32.min) {
- throw JSONDecodingError.numberRange
- }
- value = Int32(truncatingIfNeeded: n)
- }
- mutating func decodeSingularInt32Field(value: inout Int32?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- let n = try scanner.nextSInt()
- if n > Int64(Int32.max) || n < Int64(Int32.min) {
- throw JSONDecodingError.numberRange
- }
- value = Int32(truncatingIfNeeded: n)
- }
- mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextSInt()
- if n > Int64(Int32.max) || n < Int64(Int32.min) {
- throw JSONDecodingError.numberRange
- }
- value.append(Int32(truncatingIfNeeded: n))
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularInt64Field(value: inout Int64) throws {
- if scanner.skipOptionalNull() {
- value = 0
- return
- }
- value = try scanner.nextSInt()
- }
- mutating func decodeSingularInt64Field(value: inout Int64?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- value = try scanner.nextSInt()
- }
- mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextSInt()
- value.append(n)
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularUInt32Field(value: inout UInt32) throws {
- if scanner.skipOptionalNull() {
- value = 0
- return
- }
- let n = try scanner.nextUInt()
- if n > UInt64(UInt32.max) {
- throw JSONDecodingError.numberRange
- }
- value = UInt32(truncatingIfNeeded: n)
- }
- mutating func decodeSingularUInt32Field(value: inout UInt32?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- let n = try scanner.nextUInt()
- if n > UInt64(UInt32.max) {
- throw JSONDecodingError.numberRange
- }
- value = UInt32(truncatingIfNeeded: n)
- }
- mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextUInt()
- if n > UInt64(UInt32.max) {
- throw JSONDecodingError.numberRange
- }
- value.append(UInt32(truncatingIfNeeded: n))
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularUInt64Field(value: inout UInt64) throws {
- if scanner.skipOptionalNull() {
- value = 0
- return
- }
- value = try scanner.nextUInt()
- }
- mutating func decodeSingularUInt64Field(value: inout UInt64?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- value = try scanner.nextUInt()
- }
- mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextUInt()
- value.append(n)
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularSInt32Field(value: inout Int32) throws {
- try decodeSingularInt32Field(value: &value)
- }
- mutating func decodeSingularSInt32Field(value: inout Int32?) throws {
- try decodeSingularInt32Field(value: &value)
- }
- mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws {
- try decodeRepeatedInt32Field(value: &value)
- }
- mutating func decodeSingularSInt64Field(value: inout Int64) throws {
- try decodeSingularInt64Field(value: &value)
- }
- mutating func decodeSingularSInt64Field(value: inout Int64?) throws {
- try decodeSingularInt64Field(value: &value)
- }
- mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws {
- try decodeRepeatedInt64Field(value: &value)
- }
- mutating func decodeSingularFixed32Field(value: inout UInt32) throws {
- try decodeSingularUInt32Field(value: &value)
- }
- mutating func decodeSingularFixed32Field(value: inout UInt32?) throws {
- try decodeSingularUInt32Field(value: &value)
- }
- mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws {
- try decodeRepeatedUInt32Field(value: &value)
- }
- mutating func decodeSingularFixed64Field(value: inout UInt64) throws {
- try decodeSingularUInt64Field(value: &value)
- }
- mutating func decodeSingularFixed64Field(value: inout UInt64?) throws {
- try decodeSingularUInt64Field(value: &value)
- }
- mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws {
- try decodeRepeatedUInt64Field(value: &value)
- }
- mutating func decodeSingularSFixed32Field(value: inout Int32) throws {
- try decodeSingularInt32Field(value: &value)
- }
- mutating func decodeSingularSFixed32Field(value: inout Int32?) throws {
- try decodeSingularInt32Field(value: &value)
- }
- mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws {
- try decodeRepeatedInt32Field(value: &value)
- }
- mutating func decodeSingularSFixed64Field(value: inout Int64) throws {
- try decodeSingularInt64Field(value: &value)
- }
- mutating func decodeSingularSFixed64Field(value: inout Int64?) throws {
- try decodeSingularInt64Field(value: &value)
- }
- mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws {
- try decodeRepeatedInt64Field(value: &value)
- }
- mutating func decodeSingularBoolField(value: inout Bool) throws {
- if scanner.skipOptionalNull() {
- value = false
- return
- }
- if isMapKey {
- value = try scanner.nextQuotedBool()
- } else {
- value = try scanner.nextBool()
- }
- }
- mutating func decodeSingularBoolField(value: inout Bool?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- if isMapKey {
- value = try scanner.nextQuotedBool()
- } else {
- value = try scanner.nextBool()
- }
- }
- mutating func decodeRepeatedBoolField(value: inout [Bool]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextBool()
- value.append(n)
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularStringField(value: inout String) throws {
- if scanner.skipOptionalNull() {
- value = String()
- return
- }
- value = try scanner.nextQuotedString()
- }
- mutating func decodeSingularStringField(value: inout String?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- value = try scanner.nextQuotedString()
- }
- mutating func decodeRepeatedStringField(value: inout [String]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextQuotedString()
- value.append(n)
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularBytesField(value: inout Data) throws {
- if scanner.skipOptionalNull() {
- value = Data()
- return
- }
- value = try scanner.nextBytesValue()
- }
- mutating func decodeSingularBytesField(value: inout Data?) throws {
- if scanner.skipOptionalNull() {
- value = nil
- return
- }
- value = try scanner.nextBytesValue()
- }
- mutating func decodeRepeatedBytesField(value: inout [Data]) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- let n = try scanner.nextBytesValue()
- value.append(n)
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularEnumField<E: Enum>(value: inout E?) throws
- where E.RawValue == Int {
- if scanner.skipOptionalNull() {
- if let customDecodable = E.self as? any _CustomJSONCodable.Type {
- value = try customDecodable.decodedFromJSONNull() as? E
- return
- }
- value = nil
- return
- }
- // Only change the value if a value was read.
- if let e: E = try scanner.nextEnumValue() {
- value = e
- }
- }
- mutating func decodeSingularEnumField<E: Enum>(value: inout E) throws
- where E.RawValue == Int {
- if scanner.skipOptionalNull() {
- if let customDecodable = E.self as? any _CustomJSONCodable.Type {
- value = try customDecodable.decodedFromJSONNull() as! E
- return
- }
- value = E()
- return
- }
- if let e: E = try scanner.nextEnumValue() {
- value = e
- }
- }
- mutating func decodeRepeatedEnumField<E: Enum>(value: inout [E]) throws
- where E.RawValue == Int {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- let maybeCustomDecodable = E.self as? any _CustomJSONCodable.Type
- while true {
- if scanner.skipOptionalNull() {
- if let customDecodable = maybeCustomDecodable {
- let e = try customDecodable.decodedFromJSONNull() as! E
- value.append(e)
- } else {
- throw JSONDecodingError.illegalNull
- }
- } else {
- if let e: E = try scanner.nextEnumValue() {
- value.append(e)
- }
- }
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- internal mutating func decodeFullObject<M: Message>(message: inout M) throws {
- guard let nameProviding = (M.self as? any _ProtoNameProviding.Type) else {
- throw JSONDecodingError.missingFieldNames
- }
- fieldNameMap = nameProviding._protobuf_nameMap
- if let m = message as? (any _CustomJSONCodable) {
- var customCodable = m
- try customCodable.decodeJSON(from: &self)
- message = customCodable as! M
- } else {
- try scanner.skipRequiredObjectStart()
- if scanner.skipOptionalObjectEnd() {
- return
- }
- try message.decodeMessage(decoder: &self)
- }
- }
- mutating func decodeSingularMessageField<M: Message>(value: inout M?) throws {
- if scanner.skipOptionalNull() {
- if M.self is any _CustomJSONCodable.Type {
- value =
- try (M.self as! any _CustomJSONCodable.Type).decodedFromJSONNull() as? M
- return
- }
- // All other message field types treat 'null' as an unset
- value = nil
- return
- }
- if value == nil {
- value = M()
- }
- var subDecoder = JSONDecoder(scanner: scanner, messageType: M.self)
- try subDecoder.decodeFullObject(message: &value!)
- assert(scanner.recursionBudget == subDecoder.scanner.recursionBudget)
- scanner = subDecoder.scanner
- }
- mutating func decodeRepeatedMessageField<M: Message>(
- value: inout [M]
- ) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredArrayStart()
- if scanner.skipOptionalArrayEnd() {
- return
- }
- while true {
- if scanner.skipOptionalNull() {
- var appended = false
- if M.self is any _CustomJSONCodable.Type {
- if let message = try (M.self as! any _CustomJSONCodable.Type)
- .decodedFromJSONNull() as? M
- {
- value.append(message)
- appended = true
- }
- }
- if !appended {
- throw JSONDecodingError.illegalNull
- }
- } else {
- var message = M()
- var subDecoder = JSONDecoder(scanner: scanner, messageType: M.self)
- try subDecoder.decodeFullObject(message: &message)
- value.append(message)
- assert(scanner.recursionBudget == subDecoder.scanner.recursionBudget)
- scanner = subDecoder.scanner
- }
- if scanner.skipOptionalArrayEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeSingularGroupField<G: Message>(value: inout G?) throws {
- try decodeSingularMessageField(value: &value)
- }
- mutating func decodeRepeatedGroupField<G: Message>(value: inout [G]) throws {
- try decodeRepeatedMessageField(value: &value)
- }
- mutating func decodeMapField<KeyType, ValueType: MapValueType>(
- fieldType: _ProtobufMap<KeyType, ValueType>.Type,
- value: inout _ProtobufMap<KeyType, ValueType>.BaseType
- ) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredObjectStart()
- if scanner.skipOptionalObjectEnd() {
- return
- }
- while true {
- // Next character must be double quote, because
- // map keys must always be quoted strings.
- let c = try scanner.peekOneCharacter()
- if c != "\"" {
- throw JSONDecodingError.unquotedMapKey
- }
- isMapKey = true
- var keyField: KeyType.BaseType?
- try KeyType.decodeSingular(value: &keyField, from: &self)
- isMapKey = false
- try scanner.skipRequiredColon()
- var valueField: ValueType.BaseType?
- try ValueType.decodeSingular(value: &valueField, from: &self)
- if let keyField = keyField, let valueField = valueField {
- value[keyField] = valueField
- } else {
- throw JSONDecodingError.malformedMap
- }
- if scanner.skipOptionalObjectEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeMapField<KeyType, ValueType>(
- fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
- value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType
- ) throws where ValueType.RawValue == Int {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredObjectStart()
- if scanner.skipOptionalObjectEnd() {
- return
- }
- while true {
- // Next character must be double quote, because
- // map keys must always be quoted strings.
- let c = try scanner.peekOneCharacter()
- if c != "\"" {
- throw JSONDecodingError.unquotedMapKey
- }
- isMapKey = true
- var keyFieldOpt: KeyType.BaseType?
- try KeyType.decodeSingular(value: &keyFieldOpt, from: &self)
- guard let keyField = keyFieldOpt else {
- throw JSONDecodingError.malformedMap
- }
- isMapKey = false
- try scanner.skipRequiredColon()
- var valueField: ValueType?
- try decodeSingularEnumField(value: &valueField)
- if let valueField = valueField {
- value[keyField] = valueField
- } else {
- // Nothing, the only way ``decodeSingularEnumField(value:)`` leaves
- // it as nil is if ignoreUnknownFields option is enabled which also
- // means to ignore unknown enum values.
- }
- if scanner.skipOptionalObjectEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeMapField<KeyType, ValueType>(
- fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
- value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType
- ) throws {
- if scanner.skipOptionalNull() {
- return
- }
- try scanner.skipRequiredObjectStart()
- if scanner.skipOptionalObjectEnd() {
- return
- }
- while true {
- // Next character must be double quote, because
- // map keys must always be quoted strings.
- let c = try scanner.peekOneCharacter()
- if c != "\"" {
- throw JSONDecodingError.unquotedMapKey
- }
- isMapKey = true
- var keyField: KeyType.BaseType?
- try KeyType.decodeSingular(value: &keyField, from: &self)
- isMapKey = false
- try scanner.skipRequiredColon()
- var valueField: ValueType?
- try decodeSingularMessageField(value: &valueField)
- if let keyField = keyField, let valueField = valueField {
- value[keyField] = valueField
- } else {
- throw JSONDecodingError.malformedMap
- }
- if scanner.skipOptionalObjectEnd() {
- return
- }
- try scanner.skipRequiredComma()
- }
- }
- mutating func decodeExtensionField(
- values: inout ExtensionFieldValueSet,
- messageType: any Message.Type,
- fieldNumber: Int
- ) throws {
- // Force-unwrap: we can only get here if the extension exists.
- let ext = scanner.extensions[messageType, fieldNumber]!
- try values.modify(index: fieldNumber) { fieldValue in
- if fieldValue != nil {
- try fieldValue!.decodeExtensionField(decoder: &self)
- } else {
- fieldValue = try ext._protobuf_newField(decoder: &self)
- }
- }
- }
- }
|