use of org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.ValueSpecification in project legend-engine by finos.
the class HelperMappingBuilder method processPurePropertyMappingTransform.
public static LambdaFunction processPurePropertyMappingTransform(PurePropertyMapping ppm, Lambda lambda, PropertyMappingsImplementation owner, org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type inputVarType, CompileContext context, String mappingName) {
List<ValueSpecification> expressions = lambda.body;
VariableExpression lambdaParam = new Root_meta_pure_metamodel_valuespecification_VariableExpression_Impl("")._name("src")._multiplicity(context.pureModel.getMultiplicity("one"))._genericType(new Root_meta_pure_metamodel_type_generics_GenericType_Impl("")._rawType(inputVarType));
MutableList<VariableExpression> pureParameters = Lists.mutable.with(lambdaParam);
ProcessingContext ctx = new ProcessingContext("Pure M2M Transform Lambda");
ctx.addInferredVariables("src", lambdaParam);
MutableList<String> openVariables = Lists.mutable.empty();
MutableList<org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification> valueSpecifications = ListIterate.collect(expressions, p -> p.accept(new ValueSpecificationBuilder(context, openVariables, ctx)));
MutableList<String> cleanedOpenVariables = openVariables.distinct();
cleanedOpenVariables.removeAll(pureParameters.collect(e -> e._name()));
GenericType functionType = context.pureModel.buildFunctionType(pureParameters, valueSpecifications.getLast()._genericType(), valueSpecifications.getLast()._multiplicity());
String propertyName = owner._id() + "." + ppm.property.property;
String mappingPath = Root_meta_pure_functions_meta_elementToPath_PackageableElement_1__String_1_(owner._parent(), context.pureModel.getExecutionSupport()).replace("::", "_");
ctx.flushVariable("src");
return new Root_meta_pure_metamodel_function_LambdaFunction_Impl(propertyName, new SourceInformation(mappingPath, 0, 0, 0, 0), null)._classifierGenericType(new Root_meta_pure_metamodel_type_generics_GenericType_Impl("")._rawType(context.pureModel.getType("meta::pure::metamodel::function::LambdaFunction"))._typeArguments(FastList.newListWith(functionType)))._openVariables(cleanedOpenVariables)._expressionSequence(valueSpecifications);
}
use of org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.ValueSpecification in project legend-engine by finos.
the class HelperModelBuilder method processConstraints.
public static RichIterable<org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.constraint.Constraint> processConstraints(List<org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Constraint> constraints, CompileContext context, String _package, String _name, ValueSpecificationContext vsContext, ProcessingContext ctx) {
String constraintSourceId = context.pureModel.buildPackageString(_package, _name).replace("::", "_") + "_Constraint$";
SourceInformation si = new SourceInformation(constraintSourceId, 0, 0, 0, 0);
return ListIterate.collect(constraints, c -> {
ctx.push("Constraint " + c.name);
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction<?> lf;
try {
lf = HelperValueSpecificationBuilder.buildLambdaWithContext(c.name, c.functionDefinition.body, c.functionDefinition.parameters, context, ctx);
lf._expressionSequence().forEach((Procedure<ValueSpecification>) es -> es._usageContext(vsContext));
lf.setSourceInformation(si);
} catch (Exception e) {
LOGGER.warn(new LogInfo(null, LoggingEventType.GRAPH_EXPRESSION_ERROR, "Can't build constraint '" + c.name + "' of class '" + context.pureModel.buildPackageString(_package, _name) + "- stack: " + ctx.getStack()).toString());
System.out.println(e.getMessage());
if (e instanceof EngineException) {
throw e;
}
throw new EngineException(e.getMessage(), c.sourceInformation, EngineErrorType.COMPILATION);
}
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction<?> mf = null;
try {
if (c.messageFunction != null) {
mf = HelperValueSpecificationBuilder.buildLambdaWithContext(c.name, c.messageFunction.body, c.messageFunction.parameters, context, ctx);
mf._expressionSequence().forEach((Procedure<ValueSpecification>) es -> es._usageContext(vsContext));
mf.setSourceInformation(si);
}
} catch (Exception e) {
mf = null;
LOGGER.warn(new LogInfo(null, LoggingEventType.GRAPH_EXPRESSION_ERROR, "Can't build the message function for constraint '" + c.name + "' of class '" + context.pureModel.buildPackageString(_package, _name) + "' - stack: " + ctx.getStack()).toString());
/* We let these through as a warning because there are invalid message functions that are not properly caught by the PURE compiler .
For example:
~message: 'String ' + $this.maybe
where maybe is String[0..1]
which should cause a multiplicity error as arguments to plus should all be [1] (to become elements of to plus(parts:String[*]))
In the absence of a message the system will fall back on the default failure message.
*/
}
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.constraint.Constraint pureConstraint = new Root_meta_pure_metamodel_constraint_Constraint_Impl(constraintSourceId);
pureConstraint.setSourceInformation(si);
pureConstraint._functionDefinition(lf);
pureConstraint._name(c.name);
pureConstraint._externalId(c.externalId);
pureConstraint._enforcementLevel(c.enforcementLevel);
pureConstraint._messageFunction(mf);
ctx.pop();
if (!lf._expressionSequence().getLast()._genericType()._rawType().equals(context.pureModel.getType("Boolean"))) {
throw new EngineException("Constraint must be of type 'Boolean'", c.functionDefinition.body.get(c.functionDefinition.body.size() - 1).sourceInformation, EngineErrorType.COMPILATION);
}
return pureConstraint;
});
}
use of org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.ValueSpecification in project legend-engine by finos.
the class PackageableElementFirstPassBuilder method visit.
@Override
public PackageableElement visit(Function function) {
// NOTE: in the protocol, we still store the function name as is, but in the function index, we will store the function based on its function signature
String functionSignature = HelperModelBuilder.getSignature(function);
String functionFullName = this.context.pureModel.buildPackageString(function._package, functionSignature);
String functionName = this.context.pureModel.buildPackageString(function._package, HelperModelBuilder.getFunctionNameWithoutSignature(function));
final org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition<?> targetFunc = new Root_meta_pure_metamodel_function_ConcreteFunctionDefinition_Impl<>(functionSignature, SourceInformationHelper.toM3SourceInformation(function.sourceInformation), null);
this.context.pureModel.functionsIndex.put(functionFullName, targetFunc);
ProcessingContext ctx = new ProcessingContext("Function '" + functionFullName + "' First Pass");
org.finos.legend.pure.m3.coreinstance.Package pack = this.context.pureModel.getOrCreatePackage(function._package);
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition<?> res = targetFunc._name(// function signature here - e.g. isAfterDay_Date_1__Date_1__Boolean_1_
HelperModelBuilder.getTerseSignature(function))._functionName(// function name to be used in the handler map -> meta::pure::functions::date::isAfterDay
functionName)._classifierGenericType(new Root_meta_pure_metamodel_type_generics_GenericType_Impl("")._rawType(this.context.pureModel.getType("meta::pure::metamodel::function::ConcreteFunctionDefinition"))._typeArguments(Lists.fixedSize.of(PureModel.buildFunctionType(ListIterate.collect(function.parameters, p -> (VariableExpression) p.accept(new ValueSpecificationBuilder(this.context, Lists.mutable.empty(), ctx))), this.context.resolveGenericType(function.returnType, function.sourceInformation), this.context.pureModel.getMultiplicity(function.returnMultiplicity)))))._stereotypes(ListIterate.collect(function.stereotypes, s -> this.context.resolveStereotype(s.profile, s.value, s.profileSourceInformation, s.sourceInformation)))._taggedValues(ListIterate.collect(function.taggedValues, t -> new Root_meta_pure_metamodel_extension_TaggedValue_Impl("")._tag(this.context.resolveTag(t.tag.profile, t.tag.value, t.tag.profileSourceInformation, t.sourceInformation))._value(t.value)))._package(pack);
HelperModelBuilder.processFunctionConstraints(function, this.context, res, ctx);
pack._childrenAdd(res);
this.context.pureModel.handlers.register(new UserDefinedFunctionHandler(functionFullName, res, ps -> new TypeAndMultiplicity(this.context.resolveGenericType(function.returnType, function.sourceInformation), this.context.pureModel.getMultiplicity(function.returnMultiplicity)), ps -> {
List<ValueSpecification> vs = ListIterate.collect(function.parameters, p -> p.accept(new ValueSpecificationBuilder(this.context, Lists.mutable.empty(), ctx)));
if (ps.size() == function.parameters.size()) {
int size = ps.size();
// TODO clean up the check....
try {
for (int i = 0; i < size; i++) {
HelperModelBuilder.checkCompatibility(this.context, ps.get(i)._genericType()._rawType(), ps.get(i)._multiplicity(), vs.get(i)._genericType()._rawType(), vs.get(i)._multiplicity(), "Error in function '" + functionFullName + "'", function.body.get(function.body.size() - 1).sourceInformation);
}
} catch (Exception e) {
return false;
}
return true;
}
return false;
}));
return res;
}
use of org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.ValueSpecification in project legend-engine by finos.
the class ClassMappingSecondPassBuilder method visit.
@Override
public SetImplementation visit(PureInstanceClassMapping classMapping) {
PureInstanceSetImplementation s = (PureInstanceSetImplementation) parentMapping._classMappings().select(c -> c._id().equals(HelperMappingBuilder.getClassMappingId(classMapping, this.context))).getFirst();
s._propertyMappings().forEachWithIndex((ObjectIntProcedure<org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.PropertyMapping>) ((p, i) -> {
org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping pm = (org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping) p;
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.Property<?, ?> property = pm._property();
SourceInformation pSourceInformation = SourceInformationHelper.fromM3SourceInformation(p.getSourceInformation());
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification last = pm._transform()._expressionSequence().getLast();
List<Type> typesToCheck;
if (property._genericType()._rawType()._classifierGenericType()._rawType()._name().equals("Class")) {
SetImplementation setImplementation;
if (p._targetSetImplementationId() != null && !p._targetSetImplementationId().equals("")) {
setImplementation = parentMapping._classMappingByIdRecursive(Lists.fixedSize.with(p._targetSetImplementationId()), this.context.pureModel.getExecutionSupport()).getFirst();
Assert.assertTrue(setImplementation != null, () -> "Can't find class mapping '" + p._targetSetImplementationId() + "'", pSourceInformation, EngineErrorType.COMPILATION);
} else {
setImplementation = parentMapping.classMappingByClass((org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class<Object>) property._genericType()._rawType(), this.context.pureModel.getExecutionSupport()).getFirst();
Assert.assertTrue(setImplementation != null, () -> "Can't find class mapping for '" + HelperModelBuilder.getElementFullPath(property._genericType()._rawType(), this.context.pureModel.getExecutionSupport()) + "'", pSourceInformation, EngineErrorType.COMPILATION);
}
List<? extends InstanceSetImplementation> setImpls = core_pure_router_router_routing.Root_meta_pure_router_routing_resolveOperation_SetImplementation_MANY__Mapping_1__InstanceSetImplementation_MANY_(Lists.immutable.of(setImplementation), parentMapping, this.context.pureModel.getExecutionSupport()).toList();
typesToCheck = setImpls.stream().map(setImpl -> ((PureInstanceSetImplementation) setImpl)._srcClass()).collect(Collectors.toList());
} else if (((org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping) p)._transformer() != null) {
EnumerationMapping<Object> m = ((EnumerationMapping<Object>) ((org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping) p)._transformer());
Object val = m._enumValueMappings().getFirst()._sourceValues().getFirst();
if (val instanceof String) {
typesToCheck = Collections.singletonList(this.context.pureModel.getType("String"));
} else if (val instanceof Long) {
typesToCheck = Collections.singletonList(this.context.pureModel.getType("Integer"));
} else if (val instanceof EnumValue) {
typesToCheck = Collections.singletonList(this.context.resolveEnumeration(((EnumValue) val).fullPath, pSourceInformation));
} else if (val instanceof Enum) {
GenericType genericType = ((Enum) val)._classifierGenericType();
typesToCheck = genericType != null ? Collections.singletonList(this.context.resolveEnumeration(PackageableElement.getUserPathForPackageableElement(genericType._rawType()), pSourceInformation)) : Collections.emptyList();
} else {
typesToCheck = Collections.emptyList();
}
} else {
typesToCheck = Collections.singletonList(property._genericType()._rawType());
}
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity multiplicityToCheck = pm._explodeProperty() != null && pm._explodeProperty() ? this.context.pureModel.getMultiplicity("zeromany") : property._multiplicity();
List<ValueSpecification> lines = ((PurePropertyMapping) classMapping.propertyMappings.get(i)).transform.body;
typesToCheck.stream().filter(Objects::nonNull).forEach(t -> HelperModelBuilder.checkTypeCompatibility(this.context, last._genericType()._rawType(), t, "Error in class mapping '" + HelperModelBuilder.getElementFullPath(parentMapping, this.context.pureModel.getExecutionSupport()) + "' for property '" + pm._property()._name() + "'", lines.get(lines.size() - 1).sourceInformation));
HelperModelBuilder.checkMultiplicityCompatibility(last._multiplicity(), multiplicityToCheck, "Error in class mapping '" + HelperModelBuilder.getElementFullPath(parentMapping, this.context.pureModel.getExecutionSupport()) + "' for property '" + pm._property()._name() + "'", lines.get(lines.size() - 1).sourceInformation);
}));
return s;
}
use of org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.ValueSpecification in project legend-engine by finos.
the class ValueSpecificationBuilder method visit.
@Override
public ValueSpecification visit(AppliedFunction appliedFunction) {
processingContext.push("Applying " + appliedFunction.function);
if (appliedFunction.function.equals("letFunction")) {
MutableList<org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification> vs = ListIterate.collect(appliedFunction.parameters, expression -> expression.accept(new ValueSpecificationBuilder(this.context, openVariables, processingContext)));
String letName = ((CString) appliedFunction.parameters.get(0)).values.get(0);
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification ve = new Root_meta_pure_metamodel_valuespecification_VariableExpression_Impl("")._name(letName);
ve._genericType(vs.get(1)._genericType());
ve._multiplicity(vs.get(1)._multiplicity());
processingContext.addInferredVariables(letName, ve);
}
org.eclipse.collections.api.tuple.Pair<SimpleFunctionExpression, List<ValueSpecification>> func = this.context.buildFunctionExpression(appliedFunction.function, appliedFunction.fControl, appliedFunction.parameters, openVariables, appliedFunction.sourceInformation, processingContext);
processingContext.pop();
Assert.assertTrue(func != null, () -> "Can't find a match for function '" + appliedFunction.function + "(?)'", appliedFunction.sourceInformation, EngineErrorType.COMPILATION);
Assert.assertTrue(func.getOne() != null, () -> "Can't find a match for function '" + appliedFunction.function + "(" + (func.getTwo() == null ? "?" : LazyIterate.collect(func.getTwo(), v -> (v._genericType() == null ? "?" : v._genericType()._rawType()._name()) + org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.print(v._multiplicity())).makeString(",")) + ")'", appliedFunction.sourceInformation, EngineErrorType.COMPILATION);
ValueSpecification result = func.getOne();
result.setSourceInformation(SourceInformationHelper.toM3SourceInformation(appliedFunction.sourceInformation));
return result;
}
Aggregations