UNPKG

@finos/legend-graph

Version:
549 lines 43 kB
/** * 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 { LogEvent, assertNonNullable, assertNonEmptyString, guaranteeType, guaranteeNonNullable, returnUndefOnError, UnsupportedOperationError, } from '@finos/legend-shared'; import { GRAPH_MANAGER_EVENT } from '../../../../../../../__lib__/GraphManagerEvent.js'; import { PurePropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/store/modelToModel/mapping/PurePropertyMapping.js'; import { RelationalPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping.js'; import { EmbeddedFlatDataPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/store/flatData/mapping/EmbeddedFlatDataPropertyMapping.js'; import { FlatDataPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/store/flatData/mapping/FlatDataPropertyMapping.js'; import { Class } from '../../../../../../../graph/metamodel/pure/packageableElements/domain/Class.js'; import { InferableMappingElementIdExplicitValue } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/InferableMappingElementId.js'; import { PackageableElementImplicitReference, } from '../../../../../../../graph/metamodel/pure/packageableElements/PackageableElementReference.js'; import { PropertyImplicitReference, } from '../../../../../../../graph/metamodel/pure/packageableElements/domain/PropertyReference.js'; import { RootRelationalInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation.js'; import { OtherwiseEmbeddedRelationalInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/store/relational/mapping/OtherwiseEmbeddedRelationalInstanceSetImplementation.js'; import { EmbeddedRelationalInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation.js'; import { InlineEmbeddedRelationalInstanceSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/store/relational/mapping/InlineEmbeddedRelationalInstanceSetImplementation.js'; import { AssociationImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/AssociationImplementation.js'; import { V1_buildRelationalOperationElement } from './helpers/V1_DatabaseBuilderHelper.js'; import { V1_buildEmbeddedRelationalMappingProperty } from './helpers/V1_RelationalPropertyMappingBuilder.js'; import { XStorePropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/xStore/XStorePropertyMapping.js'; import { Property } from '../../../../../../../graph/metamodel/pure/packageableElements/domain/Property.js'; import { MappingClass } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/MappingClass.js'; import { LocalMappingPropertyInfo } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/LocalMappingPropertyInfo.js'; import { AggregationAwarePropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/aggregationAware/AggregationAwarePropertyMapping.js'; import { V1_buildRawLambdaWithResolvedPaths } from './helpers/V1_ValueSpecificationPathResolver.js'; import { V1_deserializeRelationalOperationElement, V1_serializeRelationalOperationElement, } from '../../pureProtocol/serializationHelpers/V1_DatabaseSerializationHelper.js'; import { V1_transformRelationalOperationElement } from '../from/V1_DatabaseTransformer.js'; import { V1_GraphTransformerContextBuilder } from '../from/V1_GraphTransformerContext.js'; import { getAllEnumerationMappings, getAllIncludedMappings, getClassMappingById, getClassMappingsByClass, } from '../../../../../../../graph/helpers/DSL_Mapping_Helper.js'; import { GraphBuilderError } from '../../../../../../../graph-manager/GraphManagerUtils.js'; import { BindingTransformer } from '../../../../../../../graph/metamodel/pure/packageableElements/externalFormat/store/DSL_ExternalFormat_BindingTransformer.js'; import { V1_resolveBinding } from './V1_DSL_ExternalFormat_GraphBuilderHelper.js'; import { INTERNAL__UnresolvedSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnresolvedSetImplementation.js'; import { getAssociatedPropertyClass, getOwnProperty, getClassProperty, } from '../../../../../../../graph/helpers/DomainHelper.js'; import { SetImplementationImplicitReference } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/SetImplementationReference.js'; import { EnumerationMappingExplicitReference } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/EnumerationMappingReference.js'; import { FlatDataAssociationPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/store/flatData/mapping/FlatDataAssociationPropertyMapping.js'; import { INTERNAL__UnknownPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnknownPropertyMapping.js'; import { INTERNAL__PseudoMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__PseudoMapping.js'; import { RelationFunctionPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/relationFunction/RelationFunctionPropertyMapping.js'; import { RelationColumn } from '../../../../../../../graph/metamodel/pure/packageableElements/relation/RelationType.js'; const TEMPORARY__resolveSetImplementationByID = (mapping, id, context) => { const classMapping = returnUndefOnError(() => getClassMappingById(mapping, id)); const isMappingWithUnknownMappingIncludes = getAllIncludedMappings(mapping).includes(INTERNAL__PseudoMapping.INSTANCE); if (!classMapping) { const message = `Can't find class mapping with ID '${id}' in mapping '${mapping.path}'`; /** * If the mapping has unknown mapping includes, this kind of problems * might be due to the fact that the class mapping is not reachable due to the system * not knowing how to analyze the unknown mapping include, as such, we will not throw * errors, otherwise, we should in strict-mode * * See https://github.com/finos/legend-studio/issues/880 * See https://github.com/finos/legend-studio/issues/941 * * @discrepancy graph-building */ if (context.options?.strict && !isMappingWithUnknownMappingIncludes) { throw new GraphBuilderError(message); } context.logService.warn(LogEvent.create(message)); return new INTERNAL__UnresolvedSetImplementation(id, mapping); } return classMapping; }; const resolvePropertyMappingSourceImplementation = (immediateParent, value, topParent, context) => { if (immediateParent instanceof AssociationImplementation) { if (value.source) { return TEMPORARY__resolveSetImplementationByID(immediateParent._PARENT, value.source, context); } const property = getOwnProperty(immediateParent.association.value, value.property.property); const _class = getAssociatedPropertyClass(immediateParent.association.value, property); const setImpls = getClassMappingsByClass(immediateParent._PARENT, _class); return setImpls.find((r) => r.root.value) ?? setImpls[0]; } return topParent; }; export class V1_PropertyMappingBuilder { context; immediateParent; // either root instance set implementation or the immediate embedded parent property mapping (needed for processing embedded property mapping) topParent; allEnumerationMappings = []; tableAliasIndex; allClassMappings; xStoreParent; aggregationAwareParent; constructor(context, immediateParent, topParent, allEnumerationMappings, tableAliasMap, allClassMappings, xStoreParent, aggregationAwareParent) { this.context = context; this.immediateParent = immediateParent; this.topParent = topParent; this.allEnumerationMappings = allEnumerationMappings; this.tableAliasIndex = tableAliasMap ?? new Map(); this.allClassMappings = allClassMappings ?? []; this.xStoreParent = xStoreParent; this.aggregationAwareParent = aggregationAwareParent; } visit_PropertyMapping(propertyMapping) { const extraPropertyMappingBuilders = this.context.extensions.plugins.flatMap((plugin) => plugin.V1_getExtraPropertyMappingBuilders?.() ?? []); for (const builder of extraPropertyMappingBuilders) { const extraPropertyMapping = builder(propertyMapping, this.context); if (extraPropertyMapping) { return extraPropertyMapping; } } throw new UnsupportedOperationError(`Can't build property mapping: no compatible builder available from plugins`, propertyMapping); } visit_INTERNAL__UnknownPropertyMapping(propertyMapping) { const metamodel = new INTERNAL__UnknownPropertyMapping(); metamodel.content = propertyMapping.content; return metamodel; } visit_PurePropertyMapping(protocol) { assertNonNullable(protocol.property, `Pure instance property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Pure instance property mapping 'property.property' field is missing or empty`); assertNonNullable(protocol.transform, `Pure instance property mapping 'transform' field is missing`); // NOTE: mapping for derived property is not supported let property; let localMapping; if (protocol.localMappingProperty) { const localMappingProperty = protocol.localMappingProperty; const mappingClass = new MappingClass(`${this.topParent?._PARENT.path}_${this.topParent?.id}${protocol.property.property}`); const _multiplicity = this.context.graph.getMultiplicity(localMappingProperty.multiplicity.lowerBound, localMappingProperty.multiplicity.upperBound); const _property = new Property(protocol.property.property, _multiplicity, this.context.resolveGenericType(localMappingProperty.type), mappingClass); property = PropertyImplicitReference.create(PackageableElementImplicitReference.create(mappingClass, protocol.property.class), _property); localMapping = new LocalMappingPropertyInfo(); localMapping.localMappingProperty = true; localMapping.localMappingPropertyMultiplicity = _multiplicity; localMapping.localMappingPropertyType = this.context.resolveType(localMappingProperty.type); } else { assertNonEmptyString(protocol.property.class, `Pure instance property mapping 'property.class' field is missing or empty`); property = this.context.resolveProperty(protocol.property); } const propertyType = property.value.genericType.value.rawType; let targetSetImplementation; const topParent = guaranteeNonNullable(this.topParent); if (propertyType instanceof Class) { if (protocol.target) { targetSetImplementation = TEMPORARY__resolveSetImplementationByID(topParent._PARENT, protocol.target, this.context); } else { // NOTE: if no there is one non-root class mapping, auto-nominate that as the target set implementation targetSetImplementation = getClassMappingsByClass(topParent._PARENT, guaranteeType(propertyType, Class))[0]; } } const sourceSetImplementation = protocol.source ? TEMPORARY__resolveSetImplementationByID(topParent._PARENT, protocol.source, this.context) : undefined; const purePropertyMapping = new PurePropertyMapping(topParent, property, V1_buildRawLambdaWithResolvedPaths([], protocol.transform.body, this.context), SetImplementationImplicitReference.create(sourceSetImplementation ?? topParent, protocol.source), targetSetImplementation ? SetImplementationImplicitReference.create(targetSetImplementation, protocol.target) : undefined, protocol.explodeProperty); if (protocol.enumMappingId) { const enumerationMapping = this.allEnumerationMappings.find((em) => em.id.value === protocol.enumMappingId); if (!enumerationMapping) { // TODO: Since we don't support includedMappings, this will throw errors, but right now we can just make it undefined. this.context.logService.debug(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), `Can't find enumeration mapping with ID '${protocol.enumMappingId}' in mapping '${topParent._PARENT.path}' (perhaps because we haven't supported included mappings)`); } purePropertyMapping.transformer = enumerationMapping ? EnumerationMappingExplicitReference.create(enumerationMapping) : undefined; } purePropertyMapping.localMappingProperty = localMapping; return purePropertyMapping; } visit_FlatDataPropertyMapping(protocol) { assertNonNullable(protocol.property, `Flat-data property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Flat-data property mapping 'property.property' field is missing or empty`); assertNonNullable(protocol.transform, `Flat-data property mapping 'transform' field is missing`); // NOTE: there are cases that property pointer class might be missing, such as when we transform grammar to JSON // since we do not do look up, due to nesting structure introudced by embedded mappings, we might not have the class information // as such, here we have to resolve the class being mapped depending on where the property mapping is in the class mapping let propertyOwnerClass; if (protocol.property.class) { propertyOwnerClass = this.context.resolveClass(protocol.property.class).value; } else if (this.immediateParent instanceof EmbeddedFlatDataPropertyMapping) { propertyOwnerClass = this.immediateParent.class.value; } else { throw new GraphBuilderError(`Can't find property owner class for property '${protocol.property.property}'`); } // NOTE: mapping for derived property is not supported const property = getClassProperty(propertyOwnerClass, protocol.property.property); const sourceSetImplementation = guaranteeNonNullable(this.immediateParent instanceof EmbeddedFlatDataPropertyMapping ? this.immediateParent : this.topParent); // target let targetSetImplementation; const propertyType = property.genericType.value.rawType; if (propertyType instanceof Class && protocol.target) { targetSetImplementation = this.topParent ? TEMPORARY__resolveSetImplementationByID(this.topParent._PARENT, protocol.target, this.context) : undefined; } const flatDataPropertyMapping = new FlatDataPropertyMapping(this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(propertyOwnerClass, protocol.property.class ?? ''), property), V1_buildRawLambdaWithResolvedPaths([], protocol.transform.body, this.context), SetImplementationImplicitReference.create(sourceSetImplementation, protocol.source), targetSetImplementation ? SetImplementationImplicitReference.create(targetSetImplementation, protocol.target) : undefined); if (protocol.enumMappingId) { const enumerationMapping = this.allEnumerationMappings.find((em) => em.id.value === protocol.enumMappingId); if (!enumerationMapping) { // TODO: Since we don't support includedMappings, this will throw errors, but right now we can just make it undefined. this.context.logService.debug(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), `Can't find enumeration mapping with ID '${protocol.enumMappingId}' in mapping '${this.topParent?._PARENT.path} (perhaps because we haven't supported included mappings)`); } flatDataPropertyMapping.transformer = enumerationMapping ? EnumerationMappingExplicitReference.create(enumerationMapping) : undefined; } return flatDataPropertyMapping; } visit_EmbeddedFlatDataPropertyMapping(protocol) { assertNonNullable(protocol.property, `Embedded flat-data property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Embedded flat-data property mapping property 'property.property' field is missing or empty`); // NOTE: there are cases that property pointer class might be missing, such as when we transform grammar to JSON // since we do not do look up, due to nesting structure introudced by embedded mappings, we might not have the class information // as such, here we have to resolve the class being mapped depending on where the property mapping is in the class mapping let propertyOwnerClass; if (protocol.property.class) { propertyOwnerClass = this.context.resolveClass(protocol.property.class).value; } else if (this.immediateParent instanceof EmbeddedFlatDataPropertyMapping) { propertyOwnerClass = this.immediateParent.class.value; } else { throw new GraphBuilderError(`Can't find property owner class for property '${protocol.property.property}'`); } const property = getClassProperty(propertyOwnerClass, protocol.property.property); let _class; if (protocol.class) { _class = this.context.resolveClass(protocol.class); } else { const propertyType = property.genericType.value.rawType; const complexClass = guaranteeType(propertyType, Class, 'Only complex classes can be the target of an embedded property mapping'); _class = PackageableElementImplicitReference.create(complexClass, ''); } const sourceSetImplementation = guaranteeNonNullable(this.immediateParent instanceof EmbeddedFlatDataPropertyMapping ? this.immediateParent : this.topParent); const embeddedPropertyMapping = new EmbeddedFlatDataPropertyMapping(this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(propertyOwnerClass, protocol.property.class ?? ''), property), guaranteeNonNullable(this.topParent), SetImplementationImplicitReference.create(sourceSetImplementation, protocol.source), _class, InferableMappingElementIdExplicitValue.create(`${sourceSetImplementation.id.value}.${property.name}`, ''), undefined); embeddedPropertyMapping.targetSetImplementation = protocol.target ? SetImplementationImplicitReference.create(embeddedPropertyMapping, protocol.target) : undefined; embeddedPropertyMapping.propertyMappings = protocol.propertyMappings.map((propertyMapping) => propertyMapping.accept_PropertyMappingVisitor(new V1_PropertyMappingBuilder(this.context, embeddedPropertyMapping, this.topParent, this.allEnumerationMappings))); return embeddedPropertyMapping; } visit_RelationalPropertyMapping(protocol) { assertNonNullable(protocol.property, `Relational property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Relational property mapping 'property.property' field is missing or empty`); assertNonNullable(protocol.relationalOperation, `Relational property mapping 'relationalOperation' field is missing`); // NOTE: mapping for derived property is not supported let propertyOwner; let property; let localMapping; if (protocol.localMappingProperty) { const localMappingProperty = protocol.localMappingProperty; const mappingClass = new MappingClass(`${this.topParent?._PARENT.path}_${this.topParent?.id}${protocol.property.property}`); const _multiplicity = this.context.graph.getMultiplicity(localMappingProperty.multiplicity.lowerBound, localMappingProperty.multiplicity.upperBound); const _property = new Property(protocol.property.property, _multiplicity, this.context.resolveGenericType(localMappingProperty.type), mappingClass); property = PropertyImplicitReference.create(PackageableElementImplicitReference.create(mappingClass, protocol.property.class), _property).value; localMapping = new LocalMappingPropertyInfo(); localMapping.localMappingProperty = true; localMapping.localMappingPropertyMultiplicity = _multiplicity; localMapping.localMappingPropertyType = this.context.resolveType(localMappingProperty.type); propertyOwner = property._OWNER; } else { if (this.immediateParent instanceof AssociationImplementation) { propertyOwner = this.immediateParent.association.value; } else if (protocol.property.class) { propertyOwner = this.context.resolveClass(protocol.property.class).value; } else if (this.immediateParent instanceof EmbeddedRelationalInstanceSetImplementation) { propertyOwner = this.immediateParent._OWNER instanceof EmbeddedRelationalInstanceSetImplementation && this.immediateParent.property.value.name === protocol.property.property ? this.immediateParent.property.ownerReference.value : this.immediateParent.class.value; } else { throw new GraphBuilderError(`Can't find property owner class for property '${protocol.property.property}'`); } property = propertyOwner instanceof Class ? getClassProperty(propertyOwner, protocol.property.property) : getOwnProperty(propertyOwner, protocol.property.property); } // NOTE: mapping for derived property is not supported // since we are not doing embedded property mappings yet, the target must have already been added to the mapping const propertyType = property.genericType.value.rawType; let targetSetImplementation; if (propertyType instanceof Class) { let parentMapping = this.topParent?._PARENT; if (!parentMapping && this.immediateParent instanceof AssociationImplementation) { parentMapping = this.immediateParent._PARENT; } if (protocol.target) { targetSetImplementation = parentMapping ? TEMPORARY__resolveSetImplementationByID(parentMapping, protocol.target, this.context) : undefined; } else { targetSetImplementation = parentMapping ? getClassMappingsByClass(parentMapping, guaranteeType(propertyType, Class))[0] : undefined; } } const sourceSetImplementation = guaranteeNonNullable(resolvePropertyMappingSourceImplementation(this.immediateParent, protocol, this.topParent, this.context)); const relationalPropertyMapping = new RelationalPropertyMapping(this.topParent ?? this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(propertyOwner, protocol.property.class ?? ''), property), SetImplementationImplicitReference.create(sourceSetImplementation, protocol.source), targetSetImplementation ? SetImplementationImplicitReference.create(targetSetImplementation, protocol.target) : undefined); if (protocol.bindingTransformer?.binding) { const bindingTransformer = new BindingTransformer(); const binding = V1_resolveBinding(protocol.bindingTransformer.binding, this.context); bindingTransformer.binding = binding; relationalPropertyMapping.bindingTransformer = bindingTransformer; } // NOTE: we only need to use the raw form of the operation for the editor // but we need to process it anyway so we can: // 1. do analytics on table alias map // 2. and to resolve paths (similar to lambda). // As such, we will need to do a full round-trip processing for the operation // See https://github.com/finos/legend-studio/pull/173 try { relationalPropertyMapping.relationalOperation = V1_serializeRelationalOperationElement(V1_transformRelationalOperationElement(V1_buildRelationalOperationElement(V1_deserializeRelationalOperationElement(protocol.relationalOperation), this.context, this.tableAliasIndex, []), new V1_GraphTransformerContextBuilder(this.context.extensions.plugins).build(), { // NOTE: here we will always resolve paths found in the operation to full // since right now we still delete the section index, which will cause // these paths to be potentially become corrupted. TEMPORARY__resolveToFullPath: true, })); } catch { relationalPropertyMapping.relationalOperation = protocol.relationalOperation; } if (protocol.enumMappingId) { const enumerationMapping = this.allEnumerationMappings.find((em) => em.id.value === protocol.enumMappingId); if (!enumerationMapping) { // TODO: Since we don't support includedMappings, this will throw errors, but right now we can just make it undefined. this.context.logService.debug(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), `Can't find enumeration mapping with ID '${protocol.enumMappingId}' in mapping '${this.topParent?._PARENT.path}' (perhaps because we haven't supported included mappings)`); } relationalPropertyMapping.transformer = enumerationMapping ? EnumerationMappingExplicitReference.create(enumerationMapping) : undefined; } relationalPropertyMapping.localMappingProperty = localMapping; return relationalPropertyMapping; } visit_FlatDataAssociationPropertyMapping(protocol) { assertNonNullable(protocol.property, `FlatData property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `FlatData property mapping 'property.property' field is missing or empty`); assertNonNullable(protocol.flatData, `FlatData property mapping 'flatdata' field is missing`); assertNonNullable(protocol.sectionName, `FlatData property mapping 'sectionName' field is missing`); // NOTE: mapping for derived property is not supported let propertyOwner; if (this.immediateParent instanceof AssociationImplementation) { propertyOwner = this.immediateParent.association.value; } else { throw new GraphBuilderError(`Can't find property owner class for property '${protocol.property.property}'`); } const property = getOwnProperty(propertyOwner, protocol.property.property); // NOTE: mapping for derived property is not supported // since we are not doing embedded property mappings yet, the target must have already been added to the mapping const propertyType = property.genericType.value.rawType; let targetSetImplementation; if (propertyType instanceof Class) { const parentMapping = this.immediateParent._PARENT; if (protocol.target) { targetSetImplementation = TEMPORARY__resolveSetImplementationByID(parentMapping, protocol.target, this.context); } else { targetSetImplementation = getClassMappingsByClass(parentMapping, guaranteeType(propertyType, Class))[0]; } } const sourceSetImplementation = guaranteeNonNullable(resolvePropertyMappingSourceImplementation(this.immediateParent, protocol, this.topParent, this.context)); const flatDataAssociationPropertyMapping = new FlatDataAssociationPropertyMapping(this.topParent ?? this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(propertyOwner, protocol.property.class ?? ''), property), SetImplementationImplicitReference.create(sourceSetImplementation, protocol.source), targetSetImplementation ? SetImplementationImplicitReference.create(targetSetImplementation, protocol.target) : undefined); flatDataAssociationPropertyMapping.flatData = protocol.flatData; flatDataAssociationPropertyMapping.sectionName = protocol.sectionName; return flatDataAssociationPropertyMapping; } visit_InlineEmbeddedPropertyMapping(protocol) { assertNonNullable(protocol.property, `Inline embedded property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Inline embedded property mapping 'property.property' field is missing or empty`); let propertyOwnerClass; if (protocol.property.class) { propertyOwnerClass = this.context.resolveClass(protocol.property.class).value; } else if (this.immediateParent instanceof RootRelationalInstanceSetImplementation || this.immediateParent instanceof EmbeddedRelationalInstanceSetImplementation) { propertyOwnerClass = this.immediateParent.class.value; } else { throw new GraphBuilderError(`Can't find property owner class for property '${protocol.property.property}'`); } const property = getClassProperty(propertyOwnerClass, protocol.property.property); const propertyType = property.genericType.value.rawType; const complexClass = guaranteeType(propertyType, Class, 'Only complex classes can be the target of an embedded property mapping'); const _class = PackageableElementImplicitReference.create(complexClass, protocol.property.class ?? ''); const id = `${this.immediateParent.id.value}_${property.name}`; const topParent = guaranteeNonNullable(this.topParent); const sourceSetImplementation = this.immediateParent instanceof RootRelationalInstanceSetImplementation ? this.immediateParent : topParent; const inline = new InlineEmbeddedRelationalInstanceSetImplementation(this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(propertyOwnerClass, protocol.property.class ?? ''), property), guaranteeType(this.topParent, RootRelationalInstanceSetImplementation), SetImplementationImplicitReference.create(sourceSetImplementation, protocol.source), _class, InferableMappingElementIdExplicitValue.create(id, ''), undefined); inline.inlineSetImplementation = TEMPORARY__resolveSetImplementationByID(topParent._PARENT, protocol.setImplementationId, this.context); return inline; } visit_EmbeddedRelationalPropertyMapping(protocol) { assertNonNullable(protocol.property, `Embedded relational property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Embedded relational property mapping 'property.property' field is missing or empty`); const property = V1_buildEmbeddedRelationalMappingProperty(protocol, this.immediateParent, guaranteeNonNullable(this.topParent), this.context); const embedded = new EmbeddedRelationalInstanceSetImplementation(this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(property.propertyOwnerClass, protocol.property.class ?? ''), property.property), guaranteeType(this.topParent, RootRelationalInstanceSetImplementation), SetImplementationImplicitReference.create(property.sourceSetImplementation, protocol.source), property._class, InferableMappingElementIdExplicitValue.create(`${property.id.value}`, ''), undefined); embedded.primaryKey = protocol.classMapping.primaryKey.map((key) => V1_buildRelationalOperationElement(key, this.context, this.tableAliasIndex, [])); embedded.propertyMappings = protocol.classMapping.propertyMappings.map((propertyMapping) => propertyMapping.accept_PropertyMappingVisitor(new V1_PropertyMappingBuilder(this.context, embedded, this.topParent, this.topParent?._PARENT ? getAllEnumerationMappings(this.topParent._PARENT) : [], this.tableAliasIndex))); return embedded; } visit_OtherwiseEmbeddedRelationalPropertyMapping(protocol) { assertNonNullable(protocol.property, `Otherwise embedded relational property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Otherwise embedded relational property mapping 'property.property' field is missing or empty`); const property = V1_buildEmbeddedRelationalMappingProperty(protocol, this.immediateParent, guaranteeNonNullable(this.topParent), this.context); const otherwiseEmbedded = new OtherwiseEmbeddedRelationalInstanceSetImplementation(this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(property.propertyOwnerClass, protocol.property.class ?? ''), property.property), guaranteeType(this.topParent, RootRelationalInstanceSetImplementation), SetImplementationImplicitReference.create(property.sourceSetImplementation, protocol.source), property._class, InferableMappingElementIdExplicitValue.create(`${property.id.value}`, ''), undefined); otherwiseEmbedded.primaryKey = protocol.classMapping.primaryKey.map((key) => V1_buildRelationalOperationElement(key, this.context, this.tableAliasIndex, [])); otherwiseEmbedded.propertyMappings = protocol.classMapping.propertyMappings.map((propertyMapping) => propertyMapping.accept_PropertyMappingVisitor(new V1_PropertyMappingBuilder(this.context, otherwiseEmbedded, this.topParent, this.topParent?._PARENT ? getAllEnumerationMappings(this.topParent._PARENT) : [], this.tableAliasIndex))); otherwiseEmbedded.otherwisePropertyMapping = guaranteeType(protocol.otherwisePropertyMapping.accept_PropertyMappingVisitor(new V1_PropertyMappingBuilder(this.context, otherwiseEmbedded, this.topParent, this.topParent?._PARENT ? getAllEnumerationMappings(this.topParent._PARENT) : [], this.tableAliasIndex)), RelationalPropertyMapping); return otherwiseEmbedded; } visit_XStorePropertyMapping(protocol) { assertNonNullable(protocol.property, `XStore property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.class, `XStore property mapping 'property.class' field is missing or empty`); assertNonEmptyString(protocol.property.property, `XStore property mapping 'property.property' field is missing or empty`); assertNonNullable(protocol.crossExpression, `XStore property mapping 'crossExpression' field is missing`); const xStoreParent = guaranteeNonNullable(this.xStoreParent, `XStore property 'xStoreParent' field is missing`); const _association = xStoreParent.association.value; const property = getOwnProperty(_association, protocol.property.property); const sourceSetImplementation = guaranteeNonNullable(resolvePropertyMappingSourceImplementation(this.immediateParent, protocol, this.topParent, this.context)); let targetSetImplementation; const propertyType = property.genericType.value.rawType; if (propertyType instanceof Class) { const parentMapping = this.immediateParent._PARENT; if (protocol.target) { targetSetImplementation = TEMPORARY__resolveSetImplementationByID(parentMapping, protocol.target, this.context); } else { targetSetImplementation = getClassMappingsByClass(parentMapping, guaranteeType(propertyType, Class))[0]; } } const xStorePropertyMapping = new XStorePropertyMapping(xStoreParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(_association, protocol.property.class), property), SetImplementationImplicitReference.create(sourceSetImplementation, protocol.source), targetSetImplementation ? SetImplementationImplicitReference.create(targetSetImplementation, protocol.target) : undefined); xStorePropertyMapping.crossExpression = V1_buildRawLambdaWithResolvedPaths(protocol.crossExpression.parameters, protocol.crossExpression.body, this.context); return xStorePropertyMapping; } visit_AggregationAwarePropertyMapping(protocol) { assertNonNullable(protocol.property, `Aggregation-aware property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.class, `Aggregation-aware property mapping 'property.class' field is missing or empty`); assertNonEmptyString(protocol.property.property, `Aggregation-aware property mapping 'property.property' field is missing or empty`); const aggregationAwareParent = guaranteeNonNullable(this.aggregationAwareParent, `Aggregation-aware property 'aggregationAwareParent' field is missing`); const propertyMapping = aggregationAwareParent.mainSetImplementation.propertyMappings.find((p) => p.property.value.name === protocol.property.property); const property = propertyMapping?.property ?? this.context.resolveProperty(protocol.property); const sourceSetImplementation = guaranteeNonNullable(resolvePropertyMappingSourceImplementation(this.immediateParent, protocol, this.topParent, this.context)); let targetSetImplementation; const propertyType = property.value.genericType.value.rawType; if (propertyType instanceof Class) { const parentMapping = this.immediateParent._PARENT; if (protocol.target) { targetSetImplementation = TEMPORARY__resolveSetImplementationByID(parentMapping, protocol.target, this.context); } else { targetSetImplementation = getClassMappingsByClass(parentMapping, guaranteeType(propertyType, Class))[0]; } } const aggregationAwarePropertyMapping = new AggregationAwarePropertyMapping(this.topParent ?? this.immediateParent, property, SetImplementationImplicitReference.create(guaranteeNonNullable(sourceSetImplementation), protocol.source), targetSetImplementation ? SetImplementationImplicitReference.create(targetSetImplementation, protocol.target) : undefined); if (protocol.localMappingProperty && propertyMapping?.localMappingProperty) { aggregationAwarePropertyMapping.localMappingProperty = guaranteeNonNullable(propertyMapping.localMappingProperty); } return aggregationAwarePropertyMapping; } visit_RelationFunctionPropertyMapping(protocol) { assertNonNullable(protocol.property, `Relation Function property mapping 'property' field is missing`); assertNonEmptyString(protocol.property.property, `Relation Function property mapping 'property.property' field is missing or empty`); let propertyOwner; let property; let localMapping; if (protocol.localMappingProperty) { const localMappingProperty = protocol.localMappingProperty; const mappingClass = new MappingClass(`${this.topParent?._PARENT.path}_${this.topParent?.id}${protocol.property.property}`); const _multiplicity = this.context.graph.getMultiplicity(localMappingProperty.multiplicity.lowerBound, localMappingProperty.multiplicity.upperBound); const _property = new Property(protocol.property.property, _multiplicity, this.context.resolveGenericType(localMappingProperty.type), mappingClass); property = PropertyImplicitReference.create(PackageableElementImplicitReference.create(mappingClass, protocol.property.class), _property).value; localMapping = new LocalMappingPropertyInfo(); localMapping.localMappingProperty = true; localMapping.localMappingPropertyMultiplicity = _multiplicity; localMapping.localMappingPropertyType = this.context.resolveType(localMappingProperty.type); propertyOwner = property._OWNER; } else { if (protocol.property.class) { propertyOwner = this.context.resolveClass(protocol.property.class).value; } else { throw new GraphBuilderError(`Can't find property owner class for property '${protocol.property.property}'`); } property = propertyOwner instanceof Class ? getClassProperty(propertyOwner, protocol.property.property) : getOwnProperty(propertyOwner, protocol.property.property); } const sourceSetImplementation = guaranteeNonNullable(resolvePropertyMappingSourceImplementation(this.immediateParent, protocol, this.topParent, this.context)); const propertyType = property.genericType.value.rawType; const propertyMapping = new RelationFunctionPropertyMapping(this.topParent ?? this.immediateParent, PropertyImplicitReference.create(PackageableElementImplicitReference.create(propertyOwner, protocol.property.class ?? ''), property), SetImplementationImplicitReference.create(sourceSetImplementation, protocol.source), undefined, new RelationColumn(protocol.column, propertyType)); propertyMapping.localMappingProperty = localMapping; return propertyMapping; } } //# sourceMappingURL=V1_PropertyMappingBuilder.js.map