"""ANTLR3 exception hierarchy"""

# begin[licence]
#
# [The "BSD licence"]
# Copyright (c) 2005-2008 Terence Parr
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# end[licence]

from google.appengine._internal.antlr3.constants import INVALID_TOKEN_TYPE


class BacktrackingFailed(Exception):
    """@brief Raised to signal failed backtrack attempt"""

    pass


class RecognitionException(Exception):
    """@brief The root of the ANTLR exception hierarchy.

    To avoid English-only error messages and to generally make things
    as flexible as possible, these exceptions are not created with strings,
    but rather the information necessary to generate an error.  Then
    the various reporting methods in Parser and Lexer can be overridden
    to generate a localized error message.  For example, MismatchedToken
    exceptions are built with the expected token type.
    So, don't expect getMessage() to return anything.

    Note that as of Java 1.4, you can access the stack trace, which means
    that you can compute the complete trace of rules from the start symbol.
    This gives you considerable context information with which to generate
    useful error messages.

    ANTLR generates code that throws exceptions upon recognition error and
    also generates code to catch these exceptions in each rule.  If you
    want to quit upon first error, you can turn off the automatic error
    handling mechanism using rulecatch action, but you still need to
    override methods mismatch and recoverFromMismatchSet.

    In general, the recognition exceptions can track where in a grammar a
    problem occurred and/or what was the expected input.  While the parser
    knows its state (such as current input symbol and line info) that
    state can change before the exception is reported so current token index
    is computed and stored at exception time.  From this info, you can
    perhaps print an entire line of input not just a single token, for example.
    Better to just say the recognizer had a problem and then let the parser
    figure out a fancy report.

    """

    def __init__(self, input=None):
        Exception.__init__(self)

	# What input stream did the error occur in?
        self.input = None

        # What is index of token/char were we looking at when the error
        # occurred?
        self.index = None

	# The current Token when an error occurred.  Since not all streams
	# can retrieve the ith Token, we have to track the Token object.
	# For parsers.  Even when it's a tree parser, token might be set.
        self.token = None

	# If this is a tree parser exception, node is set to the node with
	# the problem.
        self.node = None

	# The current char when an error occurred. For lexers.
        self.c = None

	# Track the line at which the error occurred in case this is
	# generated from a lexer.  We need to track this since the
        # unexpected char doesn't carry the line info.
        self.line = None

        self.charPositionInLine = None

        # If you are parsing a tree node stream, you will encounter som
        # imaginary nodes w/o line/col info.  We now search backwards looking
        # for most recent token with line/col info, but notify getErrorHeader()
        # that info is approximate.
        self.approximateLineInfo = False


        if input is not None:
            self.input = input
            self.index = input.index()

            # late import to avoid cyclic dependencies
            from google.appengine._internal.antlr3.streams import TokenStream, CharStream
            from google.appengine._internal.antlr3.tree import TreeNodeStream

            if isinstance(self.input, TokenStream):
                self.token = self.input.LT(1)
                self.line = self.token.line
                self.charPositionInLine = self.token.charPositionInLine

            if isinstance(self.input, TreeNodeStream):
                self.extractInformationFromTreeNodeStream(self.input)

            else:
                if isinstance(self.input, CharStream):
                    self.c = self.input.LT(1)
                    self.line = self.input.line
                    self.charPositionInLine = self.input.charPositionInLine

                else:
                    self.c = self.input.LA(1)

    def extractInformationFromTreeNodeStream(self, nodes):
        from google.appengine._internal.antlr3.tree import Tree, CommonTree
        from google.appengine._internal.antlr3.tokens import CommonToken

        self.node = nodes.LT(1)
        adaptor = nodes.adaptor
        payload = adaptor.getToken(self.node)
        if payload is not None:
            self.token = payload
            if payload.line <= 0:
                # imaginary node; no line/pos info; scan backwards
                i = -1
                priorNode = nodes.LT(i)
                while priorNode is not None:
                    priorPayload = adaptor.getToken(priorNode)
                    if priorPayload is not None and priorPayload.line > 0:
                        # we found the most recent real line / pos info
                        self.line = priorPayload.line
                        self.charPositionInLine = priorPayload.charPositionInLine
                        self.approximateLineInfo = True
                        break

                    i -= 1
                    priorNode = nodes.LT(i)

            else: # node created from real token
                self.line = payload.line
                self.charPositionInLine = payload.charPositionInLine

        elif isinstance(self.node, Tree):
            self.line = self.node.line
            self.charPositionInLine = self.node.charPositionInLine
            if isinstance(self.node, CommonTree):
                self.token = self.node.token

        else:
            type = adaptor.getType(self.node)
            text = adaptor.getText(self.node)
            self.token = CommonToken(type=type, text=text)


    def getUnexpectedType(self):
        """Return the token type or char of the unexpected input element"""

        from google.appengine._internal.antlr3.streams import TokenStream
        from google.appengine._internal.antlr3.tree import TreeNodeStream

        if isinstance(self.input, TokenStream):
            return self.token.type

        elif isinstance(self.input, TreeNodeStream):
            adaptor = self.input.treeAdaptor
            return adaptor.getType(self.node)

        else:
            return self.c

    unexpectedType = property(getUnexpectedType)


