//generated by abstract-syntax-gen
package de.peeeq.wurstscript.jassAst;
import java.util.*;

public interface Element {
    Element getParent();
    Element copy();
    Element copyWithRefs();
    int size();
    void clearAttributes();
    void clearAttributesLocal();
    Element get(int i);
    Element set(int i, Element newElement);
    void forEachElement(java.util.function.Consumer<? super Element> action);
    default void trimToSize() {        forEachElement(Element::trimToSize);    }    void setParent(Element parent);
    void replaceBy(Element other);
    boolean structuralEquals(Element elem);
    default List<Integer> pathTo(Element  elem) {
        List<Integer> path = new ArrayList<>();
        while (elem != this) {
            if (elem == null) {
                throw new RuntimeException("Element " + elem + " is not a parent of " + this);
            }
            Element parent = elem.getParent();
            for (int i = 0; i < parent.size(); i++) {
                if (parent.get(i) == elem) {
                    path.add(i);
                    break;
                }
            }
            elem = parent;
        }
        Collections.reverse(path);
        return path;
    }

    default Element followPath(Iterable<Integer> path) {
        Element elem = this;
        for (Integer i : path) {
            elem = elem.get(i);
        }
        return elem;
    }
    <T> T match(Matcher<T> s);
    void match(MatcherVoid s);
    public interface Matcher<T> {
        T case_JassVars(JassVars jassVars);
        T case_JassOpDiv(JassOpDiv jassOpDiv);
        T case_JassInitializedVar(JassInitializedVar jassInitializedVar);
        T case_JassStmtLoop(JassStmtLoop jassStmtLoop);
        T case_JassOpPlus(JassOpPlus jassOpPlus);
        T case_JassExprUnary(JassExprUnary jassExprUnary);
        T case_JassArrayVar(JassArrayVar jassArrayVar);
        T case_JassOpGreaterEq(JassOpGreaterEq jassOpGreaterEq);
        T case_JassOpNot(JassOpNot jassOpNot);
        T case_JassStmtReturn(JassStmtReturn jassStmtReturn);
        T case_JassProgs(JassProgs jassProgs);
        T case_JassNative(JassNative jassNative);
        T case_JassExprStringVal(JassExprStringVal jassExprStringVal);
        T case_JassSimpleVars(JassSimpleVars jassSimpleVars);
        T case_JassExprRealVal(JassExprRealVal jassExprRealVal);
        T case_JassFunction(JassFunction jassFunction);
        T case_JassExprVarArrayAccess(JassExprVarArrayAccess jassExprVarArrayAccess);
        T case_JassExprFunctionCall(JassExprFunctionCall jassExprFunctionCall);
        T case_JassProg(JassProg jassProg);
        T case_JassOpLess(JassOpLess jassOpLess);
        T case_JassOpMinus(JassOpMinus jassOpMinus);
        T case_JassStmtIf(JassStmtIf jassStmtIf);
        T case_JassExprBoolVal(JassExprBoolVal jassExprBoolVal);
        T case_JassStmtExitwhen(JassStmtExitwhen jassStmtExitwhen);
        T case_JassStatements(JassStatements jassStatements);
        T case_JassStmtCall(JassStmtCall jassStmtCall);
        T case_JassOpMult(JassOpMult jassOpMult);
        T case_JassOpGreater(JassOpGreater jassOpGreater);
        T case_JassExprBinary(JassExprBinary jassExprBinary);
        T case_JassNatives(JassNatives jassNatives);
        T case_JassFunctions(JassFunctions jassFunctions);
        T case_JassExprFuncRef(JassExprFuncRef jassExprFuncRef);
        T case_JassOpEquals(JassOpEquals jassOpEquals);
        T case_JassExprIntVal(JassExprIntVal jassExprIntVal);
        T case_JassExprNull(JassExprNull jassExprNull);
        T case_JassOpOr(JassOpOr jassOpOr);
        T case_JassOpLessEq(JassOpLessEq jassOpLessEq);
        T case_JassOpAnd(JassOpAnd jassOpAnd);
        T case_JassExprlist(JassExprlist jassExprlist);
        T case_JassStmtSetArray(JassStmtSetArray jassStmtSetArray);
        T case_JassExprVarAccess(JassExprVarAccess jassExprVarAccess);
        T case_JassTypeDef(JassTypeDef jassTypeDef);
        T case_JassSimpleVar(JassSimpleVar jassSimpleVar);
        T case_JassStmtSet(JassStmtSet jassStmtSet);
        T case_JassOpUnequals(JassOpUnequals jassOpUnequals);
        T case_JassTypeDefs(JassTypeDefs jassTypeDefs);
        T case_JassStmtReturnVoid(JassStmtReturnVoid jassStmtReturnVoid);
    }

