﻿/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
 * Use of this file is governed by the BSD 3-clause license that
 * can be found in the LICENSE.txt file in the project root.
 */

#pragma once

#include "Recognizer.h"
#include "tree/ParseTreeListener.h"
#include "tree/ParseTree.h"
#include "TokenStream.h"
#include "TokenSource.h"
#include "misc/Interval.h"

namespace antlr4 {

  /// This is all the parsing support code essentially; most of it is error recovery stuff.
  class ANTLR4CPP_PUBLIC Parser : public Recognizer {
  public:

    class TraceListener : public tree::ParseTreeListener {
    public:
      TraceListener(Parser *outerInstance);
      virtual ~TraceListener();

      virtual void enterEveryRule(ParserRuleContext *ctx) override;
      virtual void visitTerminal(tree::TerminalNode *node) override;
      virtual void visitErrorNode(tree::ErrorNode *node) override;
      virtual void exitEveryRule(ParserRuleContext *ctx) override;

    private:
      Parser *const outerInstance;
    };

    class TrimToSizeListener : public tree::ParseTreeListener {
    public:
      static TrimToSizeListener INSTANCE;

      virtual ~TrimToSizeListener();

      virtual void enterEveryRule(ParserRuleContext *ctx) override;
      virtual void visitTerminal(tree::TerminalNode *node) override;
      virtual void visitErrorNode(tree::ErrorNode *node) override;
      virtual void exitEveryRule(ParserRuleContext *ctx) override;
    };

    Parser(TokenStream *input);
    virtual ~Parser();

    /// reset the parser's state
    virtual void reset();

    /// <summary>
    /// Match current input symbol against {@code ttype}. If the symbol type
    /// matches, <seealso cref="ANTLRErrorStrategy#reportMatch"/> and <seealso cref="#consume"/> are
    /// called to complete the match process.
    ///
    /// If the symbol type does not match,
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is called on the current error
    /// strategy to attempt recovery. If <seealso cref="#getBuildParseTree"/> is
    /// {@code true} and the token index of the symbol returned by
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is -1, the symbol is added to
    /// the parse tree by calling {@link #createErrorNode(ParserRuleContext, Token)} then
    /// {@link ParserRuleContext#addErrorNode(ErrorNode)}.
    /// </summary>
    /// <param name="ttype"> the token type to match </param>
    /// <returns> the matched symbol </returns>
    /// <exception cref="RecognitionException"> if the current input symbol did not match
    /// {@code ttype} and the error strategy could not recover from the
    /// mismatched symbol </exception>
    virtual Token* match(size_t ttype);

    /// <summary>
    /// Match current input symbol as a wildcard. If the symbol type matches
    /// (i.e. has a value greater than 0), <seealso cref="ANTLRErrorStrategy#reportMatch"/>
    /// and <seealso cref="#consume"/> are called to complete the match process.
    /// <p/>
    /// If the symbol type does not match,
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is called on the current error
    /// strategy to attempt recovery. If <seealso cref="#getBuildParseTree"/> is
    /// {@code true} and the token index of the symbol returned by
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is -1, the symbol is added to
    /// the parse tree by calling <seealso cref="ParserRuleContext#addErrorNode"/>.
    /// </summary>
    /// <returns> the matched symbol </returns>
    /// <exception cref="RecognitionException"> if the current input symbol did not match
    /// a wildcard and the error strategy could not recover from the mismatched
    /// symbol </exception>
    virtual Token* matchWildcard();

    /// <summary>
    /// Track the <seealso cref="ParserRuleContext"/> objects during the parse and hook
    /// them up using the <seealso cref="ParserRuleContext#children"/> list so that it
    /// forms a parse tree. The <seealso cref="ParserRuleContext"/> returned from the start
    /// rule represents the root of the parse tree.
    /// <p/>
    /// Note that if we are not building parse trees, rule contexts only point
    /// upwards. When a rule exits, it returns the context but that gets garbage
    /// collected if nobody holds a reference. It points upwards but nobody
    /// points at it.
    /// <p/>
    /// When we build parse trees, we are adding all of these contexts to
    /// <seealso cref="ParserRuleContext#children"/> list. Contexts are then not candidates
    /// for garbage collection.
    /// </summary>
    virtual void setBuildParseTree(bool buildParseTrees);

    /// <summary>
    /// Gets whether or not a complete parse tree will be constructed while
    /// parsing. This property is {@code true} for a newly constructed parser.
    /// </summary>
    /// <returns> {@code true} if a complete parse tree will be constructed while
    /// parsing, otherwise {@code false} </returns>
    virtual bool getBuildParseTree();

