@finos/legend-graph
Version:
Legend graph and graph manager
177 lines • 8.17 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, assertTrue, isNonNullable, assertErrorThrown, guaranteeNonNullable, LogEvent, addUniqueEntry, } from '@finos/legend-shared';
import { CORE_PURE_PATH } from '../../../../../../../graph/MetaModelConst.js';
import { Class } from '../../../../../../../graph/metamodel/pure/packageableElements/domain/Class.js';
import { V1_buildFullPath, } from './V1_GraphBuilderContext.js';
import { V1_ClassMappingFirstPassBuilder } from './V1_ClassMappingFirstPassBuilder.js';
import { V1_buildAssociationProperty, V1_buildDerivedProperty, V1_buildProperty, V1_buildTaggedValue, } from './helpers/V1_DomainBuilderHelper.js';
import { V1_buildDatabaseSchemaViewsFirstPass } from './helpers/V1_DatabaseBuilderHelper.js';
import { GraphBuilderError } from '../../../../../../../graph-manager/GraphManagerUtils.js';
import { V1_TEMPORARY__buildMilestoningClass } from './helpers/V1_MilestoneBuilderHelper.js';
export class V1_ElementThirdPassBuilder {
context;
constructor(context) {
this.context = context;
}
visit_PackageableElement(element) {
this.context.extensions
.getExtraBuilderOrThrow(element)
.runThirdPass(element, this.context);
}
visit_INTERNAL__UnknownElement(element) {
throw new UnsupportedOperationError();
}
visit_INTERNAL__UnknownPackageableElement(element) {
throw new UnsupportedOperationError();
}
visit_IngestDefinition(element) {
throw new UnsupportedOperationError();
}
visit_INTERNAL__UnknownFunctionActivator(element) {
throw new UnsupportedOperationError();
}
visit_INTERNAL__UnknownStore(element) {
return;
}
visit_Profile(element) {
throw new UnsupportedOperationError();
}
visit_Enumeration(element) {
throw new UnsupportedOperationError();
}
visit_Measure(element) {
throw new UnsupportedOperationError();
}
visit_SnowflakeApp(element) {
throw new UnsupportedOperationError();
}
visit_HostedService(element) {
throw new UnsupportedOperationError();
}
visit_ExecutionEnvironmentInstance(element) {
throw new UnsupportedOperationError();
}
visit_Class(element) {
const _class = this.context.currentSubGraph.getOwnClass(V1_buildFullPath(element.package, element.name));
element.superTypes.forEach((pointer) => {
const type = pointer.path;
// supertype `Any` will not be processed
if (type !== CORE_PURE_PATH.ANY) {
try {
const genericTypeReference = this.context.resolveGenericType(type);
addUniqueEntry(_class.generalizations, genericTypeReference);
if (genericTypeReference.ownerReference.value instanceof Class) {
addUniqueEntry(genericTypeReference.ownerReference.value._subclasses, _class);
}
}
catch (error) {
assertErrorThrown(error);
// NOTE: reconsider this as we might need to get elements from `system` and `platform` as well
throw new GraphBuilderError(`Can't find supertype '${type}' of class '${V1_buildFullPath(element.package, element.name)}': ${error.message}`);
}
}
});
const uniqueProperties = new Set();
element.properties.forEach((property) => {
if (uniqueProperties.has(property.name)) {
const message = `Found duplicated property '${property.name}' in class '${_class.path}'`;
/**
* In strict-mode, graph builder will consider this as an error
* See https://github.com/finos/legend-studio/issues/941
*
* @discrepancy graph-building
*/
if (this.context.options?.strict) {
throw new GraphBuilderError(message);
}
this.context.logService.warn(LogEvent.create(message));
}
_class.properties.push(V1_buildProperty(property, this.context, _class));
uniqueProperties.add(property.name);
});
V1_TEMPORARY__buildMilestoningClass(_class, this.context.graph);
}
visit_Association(element) {
const association = this.context.currentSubGraph.getOwnAssociation(V1_buildFullPath(element.package, element.name));
assertTrue(element.properties.length === 2, 'Association must have exactly 2 properties');
const first = guaranteeNonNullable(element.properties[0]);
const second = guaranteeNonNullable(element.properties[1]);
if (first.name === second.name) {
const message = `Found duplicated property '${element.properties[0]?.name}' in association '${element.path}'`;
/**
* In strict-mode, graph builder will consider this as an error
* See https://github.com/finos/legend-studio/issues/941
*
* @discrepancy graph-building
*/
if (this.context.options?.strict) {
throw new GraphBuilderError(message);
}
this.context.logService.warn(LogEvent.create(message));
}
association.properties = [
V1_buildAssociationProperty(first, second, this.context, association),
V1_buildAssociationProperty(second, first, this.context, association),
];
association.stereotypes = element.stereotypes
.map((stereotype) => this.context.resolveStereotype(stereotype))
.filter(isNonNullable);
association.taggedValues = element.taggedValues
.map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
.filter(isNonNullable);
association.derivedProperties = element.derivedProperties.map((derivedProperty) => V1_buildDerivedProperty(derivedProperty, this.context, association));
}
visit_ConcreteFunctionDefinition(element) {
throw new UnsupportedOperationError();
}
visit_FlatData(element) {
return;
}
visit_Database(element) {
const database = this.context.currentSubGraph.getOwnDatabase(V1_buildFullPath(element.package, element.name));
element.schemas.forEach((schema) => V1_buildDatabaseSchemaViewsFirstPass(schema, database, this.context));
}
visit_Mapping(element) {
const mapping = this.context.currentSubGraph.getOwnMapping(V1_buildFullPath(element.package, element.name));
mapping.classMappings = element.classMappings.map((classMapping) => classMapping.accept_ClassMappingVisitor(new V1_ClassMappingFirstPassBuilder(this.context, mapping)));
}
visit_Service(element) {
throw new UnsupportedOperationError();
}
visit_FileGeneration(element) {
throw new UnsupportedOperationError();
}
visit_GenerationSpecification(element) {
throw new UnsupportedOperationError();
}
visit_SectionIndex(element) {
throw new UnsupportedOperationError();
}
visit_PackageableRuntime(element) {
throw new UnsupportedOperationError();
}
visit_PackageableConnection(element) {
throw new UnsupportedOperationError();
}
visit_DataElement(element) {
throw new UnsupportedOperationError();
}
visit_DataProduct(element) {
throw new UnsupportedOperationError();
}
}
//# sourceMappingURL=V1_ElementThirdPassBuilder.js.map