    public interface MatcherVoid {
        void case_JassVars(JassVars jassVars);
        void case_JassOpDiv(JassOpDiv jassOpDiv);
        void case_JassInitializedVar(JassInitializedVar jassInitializedVar);
        void case_JassStmtLoop(JassStmtLoop jassStmtLoop);
        void case_JassOpPlus(JassOpPlus jassOpPlus);
        void case_JassExprUnary(JassExprUnary jassExprUnary);
        void case_JassArrayVar(JassArrayVar jassArrayVar);
        void case_JassOpGreaterEq(JassOpGreaterEq jassOpGreaterEq);
        void case_JassOpNot(JassOpNot jassOpNot);
        void case_JassStmtReturn(JassStmtReturn jassStmtReturn);
        void case_JassProgs(JassProgs jassProgs);
        void case_JassNative(JassNative jassNative);
        void case_JassExprStringVal(JassExprStringVal jassExprStringVal);
        void case_JassSimpleVars(JassSimpleVars jassSimpleVars);
        void case_JassExprRealVal(JassExprRealVal jassExprRealVal);
        void case_JassFunction(JassFunction jassFunction);
        void case_JassExprVarArrayAccess(JassExprVarArrayAccess jassExprVarArrayAccess);
        void case_JassExprFunctionCall(JassExprFunctionCall jassExprFunctionCall);
        void case_JassProg(JassProg jassProg);
        void case_JassOpLess(JassOpLess jassOpLess);
        void case_JassOpMinus(JassOpMinus jassOpMinus);
        void case_JassStmtIf(JassStmtIf jassStmtIf);
        void case_JassExprBoolVal(JassExprBoolVal jassExprBoolVal);
        void case_JassStmtExitwhen(JassStmtExitwhen jassStmtExitwhen);
        void case_JassStatements(JassStatements jassStatements);
        void case_JassStmtCall(JassStmtCall jassStmtCall);
        void case_JassOpMult(JassOpMult jassOpMult);
        void case_JassOpGreater(JassOpGreater jassOpGreater);
        void case_JassExprBinary(JassExprBinary jassExprBinary);
        void case_JassNatives(JassNatives jassNatives);
        void case_JassFunctions(JassFunctions jassFunctions);
        void case_JassExprFuncRef(JassExprFuncRef jassExprFuncRef);
        void case_JassOpEquals(JassOpEquals jassOpEquals);
        void case_JassExprIntVal(JassExprIntVal jassExprIntVal);
        void case_JassExprNull(JassExprNull jassExprNull);
        void case_JassOpOr(JassOpOr jassOpOr);
        void case_JassOpLessEq(JassOpLessEq jassOpLessEq);
        void case_JassOpAnd(JassOpAnd jassOpAnd);
        void case_JassExprlist(JassExprlist jassExprlist);
        void case_JassStmtSetArray(JassStmtSetArray jassStmtSetArray);
        void case_JassExprVarAccess(JassExprVarAccess jassExprVarAccess);
        void case_JassTypeDef(JassTypeDef jassTypeDef);
        void case_JassSimpleVar(JassSimpleVar jassSimpleVar);
        void case_JassStmtSet(JassStmtSet jassStmtSet);
        void case_JassOpUnequals(JassOpUnequals jassOpUnequals);
        void case_JassTypeDefs(JassTypeDefs jassTypeDefs);
        void case_JassStmtReturnVoid(JassStmtReturnVoid jassStmtReturnVoid);
    }

