diff --git a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/legend/tools/devUtils.pure b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/legend/tools/devUtils.pure index 76ca1bf7f62..aab50f8fd70 100644 --- a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/legend/tools/devUtils.pure +++ b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/legend/tools/devUtils.pure @@ -45,3 +45,10 @@ function meta::legend::executePlanAsJSON(plan:String[1], vars: Pair let func = $fStr->pathToElement()->cast(@Function<{String[1], Pair[*]->String[1]}>); $func->eval($plan, $vars); } + +function meta::legend::compileLegendPMCD(pmcdJSON : String[1]):PackageableElement[*] +{ + let fStr = 'meta::legend::compilePMCD_String_1__PackageableElement_MANY_'; + let func = $fStr->pathToElement()->cast(@Function<{String[1]->PackageableElement[*]}>); + $func->eval($pmcdJSON); +} \ No newline at end of file diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-functions-legendCompiler-pure/src/main/resources/core_external_compiler/compiler.pure b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-functions-legendCompiler-pure/src/main/resources/core_external_compiler/compiler.pure index 4c6359d77d3..073f41a19dc 100644 --- a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-functions-legendCompiler-pure/src/main/resources/core_external_compiler/compiler.pure +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-functions-legendCompiler-pure/src/main/resources/core_external_compiler/compiler.pure @@ -19,3 +19,5 @@ import meta::pure::mapping::*; native function meta::legend::compile(s:String[1]):PackageableElement[*]; native function meta::legend::compileVS(s:String[1]):Any[1]; + +native function meta::legend::compilePMCD(pmcdJSON:String[1]):PackageableElement[*]; diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-compiled-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/compiled/CompileExtensionCompiled.java b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-compiled-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/compiled/CompileExtensionCompiled.java index 562fd431ee3..47d03bc8f10 100644 --- a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-compiled-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/compiled/CompileExtensionCompiled.java +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-compiled-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/compiled/CompileExtensionCompiled.java @@ -16,6 +16,7 @@ import org.eclipse.collections.api.factory.Lists; import org.finos.legend.engine.pure.runtime.compiler.compiled.natives.LegendCompile; +import org.finos.legend.engine.pure.runtime.compiler.compiled.natives.LegendCompilePMCD; import org.finos.legend.engine.pure.runtime.compiler.compiled.natives.LegendCompileVS; import org.finos.legend.pure.runtime.java.compiled.extension.BaseCompiledExtension; import org.finos.legend.pure.runtime.java.compiled.extension.CompiledExtension; @@ -26,7 +27,7 @@ public CompileExtensionCompiled() { super( "core_external_compiler", - () -> Lists.fixedSize.with(new LegendCompile(), new LegendCompileVS()), + () -> Lists.fixedSize.with(new LegendCompile(), new LegendCompileVS(), new LegendCompilePMCD()), Lists.fixedSize.with(), Lists.fixedSize.empty(), Lists.fixedSize.empty()); diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-compiled-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/compiled/natives/LegendCompilePMCD.java b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-compiled-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/compiled/natives/LegendCompilePMCD.java new file mode 100644 index 00000000000..435e8646305 --- /dev/null +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-compiled-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/compiled/natives/LegendCompilePMCD.java @@ -0,0 +1,65 @@ +// Copyright 2022 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. + +package org.finos.legend.engine.pure.runtime.compiler.compiled.natives; + +import org.eclipse.collections.api.list.ListIterable; +import org.eclipse.collections.api.list.MutableList; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.PackageableElement; +import org.finos.legend.pure.m3.execution.ExecutionSupport; +import org.finos.legend.pure.m3.navigation.Instance; +import org.finos.legend.pure.m3.navigation.M3Properties; +import org.finos.legend.pure.m3.navigation.ProcessorSupport; +import org.finos.legend.pure.m4.coreinstance.CoreInstance; +import org.finos.legend.pure.runtime.java.compiled.execution.CompiledExecutionSupport; +import org.finos.legend.pure.runtime.java.compiled.generation.ProcessorContext; +import org.finos.legend.pure.runtime.java.compiled.generation.processors.natives.AbstractNative; +import org.finos.legend.pure.runtime.java.compiled.generation.processors.valuespecification.ValueSpecificationProcessor; + +public class LegendCompilePMCD extends AbstractNative +{ + public LegendCompilePMCD() + { + super("compilePMCD_String_1__PackageableElement_MANY_"); + } + + @Override + public String build(CoreInstance topLevelElement, CoreInstance functionExpression, ListIterable listIterable, ProcessorContext processorContext) + { + final ProcessorSupport processorSupport = processorContext.getSupport(); + final ListIterable parametersValues = Instance.getValueForMetaPropertyToManyResolved(functionExpression, M3Properties.parametersValues, processorSupport); + + String code = ValueSpecificationProcessor.processValueSpecification(topLevelElement, parametersValues.get(0), processorContext); + + return "org.finos.legend.engine.pure.runtime.compiler.compiled.natives.LegendCompilePMCD.compileExecPMCD(" + code + ", es)"; + } + + @Override + public String buildBody() + { + return "new SharedPureFunction()\n" + + " {\n" + + " @Override\n" + + " public Object execute(ListIterable vars, final ExecutionSupport es)\n" + + " {\n" + + " return org.finos.legend.engine.pure.runtime.compiler.compiled.natives.LegendCompilePMCD.compileExecPMCD((String) vars.get(0), es);\n" + + " }\n" + + " }"; + } + + public static MutableList compileExecPMCD(String code, final ExecutionSupport es) + { + return org.finos.legend.engine.pure.runtime.compiler.shared.LegendCompile.doCompilePMCD(code, ((CompiledExecutionSupport) es).getProcessorSupport().getMetadata()); + } +} diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/pom.xml b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/pom.xml index 714fec4ce93..684784a5485 100644 --- a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/pom.xml +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/pom.xml @@ -67,7 +67,6 @@ legend-pure-m2-dsl-diagram-grammar runtime - org.eclipse.collections eclipse-collections-api diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/interpreted/CompileExtensionInterpreted.java b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/interpreted/CompileExtensionInterpreted.java index 0299c33682e..f87383dcaec 100644 --- a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/interpreted/CompileExtensionInterpreted.java +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/interpreted/CompileExtensionInterpreted.java @@ -17,6 +17,7 @@ import org.eclipse.collections.impl.factory.Lists; import org.eclipse.collections.impl.tuple.Tuples; import org.finos.legend.engine.pure.runtime.compiler.interpreted.natives.LegendCompile; +import org.finos.legend.engine.pure.runtime.compiler.interpreted.natives.LegendCompilePMCD; import org.finos.legend.engine.pure.runtime.compiler.interpreted.natives.LegendCompileVS; import org.finos.legend.pure.runtime.java.interpreted.extension.BaseInterpretedExtension; import org.finos.legend.pure.runtime.java.interpreted.extension.InterpretedExtension; @@ -27,7 +28,8 @@ public CompileExtensionInterpreted() { super(Lists.mutable.with( Tuples.pair("compile_String_1__PackageableElement_MANY_", LegendCompile::new), - Tuples.pair("compileVS_String_1__Any_1_", LegendCompileVS::new) + Tuples.pair("compileVS_String_1__Any_1_", LegendCompileVS::new), + Tuples.pair("compilePMCD_String_1__PackageableElement_MANY_", LegendCompilePMCD::new) )); } diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/interpreted/natives/LegendCompilePMCD.java b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/interpreted/natives/LegendCompilePMCD.java new file mode 100644 index 00000000000..d12d92164ea --- /dev/null +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-interpreted-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/interpreted/natives/LegendCompilePMCD.java @@ -0,0 +1,56 @@ +// Copyright 2022 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. + +package org.finos.legend.engine.pure.runtime.compiler.interpreted.natives; + +import org.eclipse.collections.api.list.ListIterable; +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.api.map.MutableMap; +import org.finos.legend.pure.m3.compiler.Context; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.PackageableElement; +import org.finos.legend.pure.m3.exception.PureExecutionException; +import org.finos.legend.pure.m3.navigation.Instance; +import org.finos.legend.pure.m3.navigation.M3Properties; +import org.finos.legend.pure.m3.navigation.ProcessorSupport; +import org.finos.legend.pure.m3.navigation.ValueSpecificationBootstrap; +import org.finos.legend.pure.m4.ModelRepository; +import org.finos.legend.pure.m4.coreinstance.CoreInstance; +import org.finos.legend.pure.runtime.java.interpreted.ExecutionSupport; +import org.finos.legend.pure.runtime.java.interpreted.FunctionExecutionInterpreted; +import org.finos.legend.pure.runtime.java.interpreted.VariableContext; +import org.finos.legend.pure.runtime.java.interpreted.natives.InstantiationContext; +import org.finos.legend.pure.runtime.java.interpreted.natives.NativeFunction; +import org.finos.legend.pure.runtime.java.interpreted.profiler.Profiler; + +import java.util.Stack; + +public class LegendCompilePMCD extends NativeFunction +{ + private final FunctionExecutionInterpreted functionExecution; + + public LegendCompilePMCD(FunctionExecutionInterpreted functionExecution, ModelRepository modelRepository) + { + this.functionExecution = functionExecution; + } + + @Override + public CoreInstance execute(ListIterable params, Stack> stack, Stack> stack1, VariableContext variableContext, CoreInstance coreInstance, Profiler profiler, InstantiationContext instantiationContext, ExecutionSupport executionSupport, Context context, ProcessorSupport processorSupport) throws PureExecutionException + { + String code = Instance.getValueForMetaPropertyToOneResolved(params.get(0), M3Properties.values, processorSupport).getName(); + + MutableList createdElements = null; + createdElements = org.finos.legend.engine.pure.runtime.compiler.shared.LegendCompile.doCompilePMCD(code, new InterpretedMetadata(processorSupport)); + return ValueSpecificationBootstrap.wrapValueSpecification(createdElements, true, functionExecution.getProcessorSupport()); + } +} diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/pom.xml b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/pom.xml index c4d9faa6328..f23135eea55 100644 --- a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/pom.xml +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/pom.xml @@ -92,5 +92,14 @@ junit junit + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/shared/LegendCompile.java b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/shared/LegendCompile.java index a9f5a324494..21052e1138a 100644 --- a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/shared/LegendCompile.java +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/main/java/org/finos/legend/engine/pure/runtime/compiler/shared/LegendCompile.java @@ -14,6 +14,8 @@ package org.finos.legend.engine.pure.runtime.compiler.shared; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.impl.utility.ListIterate; import org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperModelBuilder; @@ -22,9 +24,9 @@ import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Function; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.section.SectionIndex; +import org.finos.legend.engine.shared.core.ObjectMapperFactory; import org.finos.legend.engine.shared.core.deployment.DeploymentMode; import org.finos.legend.engine.shared.core.identity.Identity; -import org.finos.legend.engine.shared.core.identity.factory.*; import org.finos.legend.engine.shared.core.operational.Assert; import org.finos.legend.pure.m3.coreinstance.Package; import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.ModelElementAccessor; @@ -55,6 +57,27 @@ public static ValueSpecification doCompileVS(String code, Metadata metadata) return ((ConcreteFunctionDefinition) extractCreatedElementFromCompiledGraph(data, pm).getFirst())._expressionSequence().getFirst(); } + public static MutableList doCompilePMCD(String code, Metadata metadata) + { + // Parse + ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + PureModelContextData data = null; + try + { + data = objectMapper.readValue(code, PureModelContextData.class); + } + catch (JsonProcessingException e) + { + throw new RuntimeException(e); + } + + // Compile + PureModel pm = org.finos.legend.engine.language.pure.compiler.Compiler.compile(data, DeploymentMode.PROD, Identity.getAnonymousIdentity().getName(), "", metadata); + + // Extract Compiled created elements + return extractCreatedElementFromCompiledGraph(data, pm); + } + private static MutableList extractCreatedElementFromCompiledGraph(PureModelContextData pureModelContextData, PureModel pureModel) { return ListIterate.collectIf(pureModelContextData.getElements(), diff --git a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/test/java/org/finos/legend/engine/pure/runtime/compiler/test/LegendCompileTest.java b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/test/java/org/finos/legend/engine/pure/runtime/compiler/test/LegendCompileTest.java index 4474a2e780d..712fb6a6afb 100644 --- a/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/test/java/org/finos/legend/engine/pure/runtime/compiler/test/LegendCompileTest.java +++ b/legend-engine-pure/legend-engine-pure-runtime/legend-engine-pure-runtime-legendCompiler/legend-engine-pure-runtime-java-extension-shared-functions-legendCompiler/src/test/java/org/finos/legend/engine/pure/runtime/compiler/test/LegendCompileTest.java @@ -14,7 +14,12 @@ package org.finos.legend.engine.pure.runtime.compiler.test; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.collections.impl.tuple.Tuples; +import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Class; +import org.finos.legend.engine.shared.core.ObjectMapperFactory; import org.finos.legend.pure.m3.execution.FunctionExecution; import org.finos.legend.pure.m3.serialization.runtime.PureRuntime; import org.junit.Test; @@ -127,6 +132,23 @@ public void testValueSpecificationEmbeddedPure() "assertEquals('X X Test', $x);"); } + @Test + public void testPMCD() throws JsonProcessingException + { + Class test = new Class(); + test.name = "a"; + test._package = "test::class"; + + PureModelContextData pmcd = PureModelContextData.newBuilder().withElement(test).build(); + ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + String pmcdJson = objectMapper.writeValueAsString(pmcd); + + test("let x = meta::legend::compilePMCD('" + pmcdJson + "');\n" + + "let p = $x->at(0)->cast(@Class).name;\n " + + "assertEquals('a', $p);" + ); + } + private void test(String code)