/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * JQL.g
 *
 * Created on March 8, 2000
 */

header
{
    package com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc;

    import antlr.MismatchedTokenException;
    import antlr.MismatchedCharException;
    import antlr.NoViableAltException;
    import antlr.NoViableAltForCharException;
    import antlr.TokenStreamRecognitionException;
    
    import java.util.Locale;
    import java.util.ResourceBundle;
    import com.sun.jdo.api.persistence.support.JDOQueryException;
    import com.sun.jdo.api.persistence.support.JDOFatalInternalException;
    import org.glassfish.persistence.common.I18NHelper;

}

//===== Lexical Analyzer Class Definitions =====

/**
 * This class defines the lexical analysis for the JQL compiler.
 *
 * @author  Michael Bouschen
 * @author  Shing Wai Chan
 * @version 0.1
 */
class JQLLexer extends Lexer;
options
{
    k = 2;
    exportVocab = JQL;
    charVocabulary = '\u0000'..'\uFFFE'; //NOI18N
}

tokens {

    IMPORT = "import"; //NOI18N
    THIS = "this"; //NOI18N
    ASCENDING = "ascending"; //NOI18N
    DESCENDING = "descending"; //NOI18N

    // non-standard extensions
    DISTINCT = "distinct"; //NOI18N
    
    // types
    
    BOOLEAN = "boolean"; //NOI18N
    BYTE = "byte"; //NOI18N
    CHAR = "char"; //NOI18N
    SHORT = "short"; //NOI18N
    INT = "int"; //NOI18N
    FLOAT = "float"; //NOI18N
    LONG = "long"; //NOI18N
    DOUBLE = "double"; //NOI18N
    
    // literals
    
    NULL = "null"; //NOI18N
    TRUE = "true"; //NOI18N
    FALSE = "false"; //NOI18N

    // aggregate functions
    AVG = "avg"; //NOI18N
    MAX = "max"; //NOI18N
    MIN = "min"; //NOI18N
    SUM = "sum"; //NOI18N
    COUNT = "count"; //NOI18N
    
}

{
    /**
     * I18N support
     */
    private final static ResourceBundle messages = I18NHelper.loadBundle(
            JQLLexer.class);
    
    /**
     *
     */
    protected ErrorMsg errorMsg;
    
    /**
     * The width of a tab stop.
     * This value is used to calculate the correct column in a line
     * conatining a tab character.
     */
    protected static final int TABSIZE = 4;

    /**
     *
     */
    public void init(ErrorMsg errorMsg)
    {
        this.errorMsg = errorMsg;
    }
    
    /**
     *
     */
    public void tab() 
    {
        int column = getColumn();
        int newColumn = (((column-1)/TABSIZE)+1)*TABSIZE+1;
        setColumn(newColumn);
    }

    /**
     *
     */
    public void reportError(int line, int column, String s)
    {
        errorMsg.error(line, column, s);
    }

    /**
     * Report lexer exception errors caught in nextToken()
     */
    public void reportError(RecognitionException e)
    {
        JQLParser.handleANTLRException(e, errorMsg);
    }

    /**
     * Lexer error-reporting function
     */
    public void reportError(String s)
    {
        errorMsg.error(0, 0, s);
    }

    /**
     * Lexer warning-reporting function
     */
    public void reportWarning(String s)
    {
        throw new JDOQueryException(s);
    }
}

// OPERATORS
LPAREN          :   '('     ;
RPAREN          :   ')'     ;
COMMA           :   ','     ;
//DOT           :   '.'     ;
EQUAL           :   "=="    ; //NOI18N
LNOT            :   '!'     ;
BNOT            :   '~'     ;
NOT_EQUAL       :   "!="    ; //NOI18N
DIV             :   '/'     ;
PLUS            :   '+'     ;
MINUS           :   '-'     ;
STAR            :   '*'     ;
MOD             :   '%'     ;
GE              :   ">="    ; //NOI18N
GT              :   ">"     ; //NOI18N
LE              :   "<="    ; //NOI18N
LT              :   '<'     ;
BXOR            :   '^'     ;
BOR             :   '|'     ;
OR              :   "||"    ; //NOI18N
BAND            :   '&'     ;
AND             :   "&&"    ; //NOI18N
SEMI            :   ';'     ;

// Whitespace -- ignored
WS
    :   (   ' '
        |   '\t'
        |   '\f'
        )
        { _ttype = Token.SKIP; }
    ;