    /// <summary>
    /// Trim the internal lists of the parse tree during parsing to conserve memory.
    /// This property is set to {@code false} by default for a newly constructed parser.
    /// </summary>
    /// <param name="trimParseTrees"> {@code true} to trim the capacity of the <seealso cref="ParserRuleContext#children"/>
    /// list to its size after a rule is parsed. </param>
    virtual void setTrimParseTree(bool trimParseTrees);

    /// <returns> {@code true} if the <seealso cref="ParserRuleContext#children"/> list is trimmed
    /// using the default <seealso cref="Parser.TrimToSizeListener"/> during the parse process. </returns>
    virtual bool getTrimParseTree();

    virtual std::vector<tree::ParseTreeListener *> getParseListeners();

    /// <summary>
    /// Registers {@code listener} to receive events during the parsing process.
    /// <p/>
    /// To support output-preserving grammar transformations (including but not
    /// limited to left-recursion removal, automated left-factoring, and
    /// optimized code generation), calls to listener methods during the parse
    /// may differ substantially from calls made by
    /// <seealso cref="ParseTreeWalker#DEFAULT"/> used after the parse is complete. In
    /// particular, rule entry and exit events may occur in a different order
    /// during the parse than after the parser. In addition, calls to certain
    /// rule entry methods may be omitted.
    /// <p/>
    /// With the following specific exceptions, calls to listener events are
    /// <em>deterministic</em>, i.e. for identical input the calls to listener
    /// methods will be the same.
    ///
    /// <ul>
    /// <li>Alterations to the grammar used to generate code may change the
    /// behavior of the listener calls.</li>
    /// <li>Alterations to the command line options passed to ANTLR 4 when
    /// generating the parser may change the behavior of the listener calls.</li>
    /// <li>Changing the version of the ANTLR Tool used to generate the parser
    /// may change the behavior of the listener calls.</li>
    /// </ul>
    /// </summary>
    /// <param name="listener"> the listener to add
    /// </param>
    /// <exception cref="NullPointerException"> if {@code} listener is {@code null} </exception>
    virtual void addParseListener(tree::ParseTreeListener *listener);

    /// <summary>
    /// Remove {@code listener} from the list of parse listeners.
    /// <p/>
    /// If {@code listener} is {@code null} or has not been added as a parse
    /// listener, this method does nothing.
    /// </summary>
    /// <seealso cref= #addParseListener
    /// </seealso>
    /// <param name="listener"> the listener to remove </param>
    virtual void removeParseListener(tree::ParseTreeListener *listener);

    /// <summary>
    /// Remove all parse listeners.
    /// </summary>
    /// <seealso cref= #addParseListener </seealso>
    virtual void removeParseListeners();

    /// <summary>
    /// Notify any parse listeners of an enter rule event.
    /// </summary>
    /// <seealso cref= #addParseListener </seealso>
    virtual void triggerEnterRuleEvent();

    /// <summary>
    /// Notify any parse listeners of an exit rule event.
    /// </summary>
    /// <seealso cref= #addParseListener </seealso>
    virtual void triggerExitRuleEvent();

    /// <summary>
    /// Gets the number of syntax errors reported during parsing. This value is
    /// incremented each time <seealso cref="#notifyErrorListeners"/> is called.
    /// </summary>
    /// <seealso cref= #notifyErrorListeners </seealso>
    virtual size_t getNumberOfSyntaxErrors();

    virtual TokenFactory<CommonToken>* getTokenFactory() override;

    /// <summary>
    /// Tell our token source and error strategy about a new way to create tokens. </summary>
    template<typename T1>
    void setTokenFactory(TokenFactory<T1> *factory)  {
      _input->getTokenSource()->setTokenFactory(factory);
    }

    /// The ATN with bypass alternatives is expensive to create so we create it
    /// lazily. The ATN is owned by us.
    virtual const atn::ATN& getATNWithBypassAlts();

    /// <summary>
    /// The preferred method of getting a tree pattern. For example, here's a
    /// sample use:
    ///
    /// <pre>
    /// ParseTree t = parser.expr();
    /// ParseTreePattern p = parser.compileParseTreePattern("<ID>+0", MyParser.RULE_expr);
    /// ParseTreeMatch m = p.match(t);
    /// String id = m.get("ID");
    /// </pre>
    /// </summary>
    virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::string &pattern, int patternRuleIndex);

