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

@SuppressWarnings({"cast", "unused", "rawtypes"})
class ExprEmptyImpl implements ExprEmpty{
    ExprEmptyImpl(de.peeeq.wurstscript.parser.WPos source) {
        if (source == null)
            throw new IllegalArgumentException("Element source must not be null.");
        this.source = source;
    }

    private Element parent;
    public Element getParent() { return parent; }
    public void setParent(Element parent) {
        if (parent != null && this.parent != null) {
            throw new Error("Cannot change parent of element " + this.getClass().getSimpleName() + ", as it is already used in another tree."
                + "Use the copy method to create a new tree or remove the tree from its old parent or set the parent to null before moving the tree. ");
        }
        this.parent = parent;
    }

    public void replaceBy(Element other) {
        if (parent == null)
            throw new RuntimeException("Node not attached to tree.");
        for (int i=0; i<parent.size(); i++) {
            if (parent.get(i) == this) {
                parent.set(i, other);
                return;
            }
        }
    }

    private de.peeeq.wurstscript.parser.WPos source;
    public void setSource(de.peeeq.wurstscript.parser.WPos source) {
        if (source == null) throw new IllegalArgumentException();
        this.source = source;
    } 
    public de.peeeq.wurstscript.parser.WPos getSource() { return source; }

    public Element get(int i) {
        switch (i) {
            default: throw new IllegalArgumentException("Index out of range: " + i);
        }
    }
    public Element set(int i, Element newElem) {
        Element oldElem;
        switch (i) {
            default: throw new IllegalArgumentException("Index out of range: " + i);
        }
    }

    @Override
    public void forEachElement(java.util.function.Consumer<? super Element> action) {
    }
    public int size() {
        return 0;
    }
    @Override public ExprEmpty copy() {
        ExprEmpty result = new ExprEmptyImpl(source);
        return result;
    }

    @Override public ExprEmpty copyWithRefs() {
        ExprEmpty res = copy();
        return res;
    }

