Skip to content

Commit

Permalink
Implement runtime, connection, and service navigations (finos#146)
Browse files Browse the repository at this point in the history
* Implement runtime, connection, and service navigations

* Add required files

---------

Co-authored-by: Bey-Hernandez, Rafael E [Engineering] <[email protected]>
  • Loading branch information
jake-kim1 and rafaelbey authored Feb 23, 2024
1 parent e88f213 commit cee0208
Show file tree
Hide file tree
Showing 12 changed files with 1,101 additions and 14 deletions.
12 changes: 12 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
stages:
- clmscan


clm_scan:
stage: clmscan
tags: [sdlc]
image: ${CI_REGISTRY}/dx/sdlc-tools/aws-gitlab-clm-plugin/aws-gitlab-clm-plugin:current
before_script: []
script:
- /opt/clm/request-clmscan.sh "${CI_PROJECT_DIR}"

1 change: 1 addition & 0 deletions .gs-project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
productGuid: "product::630429"
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ public Optional<LegendReference> getLegendReference(SectionState section, TextPo
Optional<PackageableElement> elementAtPosition = this.getElementAtPosition(section, textPosition);

return elementAtPosition.flatMap(pe ->
this.geReferenceResolversResult(section, pe)
this.getReferenceResolversResult(section, pe)
.stream()
.filter(ref -> ref.getLocation().getTextInterval().includes(textPosition))
.findAny()
Expand Down Expand Up @@ -719,7 +719,7 @@ public Optional<LegendReference> getLegendReference(SectionState section, TextPo
}));
}

