/* Generated By:JavaCC: Do not edit this line. JsonParser.java */
package org.codehaus.groovy.grails.web.json.parser;

import org.codehaus.groovy.grails.web.json.JSONArray;
import org.codehaus.groovy.grails.web.json.JSONElement;
import org.codehaus.groovy.grails.web.json.JSONObject;


@SuppressWarnings("all")
public final class JSONParser implements JsonParserConstants {

    final public Object parse() throws ParseException {
        Object json = null;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 20:
                json = JsonObject();
                break;
            case 25:
                json = JsonArray();
                break;
            case DIGITS:
            case SINGLE_QUOTE_LITERAL:
            case DOUBLE_QUOTE_LITERAL:
            case 27:
            case 28:
            case 29:
                json = JsonPrimitive();
                break;
            case 22:
                json = JsonNull();
                break;
            default:
                jj_la1[0] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
        }
        {
            if (true) return json;
        }
        throw new Error("Missing return statement in function");
    }

    final public JSONElement parseJSON() throws ParseException {
        JSONElement json = null;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 20:
                json = JsonObject();
                break;
            case 25:
                json = JsonArray();
                break;
            default:
                jj_la1[1] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
        }
        {
            if (true) return json;
        }
        throw new Error("Missing return statement in function");
    }

    final private JSONObject JsonObject() throws ParseException {
        JSONObject o = new JSONObject();
        jj_consume_token(20);
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case SINGLE_QUOTE_LITERAL:
            case DOUBLE_QUOTE_LITERAL:
                Members(o);
                break;
            default:
                jj_la1[2] = jj_gen;
                ;
        }
        jj_consume_token(21);
        {
            if (true) return o;
        }
        throw new Error("Missing return statement in function");
    }

    final private Object JsonNull() throws ParseException {
        Object o = null;
        jj_consume_token(22);
        {
            if (true) return o;
        }
        throw new Error("Missing return statement in function");
    }

    final private void Members(JSONObject o) throws ParseException {
        Pair(o);
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 23:
                jj_consume_token(23);
                Members(o);
                break;
            default:
                jj_la1[3] = jj_gen;
                ;
        }
    }

    final private void Pair(JSONObject o) throws ParseException {
        String property;
        Object value;
        property = JsonString();
        jj_consume_token(24);
        value = JsonValue();
        o.put(property, value);
    }

    final private JSONArray JsonArray() throws ParseException {
        JSONArray array = new JSONArray();
        jj_consume_token(25);
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case DIGITS:
            case SINGLE_QUOTE_LITERAL:
            case DOUBLE_QUOTE_LITERAL:
            case 20:
            case 22:
            case 25:
            case 27:
            case 28:
            case 29:
                Elements(array);
                break;
            default:
                jj_la1[4] = jj_gen;
                ;
        }
        jj_consume_token(26);
        //array.reverse();
        {
            if (true) return array;
        }
        throw new Error("Missing return statement in function");
    }

    final private void Elements(JSONArray array) throws ParseException {
        Object element;
        element = JsonValue();
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 23:
                jj_consume_token(23);
                Elements(array);
                break;
            default:
                jj_la1[5] = jj_gen;
                ;
        }
        array.add(element);
    }

    final private Object JsonValue() throws ParseException {
        Object o = null;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case SINGLE_QUOTE_LITERAL:
            case DOUBLE_QUOTE_LITERAL:
                o = JsonString();
                break;
            case DIGITS:
            case 29:
                o = JsonNumber();
                break;
            case 20:
                o = JsonObject();
                break;
            case 25:
                o = JsonArray();
                break;
            case 27:
                jj_consume_token(27);
                o = Boolean.TRUE;
                break;
            case 28:
                jj_consume_token(28);
                o = Boolean.FALSE;
                break;
            case 22:
                jj_consume_token(22);
                break;
            default:
                jj_la1[6] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
        }
        {
            if (true) return o;
        }
        throw new Error("Missing return statement in function");
    }

    final private Object JsonPrimitive() throws ParseException {
        Object value;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case SINGLE_QUOTE_LITERAL:
            case DOUBLE_QUOTE_LITERAL:
                value = JsonString();
            {
                if (true) return value;
            }
            break;
            case DIGITS:
            case 29:
                value = JsonNumber();
            {
                if (true) return value;
            }
            break;
            case 27:
                jj_consume_token(27);
            {
                if (true) return Boolean.TRUE;
            }
            break;
            case 28:
                jj_consume_token(28);
            {
                if (true) return Boolean.FALSE;
            }
            break;
            default:
                jj_la1[7] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
        }
        throw new Error("Missing return statement in function");
    }

    final private Object JsonNumber() throws ParseException {
        String intpart = null,
                fracpart = null,
                exppart = null;
        intpart = JsonInt();
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 30:
                fracpart = JsonFrac();
                break;
            default:
                jj_la1[8] = jj_gen;
                ;
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case E:
                exppart = JsonExp();
                break;
            default:
                jj_la1[9] = jj_gen;
                ;
        }
        Number n;
        if (exppart != null) {
            n = new java.math.BigDecimal(intpart + fracpart + exppart);
        } else if (fracpart != null) {
            n = new Double(intpart + fracpart);
        } else {
            // See if the number fits in an integer, or long
            // Use BigInteger only if it is big enough.
            if (intpart.length() < 10) {
                n = new Integer(intpart);
            } else if (intpart.length() < 19) {
                n = new Long(intpart);
            } else {
                n = new java.math.BigInteger(intpart);
            }
        }
        {
            if (true) return n;
        }
        throw new Error("Missing return statement in function");
    }

    final private String JsonInt() throws ParseException {
        String digits;
        boolean negative = false;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 29:
                jj_consume_token(29);
                negative = true;
                break;
            default:
                jj_la1[10] = jj_gen;
                ;
        }
        digits = Digits();
        if (negative) {
            if (true) return "-" + digits;
        }
        {
            if (true) return digits;
        }
        throw new Error("Missing return statement in function");
    }

    final private String JsonFrac() throws ParseException {
        String digits;
        jj_consume_token(30);
        digits = Digits();
        {
            if (true) return "." + digits;
        }
        throw new Error("Missing return statement in function");
    }

    final private String JsonExp() throws ParseException {
        Token t;
        String digits;
        t = jj_consume_token(E);
        digits = Digits();
        {
            if (true) return t.image + digits;
        }
        throw new Error("Missing return statement in function");
    }

    final private String Digits() throws ParseException {
        Token t;
        t = jj_consume_token(DIGITS);
        {
            if (true) return t.image;
        }
        throw new Error("Missing return statement in function");
    }

    final private String JsonString() throws ParseException {
        Token t;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case SINGLE_QUOTE_LITERAL:
                t = jj_consume_token(SINGLE_QUOTE_LITERAL);
                break;
            case DOUBLE_QUOTE_LITERAL:
                t = jj_consume_token(DOUBLE_QUOTE_LITERAL);
                break;
            default:
                jj_la1[11] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
        }
        {
            if (true) return StringUnmarshaller.unmarshall(t.image);
        }
        throw new Error("Missing return statement in function");
    }

    /**
     * Generated Token Manager.
     */
    public JsonParserTokenManager token_source;
    SimpleCharStream jj_input_stream;
    /**
     * Current token.
     */
    public Token token;
    /**
     * Next token.
     */
    public Token jj_nt;
    private int jj_ntk;
    private int jj_gen;
    final private int[] jj_la1 = new int[12];
    static private int[] jj_la1_0;

    static {
        jj_la1_init_0();
    }

    private static void jj_la1_init_0() {
        jj_la1_0 = new int[]{0x3a500c40, 0x2100000, 0xc00, 0x800000, 0x3a500c40, 0x800000, 0x3a500c40, 0x38000c40, 0x40000000, 0x20, 0x20000000, 0xc00,};
    }

    /**
     * Constructor with InputStream.
     */
    public JSONParser(java.io.InputStream stream) {
        this(stream, null);
    }

    /**
     * Constructor with InputStream and supplied encoding
     */
    public JSONParser(java.io.InputStream stream, String encoding) {
        try {
            jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1);
        } catch (java.io.UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        token_source = new JsonParserTokenManager(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 12; i++) jj_la1[i] = -1;
    }

    /**
     * Reinitialise.
     */
    public void ReInit(java.io.InputStream stream) {
        ReInit(stream, null);
    }

    /**
     * Reinitialise.
     */
    public void ReInit(java.io.InputStream stream, String encoding) {
        try {
            jj_input_stream.ReInit(stream, encoding, 1, 1);
        } catch (java.io.UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        token_source.ReInit(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 12; i++) jj_la1[i] = -1;
    }

    /**
     * Constructor.
     */
    public JSONParser(java.io.Reader stream) {
        jj_input_stream = new SimpleCharStream(stream, 1, 1);
        token_source = new JsonParserTokenManager(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 12; i++) jj_la1[i] = -1;
    }

    /**
     * Reinitialise.
     */
    public void ReInit(java.io.Reader stream) {
        jj_input_stream.ReInit(stream, 1, 1);
        token_source.ReInit(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 12; i++) jj_la1[i] = -1;
    }

    /**
     * Constructor with generated Token Manager.
     */
    public JSONParser(JsonParserTokenManager tm) {
        token_source = tm;
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 12; i++) jj_la1[i] = -1;
    }

    /**
     * Reinitialise.
     */
    public void ReInit(JsonParserTokenManager tm) {
        token_source = tm;
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 12; i++) jj_la1[i] = -1;
    }

    private Token jj_consume_token(int kind) throws ParseException {
        Token oldToken;
        if ((oldToken = token).next != null) token = token.next;
        else token = token.next = token_source.getNextToken();
        jj_ntk = -1;
        if (token.kind == kind) {
            jj_gen++;
            return token;
        }
        token = oldToken;
        jj_kind = kind;
        throw generateParseException();
    }


    /**
     * Get the next Token.
     */
    final public Token getNextToken() {
        if (token.next != null) token = token.next;
        else token = token.next = token_source.getNextToken();
        jj_ntk = -1;
        jj_gen++;
        return token;
    }

    /**
     * Get the specific Token.
     */
    final public Token getToken(int index) {
        Token t = token;
        for (int i = 0; i < index; i++) {
            if (t.next != null) t = t.next;
            else t = t.next = token_source.getNextToken();
        }
        return t;
    }

    private int jj_ntk() {
        if ((jj_nt = token.next) == null)
            return (jj_ntk = (token.next = token_source.getNextToken()).kind);
        else
            return (jj_ntk = jj_nt.kind);
    }

    private java.util.List jj_expentries = new java.util.ArrayList();
    private int[] jj_expentry;
    private int jj_kind = -1;

    /**
     * Generate ParseException.
     */
    public ParseException generateParseException() {
        jj_expentries.clear();
        boolean[] la1tokens = new boolean[31];
        if (jj_kind >= 0) {
            la1tokens[jj_kind] = true;
            jj_kind = -1;
        }
        for (int i = 0; i < 12; i++) {
            if (jj_la1[i] == jj_gen) {
                for (int j = 0; j < 32; j++) {
                    if ((jj_la1_0[i] & (1 << j)) != 0) {
                        la1tokens[j] = true;
                    }
                }
            }
        }
        for (int i = 0; i < 31; i++) {
            if (la1tokens[i]) {
                jj_expentry = new int[1];
                jj_expentry[0] = i;
                jj_expentries.add(jj_expentry);
            }
        }
        int[][] exptokseq = new int[jj_expentries.size()][];
        for (int i = 0; i < jj_expentries.size(); i++) {
            exptokseq[i] = (int[]) jj_expentries.get(i);
        }
        return new ParseException(token, exptokseq, tokenImage);
    }

    /**
     * Enable tracing.
     */
    final public void enable_tracing() {
    }

    /**
     * Disable tracing.
     */
    final public void disable_tracing() {
    }

}
