/**
   * It is called when parser enters grammar rule (typedef), it perform validations and updates the
   * data model tree.
   *
   * @param listener listener's object
   * @param ctx context object of the grammar rule
   */
  public static void processTypeDefEntry(
      TreeWalkListener listener, GeneratedYangParser.TypedefStatementContext ctx) {

    // Check for stack to be non empty.
    checkStackIsNotEmpty(listener, MISSING_HOLDER, TYPEDEF_DATA, ctx.identifier().getText(), ENTRY);

    String identifier = getValidIdentifier(ctx.identifier().getText(), TYPEDEF_DATA, ctx);

    // Validate sub statement cardinality.
    validateSubStatementsCardinality(ctx);

    /*
     * Create a derived type information, the base type must be set in type
     * listener.
     */
    YangTypeDef typeDefNode = getYangTypeDefNode(JAVA_GENERATION);
    typeDefNode.setName(identifier);

    Parsable curData = listener.getParsedDataStack().peek();

    if (curData instanceof YangModule
        || curData instanceof YangSubModule
        || curData instanceof YangContainer
        || curData instanceof YangList
        || curData instanceof YangNotification
        || curData instanceof YangRpc
        || curData instanceof YangInput
        || curData instanceof YangOutput
        || curData instanceof YangGrouping) {

      YangNode curNode = (YangNode) curData;
      try {
        curNode.addChild(typeDefNode);
      } catch (DataModelException e) {
        throw new ParserException(
            constructExtendedListenerErrorMessage(
                UNHANDLED_PARSED_DATA,
                TYPEDEF_DATA,
                ctx.identifier().getText(),
                ENTRY,
                e.getMessage()));
      }
      listener.getParsedDataStack().push(typeDefNode);
    } else {
      throw new ParserException(
          constructListenerErrorMessage(
              INVALID_HOLDER, TYPEDEF_DATA, ctx.identifier().getText(), ENTRY));
    }
  }
  /**
   * It is called when parser exits from grammar rule (typedef), it perform validations and updates
   * the data model tree.
   *
   * @param listener listener's object
   * @param ctx context object of the grammar rule
   */
  public static void processTypeDefExit(
      TreeWalkListener listener, GeneratedYangParser.TypedefStatementContext ctx) {

    // Check for stack to be non empty.
    checkStackIsNotEmpty(listener, MISSING_HOLDER, TYPEDEF_DATA, ctx.identifier().getText(), EXIT);

    if (listener.getParsedDataStack().peek() instanceof YangTypeDef) {
      YangTypeDef typeDefNode = (YangTypeDef) listener.getParsedDataStack().peek();
      try {
        typeDefNode.validateDataOnExit();
      } catch (DataModelException e) {
        throw new ParserException(
            constructListenerErrorMessage(
                INVALID_CONTENT, TYPEDEF_DATA, ctx.identifier().getText(), EXIT));
      }

      listener.getParsedDataStack().pop();
    } else {
      throw new ParserException(
          constructListenerErrorMessage(
              MISSING_CURRENT_HOLDER, TYPEDEF_DATA, ctx.identifier().getText(), EXIT));
    }
  }