| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 |
- // Sources/SwiftProtobuf/ExtensionFields.swift - Extension support
- //
- // 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
- //
- // -----------------------------------------------------------------------------
- ///
- /// Core protocols implemented by generated extensions.
- ///
- // -----------------------------------------------------------------------------
- //
- // Type-erased Extension field implementation.
- // Note that it has no "self or associated type" references, so can
- // be used as a protocol type. (In particular, although it does have
- // a hashValue property, it cannot be Hashable.)
- //
- // This can encode, decode, return a hashValue and test for
- // equality with some other extension field; but it's type-sealed
- // so you can't actually access the contained value itself.
- //
- @preconcurrency
- public protocol AnyExtensionField: Sendable, CustomDebugStringConvertible {
- func hash(into hasher: inout Hasher)
- var protobufExtension: any AnyMessageExtension { get }
- func isEqual(other: any AnyExtensionField) -> Bool
- /// Merging field decoding
- mutating func decodeExtensionField<T: Decoder>(decoder: inout T) throws
- /// Fields know their own type, so can dispatch to a visitor
- func traverse<V: Visitor>(visitor: inout V) throws
- /// Check if the field is initialized.
- var isInitialized: Bool { get }
- }
- extension AnyExtensionField {
- // Default implementation for extensions fields. The message types below provide
- // custom versions.
- public var isInitialized: Bool { true }
- }
- ///
- /// The regular ExtensionField type exposes the value directly.
- ///
- @preconcurrency
- public protocol ExtensionField: AnyExtensionField, Hashable {
- associatedtype ValueType
- var value: ValueType { get set }
- init(protobufExtension: any AnyMessageExtension, value: ValueType)
- init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws
- }
- ///
- /// Singular field
- ///
- public struct OptionalExtensionField<T: FieldType>: ExtensionField {
- public typealias BaseType = T.BaseType
- public typealias ValueType = BaseType
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: OptionalExtensionField,
- rhs: OptionalExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return String(reflecting: value)
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! OptionalExtensionField<T>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- var v: ValueType?
- try T.decodeSingular(value: &v, from: &decoder)
- if let v = v {
- value = v
- }
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType?
- try T.decodeSingular(value: &v, from: &decoder)
- if let v = v {
- self.init(protobufExtension: protobufExtension, value: v)
- } else {
- return nil
- }
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- try T.visitSingular(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
- }
- }
- ///
- /// Repeated fields
- ///
- public struct RepeatedExtensionField<T: FieldType>: ExtensionField {
- public typealias BaseType = T.BaseType
- public typealias ValueType = [BaseType]
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: RepeatedExtensionField,
- rhs: RepeatedExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! RepeatedExtensionField<T>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- try T.decodeRepeated(value: &value, from: &decoder)
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType = []
- try T.decodeRepeated(value: &v, from: &decoder)
- self.init(protobufExtension: protobufExtension, value: v)
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- if value.count > 0 {
- try T.visitRepeated(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
- }
- }
- }
- ///
- /// Packed Repeated fields
- ///
- /// TODO: This is almost (but not quite) identical to RepeatedFields;
- /// find a way to collapse the implementations.
- ///
- public struct PackedExtensionField<T: FieldType>: ExtensionField {
- public typealias BaseType = T.BaseType
- public typealias ValueType = [BaseType]
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: PackedExtensionField,
- rhs: PackedExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! PackedExtensionField<T>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- try T.decodeRepeated(value: &value, from: &decoder)
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType = []
- try T.decodeRepeated(value: &v, from: &decoder)
- self.init(protobufExtension: protobufExtension, value: v)
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- if value.count > 0 {
- try T.visitPacked(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
- }
- }
- }
- ///
- /// Enum extensions
- ///
- public struct OptionalEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
- public typealias BaseType = E
- public typealias ValueType = E
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: OptionalEnumExtensionField,
- rhs: OptionalEnumExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return String(reflecting: value)
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! OptionalEnumExtensionField<E>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- var v: ValueType?
- try decoder.decodeSingularEnumField(value: &v)
- if let v = v {
- value = v
- }
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType?
- try decoder.decodeSingularEnumField(value: &v)
- if let v = v {
- self.init(protobufExtension: protobufExtension, value: v)
- } else {
- return nil
- }
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- try visitor.visitSingularEnumField(
- value: value,
- fieldNumber: protobufExtension.fieldNumber
- )
- }
- }
- ///
- /// Repeated Enum fields
- ///
- public struct RepeatedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
- public typealias BaseType = E
- public typealias ValueType = [E]
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: RepeatedEnumExtensionField,
- rhs: RepeatedEnumExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! RepeatedEnumExtensionField<E>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- try decoder.decodeRepeatedEnumField(value: &value)
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType = []
- try decoder.decodeRepeatedEnumField(value: &v)
- self.init(protobufExtension: protobufExtension, value: v)
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- if value.count > 0 {
- try visitor.visitRepeatedEnumField(
- value: value,
- fieldNumber: protobufExtension.fieldNumber
- )
- }
- }
- }
- ///
- /// Packed Repeated Enum fields
- ///
- /// TODO: This is almost (but not quite) identical to RepeatedEnumFields;
- /// find a way to collapse the implementations.
- ///
- public struct PackedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
- public typealias BaseType = E
- public typealias ValueType = [E]
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: PackedEnumExtensionField,
- rhs: PackedEnumExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! PackedEnumExtensionField<E>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- try decoder.decodeRepeatedEnumField(value: &value)
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType = []
- try decoder.decodeRepeatedEnumField(value: &v)
- self.init(protobufExtension: protobufExtension, value: v)
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- if value.count > 0 {
- try visitor.visitPackedEnumField(
- value: value,
- fieldNumber: protobufExtension.fieldNumber
- )
- }
- }
- }
- //
- // ========== Message ==========
- //
- public struct OptionalMessageExtensionField<M: Message & Equatable>:
- ExtensionField
- {
- public typealias BaseType = M
- public typealias ValueType = BaseType
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: OptionalMessageExtensionField,
- rhs: OptionalMessageExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return String(reflecting: value)
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- value.hash(into: &hasher)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! OptionalMessageExtensionField<M>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- var v: ValueType? = value
- try decoder.decodeSingularMessageField(value: &v)
- if let v = v {
- self.value = v
- }
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType?
- try decoder.decodeSingularMessageField(value: &v)
- if let v = v {
- self.init(protobufExtension: protobufExtension, value: v)
- } else {
- return nil
- }
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- try visitor.visitSingularMessageField(
- value: value,
- fieldNumber: protobufExtension.fieldNumber
- )
- }
- public var isInitialized: Bool {
- value.isInitialized
- }
- }
- public struct RepeatedMessageExtensionField<M: Message & Equatable>:
- ExtensionField
- {
- public typealias BaseType = M
- public typealias ValueType = [BaseType]
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: RepeatedMessageExtensionField,
- rhs: RepeatedMessageExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return "[" + value.map { String(reflecting: $0) }.joined(separator: ",") + "]"
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- for e in value {
- e.hash(into: &hasher)
- }
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! RepeatedMessageExtensionField<M>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- try decoder.decodeRepeatedMessageField(value: &value)
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType = []
- try decoder.decodeRepeatedMessageField(value: &v)
- self.init(protobufExtension: protobufExtension, value: v)
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- if value.count > 0 {
- try visitor.visitRepeatedMessageField(
- value: value,
- fieldNumber: protobufExtension.fieldNumber
- )
- }
- }
- public var isInitialized: Bool {
- Internal.areAllInitialized(value)
- }
- }
- //
- // ======== Groups within Messages ========
- //
- // Protoc internally treats groups the same as messages, but
- // they serialize very differently, so we have separate serialization
- // handling here...
- public struct OptionalGroupExtensionField<G: Message & Hashable>:
- ExtensionField
- {
- public typealias BaseType = G
- public typealias ValueType = BaseType
- public var value: G
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: OptionalGroupExtensionField,
- rhs: OptionalGroupExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return value.debugDescription
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! OptionalGroupExtensionField<G>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- var v: ValueType? = value
- try decoder.decodeSingularGroupField(value: &v)
- if let v = v {
- value = v
- }
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType?
- try decoder.decodeSingularGroupField(value: &v)
- if let v = v {
- self.init(protobufExtension: protobufExtension, value: v)
- } else {
- return nil
- }
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- try visitor.visitSingularGroupField(
- value: value,
- fieldNumber: protobufExtension.fieldNumber
- )
- }
- public var isInitialized: Bool {
- value.isInitialized
- }
- }
- public struct RepeatedGroupExtensionField<G: Message & Hashable>:
- ExtensionField
- {
- public typealias BaseType = G
- public typealias ValueType = [BaseType]
- public var value: ValueType
- public var protobufExtension: any AnyMessageExtension
- public static func == (
- lhs: RepeatedGroupExtensionField,
- rhs: RepeatedGroupExtensionField
- ) -> Bool {
- lhs.value == rhs.value
- }
- public init(protobufExtension: any AnyMessageExtension, value: ValueType) {
- self.protobufExtension = protobufExtension
- self.value = value
- }
- public var debugDescription: String {
- #if DEBUG
- return "[" + value.map { $0.debugDescription }.joined(separator: ",") + "]"
- #else
- return String(reflecting: type(of: self))
- #endif
- }
- public func hash(into hasher: inout Hasher) {
- hasher.combine(value)
- }
- public func isEqual(other: any AnyExtensionField) -> Bool {
- let o = other as! RepeatedGroupExtensionField<G>
- return self == o
- }
- public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
- try decoder.decodeRepeatedGroupField(value: &value)
- }
- public init?<D: Decoder>(protobufExtension: any AnyMessageExtension, decoder: inout D) throws {
- var v: ValueType = []
- try decoder.decodeRepeatedGroupField(value: &v)
- self.init(protobufExtension: protobufExtension, value: v)
- }
- public func traverse<V: Visitor>(visitor: inout V) throws {
- if value.count > 0 {
- try visitor.visitRepeatedGroupField(
- value: value,
- fieldNumber: protobufExtension.fieldNumber
- )
- }
- }
- public var isInitialized: Bool {
- Internal.areAllInitialized(value)
- }
- }
|