4
4
5
5
package kotlinx.serialization.json.internal
6
6
7
- import kotlinx.serialization.ExperimentalSerializationApi
7
+ import kotlinx.serialization.*
8
8
import kotlinx.serialization.json.*
9
9
10
10
@OptIn(ExperimentalSerializationApi ::class )
@@ -24,53 +24,52 @@ internal class JsonTreeReader(
24
24
readObjectImpl { callRecursive(Unit ) }
25
25
26
26
private inline fun readObjectImpl (reader : () -> JsonElement ): JsonObject {
27
- var lastToken = lexer.consumeNextToken(TC_BEGIN_OBJ )
27
+ lexer.consumeNextToken(TC_BEGIN_OBJ )
28
+ lexer.path.pushDescriptor(JsonObjectSerializer .descriptor)
29
+
28
30
if (lexer.peekNextToken() == TC_COMMA ) lexer.fail(" Unexpected leading comma" )
29
31
val result = linkedMapOf<String , JsonElement >()
30
32
while (lexer.canConsumeValue()) {
33
+ lexer.path.resetCurrentMapKey()
31
34
// Read key and value
32
35
val key = if (isLenient) lexer.consumeStringLenient() else lexer.consumeString()
33
36
lexer.consumeNextToken(TC_COLON )
37
+
38
+ lexer.path.updateCurrentMapKey(key)
34
39
val element = reader()
35
40
result[key] = element
36
41
// Verify the next token
37
- lastToken = lexer.consumeNextToken()
38
- when (lastToken) {
39
- TC_COMMA -> Unit // no-op, can continue with `canConsumeValue` that verifies the token after comma
40
- TC_END_OBJ -> break // `canConsumeValue` can return incorrect result, since it checks token _after_ TC_END_OBJ
41
- else -> lexer.fail(" Expected end of the object or comma" )
42
- }
42
+ lexer.consumeCommaOrPeekEnd(
43
+ allowTrailing = trailingCommaAllowed,
44
+ expectedEnd = ' }' ,
45
+ )
43
46
}
44
- // Check for the correct ending
45
- if (lastToken == TC_BEGIN_OBJ ) { // Case of empty object
46
- lexer.consumeNextToken(TC_END_OBJ )
47
- } else if (lastToken == TC_COMMA ) { // Trailing comma
48
- if (! trailingCommaAllowed) lexer.invalidTrailingComma()
49
- lexer.consumeNextToken(TC_END_OBJ )
50
- } // else unexpected token?
47
+
48
+ lexer.consumeNextToken(TC_END_OBJ )
49
+ lexer.path.popDescriptor()
50
+
51
51
return JsonObject (result)
52
52
}
53
53
54
54
private fun readArray (): JsonElement {
55
- var lastToken = lexer.consumeNextToken()
55
+ lexer.consumeNextToken(TC_BEGIN_LIST )
56
+ lexer.path.pushDescriptor(JsonArraySerializer .descriptor)
56
57
// Prohibit leading comma
57
58
if (lexer.peekNextToken() == TC_COMMA ) lexer.fail(" Unexpected leading comma" )
58
59
val result = arrayListOf<JsonElement >()
59
60
while (lexer.canConsumeValue()) {
61
+ lexer.path.updateDescriptorIndex(result.size)
60
62
val element = read()
61
63
result.add(element)
62
- lastToken = lexer.consumeNextToken()
63
- if (lastToken != TC_COMMA ) {
64
- lexer.require(lastToken == TC_END_LIST ) { " Expected end of the array or comma" }
65
- }
66
- }
67
- // Check for the correct ending
68
- if (lastToken == TC_BEGIN_LIST ) { // Case of empty object
69
- lexer.consumeNextToken(TC_END_LIST )
70
- } else if (lastToken == TC_COMMA ) { // Trailing comma
71
- if (! trailingCommaAllowed) lexer.invalidTrailingComma(" array" )
72
- lexer.consumeNextToken(TC_END_LIST )
64
+ lexer.consumeCommaOrPeekEnd(
65
+ allowTrailing = trailingCommaAllowed,
66
+ expectedEnd = ' ]' ,
67
+ entity = " array"
68
+ )
73
69
}
70
+ lexer.consumeNextToken(TC_END_LIST )
71
+ lexer.path.popDescriptor()
72
+
74
73
return JsonArray (result)
75
74
}
76
75
@@ -103,6 +102,7 @@ internal class JsonTreeReader(
103
102
-- stackDepth
104
103
result
105
104
}
105
+
106
106
TC_BEGIN_LIST -> readArray()
107
107
else -> lexer.fail(" Cannot read Json element because of unexpected ${tokenDescription(token)} " )
108
108
}
0 commit comments