/* Generated By:JavaCC: Do not edit this line. FilterParser.java */
package org.apache.sling.resource.filter.impl;

import java.util.ArrayList;
import java.util.List;
import org.apache.sling.resource.filter.impl.node.*;

public final class FilterParser implements FilterParserConstants {

  final public Node parse() throws ParseException {
  final Node node;
    node = or();
    jj_consume_token(0);
    {if (true) return node;}
    throw new Error("Missing return statement in function");
  }

  final public Node or() throws ParseException {
  final List < Node > nodes = new ArrayList < Node > (3);
  Node node;
    node = and();
    nodes.add(node);
    label_1:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case OR:
        ;
        break;
      default:
        jj_la1[0] = jj_gen;
        break label_1;
      }
      jj_consume_token(OR);
      node = and();
      nodes.add(node);
    }
    {if (true) return nodes.size() != 1 ? new Node(FilterParserConstants.OR, nodes) : nodes.get(0);}
    throw new Error("Missing return statement in function");
  }

  final public Node and() throws ParseException {
  final List < Node > nodes = new ArrayList < Node > (3);
  Node node;
    node = constraint();
    nodes.add(node);
    label_2:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case AND:
        ;
        break;
      default:
        jj_la1[1] = jj_gen;
        break label_2;
      }
      jj_consume_token(AND);
      node = constraint();
      nodes.add(node);
    }
    {if (true) return nodes.size() != 1 ? new Node(FilterParserConstants.AND, nodes) : nodes.get(0);}
    throw new Error("Missing return statement in function");
  }

  final public Node constraint() throws ParseException {
  final Node node;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case LPAREN:
      node = group();
      break;
    case OFFSETDATETIME:
    case DATETIME:
    case DATE:
    case NUMBER:
    case STRING:
    case NULL:
    case BOOLEAN:
    case DYNAMIC_ARG:
    case FUNCTION_NAME:
    case PROPERTY:
      node = comparison();
      break;
    default:
      jj_la1[2] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    {if (true) return node;}
    throw new Error("Missing return statement in function");
  }

  final public Node group() throws ParseException {
  final Node node;
    jj_consume_token(LPAREN);
    node = or();
    jj_consume_token(RPAREN);
    {if (true) return node;}
    throw new Error("Missing return statement in function");
  }

  final public Node comparison() throws ParseException {
  Node leftValue;
  Token op;
  Node rightValue;
    leftValue = argument();
    op = comparisonValue();
    rightValue = argument();
    {if (true) return new Node(op.kind, op.image, leftValue, rightValue);}
    throw new Error("Missing return statement in function");
  }

  final public Token comparisonValue() throws ParseException {
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case EQUAL:
      jj_consume_token(EQUAL);
      break;
    case NOT_EQUAL:
      jj_consume_token(NOT_EQUAL);
      break;
    case GREATER_THAN:
      jj_consume_token(GREATER_THAN);
      break;
    case GREATER_THAN_OR_EQUAL:
      jj_consume_token(GREATER_THAN_OR_EQUAL);
      break;
    case LESS_THAN:
      jj_consume_token(LESS_THAN);
      break;
    case LESS_THAN_OR_EQUAL:
      jj_consume_token(LESS_THAN_OR_EQUAL);
      break;
    case LIKE:
      jj_consume_token(LIKE);
      break;
    case LIKE_NOT:
      jj_consume_token(LIKE_NOT);
      break;
    case CONTAINS:
      jj_consume_token(CONTAINS);
      break;
    case CONTAINS_NOT:
      jj_consume_token(CONTAINS_NOT);
      break;
    case CONTAINS_ANY:
      jj_consume_token(CONTAINS_ANY);
      break;
    case CONTAINS_NOT_ANY:
      jj_consume_token(CONTAINS_NOT_ANY);
      break;
    case IN:
      jj_consume_token(IN);
      break;
    case NOT_IN:
      jj_consume_token(NOT_IN);
      break;
    default:
      jj_la1[3] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    {if (true) return token;}
    throw new Error("Missing return statement in function");
  }

  final public List < Node > Arguments() throws ParseException {
  Object value = new ArrayList();
    jj_consume_token(LPAREN);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case OFFSETDATETIME:
    case DATETIME:
    case DATE:
    case NUMBER:
    case STRING:
    case NULL:
    case BOOLEAN:
    case DYNAMIC_ARG:
    case FUNCTION_NAME:
    case PROPERTY:
      value = commaSepArguments();
      break;
    default:
      jj_la1[4] = jj_gen;
      ;
    }
    jj_consume_token(RPAREN);
    {if (true) return (List) value;}
    throw new Error("Missing return statement in function");
  }

  final public List < Node > commaSepArguments() throws ParseException {
  final List < Node > list = new ArrayList < Node > (3);
  Node arg;
    arg = argument();
    list.add(arg);
    label_3:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case COMMA:
        ;
        break;
      default:
        jj_la1[5] = jj_gen;
        break label_3;
      }
      jj_consume_token(COMMA);
      arg = argument();
      list.add(arg);
    }
    {if (true) return list;}
    throw new Error("Missing return statement in function");
  }

  final public Node argument() throws ParseException {
  Node selector = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case OFFSETDATETIME:
    case DATETIME:
    case DATE:
    case NUMBER:
    case STRING:
    case NULL:
    case BOOLEAN:
      selector = literal();
      break;
    case PROPERTY:
      selector = property();
      break;
    case DYNAMIC_ARG:
      selector = dynamicArg();
      break;
    case FUNCTION_NAME:
      selector = function();
      break;
    default:
      jj_la1[6] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    {if (true) return selector;}
    throw new Error("Missing return statement in function");
  }

  final public Node function() throws ParseException {
  String functionName = null;
  List < Node > children = null;
    jj_consume_token(FUNCTION_NAME);
    functionName = token.image;
    jj_consume_token(LPAREN);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case OFFSETDATETIME:
    case DATETIME:
    case DATE:
    case NUMBER:
    case STRING:
    case NULL:
    case BOOLEAN:
    case DYNAMIC_ARG:
    case FUNCTION_NAME:
    case PROPERTY:
      children = commaSepArguments();
      break;
    default:
      jj_la1[7] = jj_gen;
      ;
    }
    jj_consume_token(RPAREN);
    {if (true) return new Node(FilterParserConstants.FUNCTION_NAME, functionName, children);}
    throw new Error("Missing return statement in function");
  }

  final public Node dynamicArg() throws ParseException {
  String functionName = null;
    jj_consume_token(DYNAMIC_ARG);
    jj_consume_token(FUNCTION_NAME);
    functionName = token.image;
    {if (true) return new Node(FilterParserConstants.DYNAMIC_ARG, functionName);}
    throw new Error("Missing return statement in function");
  }

  final public Node literal() throws ParseException {
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case STRING:
      jj_consume_token(STRING);
      break;
    case NUMBER:
      jj_consume_token(NUMBER);
      break;
    case NULL:
      jj_consume_token(NULL);
      break;
    case BOOLEAN:
      jj_consume_token(BOOLEAN);
      break;
    case DATE:
      jj_consume_token(DATE);
      break;
    case DATETIME:
      jj_consume_token(DATETIME);
      break;
    case OFFSETDATETIME:
      jj_consume_token(OFFSETDATETIME);
      break;
    default:
      jj_la1[8] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    {if (true) return new Node(token.kind, token.image);}
    throw new Error("Missing return statement in function");
  }

  final public Node property() throws ParseException {
    jj_consume_token(PROPERTY);
    {if (true) return new Node(token.kind, token.image);}
    throw new Error("Missing return statement in function");
  }

  /** Generated Token Manager. */
  public FilterParserTokenManager 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[9];
  static private int[] jj_la1_0;
  static private int[] jj_la1_1;
  static {
      jj_la1_init_0();
      jj_la1_init_1();
   }
   private static void jj_la1_init_0() {
      jj_la1_0 = new int[] {0x400000,0x200000,0x9843c00,0xf0000000,0x8843c00,0x4000000,0x8843c00,0x8843c00,0x8843c00,};
   }
   private static void jj_la1_init_1() {
      jj_la1_1 = new int[] {0x0,0x0,0x1c00,0x3ff,0x1c00,0x0,0x1c00,0x1c00,0x0,};
   }

  /** Constructor with InputStream. */
  public FilterParser(java.io.InputStream stream) {
     this(stream, null);
  }
  /** Constructor with InputStream and supplied encoding */
  public FilterParser(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 FilterParserTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 9; 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 < 9; i++) jj_la1[i] = -1;
  }

  /** Constructor. */
  public FilterParser(java.io.Reader stream) {
    jj_input_stream = new SimpleCharStream(stream, 1, 1);
    token_source = new FilterParserTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 9; 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 < 9; i++) jj_la1[i] = -1;
  }

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

  /** Reinitialise. */
  public void ReInit(FilterParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 9; 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<int[]> jj_expentries = new java.util.ArrayList<int[]>();
  private int[] jj_expentry;
  private int jj_kind = -1;

  /** Generate ParseException. */
  public ParseException generateParseException() {
    jj_expentries.clear();
    boolean[] la1tokens = new boolean[46];
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 9; 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;
          }
          if ((jj_la1_1[i] & (1<<j)) != 0) {
            la1tokens[32+j] = true;
          }
        }
      }
    }
    for (int i = 0; i < 46; 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] = jj_expentries.get(i);
    }
    return new ParseException(token, exptokseq, tokenImage);
  }

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

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

}
