/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { filterByType } from '@finos/legend-shared';
import { computed, makeObservable, observable, override } from 'mobx';
import { PropertyGraphFetchTree, RootGraphFetchTree, } from '../../../graph/metamodel/pure/valueSpecification/GraphFetchTree.js';
import { LambdaFunction, } from '../../../graph/metamodel/pure/valueSpecification/LambdaFunction.js';
import { ValueSpecification, } from '../../../graph/metamodel/pure/valueSpecification/ValueSpecification.js';
import { skipObservedWithContext, skipObserved, observe_PackageableElementReference, } from './CoreObserverHelper.js';
import { observe_EnumValueReference, observe_GenericTypeReference, observe_PropertyReference, } from './DomainObserverHelper.js';
const observe_Abstract_ValueSpecification = (metamodel) => {
    makeObservable(metamodel, {
        multiplicity: observable,
        hashCode: computed,
    });
    if (metamodel.genericType) {
        observe_GenericTypeReference(metamodel.genericType);
    }
};
export const observe_VariableExpression = skipObserved((metamodel) => {
    observe_Abstract_ValueSpecification(metamodel);
    makeObservable(metamodel, {
        name: observable,
        genericType: observable,
    });
    return metamodel;
});
export const observe_FunctionExpression = skipObservedWithContext(observe_Abstract_FunctionExpression);
export const observe_SimpleFunctionExpression = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_FunctionExpression(metamodel, context);
    if (metamodel.func) {
        observe_PackageableElementReference(metamodel.func);
    }
    return metamodel;
});
export const observe_AbstractPropertyExpression = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_FunctionExpression(metamodel, context);
    return metamodel;
});
export const observe_PrimitiveInstanceValue = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_InstanceValue(metamodel, context);
    makeObservable(metamodel, {
        hashCode: override,
    });
    return metamodel;
});
export const observe_EnumValueInstanceValue = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_InstanceValue(metamodel, context);
    makeObservable(metamodel, {
        hashCode: override,
    });
    metamodel.values.forEach(observe_EnumValueReference);
    return metamodel;
});
export const observe_CollectionInstanceValue = skipObservedWithContext(_observe_CollectionInstanceValue);
export const observe_KeyExpressionInstanceValue = skipObservedWithContext(_observe_KeyExpressionInstanceValue);
export const observe_GraphFetchTree = skipObservedWithContext(observe_Abstract_GraphFetchTree);
export const observe_PropertyGraphFetchTree = skipObservedWithContext(_observe_PropertyGraphFetchTree);
export const observe_RootGraphFetchTree = skipObservedWithContext(observe_Abstract_GraphFetchTree);
export const observe_GraphFetchTreeInstanceValue = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_InstanceValue(metamodel, context);
    makeObservable(metamodel, {
        hashCode: override,
    });
    metamodel.values.forEach((value) => observe_RootGraphFetchTree(value, context));
    return metamodel;
});
export const observe_ColSpec = skipObservedWithContext(_observe_ColSpec);
export const observe_ColSpecArray = skipObservedWithContext((metamodel, context) => {
    makeObservable(metamodel, {
        colSpecs: observable,
    });
    metamodel.colSpecs.forEach((value) => observe_ColSpec(value, context));
    return metamodel;
});
export const observe_ColSpecArrayInstance = skipObservedWithContext(_observe_ColSpecArrayInstance);
export const observe_ColSpecInstance = skipObservedWithContext(_observe_ColSpecInstance);
const observe_LambdaFunction = skipObservedWithContext(_observe_LambdaFunction);
const observe_LambdaFunctionInstanceValue = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_InstanceValue(metamodel, context);
    makeObservable(metamodel, {
        hashCode: override,
    });
    metamodel.values
        .filter(filterByType(LambdaFunction))
        .forEach((value) => observe_LambdaFunction(value, context));
    return metamodel;
});
const observe_FunctionType = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        returnType: observable,
        parameters: observable,
        returnMultiplicity: observable,
        hashCode: computed,
    });
    // TODO? returnType? - when we make this reference
    metamodel.parameters.forEach((parameter) => observe_VariableExpression(parameter));
    return metamodel;
});
const observe_INTERNAL__UnknownValueSpecification = skipObserved((metamodel) => {
    observe_Abstract_ValueSpecification(metamodel);
    makeObservable(metamodel, {
        content: observable.ref,
    });
    return metamodel;
});
const observe_InstanceValue = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_InstanceValue(metamodel, context);
    return metamodel;
});
class ValueSpecificationObserver {
    observerContext;
    constructor(observerContext) {
        this.observerContext = observerContext;
    }
    visit_AccessorInstanceValue(valueAccessorInstanceValue) {
        return;
    }
    visit_KeyExpressionInstanceValue(valueSpeciciation) {
        observe_KeyExpressionInstanceValue(valueSpeciciation, this.observerContext);
    }
    visit_INTERNAL__UnknownValueSpecification(valueSpecification) {
        observe_INTERNAL__UnknownValueSpecification(valueSpecification);
    }
    visit_INTERNAL__PropagatedValue(valueSpecification) {
        observe_Abstract_ValueSpecification(valueSpecification);
    }
    visit_FunctionExpression(valueSpecification) {
        observe_FunctionExpression(valueSpecification, this.observerContext);
    }
    visit_SimpleFunctionExpression(valueSpecification) {
        observe_SimpleFunctionExpression(valueSpecification, this.observerContext);
    }
    visit_VariableExpression(valueSpecification) {
        observe_VariableExpression(valueSpecification);
    }
    visit_AbstractPropertyExpression(valueSpecification) {
        observe_AbstractPropertyExpression(valueSpecification, this.observerContext);
    }
    visit_InstanceValue(valueSpecification) {
        observe_InstanceValue(valueSpecification, this.observerContext);
    }
    visit_CollectionInstanceValue(valueSpecification) {
        observe_CollectionInstanceValue(valueSpecification, this.observerContext);
    }
    visit_EnumValueInstanceValue(valueSpecification) {
        observe_EnumValueInstanceValue(valueSpecification, this.observerContext);
    }
    visit_PrimitiveInstanceValue(valueSpecification) {
        observe_PrimitiveInstanceValue(valueSpecification, this.observerContext);
    }
    visit_LambdaFunctionInstanceValue(valueSpecification) {
        observe_LambdaFunctionInstanceValue(valueSpecification, this.observerContext);
    }
    visit_GraphFetchTreeInstanceValue(valueSpecification) {
        observe_GraphFetchTreeInstanceValue(valueSpecification, this.observerContext);
    }
    visit_ColSpecArrayInstance(valueSpeciciation) {
        observe_ColSpecArrayInstance(valueSpeciciation, this.observerContext);
    }
    visit_ColSpecInstance(valueSpeciciation) {
        observe_ColSpecInstance(valueSpeciciation, this.observerContext);
    }
}
export const observe_ValueSpecification = skipObservedWithContext((valueSpecification, context) => {
    valueSpecification.accept_ValueSpecificationVisitor(new ValueSpecificationObserver(context));
    return valueSpecification;
});
function _observe_CollectionInstanceValue(metamodel, context) {
    observe_Abstract_InstanceValue(metamodel, context);
    makeObservable(metamodel, {
        hashCode: override,
    });
    return metamodel;
}
function observe_KeyExpressionValue(metamodel, context) {
    makeObservable(metamodel, {
        hashCode: computed,
        add: observable,
        key: observable,
        expression: observable,
    });
    metamodel.expression.accept_ValueSpecificationVisitor(new ValueSpecificationObserver(context));
    metamodel.key.accept_ValueSpecificationVisitor(new ValueSpecificationObserver(context));
    return metamodel;
}
function _observe_KeyExpressionInstanceValue(metamodel, context) {
    observe_Abstract_ValueSpecification(metamodel);
    makeObservable(metamodel, {
        hashCode: override,
        values: observable,
    });
    metamodel.values.forEach((keyE) => observe_KeyExpressionValue(keyE, context));
    return metamodel;
}
function observe_Abstract_FunctionExpression(metamodel, context) {
    observe_Abstract_ValueSpecification(metamodel);
    makeObservable(metamodel, {
        functionName: observable,
        parametersValues: observable,
        classifierGenericType: observable,
        func: observable,
        hashCode: override,
    });
    metamodel.parametersValues.forEach((value) => observe_ValueSpecification(value, context));
    return metamodel;
}
function observe_Abstract_GraphFetchTree(metamodel, context) {
    makeObservable(metamodel, {
        subTrees: observable,
        isEmpty: computed,
        hashCode: computed,
    });
    metamodel.subTrees.forEach((subTree) => {
        if (subTree instanceof PropertyGraphFetchTree) {
            observe_PropertyGraphFetchTree(subTree, context);
        }
        else if (subTree instanceof RootGraphFetchTree) {
            observe_RootGraphFetchTree(subTree, context);
        }
        else {
            observe_GraphFetchTree(subTree, context);
        }
    });
    return metamodel;
}
function _observe_PropertyGraphFetchTree(metamodel, context) {
    observe_Abstract_GraphFetchTree(metamodel, context);
    makeObservable(metamodel, {
        alias: observable,
        parameters: observable,
        subType: observable,
    });
    observe_PropertyReference(metamodel.property);
    metamodel.parameters.forEach((value) => observe_ValueSpecification(value, context));
    if (metamodel.subType) {
        observe_PackageableElementReference(metamodel.subType);
    }
    return metamodel;
}
function observe_Abstract_InstanceValue(metamodel, context) {
    observe_Abstract_ValueSpecification(metamodel);
    makeObservable(metamodel, {
        values: observable,
    });
    metamodel.values
        .filter(filterByType(ValueSpecification))
        .forEach((value) => observe_ValueSpecification(value, context));
}
function _observe_LambdaFunction(metamodel, context) {
    makeObservable(metamodel, {
        functionType: observable,
        openVariables: observable,
        expressionSequence: observable,
        hashCode: computed,
    });
    observe_FunctionType(metamodel.functionType);
    metamodel.expressionSequence.forEach((e) => observe_ValueSpecification(e, context));
    return metamodel;
}
function _observe_ColSpecArrayInstance(metamodel, context) {
    observe_Abstract_InstanceValue(metamodel, context);
    makeObservable(metamodel, {
        hashCode: override,
    });
    metamodel.values.forEach((value) => observe_ColSpecArray(value, context));
    return metamodel;
}
function _observe_ColSpecInstance(metamodel, context) {
    observe_Abstract_InstanceValue(metamodel, context);
    makeObservable(metamodel, {
        hashCode: override,
    });
    metamodel.values.forEach((value) => observe_ColSpec(value, context));
    return metamodel;
}
function _observe_ColSpec(metamodel, context) {
    makeObservable(metamodel, {
        name: observable,
        type: observable,
        function1: observable,
        function2: observable,
    });
    if (metamodel.function1) {
        observe_ValueSpecification(metamodel.function1, context);
    }
    if (metamodel.function2) {
        observe_ValueSpecification(metamodel.function2, context);
    }
    return metamodel;
}
//# sourceMappingURL=ValueSpecificationObserver.js.map