text: /* 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
  