mirror of
https://github.com/fankes/moshi.git
synced 2025-10-18 23:49:21 +08:00
Convert JsonValueWriter to Kotlin (#1491)
* Rename .java to .kt * Convert JsonValueWriter to Kotlin * Use knownNotNull * when of whens Co-authored-by: Parth Padgaonkar <1294660+JvmName@users.noreply.github.com> * Nix the return * Clean up Co-authored-by: Parth Padgaonkar <1294660+JvmName@users.noreply.github.com>
This commit is contained in:
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.squareup.moshi;
|
||||
|
||||
import static com.squareup.moshi.JsonScope.EMPTY_ARRAY;
|
||||
import static com.squareup.moshi.JsonScope.EMPTY_DOCUMENT;
|
||||
import static com.squareup.moshi.JsonScope.EMPTY_OBJECT;
|
||||
import static com.squareup.moshi.JsonScope.NONEMPTY_DOCUMENT;
|
||||
import static com.squareup.moshi.JsonScope.STREAMING_VALUE;
|
||||
import static java.lang.Double.NEGATIVE_INFINITY;
|
||||
import static java.lang.Double.POSITIVE_INFINITY;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSink;
|
||||
import okio.ForwardingSink;
|
||||
import okio.Okio;
|
||||
|
||||
/** Writes JSON by building a Java object comprising maps, lists, and JSON primitives. */
|
||||
final class JsonValueWriter extends JsonWriter {
|
||||
Object[] stack = new Object[32];
|
||||
private @Nullable String deferredName;
|
||||
|
||||
JsonValueWriter() {
|
||||
pushScope(EMPTY_DOCUMENT);
|
||||
}
|
||||
|
||||
public Object root() {
|
||||
int size = stackSize;
|
||||
if (size > 1 || size == 1 && scopes[size - 1] != NONEMPTY_DOCUMENT) {
|
||||
throw new IllegalStateException("Incomplete document");
|
||||
}
|
||||
return stack[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter beginArray() throws IOException {
|
||||
if (promoteValueToName) {
|
||||
throw new IllegalStateException(
|
||||
"Array cannot be used as a map key in JSON at path " + getPath());
|
||||
}
|
||||
if (stackSize == flattenStackSize && scopes[stackSize - 1] == EMPTY_ARRAY) {
|
||||
// Cancel this open. Invert the flatten stack size until this is closed.
|
||||
flattenStackSize = ~flattenStackSize;
|
||||
return this;
|
||||
}
|
||||
checkStack();
|
||||
List<Object> list = new ArrayList<>();
|
||||
add(list);
|
||||
stack[stackSize] = list;
|
||||
pathIndices[stackSize] = 0;
|
||||
pushScope(EMPTY_ARRAY);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter endArray() throws IOException {
|
||||
if (peekScope() != EMPTY_ARRAY) {
|
||||
throw new IllegalStateException("Nesting problem.");
|
||||
}
|
||||
if (stackSize == ~flattenStackSize) {
|
||||
// Cancel this close. Restore the flattenStackSize so we're ready to flatten again!
|
||||
flattenStackSize = ~flattenStackSize;
|
||||
return this;
|
||||
}
|
||||
stackSize--;
|
||||
stack[stackSize] = null;
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter beginObject() throws IOException {
|
||||
if (promoteValueToName) {
|
||||
throw new IllegalStateException(
|
||||
"Object cannot be used as a map key in JSON at path " + getPath());
|
||||
}
|
||||
if (stackSize == flattenStackSize && scopes[stackSize - 1] == EMPTY_OBJECT) {
|
||||
// Cancel this open. Invert the flatten stack size until this is closed.
|
||||
flattenStackSize = ~flattenStackSize;
|
||||
return this;
|
||||
}
|
||||
checkStack();
|
||||
Map<String, Object> map = new LinkedHashTreeMap<>();
|
||||
add(map);
|
||||
stack[stackSize] = map;
|
||||
pushScope(EMPTY_OBJECT);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter endObject() throws IOException {
|
||||
if (peekScope() != EMPTY_OBJECT) {
|
||||
throw new IllegalStateException("Nesting problem.");
|
||||
}
|
||||
if (deferredName != null) {
|
||||
throw new IllegalStateException("Dangling name: " + deferredName);
|
||||
}
|
||||
if (stackSize == ~flattenStackSize) {
|
||||
// Cancel this close. Restore the flattenStackSize so we're ready to flatten again!
|
||||
flattenStackSize = ~flattenStackSize;
|
||||
return this;
|
||||
}
|
||||
promoteValueToName = false;
|
||||
stackSize--;
|
||||
stack[stackSize] = null;
|
||||
pathNames[stackSize] = null; // Free the last path name so that it can be garbage collected!
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter name(String name) throws IOException {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("name == null");
|
||||
}
|
||||
if (stackSize == 0) {
|
||||
throw new IllegalStateException("JsonWriter is closed.");
|
||||
}
|
||||
if (peekScope() != EMPTY_OBJECT || deferredName != null || promoteValueToName) {
|
||||
throw new IllegalStateException("Nesting problem.");
|
||||
}
|
||||
deferredName = name;
|
||||
pathNames[stackSize - 1] = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter value(@Nullable String value) throws IOException {
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false;
|
||||
return name(value);
|
||||
}
|
||||
add(value);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter nullValue() throws IOException {
|
||||
if (promoteValueToName) {
|
||||
throw new IllegalStateException(
|
||||
"null cannot be used as a map key in JSON at path " + getPath());
|
||||
}
|
||||
add(null);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter value(boolean value) throws IOException {
|
||||
if (promoteValueToName) {
|
||||
throw new IllegalStateException(
|
||||
"Boolean cannot be used as a map key in JSON at path " + getPath());
|
||||
}
|
||||
add(value);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter value(@Nullable Boolean value) throws IOException {
|
||||
if (promoteValueToName) {
|
||||
throw new IllegalStateException(
|
||||
"Boolean cannot be used as a map key in JSON at path " + getPath());
|
||||
}
|
||||
add(value);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter value(double value) throws IOException {
|
||||
if (!lenient
|
||||
&& (Double.isNaN(value) || value == NEGATIVE_INFINITY || value == POSITIVE_INFINITY)) {
|
||||
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
||||
}
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false;
|
||||
return name(Double.toString(value));
|
||||
}
|
||||
add(value);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter value(long value) throws IOException {
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false;
|
||||
return name(Long.toString(value));
|
||||
}
|
||||
add(value);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonWriter value(@Nullable Number value) throws IOException {
|
||||
// If it's trivially converted to a long, do that.
|
||||
if (value instanceof Byte
|
||||
|| value instanceof Short
|
||||
|| value instanceof Integer
|
||||
|| value instanceof Long) {
|
||||
return value(value.longValue());
|
||||
}
|
||||
|
||||
// If it's trivially converted to a double, do that.
|
||||
if (value instanceof Float || value instanceof Double) {
|
||||
return value(value.doubleValue());
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return nullValue();
|
||||
}
|
||||
|
||||
// Everything else gets converted to a BigDecimal.
|
||||
BigDecimal bigDecimalValue =
|
||||
value instanceof BigDecimal ? ((BigDecimal) value) : new BigDecimal(value.toString());
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false;
|
||||
return name(bigDecimalValue.toString());
|
||||
}
|
||||
add(bigDecimalValue);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedSink valueSink() {
|
||||
if (promoteValueToName) {
|
||||
throw new IllegalStateException(
|
||||
"BufferedSink cannot be used as a map key in JSON at path " + getPath());
|
||||
}
|
||||
if (peekScope() == STREAMING_VALUE) {
|
||||
throw new IllegalStateException("Sink from valueSink() was not closed");
|
||||
}
|
||||
pushScope(STREAMING_VALUE);
|
||||
|
||||
final Buffer buffer = new Buffer();
|
||||
return Okio.buffer(
|
||||
new ForwardingSink(buffer) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (peekScope() != STREAMING_VALUE || stack[stackSize] != null) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
stackSize--; // Remove STREAMING_VALUE from the stack.
|
||||
|
||||
Object value = JsonReader.of(buffer).readJsonValue();
|
||||
boolean serializeNulls = JsonValueWriter.this.serializeNulls;
|
||||
JsonValueWriter.this.serializeNulls = true;
|
||||
try {
|
||||
add(value);
|
||||
} finally {
|
||||
JsonValueWriter.this.serializeNulls = serializeNulls;
|
||||
}
|
||||
pathIndices[stackSize - 1]++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
int size = stackSize;
|
||||
if (size > 1 || size == 1 && scopes[size - 1] != NONEMPTY_DOCUMENT) {
|
||||
throw new IOException("Incomplete document");
|
||||
}
|
||||
stackSize = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
if (stackSize == 0) {
|
||||
throw new IllegalStateException("JsonWriter is closed.");
|
||||
}
|
||||
}
|
||||
|
||||
private JsonValueWriter add(@Nullable Object newTop) {
|
||||
int scope = peekScope();
|
||||
|
||||
if (stackSize == 1) {
|
||||
if (scope != EMPTY_DOCUMENT) {
|
||||
throw new IllegalStateException("JSON must have only one top-level value.");
|
||||
}
|
||||
scopes[stackSize - 1] = NONEMPTY_DOCUMENT;
|
||||
stack[stackSize - 1] = newTop;
|
||||
|
||||
} else if (scope == EMPTY_OBJECT && deferredName != null) {
|
||||
if (newTop != null || serializeNulls) {
|
||||
@SuppressWarnings("unchecked") // Our maps always have string keys and object values.
|
||||
Map<String, Object> map = (Map<String, Object>) stack[stackSize - 1];
|
||||
Object replaced = map.put(deferredName, newTop);
|
||||
if (replaced != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Map key '"
|
||||
+ deferredName
|
||||
+ "' has multiple values at path "
|
||||
+ getPath()
|
||||
+ ": "
|
||||
+ replaced
|
||||
+ " and "
|
||||
+ newTop);
|
||||
}
|
||||
}
|
||||
deferredName = null;
|
||||
|
||||
} else if (scope == EMPTY_ARRAY) {
|
||||
@SuppressWarnings("unchecked") // Our lists always have object values.
|
||||
List<Object> list = (List<Object>) stack[stackSize - 1];
|
||||
list.add(newTop);
|
||||
|
||||
} else if (scope == STREAMING_VALUE) {
|
||||
throw new IllegalStateException("Sink from valueSink() was not closed");
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException("Nesting problem.");
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
257
moshi/src/main/java/com/squareup/moshi/JsonValueWriter.kt
Normal file
257
moshi/src/main/java/com/squareup/moshi/JsonValueWriter.kt
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.squareup.moshi
|
||||
|
||||
import com.squareup.moshi.JsonScope.EMPTY_ARRAY
|
||||
import com.squareup.moshi.JsonScope.EMPTY_DOCUMENT
|
||||
import com.squareup.moshi.JsonScope.EMPTY_OBJECT
|
||||
import com.squareup.moshi.JsonScope.NONEMPTY_DOCUMENT
|
||||
import com.squareup.moshi.JsonScope.STREAMING_VALUE
|
||||
import com.squareup.moshi.internal.knownNotNull
|
||||
import okio.Buffer
|
||||
import okio.BufferedSink
|
||||
import okio.ForwardingSink
|
||||
import okio.IOException
|
||||
import okio.buffer
|
||||
import java.math.BigDecimal
|
||||
|
||||
/** Writes JSON by building a Java object comprising maps, lists, and JSON primitives. */
|
||||
internal class JsonValueWriter : JsonWriter() {
|
||||
@JvmField // TODO remove once JsonWriter is Kotlin
|
||||
var stack = arrayOfNulls<Any>(32)
|
||||
private var deferredName: String? = null
|
||||
|
||||
init {
|
||||
pushScope(EMPTY_DOCUMENT)
|
||||
}
|
||||
|
||||
fun root(): Any? {
|
||||
val size = stackSize
|
||||
check(size <= 1 && (size != 1 || scopes[0] == NONEMPTY_DOCUMENT)) { "Incomplete document" }
|
||||
return stack[0]
|
||||
}
|
||||
|
||||
override fun beginArray(): JsonWriter {
|
||||
check(!promoteValueToName) { "Array cannot be used as a map key in JSON at path $path" }
|
||||
if (stackSize == flattenStackSize && scopes[stackSize - 1] == EMPTY_ARRAY) {
|
||||
// Cancel this open. Invert the flatten stack size until this is closed.
|
||||
flattenStackSize = flattenStackSize.inv()
|
||||
return this
|
||||
}
|
||||
checkStack()
|
||||
val list = mutableListOf<Any>()
|
||||
add(list)
|
||||
stack[stackSize] = list
|
||||
pathIndices[stackSize] = 0
|
||||
pushScope(EMPTY_ARRAY)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun endArray(): JsonWriter {
|
||||
check(peekScope() == EMPTY_ARRAY) { "Nesting problem." }
|
||||
if (stackSize == flattenStackSize.inv()) {
|
||||
// Cancel this close. Restore the flattenStackSize so we're ready to flatten again!
|
||||
flattenStackSize = flattenStackSize.inv()
|
||||
return this
|
||||
}
|
||||
stackSize--
|
||||
stack[stackSize] = null
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun beginObject(): JsonWriter {
|
||||
check(!promoteValueToName) { "Object cannot be used as a map key in JSON at path $path" }
|
||||
if (stackSize == flattenStackSize && scopes[stackSize - 1] == EMPTY_OBJECT) {
|
||||
// Cancel this open. Invert the flatten stack size until this is closed.
|
||||
flattenStackSize = flattenStackSize.inv()
|
||||
return this
|
||||
}
|
||||
checkStack()
|
||||
val map = LinkedHashTreeMap<String, Any>()
|
||||
add(map)
|
||||
stack[stackSize] = map
|
||||
pushScope(EMPTY_OBJECT)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun endObject(): JsonWriter {
|
||||
check(peekScope() == EMPTY_OBJECT) { "Nesting problem." }
|
||||
check(deferredName == null) { "Dangling name: $deferredName" }
|
||||
if (stackSize == flattenStackSize.inv()) {
|
||||
// Cancel this close. Restore the flattenStackSize so we're ready to flatten again!
|
||||
flattenStackSize = flattenStackSize.inv()
|
||||
return this
|
||||
}
|
||||
promoteValueToName = false
|
||||
stackSize--
|
||||
stack[stackSize] = null
|
||||
pathNames[stackSize] = null // Free the last path name so that it can be garbage collected!
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun name(name: String): JsonWriter {
|
||||
check(stackSize != 0) { "JsonWriter is closed." }
|
||||
check(peekScope() == EMPTY_OBJECT && deferredName == null && !promoteValueToName) { "Nesting problem." }
|
||||
deferredName = name
|
||||
pathNames[stackSize - 1] = name
|
||||
return this
|
||||
}
|
||||
|
||||
override fun value(value: String?): JsonWriter {
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false
|
||||
return name(value!!)
|
||||
}
|
||||
add(value)
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun nullValue(): JsonWriter {
|
||||
check(!promoteValueToName) { "null cannot be used as a map key in JSON at path $path" }
|
||||
add(null)
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun value(value: Boolean): JsonWriter {
|
||||
check(!promoteValueToName) { "Boolean cannot be used as a map key in JSON at path $path" }
|
||||
add(value)
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun value(value: Boolean?): JsonWriter {
|
||||
check(!promoteValueToName) { "Boolean cannot be used as a map key in JSON at path $path" }
|
||||
add(value)
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun value(value: Double): JsonWriter {
|
||||
require(lenient || !value.isNaN() && value != Double.NEGATIVE_INFINITY && value != Double.POSITIVE_INFINITY) {
|
||||
"Numeric values must be finite, but was $value"
|
||||
}
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false
|
||||
return name(value.toString())
|
||||
}
|
||||
add(value)
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun value(value: Long): JsonWriter {
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false
|
||||
return name(value.toString())
|
||||
}
|
||||
add(value)
|
||||
pathIndices[stackSize - 1]++
|
||||
return this
|
||||
}
|
||||
|
||||
override fun value(value: Number?): JsonWriter = apply {
|
||||
when (value) {
|
||||
null -> nullValue()
|
||||
// If it's trivially converted to a long, do that.
|
||||
is Byte, is Short, is Int, is Long -> value(value.toLong())
|
||||
// If it's trivially converted to a double, do that.
|
||||
is Float, is Double -> value(value.toDouble())
|
||||
else -> {
|
||||
// Everything else gets converted to a BigDecimal.
|
||||
val bigDecimalValue = if (value is BigDecimal) value else BigDecimal(value.toString())
|
||||
if (promoteValueToName) {
|
||||
promoteValueToName = false
|
||||
return name(bigDecimalValue.toString())
|
||||
}
|
||||
add(bigDecimalValue)
|
||||
pathIndices[stackSize - 1]++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun valueSink(): BufferedSink {
|
||||
check(!promoteValueToName) { "BufferedSink cannot be used as a map key in JSON at path $path" }
|
||||
check(peekScope() != STREAMING_VALUE) { "Sink from valueSink() was not closed" }
|
||||
pushScope(STREAMING_VALUE)
|
||||
val buffer = Buffer()
|
||||
return object : ForwardingSink(buffer) {
|
||||
override fun close() {
|
||||
if (peekScope() != STREAMING_VALUE || stack[stackSize] != null) {
|
||||
throw AssertionError()
|
||||
}
|
||||
stackSize-- // Remove STREAMING_VALUE from the stack.
|
||||
val value = JsonReader.of(buffer).readJsonValue()
|
||||
val serializeNulls = serializeNulls
|
||||
this@JsonValueWriter.serializeNulls = true
|
||||
try {
|
||||
add(value)
|
||||
} finally {
|
||||
this@JsonValueWriter.serializeNulls = serializeNulls
|
||||
}
|
||||
pathIndices[stackSize - 1]++
|
||||
}
|
||||
}.buffer()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
val size = stackSize
|
||||
if (size > 1 || size == 1 && scopes[0] != NONEMPTY_DOCUMENT) {
|
||||
throw IOException("Incomplete document")
|
||||
}
|
||||
stackSize = 0
|
||||
}
|
||||
|
||||
override fun flush() {
|
||||
check(stackSize != 0) { "JsonWriter is closed." }
|
||||
}
|
||||
|
||||
private fun add(newTop: Any?): JsonValueWriter {
|
||||
val scope = peekScope()
|
||||
when {
|
||||
stackSize == 1 -> {
|
||||
check(scope == EMPTY_DOCUMENT) { "JSON must have only one top-level value." }
|
||||
scopes[stackSize - 1] = NONEMPTY_DOCUMENT
|
||||
stack[stackSize - 1] = newTop
|
||||
}
|
||||
scope == EMPTY_OBJECT && deferredName != null -> {
|
||||
if (newTop != null || serializeNulls) {
|
||||
// Our maps always have string keys and object values.
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val map = stack[stackSize - 1] as MutableMap<String, Any?>
|
||||
// Safe to assume not null as this is single-threaded and smartcast just can't handle it
|
||||
val replaced = map.put(knownNotNull(deferredName), newTop)
|
||||
require(replaced == null) {
|
||||
"Map key '$deferredName' has multiple values at path $path: $replaced and $newTop"
|
||||
}
|
||||
}
|
||||
deferredName = null
|
||||
}
|
||||
scope == EMPTY_ARRAY -> {
|
||||
// Our lists always have object values.
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val list = stack[stackSize - 1] as MutableList<Any?>
|
||||
list.add(newTop)
|
||||
}
|
||||
scope == STREAMING_VALUE -> throw IllegalStateException("Sink from valueSink() was not closed")
|
||||
else -> throw IllegalStateException("Nesting problem.")
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user