Skip to content

Commit a381a62

Browse files
committed
Move Extension fields to the Swift 4.2 Hashable approach.
ExtensionFieldValueSet is the problem case, as AnyExtensionField isn't actually Hashable, so we have to build the support manually.
1 parent 992afa2 commit a381a62

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

Sources/SwiftProtobuf/ExtensionFieldValueSet.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ public struct ExtensionFieldValueSet: Hashable {
3939

4040
public init() {}
4141

42+
#if swift(>=4.2)
43+
public func hash(into hasher: inout Hasher) {
44+
// AnyExtensionField is not Hashable, and the Self constraint that would
45+
// add breaks some of the uses of it; so the only choice is to manually
46+
// mix things in. However, one must remember to do things in an order
47+
// independent manner.
48+
var hash = 16777619
49+
for (fieldNumber, v) in values {
50+
var localHasher = hasher
51+
localHasher.combine(fieldNumber)
52+
v.hash(into: &localHasher)
53+
hash = hash &+ localHasher.finalize()
54+
}
55+
hasher.combine(hash)
56+
}
57+
#else // swift(>=4.2)
4258
public var hashValue: Int {
4359
var hash = 16777619
4460
for (fieldNumber, v) in values {
@@ -47,6 +63,7 @@ public struct ExtensionFieldValueSet: Hashable {
4763
}
4864
return hash
4965
}
66+
#endif // swift(>=4.2)
5067

5168
public func traverse<V: Visitor>(visitor: inout V, start: Int, end: Int) throws {
5269
let validIndexes = values.keys.filter {$0 >= start && $0 < end}

Sources/SwiftProtobuf/ExtensionFields.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
///
1313
// -----------------------------------------------------------------------------
1414

15+
#if !swift(>=4.2)
1516
private let i_2166136261 = Int(bitPattern: 2166136261)
1617
private let i_16777619 = Int(16777619)
18+
#endif
1719

1820
//
1921
// Type-erased Extension field implementation.
@@ -26,7 +28,11 @@ private let i_16777619 = Int(16777619)
2628
// so you can't actually access the contained value itself.
2729
//
2830
public protocol AnyExtensionField: CustomDebugStringConvertible {
31+
#if swift(>=4.2)
32+
func hash(into hasher: inout Hasher)
33+
#else
2934
var hashValue: Int { get }
35+
#endif
3036
var protobufExtension: AnyMessageExtension { get }
3137
func isEqual(other: AnyExtensionField) -> Bool
3238

@@ -81,9 +87,15 @@ public struct OptionalExtensionField<T: FieldType>: ExtensionField {
8187
}
8288
}
8389

90+
#if swift(>=4.2)
91+
public func hash(into hasher: inout Hasher) {
92+
hasher.combine(value)
93+
}
94+
#else // swift(>=4.2)
8495
public var hashValue: Int {
8596
get { return value.hashValue }
8697
}
98+
#endif // swift(>=4.2)
8799

88100
public func isEqual(other: AnyExtensionField) -> Bool {
89101
let o = other as! OptionalExtensionField<T>
@@ -132,6 +144,11 @@ public struct RepeatedExtensionField<T: FieldType>: ExtensionField {
132144
self.value = value
133145
}
134146

147+
#if swift(>=4.2)
148+
public func hash(into hasher: inout Hasher) {
149+
hasher.combine(value)
150+
}
151+
#else // swift(>=4.2)
135152
public var hashValue: Int {
136153
get {
137154
var hash = i_2166136261
@@ -141,6 +158,7 @@ public struct RepeatedExtensionField<T: FieldType>: ExtensionField {
141158
return hash
142159
}
143160
}
161+
#endif // swift(>=4.2)
144162

145163
public func isEqual(other: AnyExtensionField) -> Bool {
146164
let o = other as! RepeatedExtensionField<T>
@@ -190,6 +208,11 @@ public struct PackedExtensionField<T: FieldType>: ExtensionField {
190208
self.value = value
191209
}
192210

211+
#if swift(>=4.2)
212+
public func hash(into hasher: inout Hasher) {
213+
hasher.combine(value)
214+
}
215+
#else // swift(>=4.2)
193216
public var hashValue: Int {
194217
get {
195218
var hash = i_2166136261
@@ -199,6 +222,7 @@ public struct PackedExtensionField<T: FieldType>: ExtensionField {
199222
return hash
200223
}
201224
}
225+
#endif // swift(>=4.2)
202226

203227
public func isEqual(other: AnyExtensionField) -> Bool {
204228
let o = other as! PackedExtensionField<T>
@@ -251,9 +275,15 @@ public struct OptionalEnumExtensionField<E: Enum>: ExtensionField where E.RawVal
251275
}
252276
}
253277

278+
#if swift(>=4.2)
279+
public func hash(into hasher: inout Hasher) {
280+
hasher.combine(value)
281+
}
282+
#else // swift(>=4.2)
254283
public var hashValue: Int {
255284
get { return value.hashValue }
256285
}
286+
#endif // swift(>=4.2)
257287

258288
public func isEqual(other: AnyExtensionField) -> Bool {
259289
let o = other as! OptionalEnumExtensionField<E>
@@ -304,6 +334,11 @@ public struct RepeatedEnumExtensionField<E: Enum>: ExtensionField where E.RawVal
304334
self.value = value
305335
}
306336

337+
#if swift(>=4.2)
338+
public func hash(into hasher: inout Hasher) {
339+
hasher.combine(value)
340+
}
341+
#else // swift(>=4.2)
307342
public var hashValue: Int {
308343
get {
309344
var hash = i_2166136261
@@ -313,6 +348,7 @@ public struct RepeatedEnumExtensionField<E: Enum>: ExtensionField where E.RawVal
313348
return hash
314349
}
315350
}
351+
#endif // swift(>=4.2)
316352

317353
public func isEqual(other: AnyExtensionField) -> Bool {
318354
let o = other as! RepeatedEnumExtensionField<E>
@@ -364,6 +400,11 @@ public struct PackedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue
364400
self.value = value
365401
}
366402

403+
#if swift(>=4.2)
404+
public func hash(into hasher: inout Hasher) {
405+
hasher.combine(value)
406+
}
407+
#else // swift(>=4.2)
367408
public var hashValue: Int {
368409
get {
369410
var hash = i_2166136261
@@ -373,6 +414,7 @@ public struct PackedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue
373414
return hash
374415
}
375416
}
417+
#endif // swift(>=4.2)
376418

377419
public func isEqual(other: AnyExtensionField) -> Bool {
378420
let o = other as! PackedEnumExtensionField<E>
@@ -428,7 +470,13 @@ public struct OptionalMessageExtensionField<M: Message & Equatable>:
428470
}
429471
}
430472

473+
#if swift(>=4.2)
474+
public func hash(into hasher: inout Hasher) {
475+
hasher.combine(value.hashValue) // TODO(thomasvl): Fix this once message is updated!
476+
}
477+
#else // swift(>=4.2)
431478
public var hashValue: Int {return value.hashValue}
479+
#endif // swift(>=4.2)
432480

433481
public func isEqual(other: AnyExtensionField) -> Bool {
434482
let o = other as! OptionalMessageExtensionField<M>
@@ -480,6 +528,13 @@ public struct RepeatedMessageExtensionField<M: Message & Equatable>:
480528
self.value = value
481529
}
482530

531+
#if swift(>=4.2)
532+
public func hash(into hasher: inout Hasher) {
533+
for e in value {
534+
hasher.combine(e.hashValue) // TODO(thomasvl): Fix this once message is updated!
535+
}
536+
}
537+
#else // swift(>=4.2)
483538
public var hashValue: Int {
484539
get {
485540
var hash = i_2166136261
@@ -489,6 +544,7 @@ public struct RepeatedMessageExtensionField<M: Message & Equatable>:
489544
return hash
490545
}
491546
}
547+
#endif // swift(>=4.2)
492548

493549
public func isEqual(other: AnyExtensionField) -> Bool {
494550
let o = other as! RepeatedMessageExtensionField<M>
@@ -544,7 +600,13 @@ public struct OptionalGroupExtensionField<G: Message & Hashable>:
544600
self.value = value
545601
}
546602

603+
#if swift(>=4.2)
604+
public func hash(into hasher: inout Hasher) {
605+
hasher.combine(value.hashValue) // TODO(thomasvl): Fix this once message is updated!
606+
}
607+
#else // swift(>=4.2)
547608
public var hashValue: Int {return value.hashValue}
609+
#endif // swift(>=4.2)
548610

549611
public var debugDescription: String { get {return value.debugDescription} }
550612

@@ -598,6 +660,13 @@ public struct RepeatedGroupExtensionField<G: Message & Hashable>:
598660
self.value = value
599661
}
600662

663+
#if swift(>=4.2)
664+
public func hash(into hasher: inout Hasher) {
665+
for e in value {
666+
hasher.combine(e.hashValue) // TODO(thomasvl): Fix this once message is updated!
667+
}
668+
}
669+
#else // swift(>=4.2)
601670
public var hashValue: Int {
602671
get {
603672
var hash = i_2166136261
@@ -607,6 +676,7 @@ public struct RepeatedGroupExtensionField<G: Message & Hashable>:
607676
return hash
608677
}
609678
}
679+
#endif // swift(>=4.2)
610680

611681
public var debugDescription: String {
612682
return "[" + value.map{$0.debugDescription}.joined(separator: ",") + "]"

0 commit comments

Comments
 (0)