NEWLINE
    :   (   "\r\n"  //NOI18N
        |   '\r'
        |   '\n'
        )
        { 
            newline(); 
            _ttype = Token.SKIP; 
        }
    ;

// character literals
CHAR_LITERAL
    :   '\'' ( ESC | ~'\'' ) '\'' 
    ;

// string literals
STRING_LITERAL
    :  '"' ( ESC | ~'"')* '"' //NOI18N
    ;

// escape sequence -- note that this is protected; it can only be called
//   from another lexer rule -- it will not ever directly return a token to
//   the parser
// There are various ambiguities hushed in this rule.  The optional
// '0'...'9' digit matches should be matched here rather than letting
// them go back to STRING_LITERAL to be matched.  ANTLR does the
// right thing by matching immediately; hence, it's ok to shut off
// the FOLLOW ambig warnings.
protected
ESC
    :   '\\'
        (   options { warnWhenFollowAmbig = false; }    
        :   'n'
        |   'r'
        |   't'
        |   'b'
        |   'f'
        |   '"' //NOI18N
        |   '\''
        |   '\\'
        |   ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
        |   ('0'..'3')
            (
                options {
                    warnWhenFollowAmbig = false;
                }
            :   ('0'..'7')
                (   
                    options {
                        warnWhenFollowAmbig = false;
                    }
                :   '0'..'7'
                )?
            )?
        |   ('4'..'7')
            (
                options {
                    warnWhenFollowAmbig = false;
                }
            :   ('0'..'9')
            )?
        )?
    ;

// hexadecimal digit (again, note it's protected!)
protected
HEX_DIGIT
    :   ('0'..'9'|'A'..'F'|'a'..'f')
    ;


// a numeric literal
INT_LITERAL
    {   
        boolean isDecimal=false;
        int tokenType = DOUBLE_LITERAL; 
    }
    :   '.' {_ttype = DOT;}
            (('0'..'9')+ {tokenType = DOUBLE_LITERAL;}
             (EXPONENT)? 
             (tokenType = FLOATINGPOINT_SUFFIX)?
            { _ttype = tokenType; })?
    |   (   '0' {isDecimal = true;} // special case for just '0'
            (   ('x'|'X')
                (                                           // hex
                    // the 'e'|'E' and float suffix stuff look
                    // like hex digits, hence the (...)+ doesn't
                    // know when to stop: ambig.  ANTLR resolves
                    // it correctly by matching immediately.  It
                    // is therefor ok to hush warning.
                    options {
                        warnWhenFollowAmbig=false;
                    }
                :   HEX_DIGIT
                )+
            |   ('0'..'7')+                                 // octal
            )?
        |   ('1'..'9') ('0'..'9')*  {isDecimal=true;}       // non-zero decimal
        )
        (   ('l'|'L') { _ttype = LONG_LITERAL; }
        
        // only check to see if it's a float if looks like decimal so far
        |   {isDecimal}?
            {tokenType = DOUBLE_LITERAL;} 
            (   '.' ('0'..'9')* (EXPONENT)? 
                (tokenType = FLOATINGPOINT_SUFFIX)?
            |   EXPONENT (tokenType = FLOATINGPOINT_SUFFIX)?
            |   tokenType = FLOATINGPOINT_SUFFIX
            )
            { _ttype = tokenType; }
        )?
    ;

// a couple protected methods to assist in matching floating point numbers
protected
EXPONENT
    :   ('e'|'E') ('+'|'-')? ('0'..'9')+
    ;

protected
FLOATINGPOINT_SUFFIX returns [int tokenType]
    : 'f' { tokenType = FLOAT_LITERAL; } 
    | 'F' { tokenType = FLOAT_LITERAL; } 
    | 'd' { tokenType = DOUBLE_LITERAL; } 
    | 'D' { tokenType = DOUBLE_LITERAL; } 
    ;

// an identifier.  Note that testLiterals is set to true!  This means
// that after we match the rule, we look in the literals table to see
// if it's a literal or really an identifer

