// Copyright (C) 2009 The Android Open Source Project
//
// 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
//
// http://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.

grammar Query;
options {
  language = Java;
  output = AST;
}

tokens {
  AND;
  OR;
  NOT;
  DEFAULT_FIELD;
}

@header {
package com.google.gerrit.index.query;
}
@members {
  static class QueryParseInternalException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    QueryParseInternalException(final String msg) {
      super(msg);
    }
  }

  public static Tree parse(final String str)
    throws QueryParseException {
    try {
      final QueryParser p = new QueryParser(
        new TokenRewriteStream(
          new QueryLexer(
            new ANTLRStringStream(str)
          )
        )
      );
      return (Tree)p.query().getTree();
    } catch (QueryParseInternalException e) {
      throw new QueryParseException(e.getMessage());
    } catch (RecognitionException e) {
      throw new QueryParseException(e.getMessage());
    }
  }

  public static boolean isSingleWord(final String value) {
    try {
      final QueryLexer lexer = new QueryLexer(new ANTLRStringStream(value));
      lexer.mSINGLE_WORD();
      return lexer.nextToken().getType() == QueryParser.EOF;
    } catch (QueryParseInternalException e) {
      return false;
    } catch (RecognitionException e) {
      return false;
    }
  }

  @Override
  public void displayRecognitionError(String[] tokenNames,
                                      RecognitionException e) {
      String hdr = getErrorHeader(e);
      String msg = getErrorMessage(e, tokenNames);
      throw new QueryParseInternalException(hdr + " " + msg);
  }
}

@lexer::header {
package com.google.gerrit.index.query;
}
@lexer::members {
  @Override
  public void displayRecognitionError(String[] tokenNames,
                                      RecognitionException e) {
      String hdr = getErrorHeader(e);
      String msg = getErrorMessage(e, tokenNames);
      throw new QueryParser.QueryParseInternalException(hdr + " " + msg);
  }
}

query
  : conditionOr
  ;

conditionOr
  : (conditionAnd OR)
    => conditionAnd OR^ conditionAnd (OR! conditionAnd)*
  | conditionAnd
  ;

conditionAnd
  : (conditionNot AND)
    => i+=conditionNot (i+=conditionAnd2)*
    -> ^(AND $i+)
  | (conditionNot conditionNot)
    => i+=conditionNot (i+=conditionAnd2)*
    -> ^(AND $i+)
  | conditionNot
  ;
conditionAnd2
  : AND! conditionNot
  | conditionNot
  ;

conditionNot
  : '-' conditionBase -> ^(NOT conditionBase)
  | NOT^ conditionBase
  | conditionBase
  ;
conditionBase
  : '('! conditionOr ')'!
  | (FIELD_NAME COLON) => FIELD_NAME^ COLON! fieldValue
  | fieldValue -> ^(DEFAULT_FIELD fieldValue)
  ;

fieldValue
  // Rewrite by invoking SINGLE_WORD fragment lexer rule, passing the field name as an argument.
  : n=FIELD_NAME -> SINGLE_WORD[n]

  // Allow field values to contain a colon. We can't do this at the lexer level, because we need to
  // emit a separate token for the field name. If we were to allow ':' in SINGLE_WORD, then
  // everything would just lex as DEFAULT_FIELD.
  //
  // Field values with a colon may be lexed either as <field>:<rest> or <word>:<rest>, depending on
  // whether the part before the colon looks like a field name.
  // TODO(dborowitz): Field values ending in colon still don't work.
  | (FIELD_NAME COLON) => n=FIELD_NAME COLON fieldValue -> SINGLE_WORD[n] COLON fieldValue
  | (SINGLE_WORD COLON) => SINGLE_WORD COLON fieldValue

  | SINGLE_WORD
  | EXACT_PHRASE
  ;

AND: 'AND' ;
OR:  'OR'  ;
NOT: 'NOT' ;

COLON: ':' ;

WS
  :  ( ' ' | '\r' | '\t' | '\n' ) { $channel=HIDDEN; }
  ;

FIELD_NAME
  : ('a'..'z' | '_')+
  ;

EXACT_PHRASE
  : '"' ( ~('"') )* '"' {
      String s = $text;
      setText(s.substring(1, s.length() - 1));
    }
  | '{' ( ~('{'|'}') )* '}' {
      String s = $text;
      setText(s.substring(1, s.length() - 1));
    }
  ;

SINGLE_WORD
  : ~( '-' | NON_WORD ) ( ~( NON_WORD ) )*
  ;
fragment NON_WORD
  :  ( '\u0000'..' '
     | '!'
     | '"'
     // '#' permit
     | '$'
     | '%'
     | '&'
     | '\''
     | '(' | ')'
     // '*'  permit
     // '+'  permit
     // ','  permit
     // '-'  permit
     // '.'  permit
     // '/'  permit
     | COLON
     | ';'
     // '<' permit
     // '=' permit
     // '>' permit
     | '?'
     | '[' | ']'
     | '{' | '}'
     // | '~' permit
     )
  ;
