@finos/legend-application-studio
Version:
Legend Studio application core
553 lines • 31.7 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 { action, computed, flow, flowResult, makeObservable, observable, } from 'mobx';
import { GRAPH_EDITOR_MODE } from './EditorConfig.js';
import { LogEvent, UnsupportedOperationError, assertErrorThrown, assertTrue, isNonNullable, NetworkClientError, guaranteeNonNullable, StopWatch, filterByType, ActionState, } from '@finos/legend-shared';
import { ElementEditorState } from './editor-state/element-editor-state/ElementEditorState.js';
import { GraphGenerationState } from './editor-state/GraphGenerationState.js';
import { MODEL_IMPORT_NATIVE_INPUT_TYPE } from './editor-state/ModelImporterState.js';
import { EntitiesWithOrigin } from '@finos/legend-storage';
import { ProjectConfiguration, applyEntityChanges, } from '@finos/legend-server-sdlc';
import { ProjectVersionEntities, ProjectDependencyCoordinates, RawProjectDependencyReport, buildDependencyReport, } from '@finos/legend-server-depot';
import { GRAPH_MANAGER_EVENT, Package, Profile, PrimitiveType, Enumeration, Class, Association, Mapping, ConcreteFunctionDefinition, Service, FlatData, PackageableConnection, PackageableRuntime, FileGenerationSpecification, GenerationSpecification, Measure, Unit, Database, SectionIndex, DependencyGraphBuilderError, GraphDataDeserializationError, DataElement, createGraphBuilderReport, ExecutionEnvironmentInstance, SnowflakeApp, GraphEntities, HostedService, } from '@finos/legend-graph';
import { CONFIGURATION_EDITOR_TAB } from './editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js';
import { PACKAGEABLE_ELEMENT_TYPE } from './utils/ModelClassifierUtils.js';
import { LEGEND_STUDIO_APP_EVENT } from '../../__lib__/LegendStudioEvent.js';
import { LEGEND_STUDIO_SETTING_KEY } from '../../__lib__/LegendStudioSetting.js';
import { LegendStudioTelemetryHelper } from '../../__lib__/LegendStudioTelemetryHelper.js';
export var GraphBuilderStatus;
(function (GraphBuilderStatus) {
GraphBuilderStatus["SUCCEEDED"] = "SUCCEEDED";
GraphBuilderStatus["FAILED"] = "FAILED";
GraphBuilderStatus["REDIRECTED_TO_TEXT_MODE"] = "REDIRECTED_TO_TEXT_MODE";
})(GraphBuilderStatus || (GraphBuilderStatus = {}));
export var GraphCompilationOutcome;
(function (GraphCompilationOutcome) {
GraphCompilationOutcome["SKIPPED"] = "SKIPPED";
GraphCompilationOutcome["SUCCEEDED"] = "SUCCEEDED";
GraphCompilationOutcome["FAILED"] = "FAILED";
})(GraphCompilationOutcome || (GraphCompilationOutcome = {}));
export class EditorGraphState {
editorStore;
graphGenerationState;
isInitializingGraph = false;
isRunningGlobalCompile = false;
isRunningGlobalGenerate = false;
isApplicationLeavingGraphEditMode = false;
isUpdatingGraph = false; // critical synchronous update to refresh the graph
isUpdatingApplication = false; // including graph update and async operations such as change detection
functionActivatorConfigurations = [];
relationalDatabseTypeConfigurations;
warnings = [];
error;
compilationResultEntities = [];
enableStrictMode;
mostRecentCompilationGraphHash = undefined;
mostRecentCompilationOutcome = undefined;
constructor(editorStore) {
makeObservable(this, {
isInitializingGraph: observable,
isRunningGlobalCompile: observable,
isRunningGlobalGenerate: observable,
isApplicationLeavingGraphEditMode: observable,
isUpdatingGraph: observable,
isUpdatingApplication: observable,
functionActivatorConfigurations: observable,
mostRecentCompilationGraphHash: observable,
mostRecentCompilationOutcome: observable,
warnings: observable,
error: observable,
enableStrictMode: observable,
relationalDatabseTypeConfigurations: observable,
problems: computed,
areProblemsStale: computed,
isApplicationUpdateOperationIsRunning: computed,
clearProblems: action,
setEnableStrictMode: action,
setMostRecentCompilationGraphHash: action,
fetchAvailableRelationalDatabseTypeConfigurations: flow,
fetchAvailableFunctionActivatorConfigurations: flow,
buildGraph: flow,
loadEntityChangesToGraph: flow,
updateGenerationGraphAndApplication: flow,
rebuildDependencies: flow,
buildGraphForLazyText: flow,
});
this.editorStore = editorStore;
this.graphGenerationState = new GraphGenerationState(this.editorStore);
this.enableStrictMode =
this.editorStore.applicationStore.settingService.getBooleanValue(LEGEND_STUDIO_SETTING_KEY.EDITOR_STRICT_MODE) ?? false;
}
get problems() {
return [this.error, ...this.warnings].filter(isNonNullable);
}
/**
* This function is temporary. There is no good way to detect if a problem not coming from
* the main graph at the moment. In text mode, we can rely on the fact that the source information
* has line 0 column 0. But this is not the case for form mode, so this is just temporary
* to help with text-mode.
*/
TEMPORARY__removeDependencyProblems(problems) {
return problems.filter((problem) => {
if (problem.sourceInformation) {
return !(problem.sourceInformation.startLine === 0 &&
problem.sourceInformation.startColumn === 0 &&
problem.sourceInformation.endLine === 0 &&
problem.sourceInformation.endColumn === 0);
}
return true;
});
}
setMostRecentCompilationGraphHash(val) {
this.mostRecentCompilationGraphHash = val;
}
setMostRecentCompilationOutcome(val) {
this.mostRecentCompilationOutcome = val;
}
get areProblemsStale() {
return (this.mostRecentCompilationGraphHash !==
this.editorStore.graphEditorMode.getCurrentGraphHash());
}
get isApplicationUpdateOperationIsRunning() {
return (this.isRunningGlobalCompile ||
this.isRunningGlobalGenerate ||
this.isApplicationLeavingGraphEditMode ||
this.isUpdatingApplication ||
this.isInitializingGraph);
}
checkIfApplicationUpdateOperationIsRunning() {
if (this.isRunningGlobalGenerate) {
this.editorStore.applicationStore.notificationService.notifyWarning('Please wait for model generation to complete');
return true;
}
if (this.isRunningGlobalCompile) {
this.editorStore.applicationStore.notificationService.notifyWarning('Please wait for graph compilation to complete');
return true;
}
if (this.isApplicationLeavingGraphEditMode) {
this.editorStore.applicationStore.notificationService.notifyWarning('Please wait for editor to leave edit mode completely');
return true;
}
if (this.isUpdatingApplication) {
this.editorStore.applicationStore.notificationService.notifyWarning('Please wait for editor state to rebuild');
return true;
}
if (this.isInitializingGraph) {
this.editorStore.applicationStore.notificationService.notifyWarning('Please wait for editor initialization to complete');
return true;
}
return false;
}
clearProblems() {
this.error = undefined;
this.editorStore.tabManagerState.tabs
.filter(filterByType(ElementEditorState))
.forEach((editorState) => editorState.clearCompilationError());
this.mostRecentCompilationGraphHash = undefined;
this.warnings = [];
}
setEnableStrictMode(val) {
this.enableStrictMode = val;
}
*fetchAvailableFunctionActivatorConfigurations() {
try {
this.functionActivatorConfigurations =
(yield this.editorStore.graphManagerState.graphManager.getAvailableFunctionActivatorConfigurations(this.editorStore.graphManagerState.coreModel, this.editorStore.graphManagerState.systemModel));
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.GENERIC_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(error);
}
}
*fetchAvailableRelationalDatabseTypeConfigurations() {
try {
this.relationalDatabseTypeConfigurations =
(yield this.editorStore.graphManagerState.graphManager.getAvailableRelationalDatabaseTypeConfigurations());
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.GENERIC_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(error);
}
}
findRelationalDatabaseTypeConfiguration(type) {
return this.relationalDatabseTypeConfigurations?.find((aFlow) => aFlow.type === type);
}
*buildGraph(entities) {
try {
this.isInitializingGraph = true;
const stopWatch = new StopWatch();
// reset
this.editorStore.graphManagerState.resetGraph();
// fetch and build dependencies
stopWatch.record();
const dependencyManager = this.editorStore.graphManagerState.graphManager.createDependencyManager();
this.editorStore.graphManagerState.graph.dependencyManager =
dependencyManager;
this.editorStore.graphManagerState.dependenciesBuildState.setMessage(`Fetching dependencies...`);
const dependencyEntitiesIndex = (yield flowResult(this.getIndexedDependencyEntities()));
stopWatch.record(GRAPH_MANAGER_EVENT.FETCH_GRAPH_DEPENDENCIES__SUCCESS);
const dependency_buildReport = createGraphBuilderReport();
yield this.editorStore.graphManagerState.graphManager.buildDependencies(this.editorStore.graphManagerState.coreModel, this.editorStore.graphManagerState.systemModel, dependencyManager, dependencyEntitiesIndex, this.editorStore.graphManagerState.dependenciesBuildState, {}, dependency_buildReport);
dependency_buildReport.timings[GRAPH_MANAGER_EVENT.FETCH_GRAPH_DEPENDENCIES__SUCCESS] = stopWatch.getRecord(GRAPH_MANAGER_EVENT.FETCH_GRAPH_DEPENDENCIES__SUCCESS);
// build graph
const graph_buildReport = createGraphBuilderReport();
yield this.editorStore.graphManagerState.graphManager.buildGraph(this.editorStore.graphManagerState.graph, entities, this.editorStore.graphManagerState.graphBuildState, {
TEMPORARY__preserveSectionIndex: this.editorStore.applicationStore.config.options
.TEMPORARY__preserveSectionIndex,
strict: this.enableStrictMode,
}, graph_buildReport);
// build generations
const generation_buildReport = createGraphBuilderReport();
yield this.editorStore.graphManagerState.graphManager.buildGenerations(this.editorStore.graphManagerState.graph, this.graphGenerationState.generatedEntities, this.editorStore.graphManagerState.generationsBuildState, {}, generation_buildReport);
// report
stopWatch.record(GRAPH_MANAGER_EVENT.INITIALIZE_GRAPH__SUCCESS);
const graphBuilderReportData = {
timings: this.editorStore.applicationStore.timeService.finalizeTimingsRecord(stopWatch),
dependencies: dependency_buildReport,
dependenciesCount: this.editorStore.graphManagerState.graph.dependencyManager
.numberOfDependencies,
graph: graph_buildReport,
generations: generation_buildReport,
generationsCount: this.graphGenerationState.generatedEntities.size,
};
LegendStudioTelemetryHelper.logEvent_GraphInitializationSucceeded(this.editorStore.applicationStore.telemetryService, graphBuilderReportData);
this.editorStore.applicationStore.logService.info(LogEvent.create(GRAPH_MANAGER_EVENT.INITIALIZE_GRAPH__SUCCESS), graphBuilderReportData);
// add generation specification if model generation elements exists in graph and no generation specification
yield flowResult(this.graphGenerationState.possiblyAddMissingGenerationSpecifications());
return {
status: GraphBuilderStatus.SUCCEEDED,
};
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), error);
if (error instanceof DependencyGraphBuilderError) {
this.editorStore.graphManagerState.graphBuildState.fail();
// no recovery if dependency models cannot be built, this makes assumption that all dependencies models are compiled successfully
// TODO: we might want to handle this more gracefully when we can show people the dependency model element in the future
this.editorStore.applicationStore.notificationService.notifyError(`Can't initialize dependency models. Error: ${error.message}`);
const projectConfigurationEditorState = this.editorStore.projectConfigurationEditorState;
projectConfigurationEditorState.setSelectedTab(CONFIGURATION_EDITOR_TAB.PROJECT_DEPENDENCIES);
this.editorStore.tabManagerState.openTab(projectConfigurationEditorState);
}
else if (error instanceof GraphDataDeserializationError) {
// if something goes wrong with de-serialization, redirect to model importer to fix
this.redirectToModelImporterForDebugging(error);
}
else if (error instanceof NetworkClientError) {
this.editorStore.graphManagerState.graphBuildState.fail();
this.editorStore.applicationStore.notificationService.notifyWarning(`Can't build graph. Error: ${error.message}`);
}
else {
// TODO: we should split this into 2 notifications when we support multiple notifications
this.editorStore.applicationStore.notificationService.notifyError(`Can't build graph. Redirected to text mode for debugging. Error: ${error.message}`);
this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), error);
try {
yield flowResult(this.editorStore.switchModes(GRAPH_EDITOR_MODE.GRAMMAR_TEXT, {
isGraphBuildFailure: true,
}));
}
catch (error2) {
assertErrorThrown(error2);
this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), error2);
if (error2 instanceof NetworkClientError) {
// in case the server cannot even transform the JSON due to corrupted protocol, we can redirect to model importer
this.redirectToModelImporterForDebugging(error2);
return {
status: GraphBuilderStatus.FAILED,
error: error2,
};
}
if (error2 instanceof Error) {
return {
status: GraphBuilderStatus.FAILED,
error: error2,
};
}
}
return {
status: GraphBuilderStatus.REDIRECTED_TO_TEXT_MODE,
error,
};
}
return {
status: GraphBuilderStatus.FAILED,
error,
};
}
finally {
this.isInitializingGraph = false;
}
}
*buildGraphForLazyText() {
this.isInitializingGraph = true;
const stopWatch = new StopWatch();
// reset
this.editorStore.graphManagerState.resetGraph();
// fetch and build dependencies
stopWatch.record();
const dependencyManager = this.editorStore.graphManagerState.graphManager.createDependencyManager();
this.editorStore.graphManagerState.graph.dependencyManager =
dependencyManager;
this.editorStore.graphManagerState.dependenciesBuildState.setMessage(`Fetching dependencies...`);
const dependencyEntitiesIndex = (yield flowResult(this.getIndexedDependencyEntities()));
stopWatch.record(GRAPH_MANAGER_EVENT.FETCH_GRAPH_DEPENDENCIES__SUCCESS);
dependencyManager.initialize(dependencyEntitiesIndex);
// set dependency manager graph origin to entities
if (dependencyManager.origin === undefined) {
dependencyManager.setOrigin(new GraphEntities(Array.from(dependencyEntitiesIndex.values())
.map((e) => e.entities)
.flat()));
}
this.isInitializingGraph = false;
this.editorStore.graphManagerState.dependenciesBuildState.sync(ActionState.create().pass());
}
redirectToModelImporterForDebugging(error) {
if (this.editorStore.isInConflictResolutionMode) {
this.editorStore.applicationStore.alertService.setBlockingAlert({
message: `Can't de-serialize graph model from entities`,
prompt: `Please refresh the application and abort conflict resolution`,
});
return;
}
this.editorStore.applicationStore.notificationService.notifyWarning(`Can't de-serialize graph model from entities. Redirected to model importer for debugging. Error: ${error.message}`);
const nativeImporterState = this.editorStore.modelImporterState.setNativeImportType(MODEL_IMPORT_NATIVE_INPUT_TYPE.ENTITIES);
// Making an async call
nativeImporterState.loadCurrentProjectEntities();
this.editorStore.tabManagerState.openTab(this.editorStore.modelImporterState);
}
/**
* Loads entity changes to graph and updates application.
*/
*loadEntityChangesToGraph(changes, baseEntities) {
try {
assertTrue(this.editorStore.graphEditorMode.mode === GRAPH_EDITOR_MODE.FORM, `Can't apply entity changes: operation only supported in form mode`);
const entities = baseEntities ??
this.editorStore.graphManagerState.graph.allOwnElements.map((element) => this.editorStore.graphManagerState.graphManager.elementToEntity(element));
const modifiedEntities = applyEntityChanges(entities, changes);
yield flowResult(this.editorStore.graphEditorMode.updateGraphAndApplication(modifiedEntities));
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.notificationService.notifyError(`Can't load entity changes: ${error.message}`);
}
}
/**
* NOTE: this can post memory-leak issue if we start having immutable elements referencing current graph elements:
* e.g. subclass analytics on the immutable class, etc.
*
* @risk memory-leak
*/
*rebuildDependencies(newGraph) {
if (this.editorStore.graphManagerState.dependenciesBuildState.hasSucceeded) {
newGraph.dependencyManager =
this.editorStore.graphManagerState.graph.dependencyManager;
}
else {
this.editorStore.projectConfigurationEditorState.setProjectConfiguration(ProjectConfiguration.serialization.fromJson((yield this.editorStore.sdlcServerClient.getConfiguration(this.editorStore.sdlcState.activeProject.projectId, this.editorStore.sdlcState.activeWorkspace))));
const dependencyManager = this.editorStore.graphManagerState.graphManager.createDependencyManager();
newGraph.dependencyManager = dependencyManager;
const dependenciesBuildState = ActionState.create();
yield this.editorStore.graphManagerState.graphManager.buildDependencies(this.editorStore.graphManagerState.coreModel, this.editorStore.graphManagerState.systemModel, dependencyManager, (yield flowResult(this.getIndexedDependencyEntities())), dependenciesBuildState);
// NOTE: here we don't want to modify the current graph build state directly
// instead, we quietly run this in the background and then sync it with the current build state
this.editorStore.graphManagerState.dependenciesBuildState.sync(dependenciesBuildState);
}
}
/**
* Used to update generation model and generation graph using the generated entities
* does not alter the main or dependency model
*/
*updateGenerationGraphAndApplication() {
assertTrue(this.editorStore.graphManagerState.graphBuildState.hasSucceeded &&
this.editorStore.graphManagerState.dependenciesBuildState.hasSucceeded, 'Both main model and dependencies must be processed to built generation graph');
this.isUpdatingApplication = true;
try {
this.editorStore.tabManagerState.cacheAndClose({ cacheGeneration: true });
yield flowResult(this.editorStore.graphManagerState.graph.generationModel.dispose());
// we reset the generation model
this.editorStore.graphManagerState.graph.generationModel =
this.editorStore.graphManagerState.graphManager.createGenerationModel();
yield this.editorStore.graphManagerState.graphManager.buildGenerations(this.editorStore.graphManagerState.graph, this.graphGenerationState.generatedEntities, this.editorStore.graphManagerState.generationsBuildState);
this.editorStore.explorerTreeState.reprocess();
this.editorStore.tabManagerState.recoverTabs();
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(`Can't build graph: ${error.message}`);
}
finally {
this.isUpdatingApplication = false;
}
}
async getIndexedDependencyEntities() {
const dependencyEntitiesIndex = new Map();
const currentConfiguration = this.editorStore.projectConfigurationEditorState
.currentProjectConfiguration;
try {
if (currentConfiguration.projectDependencies.length) {
const dependencyCoordinates = await this.buildProjectDependencyCoordinates(currentConfiguration.projectDependencies);
// NOTE: if A@v1 is transitive dependencies of 2 or more
// direct dependencies, metadata server will take care of deduplication
const dependencyEntitiesJson = await this.editorStore.depotServerClient.collectDependencyEntities(dependencyCoordinates.map((e) => ProjectDependencyCoordinates.serialization.toJson(e)), true, true);
const dependencyEntities = dependencyEntitiesJson.map((e) => ProjectVersionEntities.serialization.fromJson(e));
const dependencyProjects = new Map();
dependencyEntities.forEach((dependencyInfo) => {
const projectId = dependencyInfo.id;
// There are a few validations that must be done:
// 1. Unlike above, if in the depdendency graph, we have both A@v1 and A@v2
// then we need to throw. Both SDLC and metadata server should handle this
// validation, but haven't, so for now, we can do that in Studio.
// 2. Same as the previous case, but for version-to-version transformation
// This is a special case that needs handling, right now, SDLC does auto
// healing, by scanning all the path and convert them into versioned path
// e.g. model::someClass -> project1::v1_0_0::model::someClass
// But this is a rare and advanced use-case which we will not attempt to handle now.
if (dependencyProjects.has(projectId)) {
dependencyProjects.get(projectId)?.add(dependencyInfo.versionId);
}
else {
dependencyProjects.set(dependencyInfo.id, new Set([dependencyInfo.versionId]));
}
dependencyEntitiesIndex.set(dependencyInfo.id, new EntitiesWithOrigin(dependencyInfo.groupId, dependencyInfo.artifactId, dependencyInfo.versionId, dependencyInfo.entities));
});
const hasConflicts = Array.from(dependencyProjects.entries()).find(([k, v]) => v.size > 1);
if (hasConflicts) {
let dependencyInfo;
try {
const dependencyTree = await this.editorStore.depotServerClient.analyzeDependencyTree(dependencyCoordinates.map((e) => ProjectDependencyCoordinates.serialization.toJson(e)));
const rawReport = RawProjectDependencyReport.serialization.fromJson(dependencyTree);
dependencyInfo = buildDependencyReport(rawReport);
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.DEPOT_MANAGER_FAILURE), error);
}
const startErrorMessage = 'Depending on multiple versions of a project is not supported. Found conflicts:\n';
if (dependencyInfo?.conflicts.length) {
const conflictingProjects = dependencyInfo.conflicts
.map((c) => `project: ${c.groupId}:${c.artifactId}\nversions:[${c.versions
.map((v) => v.versionId)
.join(',')}]`)
.join('\n');
throw new UnsupportedOperationError(startErrorMessage + conflictingProjects);
}
else {
const conflictMessages = Array.from(dependencyProjects.entries())
.filter(([, v]) => v.size > 1)
.map(([k, v]) => `project: ${k}\n versions: ${Array.from(v.values()).join(',')}`)
.join('\n\n');
throw new UnsupportedOperationError(startErrorMessage + conflictMessages);
}
}
}
}
catch (error) {
assertErrorThrown(error);
const message = `Can't acquire dependency entitites. Error: ${error.message}`;
this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.GRAPH_BUILDER_FAILURE), message);
this.editorStore.applicationStore.notificationService.notifyError(error);
throw new DependencyGraphBuilderError(error);
}
return dependencyEntitiesIndex;
}
async buildProjectDependencyCoordinates(projectDependencies) {
return Promise.all(projectDependencies.map(async (dep) => Promise.resolve(new ProjectDependencyCoordinates(guaranteeNonNullable(dep.groupId), guaranteeNonNullable(dep.artifactId), dep.versionId))));
}
// -------------------------------------------------- UTILITIES -----------------------------------------------------
getPackageableElementType(element) {
if (element instanceof PrimitiveType) {
return PACKAGEABLE_ELEMENT_TYPE.PRIMITIVE;
}
else if (element instanceof Package) {
return PACKAGEABLE_ELEMENT_TYPE.PACKAGE;
}
else if (element instanceof Class) {
return PACKAGEABLE_ELEMENT_TYPE.CLASS;
}
else if (element instanceof Association) {
return PACKAGEABLE_ELEMENT_TYPE.ASSOCIATION;
}
else if (element instanceof Enumeration) {
return PACKAGEABLE_ELEMENT_TYPE.ENUMERATION;
}
else if (element instanceof Measure) {
return PACKAGEABLE_ELEMENT_TYPE.MEASURE;
}
else if (element instanceof Unit) {
return PACKAGEABLE_ELEMENT_TYPE.UNIT;
}
else if (element instanceof Profile) {
return PACKAGEABLE_ELEMENT_TYPE.PROFILE;
}
else if (element instanceof ConcreteFunctionDefinition) {
return PACKAGEABLE_ELEMENT_TYPE.FUNCTION;
}
else if (element instanceof FlatData) {
return PACKAGEABLE_ELEMENT_TYPE.FLAT_DATA_STORE;
}
else if (element instanceof Database) {
return PACKAGEABLE_ELEMENT_TYPE.DATABASE;
}
else if (element instanceof Mapping) {
return PACKAGEABLE_ELEMENT_TYPE.MAPPING;
}
else if (element instanceof Service) {
return PACKAGEABLE_ELEMENT_TYPE.SERVICE;
}
else if (element instanceof PackageableConnection) {
return PACKAGEABLE_ELEMENT_TYPE.CONNECTION;
}
else if (element instanceof PackageableRuntime) {
return PACKAGEABLE_ELEMENT_TYPE.RUNTIME;
}
else if (element instanceof FileGenerationSpecification) {
return PACKAGEABLE_ELEMENT_TYPE.FILE_GENERATION;
}
else if (element instanceof GenerationSpecification) {
return PACKAGEABLE_ELEMENT_TYPE.GENERATION_SPECIFICATION;
}
else if (element instanceof SectionIndex) {
return PACKAGEABLE_ELEMENT_TYPE.SECTION_INDEX;
}
else if (element instanceof DataElement) {
return PACKAGEABLE_ELEMENT_TYPE.DATA;
}
else if (element instanceof ExecutionEnvironmentInstance) {
return PACKAGEABLE_ELEMENT_TYPE.EXECUTION_ENVIRONMENT;
}
else if (element instanceof SnowflakeApp) {
return PACKAGEABLE_ELEMENT_TYPE.SNOWFLAKE_APP;
}
else if (element instanceof HostedService) {
return PACKAGEABLE_ELEMENT_TYPE.HOSTED_SERVICE;
}
const extraElementTypeLabelGetters = this.editorStore.pluginManager
.getApplicationPlugins()
.flatMap((plugin) => plugin.getExtraElementClassifiers?.() ?? []);
for (const labelGetter of extraElementTypeLabelGetters) {
const label = labelGetter(element);
if (label) {
return label;
}
}
return PACKAGEABLE_ELEMENT_TYPE.INTERNAL__UnknownElement;
}
}
//# sourceMappingURL=EditorGraphState.js.map