Skip to content

Commit 4edb04a

Browse files
committed
[JSON] Comment and cosmetic change
1 parent adb2fb0 commit 4edb04a

File tree

1 file changed

+52
-6
lines changed

1 file changed

+52
-6
lines changed

Sources/SwiftCompilerPluginMessageHandling/JSON/JSONDecoding.swift

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,58 @@ import ucrt
2828
#endif
2929
#endif
3030

31-
3231
func decodeFromJSON<T: Decodable>(json: UnsafeBufferPointer<UInt8>) throws -> T {
3332
try withExtendedLifetime(try JSONScanner.scan(buffer: json)) { map in
3433
let decoder = JSONDecoding(value: map.value, codingPathNode: .root)
3534
return try T.init(from: decoder)
3635
}
3736
}
3837

38+
/*
39+
JSONMap is inspired by swift-foundation's JSONMap.
40+
41+
For JSON payload such as:
42+
43+
```
44+
{"array": [-1.3, true], "number": 42}
45+
```
46+
47+
will be scanned by 'JSONScanner' into a map like:
48+
49+
```
50+
<OM> == Object Marker
51+
<AM> == Array Marker
52+
<SS> == Simple String (a variant of String that can has no escapes and can be passed directly to a UTF-8 parser)
53+
<NM> == Number Marker
54+
<TL> == NULL Marker
55+
map: [
56+
0: <OM>, -- object marker
57+
1: 15, | `- number of *map* elements in this collection
58+
2: <SS>, | --- key 1 '"array"'
59+
3: <int_ptr>, | | |- pointer in the payload
60+
4: 7, | | `- length
61+
5: <AM>, | --- value1 array
62+
6: 4, | | `- number of *map* elements in the array
63+
7: <NM>, | | -- arr elm 1 '-1.3'
64+
8: <int_ptr>, | | |
65+
9: 4, | | |
66+
10: <TL>, | | -- arr elm 2 'true'
67+
11: <SS>, | --- key 2 '"number"'
68+
12: <int_ptr>, | |
69+
13: 8, | |
70+
14: <NM> | --- value1: '42'
71+
15: <int_ptr>, | |
72+
16: 2, | |
73+
]
74+
```
75+
To decode '<root>.number' value:
76+
1. Index 0 indicates it's a object.
77+
2. Parse a key string at index 2, which is not a match for "number"
78+
3. Skip the key's value by finding it's an array, then its 'index(afterValue:)' which is 11
79+
4. Parse a key string at index 11, matching "number"
80+
5. Parse a value number at the pointer of index 15, length at index 16
81+
*/
82+
3983
private struct JSONMap {
4084
enum Descriptor: Int {
4185
case nullKeyword // [desc]
@@ -47,15 +91,18 @@ private struct JSONMap {
4791
case object // [desc, count, (key, value)...]
4892
case array // [desc, count, element...]
4993
}
94+
typealias Data = [Int]
5095
let data: [Int]
5196

97+
/// Top-level value.
5298
var value: JSONMapValue {
5399
JSONMapValue(map: data[...])
54100
}
55101
}
56102

103+
/// Slice of JSONMap representing a single value.
57104
private struct JSONMapValue {
58-
typealias Map = Array<Int>.SubSequence
105+
typealias Map = JSONMap.Data.SubSequence
59106
typealias Index = Map.Index
60107
let map: Map
61108

@@ -255,7 +302,7 @@ extension JSONMapValue {
255302
extension JSONMapValue {
256303
struct JSONArray: Collection {
257304
typealias Index = JSONMapValue.Index
258-
var map: JSONMapValue
305+
let map: JSONMapValue
259306

260307
var startIndex: Index { map.index(offset: 2) }
261308
var endIndex: Index { map.endIndex }
@@ -275,7 +322,7 @@ extension JSONMapValue {
275322
}
276323

277324
struct ObjectIterator {
278-
var map: JSONMapValue
325+
let map: JSONMapValue
279326
var currIndex: Int
280327

281328
init(map: JSONMapValue) {
@@ -289,8 +336,7 @@ extension JSONMapValue {
289336
return nil
290337
}
291338
let key = map.value(at: currIndex)
292-
currIndex = key.endIndex
293-
let val = map.value(at: currIndex)
339+
let val = map.value(at: key.endIndex)
294340
currIndex = val.endIndex
295341
return (key, val)
296342
}

0 commit comments

Comments
 (0)