| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- // Sources/SwiftProtobuf/ExtensionFieldValueSet.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
- //
- // -----------------------------------------------------------------------------
- ///
- /// A collection of extension field values on a particular object.
- /// This is only used within messages to manage the values of extension fields;
- /// it does not need to be very sophisticated.
- ///
- // -----------------------------------------------------------------------------
- public struct ExtensionFieldValueSet: Hashable, Sendable {
- fileprivate var values = [Int: any AnyExtensionField]()
- public static func == (
- lhs: ExtensionFieldValueSet,
- rhs: ExtensionFieldValueSet
- ) -> Bool {
- guard lhs.values.count == rhs.values.count else {
- return false
- }
- for (index, l) in lhs.values {
- if let r = rhs.values[index] {
- if type(of: l) != type(of: r) {
- return false
- }
- if !l.isEqual(other: r) {
- return false
- }
- } else {
- return false
- }
- }
- return true
- }
- public init() {}
- public func hash(into hasher: inout Hasher) {
- // AnyExtensionField is not Hashable, and the Self constraint that would
- // add breaks some of the uses of it; so the only choice is to manually
- // mix things in. However, one must remember to do things in an order
- // independent manner.
- var hash = 16_777_619
- for (fieldNumber, v) in values {
- var localHasher = hasher
- localHasher.combine(fieldNumber)
- v.hash(into: &localHasher)
- hash = hash &+ localHasher.finalize()
- }
- hasher.combine(hash)
- }
- public func traverse<V: Visitor>(visitor: inout V, start: Int, end: Int) throws {
- let validIndexes = values.keys.filter { $0 >= start && $0 < end }
- for i in validIndexes.sorted() {
- let value = values[i]!
- try value.traverse(visitor: &visitor)
- }
- }
- public subscript(index: Int) -> (any AnyExtensionField)? {
- get { values[index] }
- set { values[index] = newValue }
- }
- mutating func modify<ReturnType>(
- index: Int,
- _ modifier: (inout (any AnyExtensionField)?) throws -> ReturnType
- ) rethrows -> ReturnType {
- // This internal helper exists to invoke the _modify accessor on Dictionary for the given operation, which can avoid CoWs
- // during the modification operation.
- try modifier(&values[index])
- }
- public var isInitialized: Bool {
- for (_, v) in values {
- if !v.isInitialized {
- return false
- }
- }
- return true
- }
- }
|