All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ai.vespa.schemals.lsp.schema.completion.provider.FieldsCompletion Maven / Gradle / Ivy

There is a newer version: 8.441.21
Show newest version
package ai.vespa.schemals.lsp.schema.completion.provider;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.Position;

import ai.vespa.schemals.common.StringUtils;
import ai.vespa.schemals.context.EventCompletionContext;
import ai.vespa.schemals.index.Symbol;
import ai.vespa.schemals.index.Symbol.SymbolType;
import ai.vespa.schemals.lsp.schema.completion.utils.CompletionUtils;
import ai.vespa.schemals.parser.Token.TokenType;
import ai.vespa.schemals.schemadocument.SchemaDocument;
import ai.vespa.schemals.tree.CSTUtils;
import ai.vespa.schemals.tree.Node;
import ai.vespa.schemals.tree.SchemaNode;

/**
 * FieldsCompletionProvider
 * For completing user defined fields in a fieldset.
 */
public class FieldsCompletion implements CompletionProvider {

	private boolean match(EventCompletionContext context) {
        SchemaNode match = context.document.lexer().matchBackwardsOnLine(context.position, false, TokenType.FIELDS, TokenType.COLON);

        if (match != null && match.getRange().getStart().getLine() == context.position.getLine())return true;
        return false;
    }

    private int previousBeforeDot(String documentContent, Position position) {
        int originalOffset = StringUtils.positionToOffset(documentContent, position);
        for (int offset = originalOffset - 1; offset >= 0; --offset) {
            if (Character.isWhitespace(documentContent.charAt(offset))) return -1;
            if (documentContent.charAt(offset) == '.') return originalOffset - offset + 1;
        }
        return -1;
    }

    @Override
    public List getCompletionItems(EventCompletionContext context) {
        if (!(context.document instanceof SchemaDocument)) return List.of();
        if (!match(context)) return List.of();

        int beforeDotDelta = previousBeforeDot(context.document.getCurrentContent(), context.position);

        if (beforeDotDelta != -1) {
            Node prevSymbol = CSTUtils.getSymbolAtPosition(context.document.getRootNode(), new Position(context.position.getLine(), context.position.getCharacter() - beforeDotDelta));
            if (prevSymbol == null) return List.of();

            Optional prevSymbolDefinition = context.schemaIndex.getSymbolDefinition(prevSymbol.getSymbol());

            if (prevSymbolDefinition.isEmpty()) return List.of();

            List fieldSymbols = context.schemaIndex.listSymbolsInScope(prevSymbolDefinition.get(), EnumSet.of(SymbolType.FIELD, SymbolType.MAP_KEY, SymbolType.MAP_VALUE));

            Optional structDefinition = context.schemaIndex.fieldIndex().findFieldStructDefinition(prevSymbolDefinition.get());

            if (structDefinition.isPresent()) {
                fieldSymbols.addAll(context.schemaIndex.listSymbolsInScope(structDefinition.get(), SymbolType.FIELD));
            }

            List ret = new ArrayList<>();
            Set addedIdentifiers = new HashSet<>();

            for (Symbol symbol : fieldSymbols) {
                if (addedIdentifiers.contains(symbol.getShortIdentifier()))continue;
                addedIdentifiers.add(symbol.getShortIdentifier());

                ret.add(CompletionUtils.constructBasic(symbol.getShortIdentifier(), symbol.getLongIdentifier()));
            }
            return ret;
        } else {
            Optional scope = context.schemaIndex.findSymbol(null, SymbolType.DOCUMENT, ((SchemaDocument)context.document).getSchemaIdentifier());

            if (scope.isEmpty()) return List.of();

            List fieldSymbols = context.schemaIndex.listSymbolsInScope(scope.get(), SymbolType.FIELD);

            return fieldSymbols.stream()
                               .map(symbol -> CompletionUtils.constructBasic(symbol.getPrettyIdentifier()))
                               .toList();
        }
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy