UNPKG

@finos/legend-extension-dsl-data-quality

Version:
169 lines 8.52 kB
/** * Copyright (c) 2026-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 } from '@finos/legend-shared'; import { SUPPORTED_TYPES } from '../constants/DataQualityConstants.js'; import { AbstractPropertyExpression, ColSpec, ColSpecArray, ColSpecArrayInstance, ColSpecInstanceValue, Multiplicity, observe_ColSpecArrayInstance, observe_ColSpecInstance, PRIMITIVE_TYPE, PropertyExplicitReference, VariableExpression, observe_AbstractPropertyExpression, SimpleFunctionExpression, observe_SimpleFunctionExpression, observe_VariableExpression, } from '@finos/legend-graph'; import { buildPrimitiveCollectionInstanceValue, buildPrimitiveInstanceValue, } from '@finos/legend-query-builder'; export class ParsedFunctionExpression { name; processedParameters; constructor(name, processedParameters = []) { this.name = name; this.processedParameters = processedParameters; } } export class DataQualityLambdaParameterParser { static processPrimitiveParameter(param, graph, observerContext) { const { _type, value } = param; if (!DataQualityLambdaParameterParser.isSupportedPrimitive(_type)) { throw new UnsupportedOperationError(`Unsupported primitive type: ${_type}`); } const primitiveType = DataQualityLambdaParameterParser.getPrimitiveType(_type); return buildPrimitiveInstanceValue(graph, primitiveType, value, observerContext); } static processVariableDeclaration(param) { const { name = '' } = param; return observe_VariableExpression(new VariableExpression(name, Multiplicity.ZERO)); } static processColSpecArray(param, observerContext) { const { value } = param; const colSpecArray = new ColSpecArray(); colSpecArray.colSpecs = value.colSpecs.map((colSpec) => { const colSpecValue = new ColSpec(); colSpecValue.name = colSpec.name; return colSpecValue; }); const colSpecArrayInstance = new ColSpecArrayInstance(Multiplicity.ZERO_MANY); colSpecArrayInstance.values = [colSpecArray]; observe_ColSpecArrayInstance(colSpecArrayInstance, observerContext); return colSpecArrayInstance; } static processColSpec(param, observerContext) { const { value } = param; const colSpecValue = new ColSpec(); colSpecValue.name = value.name; const colSpecInstance = new ColSpecInstanceValue(Multiplicity.ZERO_MANY); colSpecInstance.values = [colSpecValue]; observe_ColSpecInstance(colSpecInstance, observerContext); return colSpecInstance; } static processPropertyParameter({ property, parameters = [] }, observerContext) { const error = new UnsupportedOperationError('Property source is not supported'); if (parameters.length > 1) { throw error; } const processedProperty = new AbstractPropertyExpression(''); processedProperty.func = PropertyExplicitReference.create({ name: property, }); processedProperty.parametersValues = parameters.map((parameter) => { if (parameter._type === SUPPORTED_TYPES.VAR) { return DataQualityLambdaParameterParser.processVariableDeclaration(parameter); } throw error; }); observe_AbstractPropertyExpression(processedProperty, observerContext); return processedProperty; } static processCollectionParameter({ values = [] }, graph, observerContext) { const firstElementType = values[0]?._type ?? SUPPORTED_TYPES.STRING; if (!DataQualityLambdaParameterParser.isSupportedPrimitive(firstElementType)) { throw new UnsupportedOperationError(`Unsupported primitive type for collection: ${firstElementType}`); } const hasMultipleTypes = values.some((value) => value._type !== firstElementType); if (hasMultipleTypes) { throw new UnsupportedOperationError('Multi-type collections are not supported. All elements must be of the same type.'); } return buildPrimitiveCollectionInstanceValue(graph, this.getPrimitiveType(firstElementType), values.map((value) => value.value), observerContext); } static processFunctionParameter({ parameters = [], function: name = '' }, graph, observerContext) { const processedParameters = parameters.map((parameter) => { if (DataQualityLambdaParameterParser.isSupportedPrimitive(parameter._type)) { return DataQualityLambdaParameterParser.processPrimitiveParameter(parameter, graph, observerContext); } else { switch (parameter._type) { case SUPPORTED_TYPES.PROPERTY: return DataQualityLambdaParameterParser.processPropertyParameter(parameter, observerContext); case SUPPORTED_TYPES.COLLECTION: return DataQualityLambdaParameterParser.processCollectionParameter(parameter, graph, observerContext); case SUPPORTED_TYPES.FUNCTION: return DataQualityLambdaParameterParser.processFunctionParameter(parameter, graph, observerContext); default: throw new UnsupportedOperationError(`Cannot process type: ${parameter._type}`); } } }); return new ParsedFunctionExpression(name, processedParameters); } static createSimpleFunctionExpression(name, parameters, observerContext) { const processedFun = new SimpleFunctionExpression(name); processedFun.parametersValues = parameters; observe_SimpleFunctionExpression(processedFun, observerContext); return processedFun; } static isSupportedPrimitive(type) { switch (type) { case SUPPORTED_TYPES.NUMBER: case SUPPORTED_TYPES.STRING: case SUPPORTED_TYPES.FLOAT: case SUPPORTED_TYPES.DECIMAL: case SUPPORTED_TYPES.INTEGER: return true; default: return false; } } static getPrimitiveType(type) { switch (type) { case SUPPORTED_TYPES.STRING: return PRIMITIVE_TYPE.STRING; case SUPPORTED_TYPES.NUMBER: return PRIMITIVE_TYPE.NUMBER; case SUPPORTED_TYPES.INTEGER: return PRIMITIVE_TYPE.INTEGER; case SUPPORTED_TYPES.FLOAT: return PRIMITIVE_TYPE.FLOAT; case SUPPORTED_TYPES.DECIMAL: return PRIMITIVE_TYPE.DECIMAL; default: throw new UnsupportedOperationError(`Unsupported primitive type: ${type}`); } } static validateLambdaParameter({ parameters = [], body = [] }) { if (parameters.length === 0) { throw new UnsupportedOperationError('Lambda parameters cannot be empty'); } if (parameters.length > 1) { throw new UnsupportedOperationError('Only single function in lambda parameters is supported'); } const firstParameter = parameters[0]; if (firstParameter?._type !== SUPPORTED_TYPES.VAR) { throw new UnsupportedOperationError(`Unsupported parameter type in lambda parameter: ${firstParameter?._type}`); } if (body.length === 0) { throw new UnsupportedOperationError('Lambda body cannot be empty'); } if (body.length > 1) { throw new UnsupportedOperationError('Only single function in lambda body is supported'); } const functionExpression = body[0]; if (functionExpression?._type !== SUPPORTED_TYPES.FUNCTION) { throw new UnsupportedOperationError(`Unsupported expression type in lambda body: ${functionExpression?._type}`); } } } //# sourceMappingURL=DataQualityLambdaParameterParser.js.map