UNPKG

@finos/legend-application-studio

Version:
245 lines 11.9 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 { observable, action, computed, makeObservable } from 'mobx'; import { InstanceSetImplementationState, PropertyMappingState, } from './MappingElementState.js'; import { assertErrorThrown, LogEvent, UnsupportedOperationError, guaranteeType, IllegalStateError, } from '@finos/legend-shared'; import { MappingElementDecorator } from './MappingElementDecorator.js'; import { LAMBDA_PIPE, GRAPH_MANAGER_EVENT, ParserError, FlatDataPropertyMapping, EmbeddedFlatDataPropertyMapping, Class, InferableMappingElementIdExplicitValue, PackageableElementExplicitReference, PropertyExplicitReference, buildSourceInformationSourceId, stub_RawLambda, isStubbed_RawLambda, SetImplementationExplicitReference, } from '@finos/legend-graph'; import { MAPPING_ELEMENT_TYPE } from './MappingEditorState.js'; export class FlatDataPropertyMappingState extends PropertyMappingState { editorStore; constructor(editorStore, instanceSetImplementationState, propertyMapping) { super(instanceSetImplementationState, propertyMapping, '', LAMBDA_PIPE); this.propertyMapping = propertyMapping; this.editorStore = editorStore; } get lambdaId() { return buildSourceInformationSourceId([ this.propertyMapping._OWNER._PARENT.path, MAPPING_ELEMENT_TYPE.CLASS, this.propertyMapping._OWNER.id.value, this.propertyMapping.property.value.name, this.uuid, // in case of duplications ]); } *convertLambdaGrammarStringToObject() { const emptyLambda = stub_RawLambda(); if (this.lambdaString) { try { const lambda = (yield this.editorStore.graphManagerState.graphManager.pureCodeToLambda(this.fullLambdaString, this.lambdaId)); this.setParserError(undefined); if (this.propertyMapping instanceof FlatDataPropertyMapping) { this.propertyMapping.transform = lambda; } } catch (error) { assertErrorThrown(error); if (error instanceof ParserError) { this.setParserError(error); } this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.PARSING_FAILURE), error); } } else { this.clearErrors(); if (this.propertyMapping instanceof FlatDataPropertyMapping) { this.propertyMapping.transform = emptyLambda; } } } *convertLambdaObjectToGrammarString(options) { if (this.propertyMapping instanceof FlatDataPropertyMapping) { if (!isStubbed_RawLambda(this.propertyMapping.transform)) { try { const lambdas = new Map(); lambdas.set(this.lambdaId, this.propertyMapping.transform); const isolatedLambdas = (yield this.editorStore.graphManagerState.graphManager.lambdasToPureCode(lambdas, options?.pretty)); const grammarText = isolatedLambdas.get(this.lambdaId); this.setLambdaString(grammarText !== undefined ? this.extractLambdaString(grammarText) : ''); this.clearErrors({ preserveCompilationError: options?.preserveCompilationError, }); } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.PARSING_FAILURE), error); } } else { this.clearErrors(); this.setLambdaString(''); } } } } export class FlatDataInstanceSetImplementationState extends InstanceSetImplementationState { isConvertingTransformLambdaObjects = false; constructor(editorStore, setImplementation) { super(editorStore, setImplementation); makeObservable(this, { isConvertingTransformLambdaObjects: observable, hasParserError: computed, setPropertyMappingStates: action, addEmbeddedPropertyMapping: action, }); this.mappingElement = setImplementation; } get hasParserError() { return this.propertyMappingStates.some((propertyMappingState) => propertyMappingState.parserError); } setPropertyMappingStates(propertyMappingState) { this.propertyMappingStates = propertyMappingState; } /** * When we decorate, we might lose the error (parser/compiler) on each of the property mapping state * so here we make sure that we reuse existing state and only add new decorated ones */ decorate() { this.mappingElement.accept_SetImplementationVisitor(new MappingElementDecorator(this.editorStore)); const newPropertyMappingStates = []; const propertyMappingstatesAfterDecoration = this.getPropertyMappingStates(this.mappingElement.propertyMappings); propertyMappingstatesAfterDecoration.forEach((propertyMappingState) => { const existingPropertyMappingState = this.propertyMappingStates.find((p) => p.propertyMapping === propertyMappingState.propertyMapping); newPropertyMappingStates.push(existingPropertyMappingState ?? propertyMappingState); }); this.setPropertyMappingStates(newPropertyMappingStates); } *convertPropertyMappingTransformObjects() { const lambdas = new Map(); const propertyMappingStates = new Map(); this.propertyMappingStates.forEach((pm) => { if (pm.propertyMapping instanceof FlatDataPropertyMapping && !isStubbed_RawLambda(pm.propertyMapping.transform)) { lambdas.set(pm.lambdaId, pm.propertyMapping.transform); propertyMappingStates.set(pm.lambdaId, pm); } // we don't have to do anything for embedded. they don't have a transform and do not require converting back and form. }); if (lambdas.size) { this.isConvertingTransformLambdaObjects = true; try { const isolatedLambdas = (yield this.editorStore.graphManagerState.graphManager.lambdasToPureCode(lambdas)); isolatedLambdas.forEach((grammarText, key) => { const flatDataPropertyMappingState = propertyMappingStates.get(key); flatDataPropertyMappingState?.setLambdaString(flatDataPropertyMappingState.extractLambdaString(grammarText)); }); } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.PARSING_FAILURE), error); } finally { this.isConvertingTransformLambdaObjects = false; } } } addEmbeddedPropertyMapping(property) { const rootInstanceSetImplementation = this.mappingElement instanceof EmbeddedFlatDataPropertyMapping ? this.mappingElement.rootInstanceSetImplementation : this.mappingElement; const _class = guaranteeType(property.genericType.value.rawType, Class); const embeddedPropertyMapping = new EmbeddedFlatDataPropertyMapping(this.mappingElement, PropertyExplicitReference.create(property), rootInstanceSetImplementation, SetImplementationExplicitReference.create(this.mappingElement), PackageableElementExplicitReference.create(_class), InferableMappingElementIdExplicitValue.create(`${this.mappingElement.id.value}.${property.name}`, ''), undefined); embeddedPropertyMapping.targetSetImplementation = SetImplementationExplicitReference.create(embeddedPropertyMapping); this.mappingElement.propertyMappings.push(embeddedPropertyMapping); return embeddedPropertyMapping; } } export class EmbeddedFlatDataInstanceSetImplementationState extends FlatDataInstanceSetImplementationState { constructor(editorStore, instanceSetImplementationState, setImplementation) { super(editorStore, setImplementation); this.instanceSetImplementationState = instanceSetImplementationState; this.mappingElement = setImplementation; this.propertyMapping = setImplementation; this.propertyMappingStates = this.getPropertyMappingStates(setImplementation.propertyMappings); } typeAheadEnabled = false; getCodeComplete(input) { throw new Error('Method not implemented.'); } setTypeAhead(val) { this.typeAheadEnabled = val; } get lambdaId() { throw new IllegalStateError(`Can't build lambda ID for embedded flat data instance set implementation state`); } getPropertyMappingStates(propertyMappings) { return propertyMappings.map((pm) => { if (pm instanceof FlatDataPropertyMapping) { return new FlatDataPropertyMappingState(this.editorStore, this.instanceSetImplementationState, pm); } else if (pm instanceof EmbeddedFlatDataPropertyMapping) { return new EmbeddedFlatDataInstanceSetImplementationState(this.editorStore, this.instanceSetImplementationState, pm); } throw new UnsupportedOperationError(); }); } // dummy lambda editor states needed because embedded flat-data should be seen as `PropertyMappingState` lambdaPrefix = ''; lambdaString = ''; parserError; compilationError; setLambdaString(val) { return; } setParserError(error) { return; } setCompilationError(error) { // TODO return; } get fullLambdaString() { throw new UnsupportedOperationError(); } processSourceInformation(sourceInformation) { throw new UnsupportedOperationError(); } extractLambdaString(fullLambdaString) { throw new UnsupportedOperationError(); } clearErrors(options) { // TODO return; } *convertLambdaGrammarStringToObject() { throw new UnsupportedOperationError(); } *convertLambdaObjectToGrammarString(options) { throw new UnsupportedOperationError(); } } export class RootFlatDataInstanceSetImplementationState extends FlatDataInstanceSetImplementationState { constructor(editorStore, setImplementation) { super(editorStore, setImplementation); this.mappingElement = setImplementation; this.propertyMappingStates = this.getPropertyMappingStates(setImplementation.propertyMappings); } getPropertyMappingStates(propertyMappings) { return propertyMappings.map((propertyMapping) => { if (propertyMapping instanceof FlatDataPropertyMapping) { return new FlatDataPropertyMappingState(this.editorStore, this, propertyMapping); } else if (propertyMapping instanceof EmbeddedFlatDataPropertyMapping) { return new EmbeddedFlatDataInstanceSetImplementationState(this.editorStore, this, propertyMapping); } throw new UnsupportedOperationError(); }); } } //# sourceMappingURL=FlatDataInstanceSetImplementationState.js.map