/** * Inserts any necessary separators and whitespace before a literal value, inline array, or inline * object. Also adjusts the stack to expect either a closing bracket or another element. * * @param root true if the value is a new array or object, the two values permitted as top-level * elements. */ private void beforeValue(boolean root) throws IOException { switch (peek()) { case EMPTY_DOCUMENT: // first in document if (!lenient && !root) { throw new IllegalStateException("JSON must start with an array or an object."); } replaceTop(JsonScope.NONEMPTY_DOCUMENT); break; case EMPTY_ARRAY: // first in array replaceTop(JsonScope.NONEMPTY_ARRAY); newline(); break; case NONEMPTY_ARRAY: // another in array out.append(','); newline(); break; case DANGLING_NAME: // value for name out.append(separator); replaceTop(JsonScope.NONEMPTY_OBJECT); break; case NONEMPTY_DOCUMENT: throw new IllegalStateException("JSON must have only one top-level value."); default: throw new IllegalStateException("Nesting problem: " + stack); } }
/** * Inserts any necessary separators and whitespace before a name. Also adjusts the stack to expect * the name's value. */ private void beforeName() throws IOException { JsonScope context = peek(); if (context == JsonScope.NONEMPTY_OBJECT) { // first in object out.write(','); } else if (context != JsonScope.EMPTY_OBJECT) { // not in an object! throw new IllegalStateException("Nesting problem: " + stack); } newline(); replaceTop(JsonScope.DANGLING_NAME); }
/** Closes the current scope by appending any necessary whitespace and the given bracket. */ private JsonWriter close(JsonScope empty, JsonScope nonempty, String closeBracket) throws IOException { JsonScope context = peek(); if (context != nonempty && context != empty) { throw new IllegalStateException("Nesting problem: " + stack); } stack.remove(stack.size() - 1); if (context == nonempty) { newline(); } out.write(closeBracket); return this; }