    /// <summary>
    /// The same as <seealso cref="#compileParseTreePattern(String, int)"/> but specify a
    /// <seealso cref="Lexer"/> rather than trying to deduce it from this parser.
    /// </summary>
    virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::string &pattern, int patternRuleIndex,
                                                                    Lexer *lexer);

    virtual Ref<ANTLRErrorStrategy> getErrorHandler();
    virtual void setErrorHandler(Ref<ANTLRErrorStrategy> const& handler);

    virtual IntStream* getInputStream() override;
    void setInputStream(IntStream *input) override;

    virtual TokenStream* getTokenStream();

    /// Set the token stream and reset the parser.
    virtual void setTokenStream(TokenStream *input);

    /// <summary>
    /// Match needs to return the current input symbol, which gets put
    ///  into the label for the associated token ref; e.g., x=ID.
    /// </summary>
    virtual Token* getCurrentToken();

    void notifyErrorListeners(const std::string &msg);

    virtual void notifyErrorListeners(Token *offendingToken, const std::string &msg, std::exception_ptr e);

    /// Consume and return the <seealso cref="#getCurrentToken current symbol"/>.
    /// <p/>
    /// E.g., given the following input with {@code A} being the current
    /// lookahead symbol, this function moves the cursor to {@code B} and returns
    /// {@code A}.
    ///
    /// <pre>
    ///  A B
    ///  ^
    /// </pre>
    ///
    /// If the parser is not in error recovery mode, the consumed symbol is added
    /// to the parse tree using <seealso cref="ParserRuleContext#addChild(TerminalNode)"/>, and
    /// <seealso cref="ParseTreeListener#visitTerminal"/> is called on any parse listeners.
    /// If the parser <em>is</em> in error recovery mode, the consumed symbol is
    /// added to the parse tree using {@link #createErrorNode(ParserRuleContext, Token)} then
    /// {@link ParserRuleContext#addErrorNode(ErrorNode)} and
    /// <seealso cref="ParseTreeListener#visitErrorNode"/> is called on any parse
    /// listeners.
    virtual Token* consume();

    /// Always called by generated parsers upon entry to a rule. Access field
    /// <seealso cref="#_ctx"/> get the current context.
    virtual void enterRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex);

    void exitRule();

    virtual void enterOuterAlt(ParserRuleContext *localctx, size_t altNum);

    /**
     * Get the precedence level for the top-most precedence rule.
     *
     * @return The precedence level for the top-most precedence rule, or -1 if
     * the parser context is not nested within a precedence rule.
     */
    int getPrecedence() const;

    /// @deprecated Use
    /// <seealso cref="#enterRecursionRule(ParserRuleContext, int, int, int)"/> instead.
    virtual void enterRecursionRule(ParserRuleContext *localctx, size_t ruleIndex);
    virtual void enterRecursionRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex, int precedence);

    /** Like {@link #enterRule} but for recursive rules.
     *  Make the current context the child of the incoming localctx.
     */
    virtual void pushNewRecursionContext(ParserRuleContext *localctx, size_t state, size_t ruleIndex);
    virtual void unrollRecursionContexts(ParserRuleContext *parentctx);
    virtual ParserRuleContext* getInvokingContext(size_t ruleIndex);
    virtual ParserRuleContext* getContext();
    virtual void setContext(ParserRuleContext *ctx);
    virtual bool precpred(RuleContext *localctx, int precedence) override;
    virtual bool inContext(const std::string &context);

    /// <summary>
    /// Checks whether or not {@code symbol} can follow the current state in the
    /// ATN. The behavior of this method is equivalent to the following, but is
    /// implemented such that the complete context-sensitive follow set does not
    /// need to be explicitly constructed.
    ///
    /// <pre>
    /// return getExpectedTokens().contains(symbol);
    /// </pre>
    /// </summary>
    /// <param name="symbol"> the symbol type to check </param>
    /// <returns> {@code true} if {@code symbol} can follow the current state in
    /// the ATN, otherwise {@code false}. </returns>
    virtual bool isExpectedToken(size_t symbol);

    bool isMatchedEOF() const;

    /// <summary>
    /// Computes the set of input symbols which could follow the current parser
    /// state and context, as given by <seealso cref="#getState"/> and <seealso cref="#getContext"/>,
    /// respectively.
    /// </summary>
    /// <seealso cref= ATN#getExpectedTokens(int, RuleContext) </seealso>
    virtual misc::IntervalSet getExpectedTokens();

    virtual misc::IntervalSet getExpectedTokensWithinCurrentRule();

    /// Get a rule's index (i.e., {@code RULE_ruleName} field) or INVALID_INDEX if not found.
    virtual size_t getRuleIndex(const std::string &ruleName);

    virtual ParserRuleContext* getRuleContext();

    /// <summary>
    /// Return List&lt;String&gt; of the rule names in your parser instance
    ///  leading up to a call to the current rule.  You could override if
    ///  you want more details such as the file/line info of where
    ///  in the ATN a rule is invoked.
    ///
    ///  This is very useful for error messages.
    /// </summary>
    virtual std::vector<std::string> getRuleInvocationStack();

    virtual std::vector<std::string> getRuleInvocationStack(RuleContext *p);

    /// <summary>
    /// For debugging and other purposes. </summary>
    virtual std::vector<std::string> getDFAStrings();

    /// <summary>
    /// For debugging and other purposes. </summary>
    virtual void dumpDFA();

    virtual std::string getSourceName();

    atn::ParseInfo getParseInfo() const;

    /**
     * @since 4.3
     */
    void setProfile(bool profile);

    /// <summary>
    /// During a parse is sometimes useful to listen in on the rule entry and exit
    ///  events as well as token matches. This is for quick and dirty debugging.
    /// </summary>
    virtual void setTrace(bool trace);

    /**
     * Gets whether a {@link TraceListener} is registered as a parse listener
     * for the parser.
     *
     * @see #setTrace(boolean)
     */
    bool isTrace() const;

    tree::ParseTreeTracker& getTreeTracker() { return _tracker; }

    /** How to create a token leaf node associated with a parent.
     *  Typically, the terminal node to create is not a function of the parent
     *  but this method must still set the parent pointer of the terminal node
     *  returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)}
     *  set the parent pointer, but the parent pointer is implementation dependent
     *  and currently there is no setParent() in {@link TerminalNode} (and can't
     *  add method in Java 1.7 without breaking backward compatibility).
     *
     * @since 4.7
     */
    tree::TerminalNode *createTerminalNode(Token *t);

    /** How to create an error node, given a token, associated with a parent.
       *  Typically, the error node to create is not a function of the parent
       *  but this method must still set the parent pointer of the terminal node
       *  returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)}
       *  set the parent pointer, but the parent pointer is implementation dependent
       *  and currently there is no setParent() in {@link ErrorNode} (and can't
       *  add method in Java 1.7 without breaking backward compatibility).
       *
       * @since 4.7
       */
    tree::ErrorNode *createErrorNode(Token *t);

  protected:
    /// The ParserRuleContext object for the currently executing rule.
    /// This is always non-null during the parsing process.
    // ml: this is one of the contexts tracked in _allocatedContexts.
    ParserRuleContext *_ctx;

    /// The error handling strategy for the parser. The default is DefaultErrorStrategy.
    /// See also getErrorHandler.
    Ref<ANTLRErrorStrategy> _errHandler;

    /// <summary>
    /// The input stream.
    /// </summary>
    /// <seealso cref= #getInputStream </seealso>
    /// <seealso cref= #setInputStream </seealso>
    TokenStream *_input;

    std::vector<int> _precedenceStack;

    /// <summary>
    /// Specifies whether or not the parser should construct a parse tree during
    /// the parsing process. The default value is {@code true}.
    /// </summary>
    /// <seealso cref= #getBuildParseTree </seealso>
    /// <seealso cref= #setBuildParseTree </seealso>
    bool _buildParseTrees;

    /// The list of <seealso cref="ParseTreeListener"/> listeners registered to receive
    /// events during the parse.
    /// <seealso cref= #addParseListener </seealso>
    std::vector<tree::ParseTreeListener *> _parseListeners;

    /// <summary>
    /// The number of syntax errors reported during parsing. This value is
    /// incremented each time <seealso cref="#notifyErrorListeners"/> is called.
    /// </summary>
    size_t _syntaxErrors;

    /** Indicates parser has match()ed EOF token. See {@link #exitRule()}. */
    bool _matchedEOF;

    virtual void addContextToParseTree();

    // All rule contexts created during a parse run. This is cleared when calling reset().
    tree::ParseTreeTracker _tracker;

  private:
    /// This field maps from the serialized ATN string to the deserialized <seealso cref="ATN"/> with
    /// bypass alternatives.
    ///
    /// <seealso cref= ATNDeserializationOptions#isGenerateRuleBypassTransitions() </seealso>
    static std::map<std::vector<uint16_t>, atn::ATN> bypassAltsAtnCache;

    /// When setTrace(true) is called, a reference to the
    /// TraceListener is stored here so it can be easily removed in a
    /// later call to setTrace(false). The listener itself is
    /// implemented as a parser listener so this field is not directly used by
    /// other parser methods.
    TraceListener *_tracer;

    void InitializeInstanceFields();
  };

} // namespace antlr4