IDENT
    options {paraphrase = "an identifier"; testLiterals=true;} //NOI18N
    :   (   'a'..'z'
        |   'A'..'Z'
        |   '_'
        |   '$'
        |   UNICODE_ESCAPE
        |   c1:'\u0080'..'\uFFFE'
            {   
                if (!Character.isJavaIdentifierStart(c1)) {
                    errorMsg.error(getLine(), getColumn(), 
                        I18NHelper.getMessage(messages, "jqlc.parser.unexpectedchar", //NOI18N
                            String.valueOf(c1)));
                }
            }
        ) 
        (   'a'..'z'
        |   'A'..'Z'
        |   '_'
        |   '$'
        |   '0'..'9'
        |   UNICODE_ESCAPE
        |   c2:'\u0080'..'\uFFFE'
            {   
                if (!Character.isJavaIdentifierPart(c2)) {
                    errorMsg.error(getLine(), getColumn(), 
                        I18NHelper.getMessage(messages, "jqlc.parser.unexpectedchar", //NOI18N
                        String.valueOf(c2)));
                }
            }
        )*
    ;

protected
UNICODE_ESCAPE
    : '\\' ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
        {
            try {
                String tmp = text.toString();
                char c  = (char)Integer.parseInt(tmp.substring(tmp.length() - 4, tmp.length()), 16);
                // problems using ANTLR feature $setText => use generated code
                text.setLength(_begin); 
                text.append(new Character(c).toString());
            }
            catch (NumberFormatException ex) {
                throw new JDOFatalInternalException(I18NHelper.getMessage(messages, "jqlc.parser.invalidunicodestr"), ex); //NOI18N
            }
        }
    ;

//===== Parser Class Definitions =====

/**
 * This class defines the syntax analysis (parser) of the JQL compiler.
 *
 * @author  Michael Bouschen
 * @version 0.1
 */
class JQLParser extends Parser;

options {
    k = 2;                   // two token lookahead
    exportVocab = JQL;
    buildAST = true;
    ASTLabelType = "JQLAST"; // AST variables are defined as JQLAST
}

tokens
{
    // "imaginary" tokens, that have no corresponding real input

    QUERY;
    CLASS_DEF;
    IMPORT_DEF;
    PARAMETER_DEF;
    VARIABLE_DEF;
    ORDERING_DEF;
    FILTER_DEF;
    ARG_LIST;

    // operators
    UNARY_MINUS;
    UNARY_PLUS;
    TYPECAST;
    OBJECT_EQUAL;
    OBJECT_NOT_EQUAL;
    COLLECTION_EQUAL;
    COLLECTION_NOT_EQUAL;
    CONCAT;

    // special dot expressions
    FIELD_ACCESS;
    STATIC_FIELD_ACCESS;
    CONTAINS;
    NOT_CONTAINS;
    NAVIGATION;
    STARTS_WITH;
    ENDS_WITH;
    IS_EMPTY;
    
    // identifier types
    VARIABLE;
    PARAMETER;
    TYPENAME;

    // constant value
    VALUE;

    // result definition
    RESULT_DEF;

    // non-standard extensions (operators)
    LIKE;
    SUBSTRING;
    INDEXOF;
    LENGTH;
    ABS;
    SQRT;

    // 
    NOT_IN;
}

