package com.google.gson.internal.bind;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
public final class JsonTreeReader extends JsonReader
{
private static final Reader UNREADABLE_READER = new Reader() {
public int read(char[] buffer, int offset, int count) throws IOException {
throw new AssertionError();
}
public void close() throws IOException {
throw new AssertionError();
}
};
private static final Object SENTINEL_CLOSED = new Object();
private final List<Object> stack = new ArrayList();
public JsonTreeReader(JsonElement element) {
super(UNREADABLE_READER);
this.stack.add(element);
}
public void beginArray() throws IOException {
expect(JsonToken.BEGIN_ARRAY);
JsonArray array = (JsonArray)peekStack();
this.stack.add(array.iterator());
}
public void endArray() throws IOException {
expect(JsonToken.END_ARRAY);
popStack();
popStack();
}
public void beginObject() throws IOException {
expect(JsonToken.BEGIN_OBJECT);
JsonObject object = (JsonObject)peekStack();
this.stack.add(object.entrySet().iterator());
}
public void endObject() throws IOException {
expect(JsonToken.END_OBJECT);
popStack();
popStack();
}
public boolean hasNext() throws IOException {
JsonToken token = peek();
return (token != JsonToken.END_OBJECT) && (token != JsonToken.END_ARRAY);
}
public JsonToken peek() throws IOException {
if (this.stack.isEmpty()) {
return JsonToken.END_DOCUMENT;
}
Object o = peekStack();
if ((o instanceof Iterator)) {
boolean isObject = this.stack.get(this.stack.size() - 2) instanceof JsonObject;
Iterator iterator = (Iterator)o;
if (iterator.hasNext()) {
if (isObject) {
return JsonToken.NAME;
}
this.stack.add(iterator.next());
return peek();
}
return isObject ? JsonToken.END_OBJECT : JsonToken.END_ARRAY;
}
if ((o instanceof JsonObject))
return JsonToken.BEGIN_OBJECT;
if ((o instanceof JsonArray))
return JsonToken.BEGIN_ARRAY;
if ((o instanceof JsonPrimitive)) {
JsonPrimitive primitive = (JsonPrimitive)o;
if (primitive.isString())
return JsonToken.STRING;
if (primitive.isBoolean())
return JsonToken.BOOLEAN;
if (primitive.isNumber()) {
return JsonToken.NUMBER;
}
throw new AssertionError();
}
if ((o instanceof JsonNull))
return JsonToken.NULL;
if (o == SENTINEL_CLOSED) {
throw new IllegalStateException("JsonReader is closed");
}
throw new AssertionError();
}
private Object peekStack()
{
return this.stack.get(this.stack.size() - 1);
}
private Object popStack() {
return this.stack.remove(this.stack.size() - 1);
}
private void expect(JsonToken expected) throws IOException {
if (peek() != expected)
throw new IllegalStateException("Expected " + expected + " but was " + peek());
}
public String nextName() throws IOException
{
expect(JsonToken.NAME);
Iterator i = (Iterator)peekStack();
Map.Entry entry = (Map.Entry)i.next();
this.stack.add(entry.getValue());
return (String)entry.getKey();
}
public String nextString() throws IOException {
JsonToken token = peek();
if ((token != JsonToken.STRING) && (token != JsonToken.NUMBER)) {
throw new IllegalStateException("Expected " + JsonToken.STRING + " but was " + token);
}
return ((JsonPrimitive)popStack()).getAsString();
}
public boolean nextBoolean() throws IOException {
expect(JsonToken.BOOLEAN);
return ((JsonPrimitive)popStack()).getAsBoolean();
}
public void nextNull() throws IOException {
expect(JsonToken.NULL);
popStack();
}
public double nextDouble() throws IOException {
JsonToken token = peek();
if ((token != JsonToken.NUMBER) && (token != JsonToken.STRING)) {
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
}
double result = ((JsonPrimitive)peekStack()).getAsDouble();
if ((!isLenient()) && ((Double.isNaN(result)) || (Double.isInfinite(result)))) {
throw new NumberFormatException("JSON forbids NaN and infinities: " + result);
}
popStack();
return result;
}
public long nextLong() throws IOException {
JsonToken token = peek();
if ((token != JsonToken.NUMBER) && (token != JsonToken.STRING)) {
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
}
long result = ((JsonPrimitive)peekStack()).getAsLong();
popStack();
return result;
}
public int nextInt() throws IOException {
JsonToken token = peek();
if ((token != JsonToken.NUMBER) && (token != JsonToken.STRING)) {
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
}
int result = ((JsonPrimitive)peekStack()).getAsInt();
popStack();
return result;
}
public void close() throws IOException {
this.stack.clear();
this.stack.add(SENTINEL_CLOSED);
}
public void skipValue() throws IOException {
if (peek() == JsonToken.NAME)
nextName();
else
popStack();
}
public String toString()
{
return getClass().getSimpleName();
}
public void promoteNameToValue() throws IOException {
expect(JsonToken.NAME);
Iterator i = (Iterator)peekStack();
Map.Entry entry = (Map.Entry)i.next();
this.stack.add(entry.getValue());
this.stack.add(new JsonPrimitive((String)entry.getKey()));
}
}