﻿/* 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 "RuleContext.h"
#include "support/CPPUtils.h"

namespace antlr4 {

  /// <summary>
  /// A rule invocation record for parsing.
  ///
  ///  Contains all of the information about the current rule not stored in the
  ///  RuleContext. It handles parse tree children list, Any ATN state
  ///  tracing, and the default values available for rule invocatons:
  ///  start, stop, rule index, current alt number.
  ///
  ///  Subclasses made for each rule and grammar track the parameters,
  ///  return values, locals, and labels specific to that rule. These
  ///  are the objects that are returned from rules.
  ///
  ///  Note text is not an actual field of a rule return value; it is computed
  ///  from start and stop using the input stream's toString() method.  I
  ///  could add a ctor to this so that we can pass in and store the input
  ///  stream, but I'm not sure we want to do that.  It would seem to be undefined
  ///  to get the .text property anyway if the rule matches tokens from multiple
  ///  input streams.
  ///
  ///  I do not use getters for fields of objects that are used simply to
  ///  group values such as this aggregate.  The getters/setters are there to
  ///  satisfy the superclass interface.
  /// </summary>
  class ANTLR4CPP_PUBLIC ParserRuleContext : public RuleContext {
  public:
    static ParserRuleContext EMPTY;

    /// <summary>
    /// For debugging/tracing purposes, we want to track all of the nodes in
    ///  the ATN traversed by the parser for a particular rule.
    ///  This list indicates the sequence of ATN nodes used to match
    ///  the elements of the children list. This list does not include
    ///  ATN nodes and other rules used to match rule invocations. It
    ///  traces the rule invocation node itself but nothing inside that
    ///  other rule's ATN submachine.
    ///
    ///  There is NOT a one-to-one correspondence between the children and
    ///  states list. There are typically many nodes in the ATN traversed
    ///  for each element in the children list. For example, for a rule
    ///  invocation there is the invoking state and the following state.
    ///
    ///  The parser setState() method updates field s and adds it to this list
    ///  if we are debugging/tracing.
    ///
    ///  This does not trace states visited during prediction.
    /// </summary>
    //	public List<Integer> states;

    Token *start;
    Token *stop;

    /// The exception that forced this rule to return. If the rule successfully
    /// completed, this is "null exception pointer".
    std::exception_ptr exception;

    ParserRuleContext();
    ParserRuleContext(ParserRuleContext *parent, size_t invokingStateNumber);
    virtual ~ParserRuleContext() {}

    /** COPY a ctx (I'm deliberately not using copy constructor) to avoid
     *  confusion with creating node with parent. Does not copy children
     *  (except error leaves).
     */
    virtual void copyFrom(ParserRuleContext *ctx);


    // Double dispatch methods for listeners

    virtual void enterRule(tree::ParseTreeListener *listener);
    virtual void exitRule(tree::ParseTreeListener *listener);

    /** Add a token leaf node child and force its parent to be this node. */
    tree::TerminalNode* addChild(tree::TerminalNode *t);
    RuleContext* addChild(RuleContext *ruleInvocation);

    /// Used by enterOuterAlt to toss out a RuleContext previously added as
    /// we entered a rule. If we have # label, we will need to remove
    /// generic ruleContext object.
    virtual void removeLastChild();

    virtual tree::TerminalNode* getToken(size_t ttype, std::size_t i);

    virtual std::vector<tree::TerminalNode *> getTokens(size_t ttype);

    template<typename T>
    T* getRuleContext(size_t i) {
      if (children.empty()) {
        return nullptr;
      }

      size_t j = 0; // what element have we found with ctxType?
      for (auto &child : children) {
        if (antlrcpp::is<T *>(child)) {
          if (j++ == i) {
            return dynamic_cast<T *>(child);
          }
        }
      }
      return nullptr;
    }

    template<typename T>
    std::vector<T *> getRuleContexts() {
      std::vector<T *> contexts;
      for (auto *child : children) {
        if (antlrcpp::is<T *>(child)) {
          contexts.push_back(dynamic_cast<T *>(child));
        }
      }

      return contexts;
    }

    virtual misc::Interval getSourceInterval() override;

    /**
     * Get the initial token in this context.
     * Note that the range from start to stop is inclusive, so for rules that do not consume anything
     * (for example, zero length or error productions) this token may exceed stop.
     */
    virtual Token *getStart();

    /**
     * Get the final token in this context.
     * Note that the range from start to stop is inclusive, so for rules that do not consume anything
     * (for example, zero length or error productions) this token may precede start.
     */
    virtual Token *getStop();

    /// <summary>
    /// Used for rule context info debugging during parse-time, not so much for ATN debugging </summary>
    virtual std::string toInfoString(Parser *recognizer);
  };

} // namespace antlr4
