@finos/legend-graph
Version:
Legend graph and graph manager
123 lines • 10.3 kB
JavaScript
/**
* 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 { UnsupportedOperationError, assertNonEmptyString, assertNonNullable, guaranteeNonNullable, } from '@finos/legend-shared';
import { OperationSetImplementation, OperationType, } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/OperationSetImplementation.js';
import { PureInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/store/modelToModel/mapping/PureInstanceSetImplementation.js';
import { FlatDataInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/store/flatData/mapping/FlatDataInstanceSetImplementation.js';
import { RootRelationalInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation.js';
import { InferableMappingElementRootExplicitValue } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/InferableMappingElementRoot.js';
import { V1_getInferredClassMappingId } from './helpers/V1_MappingBuilderHelper.js';
import { AggregationAwareSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/aggregationAware/AggregationAwareSetImplementation.js';
import { V1_buildAggregateContainer } from './helpers/V1_AggregationAwareClassMappingBuilderHelper.js';
import { V1_buildRawLambdaWithResolvedPaths } from './helpers/V1_ValueSpecificationPathResolver.js';
import { V1_buildRelationalMappingFilter } from './helpers/V1_RelationalClassMappingBuilderHelper.js';
import { MergeOperationSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/MergeOperationSetImplementation.js';
import { INTERNAL__UnknownSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnknownSetImplementation.js';
import { RelationFunctionInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/relationFunction/RelationFunctionInstanceSetImplementation.js';
const getClassMappingOperationType = (value) => guaranteeNonNullable(Object.values(OperationType).find((type) => type === value), `Encountered unsupported class mapping operation type '${value}'`);
export class V1_ClassMappingFirstPassBuilder {
context;
parent;
constructor(context, parent) {
this.context = context;
this.parent = parent;
}
visit_ClassMapping(classMapping) {
const extraClassMappingBuilders = this.context.extensions.plugins.flatMap((plugin) => plugin.V1_getExtraClassMappingFirstPassBuilders?.() ?? []);
for (const builder of extraClassMappingBuilders) {
const extraClassMapping = builder(classMapping, this.context, this.parent);
if (extraClassMapping) {
return extraClassMapping;
}
}
throw new UnsupportedOperationError(`Can't build new class mapping: no compatible builder available from plugins`, classMapping);
}
visit_INTERNAL__UnknownClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Unknown class mapping 'class' field is missing or empty`);
assertNonNullable(classMapping.root, `Unknown class mapping 'root' field is missing`);
const targetClass = this.context.resolveClass(classMapping.class);
const metamodel = new INTERNAL__UnknownSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root));
metamodel.content = classMapping.content;
return metamodel;
}
visit_OperationClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Operation class mapping 'class' field is missing or empty`);
assertNonNullable(classMapping.root, `Operation class mapping 'root' field is missing`);
assertNonNullable(classMapping.operation, `Operation class mapping operation is missing`);
const targetClass = this.context.resolveClass(classMapping.class);
return new OperationSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root), getClassMappingOperationType(classMapping.operation));
}
visit_MergeOperationClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Merge Operation class mapping 'class' field is missing or empty`);
assertNonNullable(classMapping.root, `Merge Operation class mapping 'root' field is missing`);
assertNonNullable(classMapping.operation, `Merge Operation class mapping operation is missing`);
const targetClass = this.context.resolveClass(classMapping.class);
return new MergeOperationSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root), getClassMappingOperationType(classMapping.operation), V1_buildRawLambdaWithResolvedPaths(classMapping.validationFunction.parameters, classMapping.validationFunction.body, this.context));
}
visit_PureInstanceClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Pure instance class mapping 'class' field is missing or empty`);
assertNonNullable(classMapping.root, `Pure instance class mapping 'root' field is missing`);
const targetClass = this.context.resolveClass(classMapping.class);
const srcClassReference = classMapping.srcClass
? this.context.resolveType(classMapping.srcClass)
: undefined;
const pureInstanceSetImplementation = new PureInstanceSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root), srcClassReference);
pureInstanceSetImplementation.filter = classMapping.filter
? V1_buildRawLambdaWithResolvedPaths([], classMapping.filter.body, this.context)
: undefined;
return pureInstanceSetImplementation;
}
visit_RootFlatDataClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Flat-data class mapping 'class' field is missing or empty`);
assertNonNullable(classMapping.root, `Flat-data class mapping 'root' field is missing`);
const targetClass = this.context.resolveClass(classMapping.class);
const sourceRootRecordType = this.context.resolveRootFlatDataRecordType(classMapping);
const flatDataInstanceSetImplementation = new FlatDataInstanceSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root), sourceRootRecordType);
flatDataInstanceSetImplementation.filter = classMapping.filter
? V1_buildRawLambdaWithResolvedPaths([], classMapping.filter.body, this.context)
: undefined;
return flatDataInstanceSetImplementation;
}
visit_RelationalClassMapping(classMapping) {
throw new UnsupportedOperationError();
}
visit_RootRelationalClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Relational class mapping 'class' field is missing or empty`);
assertNonNullable(classMapping.root, `Relational class mapping 'root' field is missing`);
const targetClass = this.context.resolveClass(classMapping.class);
const rootRelationalInstanceSetImplementation = new RootRelationalInstanceSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root));
rootRelationalInstanceSetImplementation.filter = classMapping.filter
? V1_buildRelationalMappingFilter(classMapping.filter, this.context)
: undefined;
return rootRelationalInstanceSetImplementation;
}
visit_AggregationAwareClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Aggregation-aware class mapping 'class' field is missing or empty`);
assertNonNullable(classMapping.root, `Aggregation-aware class mapping 'root' field is missing`);
const targetClass = this.context.resolveClass(classMapping.class);
const mapping = this.context.graph.getMapping(this.parent.path);
const aggragetionAwareInstanceSetImplementation = new AggregationAwareSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root), classMapping.mainSetImplementation.accept_ClassMappingVisitor(new V1_ClassMappingFirstPassBuilder(this.context, mapping)));
aggragetionAwareInstanceSetImplementation.aggregateSetImplementations =
classMapping.aggregateSetImplementations.map((setImplementation) => V1_buildAggregateContainer(setImplementation, this.context, mapping));
return aggragetionAwareInstanceSetImplementation;
}
visit_RelationFunctionClassMapping(classMapping) {
assertNonEmptyString(classMapping.class, `Relation function class mapping 'class' field is missing or empty`);
const targetClass = this.context.resolveClass(classMapping.class);
return new RelationFunctionInstanceSetImplementation(V1_getInferredClassMappingId(targetClass.value, classMapping), this.parent, targetClass, InferableMappingElementRootExplicitValue.create(classMapping.root));
}
}
//# sourceMappingURL=V1_ClassMappingFirstPassBuilder.js.map