    @Override public void clearAttributes() {
        clearAttributesLocal();
    }
    @Override public void clearAttributesLocal() {
        zzattr_attrReadVariables_state = 0;
        zzattr_attrTyp_state = 0;
        zzattr_attrConstantValue_state = 0;
        zzattr_attrTypRaw_state = 0;
        zzattr_attrExpectedTypRaw_state = 0;
        zzattr_attrExpectedTyp_state = 0;
        zzattr_attrUsedGlobalVariables_state = 0;
        zzattr_attrReadGlobalVariables_state = 0;
    }
    @Override public void accept(Visitor v) {
        v.visit(this);
    }
    @Override public <T> T match(VarInitialization.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(VarInitialization.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public <T> T match(HasReadVariables.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(HasReadVariables.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public <T> T match(ExprAtomic.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(ExprAtomic.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public <T> T match(Element.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(Element.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public <T> T match(OptExpr.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(OptExpr.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public <T> T match(Expr.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(Expr.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public <T> T match(AstElementWithSource.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(AstElementWithSource.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public <T> T match(ExprOrStatements.Matcher<T> matcher) {
        return matcher.case_ExprEmpty(this);
    }
    @Override public void match(ExprOrStatements.MatcherVoid matcher) {
        matcher.case_ExprEmpty(this);
    }

    @Override public String toString() {
        return "ExprEmpty(" + source+")";
    }
    public boolean structuralEquals(Element e) {
        if (e instanceof ExprEmpty) {
            ExprEmpty o = (ExprEmpty) e;
            return java.util.Objects.equals(source, o.getSource());
        } else {
            return false;
        }
    }
// circular = null
    private int zzattr_attrReadVariables_state = 0;
    private de.peeeq.immutablecollections.ImmutableList<NameDef> zzattr_attrReadVariables_cache;
    /** */
    public de.peeeq.immutablecollections.ImmutableList<NameDef> attrReadVariables() {
        if (zzattr_attrReadVariables_state == 0) {
            try {
                zzattr_attrReadVariables_state = 1;
                zzattr_attrReadVariables_cache = de.peeeq.wurstscript.attributes.ReadVariables.calculate((ExprEmpty)this);
            } finally {
                zzattr_attrReadVariables_state = 0;
            }
            zzattr_attrReadVariables_state = 2;
        } else if (zzattr_attrReadVariables_state == 1) {
            throw new CyclicDependencyError(this, "attrReadVariables");
        }
        return zzattr_attrReadVariables_cache;
    }
// circular = null
    private int zzattr_attrTyp_state = 0;
    private de.peeeq.wurstscript.types.WurstType zzattr_attrTyp_cache;
    /** */
    public de.peeeq.wurstscript.types.WurstType attrTyp() {
        if (zzattr_attrTyp_state == 0) {
            try {
                zzattr_attrTyp_state = 1;
                zzattr_attrTyp_cache = de.peeeq.wurstscript.attributes.AttrExprType.normalizedType((ExprEmpty)this);
            } finally {
                zzattr_attrTyp_state = 0;
            }
            zzattr_attrTyp_state = 2;
        } else if (zzattr_attrTyp_state == 1) {
            throw new CyclicDependencyError(this, "attrTyp");
        }
        return zzattr_attrTyp_cache;
    }
// circular = null
    private int zzattr_attrConstantValue_state = 0;
    private de.peeeq.wurstscript.intermediatelang.ILconst zzattr_attrConstantValue_cache;
    /** */
    public de.peeeq.wurstscript.intermediatelang.ILconst attrConstantValue() {
        if (zzattr_attrConstantValue_state == 0) {
            try {
                zzattr_attrConstantValue_state = 1;
                zzattr_attrConstantValue_cache = de.peeeq.wurstscript.attributes.AttrConstantValue.calculate((ExprEmpty)this);
            } finally {
                zzattr_attrConstantValue_state = 0;
            }
            zzattr_attrConstantValue_state = 2;
        } else if (zzattr_attrConstantValue_state == 1) {
            throw new CyclicDependencyError(this, "attrConstantValue");
        }
        return zzattr_attrConstantValue_cache;
    }
// circular = null
    private int zzattr_attrTypRaw_state = 0;
    private de.peeeq.wurstscript.types.WurstType zzattr_attrTypRaw_cache;
    /** */
    public de.peeeq.wurstscript.types.WurstType attrTypRaw() {
        if (zzattr_attrTypRaw_state == 0) {
            try {
                zzattr_attrTypRaw_state = 1;
                zzattr_attrTypRaw_cache = de.peeeq.wurstscript.attributes.AttrExprType.calculate((ExprEmpty)this);
            } finally {
                zzattr_attrTypRaw_state = 0;
            }
            zzattr_attrTypRaw_state = 2;
        } else if (zzattr_attrTypRaw_state == 1) {
            throw new CyclicDependencyError(this, "attrTypRaw");
        }
        return zzattr_attrTypRaw_cache;
    }
// circular = null
    private int zzattr_attrExpectedTypRaw_state = 0;
    private de.peeeq.wurstscript.types.WurstType zzattr_attrExpectedTypRaw_cache;
    /** */
    public de.peeeq.wurstscript.types.WurstType attrExpectedTypRaw() {
        if (zzattr_attrExpectedTypRaw_state == 0) {
            try {
                zzattr_attrExpectedTypRaw_state = 1;
                zzattr_attrExpectedTypRaw_cache = de.peeeq.wurstscript.attributes.AttrExprExpectedType.calculate((ExprEmpty)this);
            } finally {
                zzattr_attrExpectedTypRaw_state = 0;
            }
            zzattr_attrExpectedTypRaw_state = 2;
        } else if (zzattr_attrExpectedTypRaw_state == 1) {
            throw new CyclicDependencyError(this, "attrExpectedTypRaw");
        }
        return zzattr_attrExpectedTypRaw_cache;
    }
// circular = null
    private int zzattr_attrExpectedTyp_state = 0;
    private de.peeeq.wurstscript.types.WurstType zzattr_attrExpectedTyp_cache;
    /** "try to guess what type is expected here"*/
    public de.peeeq.wurstscript.types.WurstType attrExpectedTyp() {
        if (zzattr_attrExpectedTyp_state == 0) {
            try {
                zzattr_attrExpectedTyp_state = 1;
                zzattr_attrExpectedTyp_cache = de.peeeq.wurstscript.attributes.AttrExprExpectedType.normalizedType((ExprEmpty)this);
            } finally {
                zzattr_attrExpectedTyp_state = 0;
            }
            zzattr_attrExpectedTyp_state = 2;
        } else if (zzattr_attrExpectedTyp_state == 1) {
            throw new CyclicDependencyError(this, "attrExpectedTyp");
        }
        return zzattr_attrExpectedTyp_cache;
    }
    /** "more precise expected type, after overloading"*/
    public de.peeeq.wurstscript.types.WurstType attrExpectedTypAfterOverloading() {
        return de.peeeq.wurstscript.attributes.AttrExprExpectedType.afterOverloading((ExprEmpty)this);
    }
    /** */
    public boolean attrIsDynamicContext() {
        return de.peeeq.wurstscript.attributes.IsDynamicContext.calculate((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable PackageOrGlobal attrNearestPackage() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestPackage((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable NamedScope attrNearestNamedScope() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestNamedScope((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable WScope attrNearestScope() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestScope((ExprEmpty)this);
    }
    /** */
    public String attrPathDescription() {
        return de.peeeq.wurstscript.attributes.PathDescription.get((ExprEmpty)this);
    }
    /** */
    public CompilationUnit attrCompilationUnit() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestCompilationUnit((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassDef attrNearestClassDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassDef((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassOrInterface attrNearestClassOrInterface() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassOrInterface((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassOrModule attrNearestClassOrModule() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassOrModule((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable StructureDef attrNearestStructureDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestStructureDef((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable FunctionImplementation attrNearestFuncDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestFuncDef((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ExprClosure attrNearestExprClosure() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestExprClosure((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ExprStatementsBlock attrNearestExprStatementsBlock() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestExprStatementsBlock((ExprEmpty)this);
    }
    /** "returns the element itself if it is a NameDef or returns the referenced NameDef if the elem is a reference or returns null otherwise "*/
    public @org.eclipse.jdt.annotation.Nullable NameDef tryGetNameDef() {
        return de.peeeq.wurstscript.attributes.AttrNameDef.tryGetNameDef((ExprEmpty)this);
    }
    /** */
    public de.peeeq.wurstscript.parser.WPos attrSource() {
        return de.peeeq.wurstscript.attributes.AttrPos.getPos((ExprEmpty)this);
    }
    /** "returns the position where errors are marked"*/
    public de.peeeq.wurstscript.parser.WPos attrErrorPos() {
        return de.peeeq.wurstscript.attributes.AttrPos.getErrorPos((ExprEmpty)this);
    }
    /** */
    public WurstModel getModel() {
        return de.peeeq.wurstscript.attributes.AttrImportedPackage.getModel((ExprEmpty)this);
    }
    /** */
    public de.peeeq.wurstscript.jassIm.ImExpr imTranslateExpr(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator, de.peeeq.wurstscript.jassIm.ImFunction f) {
        return de.peeeq.wurstscript.translation.imtranslation.ExprTranslation.translate((ExprEmpty)this, translator, f);
    }
    /** */
    public de.peeeq.wurstscript.jassIm.ImExprOpt imTranslateExprOpt(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator, de.peeeq.wurstscript.jassIm.ImFunction f) {
        return de.peeeq.wurstscript.translation.imtranslation.ExprTranslation.translate((ExprEmpty)this, translator, f);
    }
    /** */
    public void addError(String msg) {
        de.peeeq.wurstscript.attributes.ErrorHandling.addError((ExprEmpty)this, msg);
    }
    /** */
    public void addWarning(String msg) {
        de.peeeq.wurstscript.attributes.ErrorHandling.addWarning((ExprEmpty)this, msg);
    }
    /** */
    public de.peeeq.wurstscript.attributes.ErrorHandler getErrorHandler() {
        return de.peeeq.wurstscript.attributes.ErrorHandling.getErrorHandler((ExprEmpty)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable TypeDef lookupType(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupType((ExprEmpty)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.PackageLink lookupPackage(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupPackage((ExprEmpty)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVar(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVar((ExprEmpty)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVarNoConfig(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVarNoConfig((ExprEmpty)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupMemberVar(de.peeeq.wurstscript.types.WurstType receiverType, String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupMemberVar((ExprEmpty)this, receiverType, name, showErrors);
    }
    /** */
    public com.google.common.collect.ImmutableCollection<de.peeeq.wurstscript.attributes.names.FuncLink> lookupFuncs(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupFuncs((ExprEmpty)this, name, showErrors);
    }
    /** */
    public com.google.common.collect.ImmutableCollection<de.peeeq.wurstscript.attributes.names.FuncLink> lookupFuncsNoConfig(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupFuncsNoConfig((ExprEmpty)this, name, showErrors);
    }
    /** */
    public com.google.common.collect.ImmutableCollection<de.peeeq.wurstscript.attributes.names.FuncLink> lookupMemberFuncs(de.peeeq.wurstscript.types.WurstType receiverType, String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupMemberFuncs((ExprEmpty)this, receiverType, name, showErrors);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable TypeDef lookupType(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupTypeShort((ExprEmpty)this, name);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.PackageLink lookupPackage(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupPackageShort((ExprEmpty)this, name);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVar(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVarShort((ExprEmpty)this, name);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupMemberVar(de.peeeq.wurstscript.types.WurstType receiverType, String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupMemberVarShort((ExprEmpty)this, receiverType, name);
    }
    /** */
    public com.google.common.collect.ImmutableCollection<de.peeeq.wurstscript.attributes.names.FuncLink> lookupFuncs(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupFuncsShort((ExprEmpty)this, name);
    }
    /** */
    public com.google.common.collect.ImmutableCollection<de.peeeq.wurstscript.attributes.names.FuncLink> lookupMemberFuncs(de.peeeq.wurstscript.types.WurstType receiverType, String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupMemberFuncsShort((ExprEmpty)this, receiverType, name);
    }
// circular = de.peeeq.wurstscript.utils.Utils.emptyList
    private int zzattr_attrUsedGlobalVariables_state = 0;
    private com.google.common.collect.ImmutableList<VarDef> zzattr_attrUsedGlobalVariables_cache;
    /** */
    public com.google.common.collect.ImmutableList<VarDef> attrUsedGlobalVariables() {
        if (zzattr_attrUsedGlobalVariables_state == 0) {
            zzattr_attrUsedGlobalVariables_state = 1;
            zzattr_attrUsedGlobalVariables_cache = de.peeeq.wurstscript.utils.Utils.emptyList();
            while (true) {
                com.google.common.collect.ImmutableList<VarDef> r = de.peeeq.wurstscript.attributes.UsedGlobalVariables.getUsedGlobals((ExprEmpty)this);
                if (zzattr_attrUsedGlobalVariables_state == 3) {
                    if (!zzattr_attrUsedGlobalVariables_cache.equals(r)) {
                        zzattr_attrUsedGlobalVariables_cache = r;
                        continue;
                    }
                }
                zzattr_attrUsedGlobalVariables_cache = r;
                break;
            }
            zzattr_attrUsedGlobalVariables_state = 2;
        } else if (zzattr_attrUsedGlobalVariables_state == 1) {
            zzattr_attrUsedGlobalVariables_state = 3;
        }
        return zzattr_attrUsedGlobalVariables_cache;
    }
// circular = de.peeeq.wurstscript.utils.Utils.emptyList
    private int zzattr_attrReadGlobalVariables_state = 0;
    private com.google.common.collect.ImmutableList<VarDef> zzattr_attrReadGlobalVariables_cache;
    /** */
    public com.google.common.collect.ImmutableList<VarDef> attrReadGlobalVariables() {
        if (zzattr_attrReadGlobalVariables_state == 0) {
            zzattr_attrReadGlobalVariables_state = 1;
            zzattr_attrReadGlobalVariables_cache = de.peeeq.wurstscript.utils.Utils.emptyList();
            while (true) {
                com.google.common.collect.ImmutableList<VarDef> r = de.peeeq.wurstscript.attributes.UsedGlobalVariables.getReadGlobals((ExprEmpty)this);
                if (zzattr_attrReadGlobalVariables_state == 3) {
                    if (!zzattr_attrReadGlobalVariables_cache.equals(r)) {
                        zzattr_attrReadGlobalVariables_cache = r;
                        continue;
                    }
                }
                zzattr_attrReadGlobalVariables_cache = r;
                break;
            }
            zzattr_attrReadGlobalVariables_state = 2;
        } else if (zzattr_attrReadGlobalVariables_state == 1) {
            zzattr_attrReadGlobalVariables_state = 3;
        }
        return zzattr_attrReadGlobalVariables_cache;
    }
    /** */
    public com.google.common.collect.ImmutableCollection<WPackage> attrUsedPackages() {
        return de.peeeq.wurstscript.attributes.UsedPackages.usedPackages((ExprEmpty)this);
    }
    /** */
    public String description() {
        return de.peeeq.wurstscript.attributes.Description.description((ExprEmpty)this);
    }
    /** */
    public String descriptionHtml() {
        return de.peeeq.wurstscript.attributes.DescriptionHtml.description((ExprEmpty)this);
    }
    /** */
    public boolean isSubtreeOf(Element other) {
        return de.peeeq.wurstscript.attributes.SmallHelpers.isSubtreeOf((ExprEmpty)this, other);
    }
    /** */
    public void prettyPrint(de.peeeq.wurstscript.attributes.prettyPrint.Spacer spacer, StringBuilder sb, int indent) {
        de.peeeq.wurstscript.attributes.prettyPrint.PrettyPrinter.prettyPrint((ExprEmpty)this, spacer, sb, indent);
    }
}