    public abstract void accept(Visitor v);
    public interface Visitor {
        void visit(JassProg jassProg);
        void visit(JassTypeDef jassTypeDef);
        void visit(JassNative jassNative);
        void visit(JassSimpleVar jassSimpleVar);
        void visit(JassArrayVar jassArrayVar);
        void visit(JassInitializedVar jassInitializedVar);
        void visit(JassFunction jassFunction);
        void visit(JassStmtIf jassStmtIf);
        void visit(JassStmtLoop jassStmtLoop);
        void visit(JassStmtSet jassStmtSet);
        void visit(JassStmtSetArray jassStmtSetArray);
        void visit(JassStmtCall jassStmtCall);
        void visit(JassStmtReturn jassStmtReturn);
        void visit(JassStmtReturnVoid jassStmtReturnVoid);
        void visit(JassStmtExitwhen jassStmtExitwhen);
        void visit(JassExprBinary jassExprBinary);
        void visit(JassExprUnary jassExprUnary);
        void visit(JassExprFunctionCall jassExprFunctionCall);
        void visit(JassExprIntVal jassExprIntVal);
        void visit(JassExprRealVal jassExprRealVal);
        void visit(JassExprStringVal jassExprStringVal);
        void visit(JassExprBoolVal jassExprBoolVal);
        void visit(JassExprFuncRef jassExprFuncRef);
        void visit(JassExprNull jassExprNull);
        void visit(JassExprVarAccess jassExprVarAccess);
        void visit(JassExprVarArrayAccess jassExprVarArrayAccess);
        void visit(JassOpOr jassOpOr);
        void visit(JassOpAnd jassOpAnd);
        void visit(JassOpEquals jassOpEquals);
        void visit(JassOpUnequals jassOpUnequals);
        void visit(JassOpLessEq jassOpLessEq);
        void visit(JassOpLess jassOpLess);
        void visit(JassOpGreaterEq jassOpGreaterEq);
        void visit(JassOpGreater jassOpGreater);
        void visit(JassOpPlus jassOpPlus);
        void visit(JassOpMinus jassOpMinus);
        void visit(JassOpMult jassOpMult);
        void visit(JassOpDiv jassOpDiv);
        void visit(JassOpNot jassOpNot);
        void visit(JassProgs jassProgs);
        void visit(JassNatives jassNatives);
        void visit(JassTypeDefs jassTypeDefs);
        void visit(JassVars jassVars);
        void visit(JassSimpleVars jassSimpleVars);
        void visit(JassFunctions jassFunctions);
        void visit(JassStatements jassStatements);
        void visit(JassExprlist jassExprlist);
    }
    public static abstract class DefaultVisitor implements Visitor {
        @Override public void visit(JassProg jassProg) {
          jassProg.getDefs().accept(this);
          jassProg.getGlobals().accept(this);
          jassProg.getNatives().accept(this);
          jassProg.getFunctions().accept(this);
     }
        @Override public void visit(JassTypeDef jassTypeDef) {
     }
        @Override public void visit(JassNative jassNative) {
          jassNative.getParams().accept(this);
     }
        @Override public void visit(JassSimpleVar jassSimpleVar) {
     }
        @Override public void visit(JassArrayVar jassArrayVar) {
     }
        @Override public void visit(JassInitializedVar jassInitializedVar) {
          jassInitializedVar.getVal().accept(this);
     }
        @Override public void visit(JassFunction jassFunction) {
          jassFunction.getParams().accept(this);
          jassFunction.getLocals().accept(this);
          jassFunction.getBody().accept(this);
     }
        @Override public void visit(JassStmtIf jassStmtIf) {
          jassStmtIf.getCond().accept(this);
          jassStmtIf.getThenBlock().accept(this);
          jassStmtIf.getElseBlock().accept(this);
     }
        @Override public void visit(JassStmtLoop jassStmtLoop) {
          jassStmtLoop.getBody().accept(this);
     }
        @Override public void visit(JassStmtSet jassStmtSet) {
          jassStmtSet.getRight().accept(this);
     }
        @Override public void visit(JassStmtSetArray jassStmtSetArray) {
          jassStmtSetArray.getIndex().accept(this);
          jassStmtSetArray.getRight().accept(this);
     }
        @Override public void visit(JassStmtCall jassStmtCall) {
          jassStmtCall.getArguments().accept(this);
     }
        @Override public void visit(JassStmtReturn jassStmtReturn) {
          jassStmtReturn.getReturnValue().accept(this);
     }
        @Override public void visit(JassStmtReturnVoid jassStmtReturnVoid) {
     }
        @Override public void visit(JassStmtExitwhen jassStmtExitwhen) {
          jassStmtExitwhen.getCond().accept(this);
     }
        @Override public void visit(JassExprBinary jassExprBinary) {
          jassExprBinary.getLeftExpr().accept(this);
          jassExprBinary.getOp().accept(this);
          jassExprBinary.getRight().accept(this);
     }
        @Override public void visit(JassExprUnary jassExprUnary) {
          jassExprUnary.getOpU().accept(this);
          jassExprUnary.getRight().accept(this);
     }
        @Override public void visit(JassExprFunctionCall jassExprFunctionCall) {
          jassExprFunctionCall.getArguments().accept(this);
     }
        @Override public void visit(JassExprIntVal jassExprIntVal) {
     }
        @Override public void visit(JassExprRealVal jassExprRealVal) {
     }
        @Override public void visit(JassExprStringVal jassExprStringVal) {
     }
        @Override public void visit(JassExprBoolVal jassExprBoolVal) {
     }
        @Override public void visit(JassExprFuncRef jassExprFuncRef) {
     }
        @Override public void visit(JassExprNull jassExprNull) {
     }
        @Override public void visit(JassExprVarAccess jassExprVarAccess) {
     }
        @Override public void visit(JassExprVarArrayAccess jassExprVarArrayAccess) {
          jassExprVarArrayAccess.getIndex().accept(this);
     }
        @Override public void visit(JassOpOr jassOpOr) {
     }
        @Override public void visit(JassOpAnd jassOpAnd) {
     }
        @Override public void visit(JassOpEquals jassOpEquals) {
     }
        @Override public void visit(JassOpUnequals jassOpUnequals) {
     }
        @Override public void visit(JassOpLessEq jassOpLessEq) {
     }
        @Override public void visit(JassOpLess jassOpLess) {
     }
        @Override public void visit(JassOpGreaterEq jassOpGreaterEq) {
     }
        @Override public void visit(JassOpGreater jassOpGreater) {
     }
        @Override public void visit(JassOpPlus jassOpPlus) {
     }
        @Override public void visit(JassOpMinus jassOpMinus) {
     }
        @Override public void visit(JassOpMult jassOpMult) {
     }
        @Override public void visit(JassOpDiv jassOpDiv) {
     }
        @Override public void visit(JassOpNot jassOpNot) {
     }
        @Override public void visit(JassProgs jassProgs) {
          for (JassProg i : jassProgs ) {
              i.accept(this);
          }
     }
        @Override public void visit(JassNatives jassNatives) {
          for (JassNative i : jassNatives ) {
              i.accept(this);
          }
     }
        @Override public void visit(JassTypeDefs jassTypeDefs) {
          for (JassTypeDef i : jassTypeDefs ) {
              i.accept(this);
          }
     }
        @Override public void visit(JassVars jassVars) {
          for (JassVar i : jassVars ) {
              i.accept(this);
          }
     }
        @Override public void visit(JassSimpleVars jassSimpleVars) {
          for (JassSimpleVar i : jassSimpleVars ) {
              i.accept(this);
          }
     }
        @Override public void visit(JassFunctions jassFunctions) {
          for (JassFunction i : jassFunctions ) {
              i.accept(this);
          }
     }
        @Override public void visit(JassStatements jassStatements) {
          for (JassStatement i : jassStatements ) {
              i.accept(this);
          }
     }
        @Override public void visit(JassExprlist jassExprlist) {
          for (JassExpr i : jassExprlist ) {
              i.accept(this);
          }
     }
    }
    /** */
    public abstract int getLine();
    /** */
    public abstract JassProg getProg();
}