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

@SuppressWarnings({"cast", "unused", "rawtypes"})
class InterfaceDefImpl implements InterfaceDef{
    InterfaceDefImpl(de.peeeq.wurstscript.parser.WPos source, Modifiers modifiers, Identifier nameId, TypeParamDefs typeParameters, TypeExprList extendsList, FuncDefs methods, GlobalVarDefs vars, ConstructorDefs constructors, ModuleInstanciations moduleInstanciations, ModuleUses moduleUses, OnDestroyDef onDestroy) {
        if (source == null)
            throw new IllegalArgumentException("Element source must not be null.");
        if (modifiers == null)
            throw new IllegalArgumentException("Element modifiers must not be null.");
        if (nameId == null)
            throw new IllegalArgumentException("Element nameId must not be null.");
        if (typeParameters == null)
            throw new IllegalArgumentException("Element typeParameters must not be null.");
        if (extendsList == null)
            throw new IllegalArgumentException("Element extendsList must not be null.");
        if (methods == null)
            throw new IllegalArgumentException("Element methods must not be null.");
        if (vars == null)
            throw new IllegalArgumentException("Element vars must not be null.");
        if (constructors == null)
            throw new IllegalArgumentException("Element constructors must not be null.");
        if (moduleInstanciations == null)
            throw new IllegalArgumentException("Element moduleInstanciations must not be null.");
        if (moduleUses == null)
            throw new IllegalArgumentException("Element moduleUses must not be null.");
        if (onDestroy == null)
            throw new IllegalArgumentException("Element onDestroy must not be null.");
        this.source = source;
        this.modifiers = modifiers;
        this.nameId = nameId;
        this.typeParameters = typeParameters;
        this.extendsList = extendsList;
        this.methods = methods;
        this.vars = vars;
        this.constructors = constructors;
        this.moduleInstanciations = moduleInstanciations;
        this.moduleUses = moduleUses;
        this.onDestroy = onDestroy;
        modifiers.setParent(this);
        nameId.setParent(this);
        typeParameters.setParent(this);
        extendsList.setParent(this);
        methods.setParent(this);
        vars.setParent(this);
        constructors.setParent(this);
        moduleInstanciations.setParent(this);
        moduleUses.setParent(this);
        onDestroy.setParent(this);
    }

    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; }

    private Modifiers modifiers;
    public void setModifiers(Modifiers modifiers) {
        if (modifiers == null) throw new IllegalArgumentException();
        this.modifiers.setParent(null);
        modifiers.setParent(this);
        this.modifiers = modifiers;
    } 
    public Modifiers getModifiers() { return modifiers; }

    private Identifier nameId;
    public void setNameId(Identifier nameId) {
        if (nameId == null) throw new IllegalArgumentException();
        this.nameId.setParent(null);
        nameId.setParent(this);
        this.nameId = nameId;
    } 
    public Identifier getNameId() { return nameId; }

    private TypeParamDefs typeParameters;
    public void setTypeParameters(TypeParamDefs typeParameters) {
        if (typeParameters == null) throw new IllegalArgumentException();
        this.typeParameters.setParent(null);
        typeParameters.setParent(this);
        this.typeParameters = typeParameters;
    } 
    public TypeParamDefs getTypeParameters() { return typeParameters; }

    private TypeExprList extendsList;
    public void setExtendsList(TypeExprList extendsList) {
        if (extendsList == null) throw new IllegalArgumentException();
        this.extendsList.setParent(null);
        extendsList.setParent(this);
        this.extendsList = extendsList;
    } 
    public TypeExprList getExtendsList() { return extendsList; }

    private FuncDefs methods;
    public void setMethods(FuncDefs methods) {
        if (methods == null) throw new IllegalArgumentException();
        this.methods.setParent(null);
        methods.setParent(this);
        this.methods = methods;
    } 
    public FuncDefs getMethods() { return methods; }

    private GlobalVarDefs vars;
    public void setVars(GlobalVarDefs vars) {
        if (vars == null) throw new IllegalArgumentException();
        this.vars.setParent(null);
        vars.setParent(this);
        this.vars = vars;
    } 
    public GlobalVarDefs getVars() { return vars; }

    private ConstructorDefs constructors;
    public void setConstructors(ConstructorDefs constructors) {
        if (constructors == null) throw new IllegalArgumentException();
        this.constructors.setParent(null);
        constructors.setParent(this);
        this.constructors = constructors;
    } 
    public ConstructorDefs getConstructors() { return constructors; }

    private ModuleInstanciations moduleInstanciations;
    public void setModuleInstanciations(ModuleInstanciations moduleInstanciations) {
        if (moduleInstanciations == null) throw new IllegalArgumentException();
        this.moduleInstanciations.setParent(null);
        moduleInstanciations.setParent(this);
        this.moduleInstanciations = moduleInstanciations;
    } 
    public ModuleInstanciations getModuleInstanciations() { return moduleInstanciations; }

    private ModuleUses moduleUses;
    public void setModuleUses(ModuleUses moduleUses) {
        if (moduleUses == null) throw new IllegalArgumentException();
        this.moduleUses.setParent(null);
        moduleUses.setParent(this);
        this.moduleUses = moduleUses;
    } 
    public ModuleUses getModuleUses() { return moduleUses; }

    private OnDestroyDef onDestroy;
    public void setOnDestroy(OnDestroyDef onDestroy) {
        if (onDestroy == null) throw new IllegalArgumentException();
        this.onDestroy.setParent(null);
        onDestroy.setParent(this);
        this.onDestroy = onDestroy;
    } 
    public OnDestroyDef getOnDestroy() { return onDestroy; }

    public Element get(int i) {
        switch (i) {
            case 0: return modifiers;
            case 1: return nameId;
            case 2: return typeParameters;
            case 3: return extendsList;
            case 4: return methods;
            case 5: return vars;
            case 6: return constructors;
            case 7: return moduleInstanciations;
            case 8: return moduleUses;
            case 9: return onDestroy;
            default: throw new IllegalArgumentException("Index out of range: " + i);
        }
    }
    public Element set(int i, Element newElem) {
        Element oldElem;
        switch (i) {
            case 0: oldElem = modifiers; setModifiers((Modifiers) newElem); return oldElem;
            case 1: oldElem = nameId; setNameId((Identifier) newElem); return oldElem;
            case 2: oldElem = typeParameters; setTypeParameters((TypeParamDefs) newElem); return oldElem;
            case 3: oldElem = extendsList; setExtendsList((TypeExprList) newElem); return oldElem;
            case 4: oldElem = methods; setMethods((FuncDefs) newElem); return oldElem;
            case 5: oldElem = vars; setVars((GlobalVarDefs) newElem); return oldElem;
            case 6: oldElem = constructors; setConstructors((ConstructorDefs) newElem); return oldElem;
            case 7: oldElem = moduleInstanciations; setModuleInstanciations((ModuleInstanciations) newElem); return oldElem;
            case 8: oldElem = moduleUses; setModuleUses((ModuleUses) newElem); return oldElem;
            case 9: oldElem = onDestroy; setOnDestroy((OnDestroyDef) newElem); return oldElem;
            default: throw new IllegalArgumentException("Index out of range: " + i);
        }
    }

    @Override
    public void forEachElement(java.util.function.Consumer<? super Element> action) {
        action.accept(this.modifiers);
        action.accept(this.nameId);
        action.accept(this.typeParameters);
        action.accept(this.extendsList);
        action.accept(this.methods);
        action.accept(this.vars);
        action.accept(this.constructors);
        action.accept(this.moduleInstanciations);
        action.accept(this.moduleUses);
        action.accept(this.onDestroy);
    }
    public int size() {
        return 10;
    }
    @Override public InterfaceDef copy() {
        InterfaceDef result = new InterfaceDefImpl(source, (Modifiers) this.modifiers.copy(), (Identifier) this.nameId.copy(), (TypeParamDefs) this.typeParameters.copy(), (TypeExprList) this.extendsList.copy(), (FuncDefs) this.methods.copy(), (GlobalVarDefs) this.vars.copy(), (ConstructorDefs) this.constructors.copy(), (ModuleInstanciations) this.moduleInstanciations.copy(), (ModuleUses) this.moduleUses.copy(), (OnDestroyDef) this.onDestroy.copy());
        return result;
    }

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

    @Override public void clearAttributes() {
        modifiers.clearAttributes();
        nameId.clearAttributes();
        typeParameters.clearAttributes();
        extendsList.clearAttributes();
        methods.clearAttributes();
        vars.clearAttributes();
        constructors.clearAttributes();
        moduleInstanciations.clearAttributes();
        moduleUses.clearAttributes();
        onDestroy.clearAttributes();
        clearAttributesLocal();
    }
    @Override public void clearAttributesLocal() {
        zzattr_attrReadVariables_state = 0;
        zzattr_attrTyp_state = 0;
        zzattr_attrTypI_state = 0;
        zzattr_attrNextScope_state = 0;
        zzattr_attrConfigActualNameDef_state = 0;
        zzattr_attrLevel_state = 0;
        zzattr_attrNameLinks_state = 0;
        zzattr_attrTypeNameLinks_state = 0;
    }
    @Override public void accept(Visitor v) {
        v.visit(this);
    }
    @Override public <T> T match(HasReadVariables.Matcher<T> matcher) {
        return matcher.case_InterfaceDef(this);
    }
    @Override public void match(HasReadVariables.MatcherVoid matcher) {
        matcher.case_InterfaceDef(this);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

    @Override public String toString() {
        return "InterfaceDef(" + source + ", " +modifiers + ", " +nameId + ", " +typeParameters + ", " +extendsList + ", " +methods + ", " +vars + ", " +constructors + ", " +moduleInstanciations + ", " +moduleUses + ", " +onDestroy+")";
    }
    public boolean structuralEquals(Element e) {
        if (e instanceof InterfaceDef) {
            InterfaceDef o = (InterfaceDef) e;
            return this.modifiers.structuralEquals(o.getModifiers())
                && this.nameId.structuralEquals(o.getNameId())
                && this.typeParameters.structuralEquals(o.getTypeParameters())
                && this.extendsList.structuralEquals(o.getExtendsList())
                && this.methods.structuralEquals(o.getMethods())
                && this.vars.structuralEquals(o.getVars())
                && this.constructors.structuralEquals(o.getConstructors())
                && this.moduleInstanciations.structuralEquals(o.getModuleInstanciations())
                && this.moduleUses.structuralEquals(o.getModuleUses())
                && this.onDestroy.structuralEquals(o.getOnDestroy());
        } 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((InterfaceDef)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.AttrVarDefType.calculate((InterfaceDef)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_attrTypI_state = 0;
    private de.peeeq.wurstscript.types.WurstTypeInterface zzattr_attrTypI_cache;
    /** */
    public de.peeeq.wurstscript.types.WurstTypeInterface attrTypI() {
        if (zzattr_attrTypI_state == 0) {
            try {
                zzattr_attrTypI_state = 1;
                zzattr_attrTypI_cache = de.peeeq.wurstscript.attributes.AttrVarDefType.calculate((InterfaceDef)this);
            } finally {
                zzattr_attrTypI_state = 0;
            }
            zzattr_attrTypI_state = 2;
        } else if (zzattr_attrTypI_state == 1) {
            throw new CyclicDependencyError(this, "attrTypI");
        }
        return zzattr_attrTypI_cache;
    }
    /** */
    public boolean attrIsDynamicContext() {
        return de.peeeq.wurstscript.attributes.IsDynamicContext.calculate((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable PackageOrGlobal attrNearestPackage() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestPackage((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable NamedScope attrNearestNamedScope() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestNamedScope((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable WScope attrNearestScope() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestScope((InterfaceDef)this);
    }
// circular = null
    private int zzattr_attrNextScope_state = 0;
    private @org.eclipse.jdt.annotation.Nullable WScope zzattr_attrNextScope_cache;
    /** "returns the scope surrounding this scope"*/
    public @org.eclipse.jdt.annotation.Nullable WScope attrNextScope() {
        if (zzattr_attrNextScope_state == 0) {
            try {
                zzattr_attrNextScope_state = 1;
                zzattr_attrNextScope_cache = de.peeeq.wurstscript.attributes.AttrNearest.nextScope((InterfaceDef)this);
            } finally {
                zzattr_attrNextScope_state = 0;
            }
            zzattr_attrNextScope_state = 2;
        } else if (zzattr_attrNextScope_state == 1) {
            throw new CyclicDependencyError(this, "attrNextScope");
        }
        return zzattr_attrNextScope_cache;
    }
    /** */
    public String attrPathDescription() {
        return de.peeeq.wurstscript.attributes.PathDescription.get((InterfaceDef)this);
    }
    /** */
    public CompilationUnit attrCompilationUnit() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestCompilationUnit((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassDef attrNearestClassDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassDef((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassOrInterface attrNearestClassOrInterface() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassOrInterface((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassOrModule attrNearestClassOrModule() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassOrModule((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable StructureDef attrNearestStructureDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestStructureDef((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable FunctionImplementation attrNearestFuncDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestFuncDef((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ExprClosure attrNearestExprClosure() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestExprClosure((InterfaceDef)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ExprStatementsBlock attrNearestExprStatementsBlock() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestExprStatementsBlock((InterfaceDef)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((InterfaceDef)this);
    }
    /** */
    public boolean attrIsCompiletime() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isCompiletime((InterfaceDef)this);
    }
    /** */
    public boolean attrHasAnnotation(String name) {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.hasAnnotation((InterfaceDef)this, name);
    }
    /** */
    public Annotation attrGetAnnotation(String name) {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.getAnnotation((InterfaceDef)this, name);
    }
    /** */
    public boolean attrIsPublic() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isPublic((InterfaceDef)this);
    }
    /** */
    public boolean attrIsPublicRead() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isPublicRead((InterfaceDef)this);
    }
    /** */
    public boolean attrIsPrivate() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isPrivate((InterfaceDef)this);
    }
    /** */
    public boolean attrIsProtected() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isProtected((InterfaceDef)this);
    }
    /** */
    public boolean attrIsStatic() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isStatic((InterfaceDef)this);
    }
    /** */
    public boolean attrIsOverride() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isOverride((InterfaceDef)this);
    }
    /** */
    public boolean attrIsAbstract() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isAbstract((InterfaceDef)this);
    }
    /** */
    public boolean attrIsConstant() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isConstant((InterfaceDef)this);
    }
    /** */
    public boolean attrIsVararg() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isVararg((InterfaceDef)this);
    }
    /** */
    public de.peeeq.wurstscript.parser.WPos attrSource() {
        return de.peeeq.wurstscript.attributes.AttrPos.getPos((InterfaceDef)this);
    }
    /** "returns the position where errors are marked"*/
    public de.peeeq.wurstscript.parser.WPos attrErrorPos() {
        return de.peeeq.wurstscript.attributes.AttrPos.getErrorPos((InterfaceDef)this);
    }
    /** */
    public WurstModel getModel() {
        return de.peeeq.wurstscript.attributes.AttrImportedPackage.getModel((InterfaceDef)this);
    }
// circular = null
    private int zzattr_attrConfigActualNameDef_state = 0;
    private NameDef zzattr_attrConfigActualNameDef_cache;
    /** */
    public NameDef attrConfigActualNameDef() {
        if (zzattr_attrConfigActualNameDef_state == 0) {
            try {
                zzattr_attrConfigActualNameDef_state = 1;
                zzattr_attrConfigActualNameDef_cache = de.peeeq.wurstscript.attributes.CofigActualDef.calculate((InterfaceDef)this);
            } finally {
                zzattr_attrConfigActualNameDef_state = 0;
            }
            zzattr_attrConfigActualNameDef_state = 2;
        } else if (zzattr_attrConfigActualNameDef_state == 1) {
            throw new CyclicDependencyError(this, "attrConfigActualNameDef");
        }
        return zzattr_attrConfigActualNameDef_cache;
    }
    /** */
    public boolean hasAnnotation(String annotation) {
        return de.peeeq.wurstscript.attributes.HasAnnotation.hasAnnotation((InterfaceDef)this, annotation);
    }
    /** */
    public Annotation getAnnotation(String annotation) {
        return de.peeeq.wurstscript.attributes.HasAnnotation.getAnnotation((InterfaceDef)this, annotation);
    }
    /** */
    public void imTranslateEntity(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator) {
        de.peeeq.wurstscript.translation.imtranslation.TLDTranslation.translate((InterfaceDef)this, translator);
    }
    /** */
    public void addError(String msg) {
        de.peeeq.wurstscript.attributes.ErrorHandling.addError((InterfaceDef)this, msg);
    }
    /** */
    public void addWarning(String msg) {
        de.peeeq.wurstscript.attributes.ErrorHandling.addWarning((InterfaceDef)this, msg);
    }
    /** */
    public de.peeeq.wurstscript.attributes.ErrorHandler getErrorHandler() {
        return de.peeeq.wurstscript.attributes.ErrorHandling.getErrorHandler((InterfaceDef)this);
    }
// circular = null
    private int zzattr_attrLevel_state = 0;
    private int zzattr_attrLevel_cache;
    /** "returns the level in the hierarchy. no supertype -> level 1"*/
    public int attrLevel() {
        if (zzattr_attrLevel_state == 0) {
            try {
                zzattr_attrLevel_state = 1;
                zzattr_attrLevel_cache = de.peeeq.wurstscript.attributes.Level.get((InterfaceDef)this);
            } finally {
                zzattr_attrLevel_state = 0;
            }
            zzattr_attrLevel_state = 2;
        } else if (zzattr_attrLevel_state == 1) {
            throw new CyclicDependencyError(this, "attrLevel");
        }
        return zzattr_attrLevel_cache;
    }
    /** "returns a TypeLink pointing to this NameDef"*/
    public de.peeeq.wurstscript.attributes.names.TypeLink createTypeLink(WScope definedIn) {
        return de.peeeq.wurstscript.attributes.names.TypeLink.create((InterfaceDef)this, definedIn);
    }
// circular = null
    private int zzattr_attrNameLinks_state = 0;
    private com.google.common.collect.ImmutableMultimap<String, de.peeeq.wurstscript.attributes.names.DefLink> zzattr_attrNameLinks_cache;
    /** "returns a map of all the names visible in this scope."*/
    public com.google.common.collect.ImmutableMultimap<String, de.peeeq.wurstscript.attributes.names.DefLink> attrNameLinks() {
        if (zzattr_attrNameLinks_state == 0) {
            try {
                zzattr_attrNameLinks_state = 1;
                zzattr_attrNameLinks_cache = de.peeeq.wurstscript.attributes.names.NameLinks.calculate((InterfaceDef)this);
            } finally {
                zzattr_attrNameLinks_state = 0;
            }
            zzattr_attrNameLinks_state = 2;
        } else if (zzattr_attrNameLinks_state == 1) {
            throw new CyclicDependencyError(this, "attrNameLinks");
        }
        return zzattr_attrNameLinks_cache;
    }
// circular = null
    private int zzattr_attrTypeNameLinks_state = 0;
    private com.google.common.collect.ImmutableMultimap<String, de.peeeq.wurstscript.attributes.names.TypeLink> zzattr_attrTypeNameLinks_cache;
    /** "returns a map of all the names visible in this scope."*/
    public com.google.common.collect.ImmutableMultimap<String, de.peeeq.wurstscript.attributes.names.TypeLink> attrTypeNameLinks() {
        if (zzattr_attrTypeNameLinks_state == 0) {
            try {
                zzattr_attrTypeNameLinks_state = 1;
                zzattr_attrTypeNameLinks_cache = de.peeeq.wurstscript.attributes.names.TypeNameLinks.calculate((InterfaceDef)this);
            } finally {
                zzattr_attrTypeNameLinks_state = 0;
            }
            zzattr_attrTypeNameLinks_state = 2;
        } else if (zzattr_attrTypeNameLinks_state == 1) {
            throw new CyclicDependencyError(this, "attrTypeNameLinks");
        }
        return zzattr_attrTypeNameLinks_cache;
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable TypeDef lookupType(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupType((InterfaceDef)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.PackageLink lookupPackage(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupPackage((InterfaceDef)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVar(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVar((InterfaceDef)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVarNoConfig(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVarNoConfig((InterfaceDef)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((InterfaceDef)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((InterfaceDef)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((InterfaceDef)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((InterfaceDef)this, receiverType, name, showErrors);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable TypeDef lookupType(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupTypeShort((InterfaceDef)this, name);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.PackageLink lookupPackage(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupPackageShort((InterfaceDef)this, name);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVar(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVarShort((InterfaceDef)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((InterfaceDef)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((InterfaceDef)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((InterfaceDef)this, receiverType, name);
    }
    /** */
    public String attrComment() {
        return de.peeeq.wurstscript.attributes.AttrWurstDoc.getComment((InterfaceDef)this);
    }
    /** */
    public com.google.common.collect.ImmutableCollection<WPackage> attrUsedPackages() {
        return de.peeeq.wurstscript.attributes.UsedPackages.usedPackages((InterfaceDef)this);
    }
    /** */
    public String description() {
        return de.peeeq.wurstscript.attributes.Description.description((InterfaceDef)this);
    }
    /** */
    public String descriptionHtml() {
        return de.peeeq.wurstscript.attributes.DescriptionHtml.description((InterfaceDef)this);
    }
    /** */
    public boolean isSubtreeOf(Element other) {
        return de.peeeq.wurstscript.attributes.SmallHelpers.isSubtreeOf((InterfaceDef)this, other);
    }
    /** */
    public void prettyPrint(de.peeeq.wurstscript.attributes.prettyPrint.Spacer spacer, StringBuilder sb, int indent) {
        de.peeeq.wurstscript.attributes.prettyPrint.PrettyPrinter.prettyPrint((InterfaceDef)this, spacer, sb, indent);
    }
    /** */
    public String getName() {
        return de.peeeq.wurstscript.attributes.SmallHelpers.getName((InterfaceDef)this);
    }
}