{
    /**
     * I18N support
     */
    private final static ResourceBundle messages = I18NHelper.loadBundle(
            JQLParser.class);

    /** */
    protected static final int EOF_CHAR = 65535; // = (char) -1 = EOF

    /**
     *
     */
    protected ErrorMsg errorMsg;
    
    /**
     *
     */
    public void init(ErrorMsg errorMsg)
    {
        this.errorMsg = errorMsg;
    }
    
    /**
     * ANTLR method called when an error was detected.
     */
    public void reportError(RecognitionException ex)
    {
        JQLParser.handleANTLRException(ex, errorMsg);
    }

    /**
     * ANTLR method called when an error was detected.
     */
    public void reportError(String s)
    {
        errorMsg.error(0, 0, s);
    }

    /**
     *
     */
    public void reportError(int line, int column, String s)
    {
        errorMsg.error(line, column, s);
    }

    /**
     * ANTLR method called when a warning was detected.
     */
    public void reportWarning(String s)
    {
        throw new JDOQueryException(s);
    }

    /**
     *
     */
    public static void handleANTLRException(ANTLRException ex, ErrorMsg errorMsg)
    {
        if (ex instanceof MismatchedCharException)
        {
            MismatchedCharException mismatched = (MismatchedCharException)ex;
            if (mismatched.mismatchType == MismatchedCharException.CHAR)
            {
                if (mismatched.foundChar == EOF_CHAR) 
                {
                    errorMsg.error(mismatched.getLine(), mismatched.getColumn(), 
                        I18NHelper.getMessage(messages, "jqlc.parser.unexpectedEOF")); //NOI18N
                }
                else 
                {
                    errorMsg.error(mismatched.getLine(), mismatched.getColumn(), 
                        I18NHelper.getMessage(messages, "jqlc.parser.expectedfoundchar", //NOI18N
                            String.valueOf((char)mismatched.expecting), 
                            String.valueOf((char)mismatched.foundChar)));
                }
                return;
            }
        }
        else if (ex instanceof MismatchedTokenException)
        {
            MismatchedTokenException mismatched = (MismatchedTokenException)ex;
            Token token = mismatched.token;
            if ((mismatched.mismatchType == MismatchedTokenException.TOKEN) &&
                (token != null)) 
            {
                if (token.getType() == Token.EOF_TYPE) {
                    errorMsg.error(token.getLine(), token.getColumn(), 
                        I18NHelper.getMessage(messages, "jqlc.parser.unexpectedEOF")); //NOI18N
                }
                else {
                    errorMsg.error(token.getLine(), token.getColumn(), 
                        I18NHelper.getMessage(messages, "jqlc.parser.syntaxerrorattoken", token.getText())); //NOI18N
                }
                return;
            }
        }
        else if (ex instanceof NoViableAltException)
        {
            Token token = ((NoViableAltException)ex).token;
            if (token != null)
            {
                if (token.getType() == Token.EOF_TYPE) 
                {
                    errorMsg.error(token.getLine(), token.getColumn(),
                        I18NHelper.getMessage(messages, "jqlc.parser.unexpectedEOF")); //NOI18N
                }
                else 
                {
                    errorMsg.error(token.getLine(), token.getColumn(), 
                        I18NHelper.getMessage(messages, "jqlc.parser.unexpectedtoken", token.getText())); //NOI18N
                }
                return;
            }
        }
        else if (ex instanceof NoViableAltForCharException)
        {
            NoViableAltForCharException noViableAlt = (NoViableAltForCharException)ex;
            errorMsg.error(noViableAlt.getLine(), noViableAlt.getColumn(), 
                I18NHelper.getMessage(messages, "jqlc.parser.unexpectedchar", //NOI18N
                    String.valueOf(noViableAlt.foundChar)));
        }
        else if (ex instanceof TokenStreamRecognitionException)
        {
            handleANTLRException(((TokenStreamRecognitionException)ex).recog, errorMsg);
        }

        // no special handling from aboves matches the exception if this line is reached =>
        // make it a syntax error
        int line = 0;
        int column = 0;
        if (ex instanceof RecognitionException)
        {
            line = ((RecognitionException)ex).getLine();
            column = ((RecognitionException)ex).getColumn();
        }
        errorMsg.error(line, column, I18NHelper.getMessage(messages, "jqlc.parser.syntaxerror")); //NOI18N
    }
}

// ----------------------------------
// rules: import declaration
// ----------------------------------

parseImports
{   
    errorMsg.setContext("declareImports");  //NOI18N
}
    :   ( declareImport ( SEMI! declareImport )* )? ( SEMI! )? EOF!
    ;

declareImport
    :   i:IMPORT^ qualifiedName //NOI18N
        {
            #i.setType(IMPORT_DEF);
        }
    ;

// ----------------------------------
// rules: parameter declaration
// ----------------------------------

parseParameters
{   
    errorMsg.setContext("declareParameters"); //NOI18N
}
    :   ( declareParameter ( COMMA! declareParameter )* )? ( COMMA! )? EOF!
    ;