class MismatchedTokenException(RecognitionException):
    """@brief A mismatched char or Token or tree node."""

    def __init__(self, expecting, input):
        RecognitionException.__init__(self, input)
        self.expecting = expecting


    def __str__(self):
        #return "MismatchedTokenException("+self.expecting+")"
        return "MismatchedTokenException(%r!=%r)" % (
            self.getUnexpectedType(), self.expecting
            )
    __repr__ = __str__


class UnwantedTokenException(MismatchedTokenException):
    """An extra token while parsing a TokenStream"""

    def getUnexpectedToken(self):
        return self.token


    def __str__(self):
        exp = ", expected %s" % self.expecting
        if self.expecting == INVALID_TOKEN_TYPE:
            exp = ""

        if self.token is None:
            return "UnwantedTokenException(found=%s%s)" % (None, exp)

        return "UnwantedTokenException(found=%s%s)" % (self.token.text, exp)
    __repr__ = __str__


class MissingTokenException(MismatchedTokenException):
    """
    We were expecting a token but it's not found.  The current token
    is actually what we wanted next.
    """

    def __init__(self, expecting, input, inserted):
        MismatchedTokenException.__init__(self, expecting, input)

        self.inserted = inserted


    def getMissingType(self):
        return self.expecting


    def __str__(self):
        if self.inserted is not None and self.token is not None:
            return "MissingTokenException(inserted %r at %r)" % (
                self.inserted, self.token.text)

        if self.token is not None:
            return "MissingTokenException(at %r)" % self.token.text

        return "MissingTokenException"
    __repr__ = __str__


class MismatchedRangeException(RecognitionException):
    """@brief The next token does not match a range of expected types."""

    def __init__(self, a, b, input):
        RecognitionException.__init__(self, input)

        self.a = a
        self.b = b


    def __str__(self):
        return "MismatchedRangeException(%r not in [%r..%r])" % (
            self.getUnexpectedType(), self.a, self.b
            )
    __repr__ = __str__


class MismatchedSetException(RecognitionException):
    """@brief The next token does not match a set of expected types."""

    def __init__(self, expecting, input):
        RecognitionException.__init__(self, input)

        self.expecting = expecting


    def __str__(self):
        return "MismatchedSetException(%r not in %r)" % (
            self.getUnexpectedType(), self.expecting
            )
    __repr__ = __str__


class MismatchedNotSetException(MismatchedSetException):
    """@brief Used for remote debugger deserialization"""

    def __str__(self):
        return "MismatchedNotSetException(%r!=%r)" % (
            self.getUnexpectedType(), self.expecting
            )
    __repr__ = __str__


class NoViableAltException(RecognitionException):
    """@brief Unable to decide which alternative to choose."""

    def __init__(
        self, grammarDecisionDescription, decisionNumber, stateNumber, input
        ):
        RecognitionException.__init__(self, input)

        self.grammarDecisionDescription = grammarDecisionDescription
        self.decisionNumber = decisionNumber
        self.stateNumber = stateNumber


    def __str__(self):
        return "NoViableAltException(%r!=[%r])" % (
            self.unexpectedType, self.grammarDecisionDescription
            )
    __repr__ = __str__


class EarlyExitException(RecognitionException):
    """@brief The recognizer did not match anything for a (..)+ loop."""

    def __init__(self, decisionNumber, input):
        RecognitionException.__init__(self, input)

        self.decisionNumber = decisionNumber


class FailedPredicateException(RecognitionException):
    """@brief A semantic predicate failed during validation.

    Validation of predicates
    occurs when normally parsing the alternative just like matching a token.
    Disambiguating predicate evaluation occurs when we hoist a predicate into
    a prediction decision.
    """

    def __init__(self, input, ruleName, predicateText):
        RecognitionException.__init__(self, input)

        self.ruleName = ruleName
        self.predicateText = predicateText


    def __str__(self):
        return "FailedPredicateException("+self.ruleName+",{"+self.predicateText+"}?)"
    __repr__ = __str__


class MismatchedTreeNodeException(RecognitionException):
    """@brief The next tree mode does not match the expected type."""

    def __init__(self, expecting, input):
        RecognitionException.__init__(self, input)

        self.expecting = expecting

    def __str__(self):
        return "MismatchedTreeNodeException(%r!=%r)" % (
            self.getUnexpectedType(), self.expecting
            )
    __repr__ = __str__