private Collection<LegendReferenceResolver> geReferenceResolversResult(SectionState section, PackageableElement packageableElement)
private Collection<LegendReferenceResolver> getReferenceResolversResult(SectionState section, PackageableElement packageableElement)
{
return section.getProperty(REFERENCE_RESULT + ":" + packageableElement.getPath(), () -> getReferenceResolvers(section, packageableElement));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,37 @@
package org.finos.legend.engine.ide.lsp.extension.connection;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Sets;
import org.eclipse.collections.api.list.ListIterable;
import org.eclipse.collections.api.set.MutableSet;
import org.finos.legend.engine.ide.lsp.extension.AbstractLegacyParserLSPGrammarExtension;
import org.finos.legend.engine.ide.lsp.extension.LegendReferenceResolver;
import org.finos.legend.engine.ide.lsp.extension.completion.LegendCompletion;
import org.finos.legend.engine.ide.lsp.extension.execution.LegendExecutionResult;
import org.finos.legend.engine.ide.lsp.extension.execution.LegendExecutionResult.Type;
import org.finos.legend.engine.ide.lsp.extension.state.GlobalState;
import org.finos.legend.engine.ide.lsp.extension.state.SectionState;
import org.finos.legend.engine.ide.lsp.extension.text.TextPosition;
import org.finos.legend.engine.language.pure.grammar.from.connection.ConnectionParser;
import org.finos.legend.engine.language.pure.grammar.from.extension.PureGrammarParserExtensionLoader;
import org.finos.legend.engine.language.pure.grammar.from.extension.PureGrammarParserExtensions;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.connection.Connection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.connection.ConnectionPointer;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.connection.ConnectionVisitor;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.connection.PackageableConnection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.modelToModel.connection.JsonModelConnection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.modelToModel.connection.ModelChainConnection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.modelToModel.connection.ModelConnection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.modelToModel.connection.XmlModelConnection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.RelationalDatabaseConnection;

/**
Expand Down Expand Up @@ -135,6 +147,63 @@ private static ListIterable<String> findKeywords()
return Lists.immutable.withAll(keywords);
}

@Override
protected Collection<LegendReferenceResolver> getReferenceResolvers(SectionState section, PackageableElement packageableElement)
{
if (!(packageableElement instanceof PackageableConnection))
{
return List.of();
}

return this.getConnectionReferences(((PackageableConnection) packageableElement).connectionValue, section.getDocumentState().getGlobalState()).collect(Collectors.toList());
}

public Stream<LegendReferenceResolver> getConnectionReferences(Connection connection, GlobalState state)
{
Stream<LegendReferenceResolver> connectionReferences = connection.accept(new ConnectionVisitor<>()
{
@Override
public Stream<LegendReferenceResolver> visit(Connection connection)
{
return state.findGrammarExtensionThatImplements(ConnectionLSPGrammarProvider.class)
.flatMap(x -> x.getConnectionReferences(connection, state));
}

@Override
public Stream<LegendReferenceResolver> visit(ConnectionPointer connectionPointer)
{
return Stream.of(LegendReferenceResolver.newReferenceResolver(connectionPointer.sourceInformation, c -> c.resolveConnection(connectionPointer.connection, connectionPointer.sourceInformation)));
}

@Override
public Stream<LegendReferenceResolver> visit(ModelConnection modelConnection)
{
return Stream.empty();
}

@Override
public Stream<LegendReferenceResolver> visit(JsonModelConnection jsonModelConnection)
{
return Stream.of(LegendReferenceResolver.newReferenceResolver(jsonModelConnection.classSourceInformation, c -> c.resolveClass(jsonModelConnection._class, jsonModelConnection.classSourceInformation)));
}

@Override
public Stream<LegendReferenceResolver> visit(XmlModelConnection xmlModelConnection)
{
return Stream.of(LegendReferenceResolver.newReferenceResolver(xmlModelConnection.classSourceInformation, c -> c.resolveClass(xmlModelConnection._class, xmlModelConnection.classSourceInformation)));
}

@Override
public Stream<LegendReferenceResolver> visit(ModelChainConnection modelChainConnection)
{
// TODO: Refactor ModelChainConnection to contain List<PackageableElementPointer> in order to reference the mappings
return Stream.empty();
}
});

return connectionReferences;
}

static class DatabaseBuilderInput
{
public DatabaseBuilderConfig config;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2024 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.ide.lsp.extension.connection;

import java.util.stream.Stream;
import org.finos.legend.engine.ide.lsp.extension.LegendReferenceResolver;
import org.finos.legend.engine.ide.lsp.extension.state.GlobalState;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.connection.Connection;

public interface ConnectionLSPGrammarProvider
{
Stream<LegendReferenceResolver> getConnectionReferences(Connection connection, GlobalState state);

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.finos.legend.engine.ide.lsp.extension.LegendReferenceResolver;
import org.finos.legend.engine.ide.lsp.extension.SourceInformationUtil;
import org.finos.legend.engine.ide.lsp.extension.completion.LegendCompletion;
import org.finos.legend.engine.ide.lsp.extension.connection.ConnectionLSPGrammarProvider;
import org.finos.legend.engine.ide.lsp.extension.declaration.LegendDeclaration;
import org.finos.legend.engine.ide.lsp.extension.execution.LegendExecutionResult;
import org.finos.legend.engine.ide.lsp.extension.mapping.MappingLSPGrammarExtension;
Expand All @@ -39,7 +40,9 @@
import org.finos.legend.engine.language.pure.grammar.from.RelationalGrammarParserExtension;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.connection.Connection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.mapping.ClassMapping;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.RelationalDatabaseConnection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.mapping.RelationalPropertyMapping;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.mapping.RootRelationalClassMapping;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.mapping.TablePtr;
Expand All @@ -64,7 +67,7 @@
/**
* Extension for the Relational grammar.
*/
public class RelationalLSPGrammarExtension extends AbstractSectionParserLSPGrammarExtension implements MappingLSPGrammarProvider
public class RelationalLSPGrammarExtension extends AbstractSectionParserLSPGrammarExtension implements MappingLSPGrammarProvider, ConnectionLSPGrammarProvider
{
private static final Logger LOGGER = LoggerFactory.getLogger(RelationalLSPGrammarExtension.class);

Expand Down Expand Up @@ -449,4 +452,20 @@ else if (element instanceof DynaFunc)

return Stream.empty();
}

@Override
public Stream<LegendReferenceResolver> getConnectionReferences(Connection connection, GlobalState state)
{
if (connection instanceof RelationalDatabaseConnection)
{
return Stream.of(toReference((RelationalDatabaseConnection) connection));
}

return Stream.empty();
}

private LegendReferenceResolver toReference(RelationalDatabaseConnection relationalDatabaseConnection)
{
return LegendReferenceResolver.newReferenceResolver(relationalDatabaseConnection.elementSourceInformation, s -> s.resolveStore(relationalDatabaseConnection.element, relationalDatabaseConnection.elementSourceInformation));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,32 @@

package org.finos.legend.engine.ide.lsp.extension.runtime;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
import org.eclipse.collections.impl.lazy.CompositeIterable;
import org.finos.legend.engine.ide.lsp.extension.AbstractLegacyParserLSPGrammarExtension;
import org.finos.legend.engine.ide.lsp.extension.LegendReferenceResolver;
import org.finos.legend.engine.ide.lsp.extension.completion.LegendCompletion;
import org.finos.legend.engine.ide.lsp.extension.connection.ConnectionLSPGrammarExtension;
import org.finos.legend.engine.ide.lsp.extension.state.GlobalState;
import org.finos.legend.engine.ide.lsp.extension.state.SectionState;
import org.finos.legend.engine.ide.lsp.extension.text.TextPosition;
import org.finos.legend.engine.language.pure.grammar.from.extension.PureGrammarParserExtensions;
import org.finos.legend.engine.language.pure.grammar.from.runtime.RuntimeParser;
import org.finos.legend.engine.protocol.pure.v1.model.context.PackageableElementPointer;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.connection.Connection;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.ConnectionStores;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.EngineRuntime;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.PackageableRuntime;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.Runtime;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.RuntimePointer;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.StoreConnections;

/**
* Extension for the Runtime grammar.
Expand Down Expand Up @@ -77,4 +92,100 @@ public Iterable<? extends LegendCompletion> getCompletions(SectionState section,

return CompositeIterable.with(legendCompletions, this.computeCompletionsForSupportedTypes(section, location, Set.of("Runtime")));
}

@Override
protected Collection<LegendReferenceResolver> getReferenceResolvers(SectionState section, PackageableElement packageableElement)
{
if (!(packageableElement instanceof PackageableRuntime))
{
return List.of();
}

return this.getRuntimeReferences(((PackageableRuntime) packageableElement).runtimeValue, section.getDocumentState().getGlobalState()).collect(Collectors.toList());
}

public Stream<LegendReferenceResolver> getRuntimeReferences(Runtime runtime, GlobalState state)
{
if (runtime instanceof EngineRuntime)
{
return this.toEngineRuntimeReferences((EngineRuntime) runtime, state);
}

if (runtime instanceof RuntimePointer)
{
return Stream.of(this.toRuntimePointerReference((RuntimePointer) runtime));
}

return Stream.empty();
}

private Stream<LegendReferenceResolver> toEngineRuntimeReferences(EngineRuntime engineRuntime, GlobalState state)
{
return Stream.concat(this.toMappingReferences(engineRuntime.mappings),
Stream.concat(this.toStoreConnectionReferences(engineRuntime.connections, state),
this.toConnectionStoreReferences(engineRuntime.connectionStores, state)));
}

private LegendReferenceResolver toRuntimePointerReference(RuntimePointer runtimePointer)
{
return LegendReferenceResolver.newReferenceResolver(
runtimePointer.sourceInformation,
x -> x.resolveRuntime(runtimePointer.runtime, runtimePointer.sourceInformation)
);
}

private Stream<LegendReferenceResolver> toMappingReferences(List<PackageableElementPointer> mappings)
{
return mappings.stream()
.map(this::toMappingReference);
}

private LegendReferenceResolver toMappingReference(PackageableElementPointer packageableElementPointer)
{
return LegendReferenceResolver.newReferenceResolver(
packageableElementPointer.sourceInformation,
x -> x.resolveMapping(packageableElementPointer.path, packageableElementPointer.sourceInformation)
);
}

private Stream<LegendReferenceResolver> toStoreConnectionReferences(List<StoreConnections> storeConnections, GlobalState state)
{
return storeConnections.stream()
.flatMap(storeConnection ->
{
LegendReferenceResolver storeReference = this.toStoreReference(storeConnection.store);
Stream<LegendReferenceResolver> connectionReferences = storeConnection.storeConnections
.stream()
.flatMap(identifiedConnection -> this.toConnectionReferences(identifiedConnection.connection, state));
return Stream.concat(Stream.of(storeReference), connectionReferences);
});
}

private Stream<LegendReferenceResolver> toConnectionStoreReferences(List<ConnectionStores> connectionStores, GlobalState state)
{
return connectionStores.stream()
.flatMap(connectionStore ->
{
Stream<LegendReferenceResolver> connectionReferences = this.toConnectionReferences(connectionStore.connectionPointer, state);
Stream<LegendReferenceResolver> storeReferences = connectionStore.storePointers
.stream()
.map(packageableElementPointer -> this.toStoreReference(packageableElementPointer));
return Stream.concat(connectionReferences, storeReferences);
});

}

private LegendReferenceResolver toStoreReference(PackageableElementPointer packageableElementPointer)
{
return LegendReferenceResolver.newReferenceResolver(
packageableElementPointer.sourceInformation,
x -> x.resolveStore(packageableElementPointer.path, packageableElementPointer.sourceInformation)
);
}

private Stream<LegendReferenceResolver> toConnectionReferences(Connection connection, GlobalState state)
{
return state.findGrammarExtensionThatImplements(ConnectionLSPGrammarExtension.class)
.flatMap(x -> x.getConnectionReferences(connection, state));
}
}
Loading

0 comments on commit cee0208

Please sign in to comment.