declareParameter
    :   type IDENT
        { #declareParameter = #(#[PARAMETER_DEF,"parameterDef"], #declareParameter); } //NOI18N
    ;

// ----------------------------------
// rules: variables declaration
// ----------------------------------

parseVariables
{   
    errorMsg.setContext("declareVariables");  //NOI18N
}
    :   ( declareVariable ( SEMI! declareVariable )* )? ( SEMI! )? EOF!
    ;

declareVariable
    :   type IDENT
        {  #declareVariable = #(#[VARIABLE_DEF,"variableDef"], #declareVariable); } //NOI18N
    ;

// ----------------------------------
// rules ordering specification
// ----------------------------------

parseOrdering
{   
    errorMsg.setContext("setOrdering");  //NOI18N
}
    :   ( orderSpec ( COMMA! orderSpec )* )? ( COMMA! )? EOF!
    ;

orderSpec!
    :   e:expression d:direction
        { #orderSpec = #(#[ORDERING_DEF,"orderingDef"], #d, #e); } //NOI18N
    ; 

direction
    :    ASCENDING
    |    DESCENDING
    ;

// ----------------------------------
// rules result expression
// ----------------------------------

parseResult
{  
    errorMsg.setContext("setResult");  //NOI18N
}
    :   ( ( DISTINCT^ )? ( a:aggregateExpr | e:expression ) )? EOF!
        {  
            // create RESULT_DEF node if there was a projection
            if (#a != null) {
                // skip a possible first distinct in case of an aggregate expr
                #parseResult = #(#[RESULT_DEF, "resultDef"], #a);
            }
            else if (#e != null) {
                #parseResult = #(#[RESULT_DEF,"resultDef"], #parseResult); //NOI18N
            }
        }
    ;

aggregateExpr
    :   ( AVG^ | MAX^ | MIN^ | SUM^ | COUNT^) LPAREN! distinctExpr RPAREN!
    ;

distinctExpr
    :   DISTINCT^ e:expression 
    |   expression
    ;

// ----------------------------------
// rules filer expression
// ----------------------------------

parseFilter!
{  
    errorMsg.setContext("setFilter");  //NOI18N
}
    :   e:expression EOF!
        {  #parseFilter = #(#[FILTER_DEF,"filterDef"], #e); } //NOI18N
    ;

// This is a list of expressions.
expressionList
    :   expression (COMMA! expression)*
    ;

expression
    :   conditionalOrExpression
    ;

// conditional or ||
conditionalOrExpression
    :   conditionalAndExpression (OR^ conditionalAndExpression)*
    ;

// conditional and &&
conditionalAndExpression
    :   inclusiveOrExpression (AND^ inclusiveOrExpression)*
    ;

// bitwise or logical or |
inclusiveOrExpression
    :   exclusiveOrExpression (BOR^ exclusiveOrExpression)*
    ;

// exclusive or ^
exclusiveOrExpression
    :   andExpression (BXOR^ andExpression)*
    ;

// bitwise or logical and &
andExpression
    :   equalityExpression (BAND^ equalityExpression)*
    ;

// equality/inequality ==/!=
equalityExpression
    :   relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)*
    ;
// boolean relational expressions
relationalExpression
    :   additiveExpression
        (   (   LT^
            |   GT^
            |   LE^
            |   GE^
            )
            additiveExpression
        )*
    ;

// binary addition/subtraction
additiveExpression
    :   multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)*
    ;
// multiplication/division/modulo
multiplicativeExpression
    :   unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)*
    ;

unaryExpression
    :   MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression
    |   PLUS^  {#PLUS.setType(UNARY_PLUS);} unaryExpression
    |   unaryExpressionNotPlusMinus
    ;

unaryExpressionNotPlusMinus
    :   BNOT^ unaryExpression
    |   LNOT^ unaryExpression
    |   ( LPAREN type RPAREN unaryExpression )=>
          lp:LPAREN^ {#lp.setType(TYPECAST);} type RPAREN! unaryExpression
    |   postfixExpression
    ;

// qualified names, field access, method invocation
postfixExpression
    :   primary
        (   DOT^ IDENT ( argList )? )*
    ;

argList
    :   LPAREN!
        (   expressionList
            {#argList = #(#[ARG_LIST,"ARG_LIST"], #argList); } //NOI18N

        |   /* empty list */
            {#argList = #[ARG_LIST,"ARG_LIST"];} //NOI18N
        )
        RPAREN!
    ;

// the basic element of an expression
primary
    :   IDENT
    |   literal
    |   THIS
    |   LPAREN! expression RPAREN!
    ;

literal
    :   TRUE
    |   FALSE
    |   INT_LITERAL
    |   LONG_LITERAL
    |   FLOAT_LITERAL
    |   DOUBLE_LITERAL
    |   c:CHAR_LITERAL
        {
            // strip quotes from the token text
            String text = #c.getText();
            #c.setText(text.substring(1,text.length()-1));
        }
    |   s:STRING_LITERAL
        {
            // strip quotes from the token text
            String text = #s.getText();
            #s.setText(text.substring(1,text.length()-1));
        }
    |   NULL
    ;

qualifiedName
    :   IDENT ( DOT^ IDENT )*
    ;

type
    :   qualifiedName
    |   primitiveType
    ;

// The primitive types.
primitiveType
    :   BOOLEAN
    |   BYTE
    |   CHAR
    |   SHORT
    |   INT
    |   FLOAT
    |   LONG
    |   DOUBLE
    ;

