diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/test/java/org/finos/legend/engine/language/pure/compiler/test/fromProtocol/TestDomainCompilationFromProtocol.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/test/java/org/finos/legend/engine/language/pure/compiler/test/fromProtocol/TestDomainCompilationFromProtocol.java
index 3c9e2d240b3..3485a1c21d5 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/test/java/org/finos/legend/engine/language/pure/compiler/test/fromProtocol/TestDomainCompilationFromProtocol.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/test/java/org/finos/legend/engine/language/pure/compiler/test/fromProtocol/TestDomainCompilationFromProtocol.java
@@ -80,4 +80,116 @@ public void testProfileLoadingWithPackageOffset()
{
testProtocolLoadingModelWithPackageOffset("profileUsedInClassExample.json", null, "update::");
}
+
+ @Test
+ public void testNewConstructorWithMissingTypeArgumentsCompiles()
+ {
+ testWithJson("{\n" +
+ " \"_type\": \"data\",\n" +
+ " \"elements\": [\n" +
+ " {\n" +
+ " \"_type\": \"function\",\n" +
+ " \"body\": [\n" +
+ " {\n" +
+ " \"_type\": \"func\",\n" +
+ " \"function\": \"new\",\n" +
+ " \"parameters\": [\n" +
+ " {\n" +
+ // ---------- type to construct, no type arguments
+ " \"_type\": \"packageableElementPtr\",\n" +
+ " \"fullPath\": \"TdsOlapRank\"\n" +
+ // ---------- type to construct, no type arguments
+ " },\n" +
+ " {\n" +
+ " \"_type\": \"string\",\n" +
+ " \"value\": \"\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"_type\": \"collection\",\n" +
+ " \"multiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"values\": [\n" +
+ " {\n" +
+ " \"_type\": \"keyExpression\",\n" +
+ " \"add\": false,\n" +
+ " \"expression\": {\n" +
+ " \"_type\": \"lambda\",\n" +
+ " \"body\": [\n" +
+ " {\n" +
+ " \"_type\": \"integer\",\n" +
+ " \"value\": 1\n" +
+ " }\n" +
+ " ],\n" +
+ " \"parameters\": [\n" +
+ " {\n" +
+ " \"_type\": \"var\",\n" +
+ " \"genericType\": {\n" +
+ " \"multiplicityArguments\": [],\n" +
+ " \"rawType\": {\n" +
+ " \"_type\": \"packageableType\",\n" +
+ " \"fullPath\": \"TDSRow\"\n" +
+ " },\n" +
+ " \"typeArguments\": [],\n" +
+ " \"typeVariableValues\": []\n" +
+ " },\n" +
+ " \"multiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"name\": \"r\"\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " \"key\": {\n" +
+ " \"_type\": \"string\",\n" +
+ " \"value\": \"func\"\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"name\": \"new__Any_1_\",\n" +
+ " \"package\": \"test\",\n" +
+ " \"parameters\": [],\n" +
+ " \"postConstraints\": [],\n" +
+ " \"preConstraints\": [],\n" +
+ " \"returnGenericType\": {\n" +
+ " \"multiplicityArguments\": [],\n" +
+ " \"rawType\": {\n" +
+ " \"_type\": \"packageableType\",\n" +
+ " \"fullPath\": \"Any\"\n" +
+ " },\n" +
+ " \"typeArguments\": [],\n" +
+ " \"typeVariableValues\": []\n" +
+ " },\n" +
+ " \"returnMultiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"stereotypes\": [],\n" +
+ " \"taggedValues\": [],\n" +
+ " \"tests\": []\n" +
+ " },\n" +
+ " {\n" +
+ " \"_type\": \"sectionIndex\",\n" +
+ " \"name\": \"SectionIndex\",\n" +
+ " \"package\": \"__internal__\",\n" +
+ " \"sections\": [\n" +
+ " {\n" +
+ " \"_type\": \"importAware\",\n" +
+ " \"elements\": [\n" +
+ " \"test::new__Any_1_\"\n" +
+ " ],\n" +
+ " \"imports\": [],\n" +
+ " \"parserName\": \"Pure\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ "}", null);
+ }
}
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar-http-api/src/test/java/org/finos/legend/engine/language/pure/grammar/api/test/TestGrammarToJsonApi.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar-http-api/src/test/java/org/finos/legend/engine/language/pure/grammar/api/test/TestGrammarToJsonApi.java
index 3846046dc5f..e5be6bd2a29 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar-http-api/src/test/java/org/finos/legend/engine/language/pure/grammar/api/test/TestGrammarToJsonApi.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar-http-api/src/test/java/org/finos/legend/engine/language/pure/grammar/api/test/TestGrammarToJsonApi.java
@@ -40,7 +40,7 @@ public void testProtocolGeneration()
@Test
public void testImportParsing()
{
- test(getJsonString("pureImportParsingTest.json"), "{\"isolatedLambdas\":{\"lambdas\":{}},\"modelDataContext\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"Person\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[{\"genericType\":{\"multiplicityArguments\":[],\"rawType\":{\"_type\":\"packageableType\",\"fullPath\":\"TargetA\",\"sourceInformation\":{\"endColumn\":18,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":12,\"startLine\":4}},\"typeArguments\":[],\"typeVariableValues\":[]},\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"targetA\",\"sourceInformation\":{\"endColumn\":22,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":3,\"startLine\":4},\"stereotypes\":[],\"taggedValues\":[]}],\"qualifiedProperties\":[],\"sourceInformation\":{\"endColumn\":1,\"endLine\":5,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":2},\"stereotypes\":[],\"superTypes\":[\"VersionClass\"],\"taggedValues\":[{\"sourceInformation\":{\"endColumn\":20,\"endLine\":2,\"sourceId\":\"\",\"startColumn\":8,\"startLine\":2},\"tag\":{\"profile\":\"doc\",\"profileSourceInformation\":{\"endColumn\":10,\"endLine\":2,\"sourceId\":\"\",\"startColumn\":8,\"startLine\":2},\"sourceInformation\":{\"endColumn\":14,\"endLine\":2,\"sourceId\":\"\",\"startColumn\":12,\"startLine\":2},\"value\":\"doc\"},\"value\":\"a\"}]},{\"_type\":\"sectionIndex\",\"name\":\"SectionIndex\",\"package\":\"__internal__\",\"sections\":[{\"_type\":\"importAware\",\"elements\":[\"model::Person\"],\"imports\":[\"projectA\"],\"parserName\":\"Pure\",\"sourceInformation\":{\"endColumn\":2,\"endLine\":7,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":1}}]}]},\"renderStyle\":\"STANDARD\"}");
+ test(getJsonString("pureImportParsingTest.json"), "{\"isolatedLambdas\":{\"lambdas\":{}},\"modelDataContext\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"Person\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[{\"genericType\":{\"multiplicityArguments\":[],\"rawType\":{\"_type\":\"packageableType\",\"fullPath\":\"TargetA\",\"sourceInformation\":{\"endColumn\":18,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":12,\"startLine\":4}},\"typeArguments\":[],\"typeVariableValues\":[]},\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"targetA\",\"sourceInformation\":{\"endColumn\":22,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":3,\"startLine\":4},\"stereotypes\":[],\"taggedValues\":[]}],\"qualifiedProperties\":[],\"sourceInformation\":{\"endColumn\":1,\"endLine\":5,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":2},\"stereotypes\":[],\"superTypes\":[{\"path\":\"VersionClass\",\"sourceInformation\":{\"endColumn\":56,\"endLine\":2,\"sourceId\":\"\",\"startColumn\":45,\"startLine\":2},\"type\":\"CLASS\"}],\"taggedValues\":[{\"sourceInformation\":{\"endColumn\":20,\"endLine\":2,\"sourceId\":\"\",\"startColumn\":8,\"startLine\":2},\"tag\":{\"profile\":\"doc\",\"profileSourceInformation\":{\"endColumn\":10,\"endLine\":2,\"sourceId\":\"\",\"startColumn\":8,\"startLine\":2},\"sourceInformation\":{\"endColumn\":14,\"endLine\":2,\"sourceId\":\"\",\"startColumn\":12,\"startLine\":2},\"value\":\"doc\"},\"value\":\"a\"}]},{\"_type\":\"sectionIndex\",\"name\":\"SectionIndex\",\"package\":\"__internal__\",\"sections\":[{\"_type\":\"importAware\",\"elements\":[\"model::Person\"],\"imports\":[\"projectA\"],\"parserName\":\"Pure\",\"sourceInformation\":{\"endColumn\":2,\"endLine\":7,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":1}}]}]},\"renderStyle\":\"STANDARD\"}");
}
@Test
@@ -96,7 +96,7 @@ public void testMappingIncludeSerialization()
@Test
public void testEnumerationMappingWithStructuredSourceValueSerialization()
{
- test("{\"code\": \"###Mapping\\nMapping a::mapping\\n(test::IncType : EnumerationMapping a\\n{ CORP : [1], LLC : [2] })\"}", "{\"isolatedLambdas\":{\"lambdas\":{}},\"modelDataContext\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"mapping\",\"associationMappings\":[],\"classMappings\":[],\"enumerationMappings\":[{\"enumValueMappings\":[{\"enumValue\":\"CORP\",\"sourceValues\":[{\"_type\":\"integerSourceValue\",\"value\":1}]},{\"enumValue\":\"LLC\",\"sourceValues\":[{\"_type\":\"integerSourceValue\",\"value\":2}]}],\"enumeration\":\"test::IncType\",\"id\":\"a\",\"sourceInformation\":{\"endColumn\":25,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":2,\"startLine\":3}}],\"includedMappings\":[],\"name\":\"mapping\",\"package\":\"a\",\"sourceInformation\":{\"endColumn\":26,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":2},\"tests\":[]},{\"_type\":\"sectionIndex\",\"name\":\"SectionIndex\",\"package\":\"__internal__\",\"sections\":[{\"_type\":\"importAware\",\"elements\":[],\"imports\":[],\"parserName\":\"Pure\",\"sourceInformation\":{\"endColumn\":8,\"endLine\":1,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":1}},{\"_type\":\"importAware\",\"elements\":[\"a::mapping\"],\"imports\":[],\"parserName\":\"Mapping\",\"sourceInformation\":{\"endColumn\":26,\"endLine\":6,\"sourceId\":\"\",\"startColumn\":8,\"startLine\":2}}]}]},\"renderStyle\":\"STANDARD\"}");
+ test("{\"code\": \"###Mapping\\nMapping a::mapping\\n(test::IncType : EnumerationMapping a\\n{ CORP : [1], LLC : [2] })\"}", "{\"isolatedLambdas\":{\"lambdas\":{}},\"modelDataContext\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"mapping\",\"associationMappings\":[],\"classMappings\":[],\"enumerationMappings\":[{\"enumValueMappings\":[{\"enumValue\":\"CORP\",\"sourceValues\":[{\"_type\":\"integerSourceValue\",\"value\":1}]},{\"enumValue\":\"LLC\",\"sourceValues\":[{\"_type\":\"integerSourceValue\",\"value\":2}]}],\"enumeration\":{\"path\":\"test::IncType\",\"sourceInformation\":{\"endColumn\":14,\"endLine\":3,\"sourceId\":\"\",\"startColumn\":2,\"startLine\":3},\"type\":\"ENUMERATION\"},\"id\":\"a\",\"sourceInformation\":{\"endColumn\":25,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":2,\"startLine\":3}}],\"includedMappings\":[],\"name\":\"mapping\",\"package\":\"a\",\"sourceInformation\":{\"endColumn\":26,\"endLine\":4,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":2},\"tests\":[]},{\"_type\":\"sectionIndex\",\"name\":\"SectionIndex\",\"package\":\"__internal__\",\"sections\":[{\"_type\":\"importAware\",\"elements\":[],\"imports\":[],\"parserName\":\"Pure\",\"sourceInformation\":{\"endColumn\":8,\"endLine\":1,\"sourceId\":\"\",\"startColumn\":1,\"startLine\":1}},{\"_type\":\"importAware\",\"elements\":[\"a::mapping\"],\"imports\":[],\"parserName\":\"Mapping\",\"sourceInformation\":{\"endColumn\":26,\"endLine\":6,\"sourceId\":\"\",\"startColumn\":8,\"startLine\":2}}]}]},\"renderStyle\":\"STANDARD\"}");
}
@Test
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/pom.xml b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/pom.xml
index 24f772691a6..c0b234701a5 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/pom.xml
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/pom.xml
@@ -154,12 +154,10 @@
com.fasterxml.jackson.core
jackson-databind
- test
com.fasterxml.jackson.core
jackson-core
- test
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/PureGrammarParser.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/PureGrammarParser.java
index 01025cf72ab..2d908aaf024 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/PureGrammarParser.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/PureGrammarParser.java
@@ -14,6 +14,7 @@
package org.finos.legend.engine.language.pure.grammar.from;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.eclipse.collections.api.factory.Lists;
@@ -37,6 +38,7 @@
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.ValueSpecification;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.classInstance.graph.RootGraphFetchTree;
+import org.finos.legend.engine.shared.core.ObjectMapperFactory;
import org.finos.legend.engine.shared.core.identity.Identity;
import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException;
import org.finos.legend.engine.shared.core.operational.logs.LogInfo;
@@ -52,6 +54,7 @@ public class PureGrammarParser
private final DEPRECATED_PureGrammarParserLibrary parsers;
private final PureGrammarParserExtensions extensions;
+ private ObjectMapper converterMapper;
private PureGrammarParser(PureGrammarParserExtensions extensions)
{
@@ -63,6 +66,7 @@ private PureGrammarParser(PureGrammarParserExtensions extensions)
connectionParser,
RuntimeParser.newInstance(connectionParser)
));
+ this.converterMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports();
}
public static PureGrammarParser newInstance(PureGrammarParserExtensions extensions)
@@ -127,7 +131,9 @@ private PureModelContextData parse(String code, DEPRECATED_PureGrammarParserLibr
sectionIndex.name = "SectionIndex";
sectionIndex._package = "__internal__";
sectionIndex.sections = ListIterate.collect(parser.definition().section(), sectionCtx -> this.visitSection(sectionCtx, parserLibrary, walkerSourceInformation, parserContext, builder::addElement, returnSourceInfo));
- return builder.withElement(sectionIndex).build();
+ // tactically run parsed values thru converters to fix old/legacy code
+ PureModelContextData pmcd = builder.withElement(sectionIndex).build();
+ return this.converterMapper.convertValue(pmcd, PureModelContextData.class);
}
private Section visitSection(CodeParserGrammar.SectionContext ctx, DEPRECATED_PureGrammarParserLibrary parserLibrary, ParseTreeWalkerSourceInformation walkerSourceInformation, PureGrammarParserContext parserContext, Consumer elementConsumer, boolean returnSourceInfo)
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/DEPRECATED_PureGrammarComposerCore.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/DEPRECATED_PureGrammarComposerCore.java
index dfe935d43cf..d76eceb33db 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/DEPRECATED_PureGrammarComposerCore.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/DEPRECATED_PureGrammarComposerCore.java
@@ -782,7 +782,7 @@ else if ("letFunction".equals(function))
}
else if ("cast".equals(function))
{
- return parameters.get(0).accept(this) + "->" + _function + "(@" + parameters.get(1).accept(this) + ")";
+ return possiblyAddParenthesis(parameters.get(0), this) + "->" + _function + "(@" + parameters.get(1).accept(this) + ")";
}
else if ("subType".equals(function))
{
@@ -791,7 +791,7 @@ else if ("subType".equals(function))
else if ("new".equals(function))
{
ValueSpecification param = parameters.get(parameters.size() - 1);
- List values = param instanceof Collection ? ((Collection) param).values : Arrays.asList(param);
+ List values = param instanceof Collection ? ((Collection) param).values : Collections.singletonList(param);
String type;
if (parameters.get(0) instanceof GenericTypeInstance)
{
@@ -842,7 +842,7 @@ else if (parameters.size() == 1)
+ (toCreateNewLine ? this.returnChar() + DEPRECATED_PureGrammarComposerCore.computeIndentationString(this, getTabSize(1)) : " ")
+ possiblyAddParenthesis(function, parameters.get(1), this);
}
- else if (function != null && CORE_FUNCTIONS_WITH_PREFIX_RENDERING.contains(function))
+ else if (CORE_FUNCTIONS_WITH_PREFIX_RENDERING.contains(function))
{
return HelperValueSpecificationGrammarComposer.renderFunctionName(function, this) + "(" +
(this.isRenderingPretty() ? this.returnChar() + DEPRECATED_PureGrammarComposerCore.computeIndentationString(this, getTabSize(1)) : "") +
@@ -877,12 +877,7 @@ public String visit(AppliedProperty appliedProperty)
@Override
public String visit(Collection collection)
{
-
- return HelperValueSpecificationGrammarComposer.renderCollection(collection.values, v ->
- {
- String value = ((ValueSpecification) v).accept(this);
- return v instanceof AppliedFunction && isInfix((AppliedFunction) v) ? "(" + value + ")" : value;
- }, this);
+ return HelperValueSpecificationGrammarComposer.renderCollection(collection.values, v -> possiblyAddParenthesis((ValueSpecification) v, this), this);
}
@Override
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/HelperValueSpecificationGrammarComposer.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/HelperValueSpecificationGrammarComposer.java
index 9773897959b..cf4cb60d031 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/HelperValueSpecificationGrammarComposer.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/HelperValueSpecificationGrammarComposer.java
@@ -179,10 +179,16 @@ public static String possiblyAddParenthesis(String function, ValueSpecification
{
if ("and".equals(function) || "or".equals(function) || "plus".equals(function) || "minus".equals(function) || "times".equals(function) || "divide".equals(function) || "not".equals(function))
{
- if (param instanceof AppliedFunction && isInfix((AppliedFunction) param))
- {
- return "(" + param.accept(transformer) + ")";
- }
+ return possiblyAddParenthesis(param, transformer);
+ }
+ return param.accept(transformer);
+ }
+
+ public static String possiblyAddParenthesis(ValueSpecification param, DEPRECATED_PureGrammarComposerCore transformer)
+ {
+ if (param instanceof AppliedFunction && isInfix((AppliedFunction) param))
+ {
+ return "(" + param.accept(transformer) + ")";
}
return param.accept(transformer);
}
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestGrammarRoundtrip.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestGrammarRoundtrip.java
index 3001358cb67..c3c3d5b7f37 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestGrammarRoundtrip.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestGrammarRoundtrip.java
@@ -152,6 +152,7 @@ private static void testFormat(String code, String unformattedCode, boolean omit
{
parsedModel = PureModelContextData.newPureModelContextData(parsedModel.getSerializer(), parsedModel.getOrigin(), LazyIterate.reject(parsedModel.getElements(), e -> e instanceof SectionIndex));
}
+
String formatted = grammarTransformer.renderPureModelContextData(parsedModel);
Assert.assertEquals(code, formatted);
// NOTE: do not remove the round-trip test for formatted code as this is a very good way to ensure that grammar <-> >protocol is bijective
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/roundtrip/TestDomainGrammarRoundtrip.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/roundtrip/TestDomainGrammarRoundtrip.java
index 146a380268e..fed2eb6e836 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/roundtrip/TestDomainGrammarRoundtrip.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-grammar/src/test/java/org/finos/legend/engine/language/pure/grammar/test/roundtrip/TestDomainGrammarRoundtrip.java
@@ -14,6 +14,7 @@
package org.finos.legend.engine.language.pure.grammar.test.roundtrip;
+import com.fasterxml.jackson.core.JsonProcessingException;
import org.finos.legend.engine.language.pure.grammar.test.TestGrammarRoundtrip;
import org.junit.Test;
@@ -497,6 +498,229 @@ public void testFunction()
"}\n");
}
+ @Test
+ public void testInFixFunctionAsParameter()
+ {
+ testFormat("function test::inFix(): Any[1]\n" +
+ "{\n" +
+ " %1970-01-01T00:00:00.000+0000->adjust((123 / 1000000)->cast(@Integer), DurationUnit.SECONDS)\n" +
+ "}\n",
+ "function test::inFix(): Any[1]\n" +
+ "{\n" +
+ " %1970-01-01T00:00:00.000+0000->adjust(cast(123 / 1000000, @Integer), DurationUnit.SECONDS)\n" +
+ "}\n");
+ }
+
+ @Test
+ public void testTypeArgumentsAreBackwardCompatibleForOldProtocolMissingIt() throws JsonProcessingException
+ {
+ testComposedGrammar("{\n" +
+ " \"_type\": \"data\",\n" +
+ " \"elements\": [\n" +
+ " {\n" +
+ " \"_type\": \"function\",\n" +
+ " \"body\": [\n" +
+ " {\n" +
+ " \"_type\": \"func\",\n" +
+ " \"function\": \"new\",\n" +
+ " \"parameters\": [\n" +
+ " {\n" +
+ // ---------- type to construct, no type arguments
+ " \"_type\": \"packageableElementPtr\",\n" +
+ " \"fullPath\": \"TdsOlapRank\"\n" +
+ // ---------- type to construct, no type arguments
+ " },\n" +
+ " {\n" +
+ " \"_type\": \"string\",\n" +
+ " \"value\": \"\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"_type\": \"collection\",\n" +
+ " \"multiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"values\": [\n" +
+ " {\n" +
+ " \"_type\": \"keyExpression\",\n" +
+ " \"add\": false,\n" +
+ " \"expression\": {\n" +
+ " \"_type\": \"lambda\",\n" +
+ " \"body\": [\n" +
+ " {\n" +
+ " \"_type\": \"integer\",\n" +
+ " \"value\": 1\n" +
+ " }\n" +
+ " ],\n" +
+ " \"parameters\": [\n" +
+ " {\n" +
+ " \"_type\": \"var\",\n" +
+ " \"genericType\": {\n" +
+ " \"multiplicityArguments\": [],\n" +
+ " \"rawType\": {\n" +
+ " \"_type\": \"packageableType\",\n" +
+ " \"fullPath\": \"TDSRow\"\n" +
+ " },\n" +
+ " \"typeArguments\": [],\n" +
+ " \"typeVariableValues\": []\n" +
+ " },\n" +
+ " \"multiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"name\": \"r\"\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " \"key\": {\n" +
+ " \"_type\": \"string\",\n" +
+ " \"value\": \"func\"\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"name\": \"new__Any_1_\",\n" +
+ " \"package\": \"test\",\n" +
+ " \"parameters\": [],\n" +
+ " \"postConstraints\": [],\n" +
+ " \"preConstraints\": [],\n" +
+ " \"returnGenericType\": {\n" +
+ " \"multiplicityArguments\": [],\n" +
+ " \"rawType\": {\n" +
+ " \"_type\": \"packageableType\",\n" +
+ " \"fullPath\": \"Any\"\n" +
+ " },\n" +
+ " \"typeArguments\": [],\n" +
+ " \"typeVariableValues\": []\n" +
+ " },\n" +
+ " \"returnMultiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"stereotypes\": [],\n" +
+ " \"taggedValues\": [],\n" +
+ " \"tests\": []\n" +
+ " }\n" +
+ " ]\n" +
+ "}",
+ "function test::new(): Any[1]\n" +
+ "{\n" +
+ " meta::pure::tds::func(r: TDSRow[1]|1)\n" +
+ "}\n");
+
+ testComposedGrammar("{\n" +
+ " \"_type\": \"data\",\n" +
+ " \"elements\": [\n" +
+ " {\n" +
+ " \"_type\": \"function\",\n" +
+ " \"body\": [\n" +
+ " {\n" +
+ " \"_type\": \"integer\",\n" +
+ " \"value\": 1\n" +
+ " }\n" +
+ " ],\n" +
+ " \"name\": \"new_Result_1__Any_1_\",\n" +
+ " \"package\": \"test\",\n" +
+ " \"parameters\": [\n" +
+ " {\n" +
+ " \"_type\": \"var\",\n" +
+ // ---------- old variable type inside class property
+ " \"class\": \"Result\",\n" +
+ // ---------- old variable type inside class property
+ " \"multiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"name\": \"res\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"postConstraints\": [],\n" +
+ " \"preConstraints\": [],\n" +
+ " \"returnGenericType\": {\n" +
+ " \"multiplicityArguments\": [],\n" +
+ " \"rawType\": {\n" +
+ " \"_type\": \"packageableType\",\n" +
+ " \"fullPath\": \"Any\"\n" +
+ " },\n" +
+ " \"typeArguments\": [],\n" +
+ " \"typeVariableValues\": []\n" +
+ " },\n" +
+ " \"returnMultiplicity\": {\n" +
+ " \"lowerBound\": 1,\n" +
+ " \"upperBound\": 1\n" +
+ " },\n" +
+ " \"stereotypes\": [],\n" +
+ " \"taggedValues\": [],\n" +
+ " \"tests\": []\n" +
+ " }\n" +
+ " ]\n" +
+ "}",
+ "function test::new(res: Result[1]): Any[1]\n" +
+ "{\n" +
+ " 1\n" +
+ "}\n");
+ }
+
+ @Test
+ public void testConvertBasicColumnSpecification()
+ {
+ testFormat("function test::new(): Any[1]\n" +
+ "{\n" +
+ " meta::pure::tds::col(r: TDSRow[1]|1, 'hello')\n" +
+ "}\n",
+ "function test::new(): Any[1]\n" +
+ "{\n" +
+ " ^BasicColumnSpecification(func=r: TDSRow[1]|1, name='hello')\n" +
+ "}\n");
+
+ testFormat("function test::new(): Any[1]\n" +
+ "{\n" +
+ " meta::pure::tds::col(r: TDSRow[1]|1, 'hello', 'documentation here')\n" +
+ "}\n",
+ "function test::new(): Any[1]\n" +
+ "{\n" +
+ " ^meta::pure::tds::BasicColumnSpecification(documentation='documentation here', func=r: TDSRow[1]|1, name='hello')\n" +
+ "}\n");
+ }
+
+ @Test
+ public void testConvertTdsOlapRank()
+ {
+ testFormat("function test::new(): Any[1]\n" +
+ "{\n" +
+ " meta::pure::tds::func(r: TDSRow[1]|1)\n" +
+ "}\n",
+ "function test::new(): Any[1]\n" +
+ "{\n" +
+ " ^meta::pure::tds::TdsOlapRank(func=r: TDSRow[1]|1)\n" +
+ "}\n");
+
+ testFormat("function test::new(): Any[1]\n" +
+ "{\n" +
+ " meta::pure::tds::func(r: TDSRow[1]|1)\n" +
+ "}\n",
+ "function test::new(): Any[1]\n" +
+ "{\n" +
+ " ^TdsOlapRank(func=r: TDSRow[1]|1)\n" +
+ "}\n");
+ }
+
+ @Test
+ public void testConvertResult()
+ {
+ testFormat("function test::new(res: Result[1]): Any[1]\n" +
+ "{\n" +
+ " 1\n" +
+ "}\n",
+ "function test::new(res: Result[1]): Any[1]\n" +
+ "{\n" +
+ " 1\n" +
+ "}\n");
+ }
+
@Test
public void testFunctionTest()
{
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/CorePureProtocolExtension.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/CorePureProtocolExtension.java
index be0ff35841a..0323e631578 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/CorePureProtocolExtension.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/CorePureProtocolExtension.java
@@ -14,10 +14,20 @@
package org.finos.legend.engine.protocol.pure.v1;
+import com.fasterxml.jackson.databind.util.StdConverter;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.collections.api.block.function.Function0;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Maps;
+import org.eclipse.collections.api.factory.Sets;
import org.eclipse.collections.api.list.MutableList;
+import org.eclipse.collections.impl.utility.ListIterate;
+import org.finos.legend.engine.protocol.pure.v1.extension.ProtocolConverter;
import org.finos.legend.engine.protocol.pure.v1.extension.ProtocolSubTypeInfo;
import org.finos.legend.engine.protocol.pure.v1.extension.PureProtocolExtension;
import org.finos.legend.engine.protocol.pure.v1.model.data.DataElementReference;
@@ -42,6 +52,7 @@
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Enumeration;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Function;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Measure;
+import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Multiplicity;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Profile;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.externalFormat.Binding;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.externalFormat.ExternalFormatSchemaSet;
@@ -71,9 +82,16 @@
import org.finos.legend.engine.protocol.pure.v1.model.test.result.TestExecuted;
import org.finos.legend.engine.protocol.pure.v1.model.test.result.TestExecutionPlanDebug;
import org.finos.legend.engine.protocol.pure.v1.model.test.result.TestResult;
-
-import java.util.List;
-import java.util.Map;
+import org.finos.legend.engine.protocol.pure.v1.model.type.GenericType;
+import org.finos.legend.engine.protocol.pure.v1.model.type.PackageableType;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.Variable;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.application.AppliedFunction;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Collection;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.KeyExpression;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.datatype.CString;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.packageableElement.GenericTypeInstance;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.packageableElement.PackageableElementPtr;
public class CorePureProtocolExtension implements PureProtocolExtension
{
@@ -180,4 +198,168 @@ public Map, String> getExtraProtoc
.withKeyValue(SectionIndex.class, "meta::pure::metamodel::section::SectionIndex")
.withKeyValue(RelationalMapper.class, "meta::relational::metamodel::RelationalMapper");
}
+
+ @Override
+ public List> getProtocolConverters()
+ {
+ return Lists.fixedSize.with(
+ new ProtocolConverter<>(new ResultVariableWithMissingTypeConverter()),
+ new ProtocolConverter<>(
+ Lists.mutable.with(
+ new BasicColumnSpecificationToColFunctionConverter(),
+ new TdsOlapRankToColFunctionConverter()))
+ );
+ }
+
+ /**
+ * Converts/fix variables of type Result to ensure they have the type and multiplicity
+ * Result[1] -> Result<Any|*>[1]
+ */
+ private static class ResultVariableWithMissingTypeConverter extends StdConverter
+ {
+ @Override
+ public Variable convert(Variable variable)
+ {
+ if (variable.genericType != null && variable.genericType.rawType instanceof PackageableType)
+ {
+ String _class = ((PackageableType) variable.genericType.rawType).fullPath;
+ if (("meta::pure::mapping::Result".equals(_class) || "Result".equals(_class)) && variable.genericType.typeArguments.size() == 0)
+ {
+ variable.genericType.typeArguments = Lists.mutable.of(new GenericType(new PackageableType("meta::pure::metamodel::type::Any")));
+ variable.genericType.multiplicityArguments = Lists.mutable.of(Multiplicity.PURE_MANY);
+ }
+ }
+ return variable;
+ }
+ }
+
+ /**
+ * Convert the usage of BasicColumnSpecification to the equivalent function
+ * ^BasicColumnSpecification(...) == col(...)
+ */
+ private static class BasicColumnSpecificationToColFunctionConverter extends StdConverter
+ {
+ @Override
+ public AppliedFunction convert(AppliedFunction appliedFunction)
+ {
+ if (appliedFunction.function.equals("new"))
+ {
+ PackageableElementPtr type;
+
+ if (appliedFunction.parameters.get(0) instanceof GenericTypeInstance)
+ {
+ GenericTypeInstance typeInstance = (GenericTypeInstance) appliedFunction.parameters.get(0);
+ if (typeInstance.genericType.typeArguments.size() >= 1 && typeInstance.genericType.typeArguments.get(0).rawType instanceof PackageableType)
+ {
+ type = (PackageableType) typeInstance.genericType.typeArguments.get(0).rawType;
+ }
+ else
+ {
+ return appliedFunction;
+ }
+ }
+ else if (appliedFunction.parameters.get(0) instanceof PackageableElementPtr)
+ {
+ type = (PackageableElementPtr) appliedFunction.parameters.get(0);
+ }
+ else
+ {
+ return appliedFunction;
+ }
+
+ Set classesThatNeedTypeFixing = Sets.fixedSize.of(
+ "meta::pure::tds::BasicColumnSpecification",
+ "BasicColumnSpecification"
+ );
+
+ if (classesThatNeedTypeFixing.contains(type.fullPath))
+ {
+ Collection collection = (Collection) appliedFunction.parameters.get(2);
+ Optional func = ListIterate.detectOptional(collection.values, x -> ((CString) ((KeyExpression) x).key).value.equals("func"))
+ .map(KeyExpression.class::cast)
+ .map(x -> x.expression)
+ .filter(Lambda.class::isInstance)
+ .map(Lambda.class::cast);
+
+ Optional name = ListIterate.detectOptional(collection.values, x -> ((CString) ((KeyExpression) x).key).value.equals("name"))
+ .map(KeyExpression.class::cast)
+ .map(x -> x.expression)
+ .filter(CString.class::isInstance)
+ .map(CString.class::cast);
+
+ Optional doc = ListIterate.detectOptional(collection.values, x -> ((CString) ((KeyExpression) x).key).value.equals("documentation"))
+ .map(KeyExpression.class::cast)
+ .map(x -> x.expression)
+ .filter(CString.class::isInstance)
+ .map(CString.class::cast);
+
+ appliedFunction.function = "meta::pure::tds::col";
+ appliedFunction.fControl = "meta::pure::tds::col_Function_1__String_1__BasicColumnSpecification_1_";
+ appliedFunction.parameters = Stream.of(func, name, doc).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
+ if (appliedFunction.parameters.size() == 3)
+ {
+ appliedFunction.fControl = "meta::pure::tds::col_Function_1__String_1__String_1__BasicColumnSpecification_1_";
+ }
+ }
+ }
+ return appliedFunction;
+ }
+ }
+
+ /**
+ * Convert the usage of TdsOlapRank to the equivalent function
+ * ^TdsOlapRank(...) == func(...)
+ */
+ private static class TdsOlapRankToColFunctionConverter extends StdConverter
+ {
+ @Override
+ public AppliedFunction convert(AppliedFunction appliedFunction)
+ {
+ if (appliedFunction.function.equals("new"))
+ {
+ PackageableElementPtr type;
+
+ if (appliedFunction.parameters.get(0) instanceof GenericTypeInstance)
+ {
+ GenericTypeInstance typeInstance = (GenericTypeInstance) appliedFunction.parameters.get(0);
+ if (typeInstance.genericType.typeArguments.size() >= 1 && typeInstance.genericType.typeArguments.get(0).rawType instanceof PackageableType)
+ {
+ type = (PackageableType) typeInstance.genericType.typeArguments.get(0).rawType;
+ }
+ else
+ {
+ return appliedFunction;
+ }
+ }
+ else if (appliedFunction.parameters.get(0) instanceof PackageableElementPtr)
+ {
+ type = (PackageableElementPtr) appliedFunction.parameters.get(0);
+ }
+ else
+ {
+ return appliedFunction;
+ }
+
+ Set classesThatNeedTypeFixing = Sets.fixedSize.of(
+ "meta::pure::tds::TdsOlapRank",
+ "TdsOlapRank"
+ );
+
+ if (classesThatNeedTypeFixing.contains(type.fullPath))
+ {
+ Collection collection = (Collection) appliedFunction.parameters.get(2);
+ Optional func = ListIterate.detectOptional(collection.values, x -> ((CString) ((KeyExpression) x).key).value.equals("func"))
+ .map(KeyExpression.class::cast)
+ .map(x -> x.expression)
+ .filter(Lambda.class::isInstance)
+ .map(Lambda.class::cast);
+
+ appliedFunction.function = "meta::pure::tds::func";
+ appliedFunction.fControl = "meta::pure::tds::func_FunctionDefinition_1__TdsOlapRank_1_";
+ appliedFunction.parameters = Stream.of(func).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
+ }
+ }
+ return appliedFunction;
+ }
+ }
}
diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/PureProtocolObjectMapperFactory.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/PureProtocolObjectMapperFactory.java
index 864ad077362..9c076d282a2 100644
--- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/PureProtocolObjectMapperFactory.java
+++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-protocol-pure/src/main/java/org/finos/legend/engine/protocol/pure/v1/PureProtocolObjectMapperFactory.java
@@ -14,13 +14,39 @@
package org.finos.legend.engine.protocol.pure.v1;
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.DeserializationConfig;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.cfg.MapperBuilder;
+import com.fasterxml.jackson.databind.cfg.MapperConfig;
+import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
+import com.fasterxml.jackson.databind.deser.std.StdDelegatingDeserializer;
+import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.jsontype.NamedType;
+import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
+import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.util.ClassUtil;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
import org.eclipse.collections.api.block.function.Function0;
import org.eclipse.collections.api.factory.Maps;
+import org.eclipse.collections.impl.factory.Lists;
import org.eclipse.collections.impl.utility.LazyIterate;
+import org.finos.legend.engine.protocol.pure.v1.extension.ProtocolConverter;
import org.finos.legend.engine.protocol.pure.v1.extension.ProtocolSubTypeInfo;
import org.finos.legend.engine.protocol.pure.v1.extension.PureProtocolExtension;
import org.finos.legend.engine.protocol.pure.v1.extension.PureProtocolExtensionLoader;
@@ -41,12 +67,6 @@
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.classInstance.relation.ColSpecArray;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.classInstance.relation.RelationStoreAccessor;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.BiConsumer;
-import java.util.function.Predicate;
-
public class PureProtocolObjectMapperFactory
{
public static > T withPureProtocolExtensions(T mapperBuilder)
@@ -79,9 +99,9 @@ public static T withPureProtocolExtensions(T objectMapp
return withPureProtocolExtensions(objectMapper, ObjectMapper::registerModule, ObjectMapper::registerSubtypes, excludeSubType);
}
- public static Map getClassInstanceTypeMappings()
+ public static Map> getClassInstanceTypeMappings()
{
- Map result = Maps.mutable.empty();
+ Map> result = Maps.mutable.empty();
result.put("path", Path.class);
result.put("rootGraphFetchTree", RootGraphFetchTree.class);
result.put(">", RelationStoreAccessor.class);
@@ -101,7 +121,7 @@ public static Map getClassInstanceTypeMappings()
result.put("runtimeInstance", RuntimeInstance.class);
result.put("executionContextInstance", ExecutionContextInstance.class);
result.put("alloySerializationConfig", SerializationConfig.class);
- PureProtocolExtensionLoader.extensions().forEach(extension -> extension.getExtraClassInstanceTypeMappings().entrySet().forEach(e -> result.put(e.getKey(), e.getValue())));
+ PureProtocolExtensionLoader.extensions().forEach(extension -> extension.getExtraClassInstanceTypeMappings().forEach(result::put));
return result;
}
@@ -158,4 +178,97 @@ public static ObjectMapper getNewObjectMapper(Set excludedSubTypes)
{
return withPureProtocolExtensions(new ObjectMapper(), excludedSubTypes);
}
+
+ public static ObjectMapper withPureProtocolConverter(ObjectMapper objectMapper)
+ {
+ List> protocolConverters = PureProtocolExtensionLoader.extensions().stream()
+ .map(PureProtocolExtension::getProtocolConverters)
+ .filter(Objects::nonNull)
+ .flatMap(List::stream)
+ .collect(Collectors.toList());
+
+ Map> converterByType = protocolConverters
+ .stream()
+ .collect(Collectors.toMap(
+ x -> x.getInputType(objectMapper.getTypeFactory()),
+ Function.identity(),
+ (a, b) -> ProtocolConverter.merge((ProtocolConverter