@@ -110,11 +110,8 @@ internal open class StreamingJsonDecoder(
110110 descriptor,
111111 discriminatorHolder
112112 )
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)
118115 }
119116 }
120117
@@ -220,35 +217,47 @@ internal open class StreamingJsonDecoder(
220217 )
221218
222219 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+
227239 val key = decodeStringKey()
228240 lexer.consumeNextToken(COLON )
229241 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
240247 }
241248
242- if (isUnknown) { // slow-path for unknown keys handling
243- hasComma = handleUnknown(descriptor, key)
249+ if (configuration.coerceInputValues && coerceInputValue(descriptor, index)) {
250+ continue
244251 }
252+ elementMarker?.mark(index)
253+ currentIndex = index
254+ return index
245255 }
246- if (hasComma && ! json.configuration.allowTrailingComma) lexer.invalidTrailingComma()
247256
248257 return elementMarker?.nextUnmarkedIndex() ? : CompositeDecoder .DECODE_DONE
249258 }
250259
251- private fun handleUnknown (descriptor : SerialDescriptor , key : String ): Boolean {
260+ private fun handleUnknown (descriptor : SerialDescriptor , key : String ) {
252261 if (descriptor.ignoreUnknownKeys(json) || discriminatorHolder.trySkip(key)) {
253262 lexer.skipElement(configuration.isLenient)
254263 } else {
@@ -257,7 +266,6 @@ internal open class StreamingJsonDecoder(
257266 lexer.path.popDescriptor()
258267 lexer.failOnUnknownKey(key)
259268 }
260- return lexer.tryConsumeComma()
261269 }
262270
263271 private fun decodeListIndex (): Int {
0 commit comments