@@ -110,11 +110,8 @@ internal open class StreamingJsonDecoder(
110
110
descriptor,
111
111
discriminatorHolder
112
112
)
113
- else -> if (mode == newMode && json.configuration.explicitNulls) {
114
- this
115
- } else {
116
- StreamingJsonDecoder (json, newMode, lexer, descriptor, discriminatorHolder)
117
- }
113
+
114
+ else -> StreamingJsonDecoder (json, newMode, lexer, descriptor, discriminatorHolder)
118
115
}
119
116
}
120
117
@@ -220,35 +217,47 @@ internal open class StreamingJsonDecoder(
220
217
)
221
218
222
219
private fun decodeObjectIndex (descriptor : SerialDescriptor ): Int {
223
- // hasComma checks are required to properly react on trailing commas
224
- var hasComma = lexer.tryConsumeComma()
225
- while (lexer.canConsumeValue()) { // TODO: consider merging comma consumption and this check
226
- hasComma = false
220
+ while (true ) {
221
+ if (currentIndex != - 1 ) {
222
+ val next = lexer.peekNextToken()
223
+ if (next == TC_END_OBJ ) {
224
+ currentIndex = CompositeDecoder .DECODE_DONE
225
+ return elementMarker?.nextUnmarkedIndex() ? : CompositeDecoder .DECODE_DONE
226
+ }
227
+
228
+ lexer.require(next == TC_COMMA ) { " Expected comma after the key-value pair" }
229
+ val commaPosition = lexer.currentPosition
230
+ lexer.consumeNextToken()
231
+ lexer.require(
232
+ configuration.allowTrailingComma || lexer.peekNextToken() != TC_END_OBJ ,
233
+ position = commaPosition
234
+ ) { " Trailing comma before the end of JSON object" }
235
+ }
236
+
237
+ if (! lexer.canConsumeValue()) break
238
+
227
239
val key = decodeStringKey()
228
240
lexer.consumeNextToken(COLON )
229
241
val index = descriptor.getJsonNameIndex(json, key)
230
- val isUnknown = if (index != UNKNOWN_NAME ) {
231
- if (configuration.coerceInputValues && coerceInputValue(descriptor, index)) {
232
- hasComma = lexer.tryConsumeComma()
233
- false // Known element, but coerced
234
- } else {
235
- elementMarker?.mark(index)
236
- return index // Known element without coercing, return it
237
- }
238
- } else {
239
- true // unknown element
242
+
243
+ if (index == UNKNOWN_NAME ) {
244
+ handleUnknown(descriptor, key)
245
+ currentIndex = UNKNOWN_NAME
246
+ continue
240
247
}
241
248
242
- if (isUnknown) { // slow-path for unknown keys handling
243
- hasComma = handleUnknown(descriptor, key)
249
+ if (configuration.coerceInputValues && coerceInputValue(descriptor, index)) {
250
+ continue
244
251
}
252
+ elementMarker?.mark(index)
253
+ currentIndex = index
254
+ return index
245
255
}
246
- if (hasComma && ! json.configuration.allowTrailingComma) lexer.invalidTrailingComma()
247
256
248
257
return elementMarker?.nextUnmarkedIndex() ? : CompositeDecoder .DECODE_DONE
249
258
}
250
259
251
- private fun handleUnknown (descriptor : SerialDescriptor , key : String ): Boolean {
260
+ private fun handleUnknown (descriptor : SerialDescriptor , key : String ) {
252
261
if (descriptor.ignoreUnknownKeys(json) || discriminatorHolder.trySkip(key)) {
253
262
lexer.skipElement(configuration.isLenient)
254
263
} else {
@@ -257,7 +266,6 @@ internal open class StreamingJsonDecoder(
257
266
lexer.path.popDescriptor()
258
267
lexer.failOnUnknownKey(key)
259
268
}
260
- return lexer.tryConsumeComma()
261
269
}
262
270
263
271
private fun decodeListIndex (): Int {
0 commit comments