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

@SuppressWarnings({"cast", "unused", "rawtypes"})
class NativeFuncImpl implements NativeFunc{
    NativeFuncImpl(de.peeeq.wurstscript.parser.WPos source, Modifiers modifiers, Identifier nameId, WParameters parameters, OptTypeExpr returnTyp) {
        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 (parameters == null)
            throw new IllegalArgumentException("Element parameters must not be null.");
        if (returnTyp == null)
            throw new IllegalArgumentException("Element returnTyp must not be null.");
        this.source = source;
        this.modifiers = modifiers;
        this.nameId = nameId;
        this.parameters = parameters;
        this.returnTyp = returnTyp;
        modifiers.setParent(this);
        nameId.setParent(this);
        parameters.setParent(this);
        returnTyp.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 WParameters parameters;
    public void setParameters(WParameters parameters) {
        if (parameters == null) throw new IllegalArgumentException();
        this.parameters.setParent(null);
        parameters.setParent(this);
        this.parameters = parameters;
    } 
    public WParameters getParameters() { return parameters; }

    private OptTypeExpr returnTyp;
    public void setReturnTyp(OptTypeExpr returnTyp) {
        if (returnTyp == null) throw new IllegalArgumentException();
        this.returnTyp.setParent(null);
        returnTyp.setParent(this);
        this.returnTyp = returnTyp;
    } 
    public OptTypeExpr getReturnTyp() { return returnTyp; }

    public Element get(int i) {
        switch (i) {
            case 0: return modifiers;
            case 1: return nameId;
            case 2: return parameters;
            case 3: return returnTyp;
            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 = parameters; setParameters((WParameters) newElem); return oldElem;
            case 3: oldElem = returnTyp; setReturnTyp((OptTypeExpr) 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.parameters);
        action.accept(this.returnTyp);
    }
    public int size() {
        return 4;
    }
    @Override public NativeFunc copy() {
        NativeFunc result = new NativeFuncImpl(source, (Modifiers) this.modifiers.copy(), (Identifier) this.nameId.copy(), (WParameters) this.parameters.copy(), (OptTypeExpr) this.returnTyp.copy());
        return result;
    }

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

    @Override public void clearAttributes() {
        modifiers.clearAttributes();
        nameId.clearAttributes();
        parameters.clearAttributes();
        returnTyp.clearAttributes();
        clearAttributesLocal();
    }
    @Override public void clearAttributesLocal() {
        zzattr_attrReadVariables_state = 0;
        zzattr_attrTyp_state = 0;
        zzattr_attrParameterTypesIncludingReceiver_state = 0;
        zzattr_attrParameterTypes_state = 0;
        zzattr_attrReceiverType_state = 0;
        zzattr_attrNextScope_state = 0;
        zzattr_attrConfigActualNameDef_state = 0;
        zzattr_attrRealFuncDef_state = 0;
        zzattr_attrNameLinks_state = 0;
        zzattr_attrTypeNameLinks_state = 0;
        zzattr_attrUsedGlobalVariables_state = 0;
        zzattr_attrReadGlobalVariables_state = 0;
    }
    @Override public void accept(Visitor v) {
        v.visit(this);
    }
    @Override public <T> T match(AstElementWithParameters.Matcher<T> matcher) {
        return matcher.case_NativeFunc(this);
    }
    @Override public void match(AstElementWithParameters.MatcherVoid matcher) {
        matcher.case_NativeFunc(this);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    @Override public String toString() {
        return "NativeFunc(" + source + ", " +modifiers + ", " +nameId + ", " +parameters + ", " +returnTyp+")";
    }
    public boolean structuralEquals(Element e) {
        if (e instanceof NativeFunc) {
            NativeFunc o = (NativeFunc) e;
            return this.modifiers.structuralEquals(o.getModifiers())
                && this.nameId.structuralEquals(o.getNameId())
                && this.parameters.structuralEquals(o.getParameters())
                && this.returnTyp.structuralEquals(o.getReturnTyp());
        } 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((NativeFunc)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;
    }
    /** */
    public de.peeeq.wurstscript.types.WurstType attrReturnTyp() {
        return de.peeeq.wurstscript.attributes.AttrReturnTyp.calculate((NativeFunc)this);
    }
// 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((NativeFunc)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;
    }
    /** */
    public boolean attrIsDynamicClassMember() {
        return de.peeeq.wurstscript.attributes.AttrIsClassMember.calculate((NativeFunc)this);
    }
// circular = null
    private int zzattr_attrParameterTypesIncludingReceiver_state = 0;
    private com.google.common.collect.ImmutableList<de.peeeq.wurstscript.types.WurstType> zzattr_attrParameterTypesIncludingReceiver_cache;
    /** */
    public com.google.common.collect.ImmutableList<de.peeeq.wurstscript.types.WurstType> attrParameterTypesIncludingReceiver() {
        if (zzattr_attrParameterTypesIncludingReceiver_state == 0) {
            try {
                zzattr_attrParameterTypesIncludingReceiver_state = 1;
                zzattr_attrParameterTypesIncludingReceiver_cache = de.peeeq.wurstscript.attributes.AttrParameterTypes.parameterTypesIncludingReceiver((NativeFunc)this);
            } finally {
                zzattr_attrParameterTypesIncludingReceiver_state = 0;
            }
            zzattr_attrParameterTypesIncludingReceiver_state = 2;
        } else if (zzattr_attrParameterTypesIncludingReceiver_state == 1) {
            throw new CyclicDependencyError(this, "attrParameterTypesIncludingReceiver");
        }
        return zzattr_attrParameterTypesIncludingReceiver_cache;
    }
// circular = null
    private int zzattr_attrParameterTypes_state = 0;
    private com.google.common.collect.ImmutableList<de.peeeq.wurstscript.types.WurstType> zzattr_attrParameterTypes_cache;
    /** */
    public com.google.common.collect.ImmutableList<de.peeeq.wurstscript.types.WurstType> attrParameterTypes() {
        if (zzattr_attrParameterTypes_state == 0) {
            try {
                zzattr_attrParameterTypes_state = 1;
                zzattr_attrParameterTypes_cache = de.peeeq.wurstscript.attributes.AttrParameterTypes.parameterTypes((NativeFunc)this);
            } finally {
                zzattr_attrParameterTypes_state = 0;
            }
            zzattr_attrParameterTypes_state = 2;
        } else if (zzattr_attrParameterTypes_state == 1) {
            throw new CyclicDependencyError(this, "attrParameterTypes");
        }
        return zzattr_attrParameterTypes_cache;
    }
// circular = null
    private int zzattr_attrReceiverType_state = 0;
    private de.peeeq.wurstscript.types.WurstType zzattr_attrReceiverType_cache;
    /** */
    public de.peeeq.wurstscript.types.WurstType attrReceiverType() {
        if (zzattr_attrReceiverType_state == 0) {
            try {
                zzattr_attrReceiverType_state = 1;
                zzattr_attrReceiverType_cache = de.peeeq.wurstscript.attributes.AttrParameterTypes.receiverType((NativeFunc)this);
            } finally {
                zzattr_attrReceiverType_state = 0;
            }
            zzattr_attrReceiverType_state = 2;
        } else if (zzattr_attrReceiverType_state == 1) {
            throw new CyclicDependencyError(this, "attrReceiverType");
        }
        return zzattr_attrReceiverType_cache;
    }
    /** */
    public boolean attrIsDynamicContext() {
        return de.peeeq.wurstscript.attributes.IsDynamicContext.calculate((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable PackageOrGlobal attrNearestPackage() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestPackage((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable NamedScope attrNearestNamedScope() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestNamedScope((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable WScope attrNearestScope() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestScope((NativeFunc)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((NativeFunc)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((NativeFunc)this);
    }
    /** */
    public CompilationUnit attrCompilationUnit() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestCompilationUnit((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassDef attrNearestClassDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassDef((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassOrInterface attrNearestClassOrInterface() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassOrInterface((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ClassOrModule attrNearestClassOrModule() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestClassOrModule((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable StructureDef attrNearestStructureDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestStructureDef((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable FunctionImplementation attrNearestFuncDef() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestFuncDef((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ExprClosure attrNearestExprClosure() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestExprClosure((NativeFunc)this);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable ExprStatementsBlock attrNearestExprStatementsBlock() {
        return de.peeeq.wurstscript.attributes.AttrNearest.nearestExprStatementsBlock((NativeFunc)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((NativeFunc)this);
    }
    /** */
    public boolean attrIsCompiletime() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isCompiletime((NativeFunc)this);
    }
    /** */
    public boolean attrHasAnnotation(String name) {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.hasAnnotation((NativeFunc)this, name);
    }
    /** */
    public Annotation attrGetAnnotation(String name) {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.getAnnotation((NativeFunc)this, name);
    }
    /** */
    public boolean attrIsPublic() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isPublic((NativeFunc)this);
    }
    /** */
    public boolean attrIsPublicRead() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isPublicRead((NativeFunc)this);
    }
    /** */
    public boolean attrIsPrivate() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isPrivate((NativeFunc)this);
    }
    /** */
    public boolean attrIsProtected() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isProtected((NativeFunc)this);
    }
    /** */
    public boolean attrIsStatic() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isStatic((NativeFunc)this);
    }
    /** */
    public boolean attrIsOverride() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isOverride((NativeFunc)this);
    }
    /** */
    public boolean attrIsAbstract() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isAbstract((NativeFunc)this);
    }
    /** */
    public boolean attrIsConstant() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isConstant((NativeFunc)this);
    }
    /** */
    public boolean attrIsVararg() {
        return de.peeeq.wurstscript.attributes.ModifiersHelper.isVararg((NativeFunc)this);
    }
    /** */
    public de.peeeq.wurstscript.parser.WPos attrSource() {
        return de.peeeq.wurstscript.attributes.AttrPos.getPos((NativeFunc)this);
    }
    /** "returns the position where errors are marked"*/
    public de.peeeq.wurstscript.parser.WPos attrErrorPos() {
        return de.peeeq.wurstscript.attributes.AttrPos.getErrorPos((NativeFunc)this);
    }
    /** */
    public WurstModel getModel() {
        return de.peeeq.wurstscript.attributes.AttrImportedPackage.getModel((NativeFunc)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((NativeFunc)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((NativeFunc)this, annotation);
    }
    /** */
    public Annotation getAnnotation(String annotation) {
        return de.peeeq.wurstscript.attributes.HasAnnotation.getAnnotation((NativeFunc)this, annotation);
    }
    /** */
    public void imTranslateTLD(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator) {
        de.peeeq.wurstscript.translation.imtranslation.TLDTranslation.translate((NativeFunc)this, translator);
    }
    /** */
    public void imTranslateEntity(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator) {
        de.peeeq.wurstscript.translation.imtranslation.TLDTranslation.translate((NativeFunc)this, translator);
    }
    /** */
    public void imCreateFuncSkeleton(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator, de.peeeq.wurstscript.jassIm.ImFunction f) {
        de.peeeq.wurstscript.translation.imtranslation.FuncSkeleton.create((NativeFunc)this, translator, f);
    }
    /** */
    public void addError(String msg) {
        de.peeeq.wurstscript.attributes.ErrorHandling.addError((NativeFunc)this, msg);
    }
    /** */
    public void addWarning(String msg) {
        de.peeeq.wurstscript.attributes.ErrorHandling.addWarning((NativeFunc)this, msg);
    }
    /** */
    public de.peeeq.wurstscript.attributes.ErrorHandler getErrorHandler() {
        return de.peeeq.wurstscript.attributes.ErrorHandling.getErrorHandler((NativeFunc)this);
    }
// circular = null
    private int zzattr_attrRealFuncDef_state = 0;
    private @org.eclipse.jdt.annotation.Nullable FunctionDefinition zzattr_attrRealFuncDef_cache;
    /** "returns the function definition which overrides this definition"*/
    public @org.eclipse.jdt.annotation.Nullable FunctionDefinition attrRealFuncDef() {
        if (zzattr_attrRealFuncDef_state == 0) {
            try {
                zzattr_attrRealFuncDef_state = 1;
                zzattr_attrRealFuncDef_cache = de.peeeq.wurstscript.attributes.OverriddenFunctions.getRealFuncDef((NativeFunc)this);
            } finally {
                zzattr_attrRealFuncDef_state = 0;
            }
            zzattr_attrRealFuncDef_state = 2;
        } else if (zzattr_attrRealFuncDef_state == 1) {
            throw new CyclicDependencyError(this, "attrRealFuncDef");
        }
        return zzattr_attrRealFuncDef_cache;
    }
    /** "returns a FuncLink pointing to this NameDef"*/
    public de.peeeq.wurstscript.attributes.names.FuncLink createFuncLink(WScope definedIn) {
        return de.peeeq.wurstscript.attributes.names.FuncLink.create((NativeFunc)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((NativeFunc)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((NativeFunc)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((NativeFunc)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.PackageLink lookupPackage(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupPackage((NativeFunc)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVar(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVar((NativeFunc)this, name, showErrors);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVarNoConfig(String name, boolean showErrors) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVarNoConfig((NativeFunc)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((NativeFunc)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((NativeFunc)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((NativeFunc)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((NativeFunc)this, receiverType, name, showErrors);
    }
    /** */
    public @org.eclipse.jdt.annotation.Nullable TypeDef lookupType(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupTypeShort((NativeFunc)this, name);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.PackageLink lookupPackage(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupPackageShort((NativeFunc)this, name);
    }
    /** */
    public de.peeeq.wurstscript.attributes.names.NameLink lookupVar(String name) {
        return de.peeeq.wurstscript.attributes.names.NameResolution.lookupVarShort((NativeFunc)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((NativeFunc)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((NativeFunc)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((NativeFunc)this, receiverType, name);
    }
    /** */
    public String attrComment() {
        return de.peeeq.wurstscript.attributes.AttrWurstDoc.getComment((NativeFunc)this);
    }
// 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((NativeFunc)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((NativeFunc)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((NativeFunc)this);
    }
    /** */
    public String description() {
        return de.peeeq.wurstscript.attributes.Description.description((NativeFunc)this);
    }
    /** */
    public String descriptionHtml() {
        return de.peeeq.wurstscript.attributes.DescriptionHtml.description((NativeFunc)this);
    }
    /** */
    public boolean isSubtreeOf(Element other) {
        return de.peeeq.wurstscript.attributes.SmallHelpers.isSubtreeOf((NativeFunc)this, other);
    }
    /** */
    public void prettyPrint(de.peeeq.wurstscript.attributes.prettyPrint.Spacer spacer, StringBuilder sb, int indent) {
        de.peeeq.wurstscript.attributes.prettyPrint.PrettyPrinter.prettyPrint((NativeFunc)this, spacer, sb, indent);
    }
    /** */
    public String getName() {
        return de.peeeq.wurstscript.attributes.SmallHelpers.getName((NativeFunc)this);
    }
}