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

ai.vespa.schemals.SchemaTextDocumentService Maven / Gradle / Ivy

There is a newer version: 8.441.21
Show newest version
package ai.vespa.schemals;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;

import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.CodeActionParams;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.CodeLensParams;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.CompletionParams;
import org.eclipse.lsp4j.DefinitionParams;
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
import org.eclipse.lsp4j.DidCloseTextDocumentParams;
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
import org.eclipse.lsp4j.DidSaveTextDocumentParams;
import org.eclipse.lsp4j.DocumentFormattingParams;
import org.eclipse.lsp4j.DocumentHighlight;
import org.eclipse.lsp4j.DocumentHighlightParams;
import org.eclipse.lsp4j.DocumentOnTypeFormattingParams;
import org.eclipse.lsp4j.DocumentRangeFormattingParams;
import org.eclipse.lsp4j.DocumentSymbol;
import org.eclipse.lsp4j.DocumentSymbolParams;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.HoverParams;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.LocationLink;
import org.eclipse.lsp4j.MessageType;
import org.eclipse.lsp4j.PrepareRenameDefaultBehavior;
import org.eclipse.lsp4j.PrepareRenameParams;
import org.eclipse.lsp4j.PrepareRenameResult;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.ReferenceParams;
import org.eclipse.lsp4j.RenameParams;
import org.eclipse.lsp4j.SemanticTokens;
import org.eclipse.lsp4j.SemanticTokensDelta;
import org.eclipse.lsp4j.SemanticTokensDeltaParams;
import org.eclipse.lsp4j.SemanticTokensParams;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.TextDocumentItem;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.eclipse.lsp4j.jsonrpc.CompletableFutures;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.jsonrpc.messages.Either3;
import org.eclipse.lsp4j.services.TextDocumentService;

import ai.vespa.schemals.common.ClientLogger;
import ai.vespa.schemals.context.EventContextCreator;
import ai.vespa.schemals.context.EventDocumentContext;
import ai.vespa.schemals.context.InvalidContextException;
import ai.vespa.schemals.index.SchemaIndex;
import ai.vespa.schemals.lsp.schema.codeaction.SchemaCodeAction;
import ai.vespa.schemals.lsp.schema.completion.SchemaCompletion;
import ai.vespa.schemals.lsp.schema.definition.SchemaDefinition;
import ai.vespa.schemals.lsp.schema.documentsymbols.SchemaDocumentSymbols;
import ai.vespa.schemals.lsp.schema.hover.SchemaHover;
import ai.vespa.schemals.lsp.schema.references.SchemaReferences;
import ai.vespa.schemals.lsp.schema.rename.SchemaPrepareRename;
import ai.vespa.schemals.lsp.schema.rename.SchemaRename;
import ai.vespa.schemals.lsp.schema.semantictokens.SchemaSemanticTokens;
import ai.vespa.schemals.lsp.yqlplus.codelens.YQLPlusCodeLens;
import ai.vespa.schemals.lsp.yqlplus.semantictokens.YQLPlusSemanticTokens;
import ai.vespa.schemals.schemadocument.SchemaDocumentScheduler;
import ai.vespa.schemals.schemadocument.DocumentManager.DocumentType;

/**
 * SchemaTextDocumentService handles incomming requests from the client.
 */
public class SchemaTextDocumentService implements TextDocumentService {

    private ClientLogger logger;
    private EventContextCreator eventContextCreator;
    private SchemaMessageHandler schemaMessageHandler;

    public SchemaTextDocumentService(ClientLogger logger, SchemaDocumentScheduler schemaDocumentScheduler, SchemaIndex schemaIndex, SchemaMessageHandler schemaMessageHandler) {
        this.logger = logger;
        this.schemaMessageHandler = schemaMessageHandler;
        eventContextCreator = new EventContextCreator(schemaDocumentScheduler, schemaIndex, schemaMessageHandler);
    }

    @Override
    public CompletableFuture, CompletionList>> completion(CompletionParams completionParams) {
        // Provide completion item.
        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {

                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                PrintStream errorLogger = new PrintStream(outputStream);
                Either, CompletionList> result =
                    Either.forLeft(SchemaCompletion.getCompletionItems(eventContextCreator.createContext(completionParams), errorLogger));

                if (outputStream.size() > 0) {
                    schemaMessageHandler.logMessage(MessageType.Error, 
                        "Completion failed with errors: " + outputStream.toString() 
                    );
                }
                return result;
            } catch(CancellationException ignore) {
                // Ignore
            } catch(InvalidContextException ignore) {
                // Ignore
            }

            // Return the list of completion items.
            return Either.forLeft(new ArrayList<>());
        });
    }

    @Override
    public CompletableFuture resolveCompletionItem(CompletionItem completionItem) {
        return null;
    }


    @Override
    public CompletableFuture>> codeAction(CodeActionParams params) {
        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {
                return SchemaCodeAction.provideActions(eventContextCreator.createContext(params));
            } catch(InvalidContextException ignore) {
                // Ignore
            } catch(Exception e) {
                logger.error("Error during code action handling: " + e.getMessage());
            }

            return new ArrayList<>();
        });
    }

    @Override
    public CompletableFuture resolveCodeAction(CodeAction unresolved) {
        return CompletableFutures.computeAsync((cancelChecker) -> {

            return unresolved;
        });
    }

    @Override
    public CompletableFuture> references(ReferenceParams params) {
        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {
                return SchemaReferences.getReferences(eventContextCreator.createContext(params));
            } catch(InvalidContextException ignore) {
                // Ignore
            }
            return List.of();
        });
    }

    @Override
    public CompletableFuture>> documentSymbol(
            DocumentSymbolParams params) {
        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {
                EventDocumentContext context = eventContextCreator.createContext(params);
                return SchemaDocumentSymbols.documentSymbols(context);
            } catch(InvalidContextException ignore) {
                // Ignore
            } catch(Exception e) {
                logger.error("Error during document symbol handling: " + e.getMessage());
            }
            return List.of();
        });
    }

    @Override
    public CompletableFuture> codeLens(CodeLensParams codeLensParams) {

        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {
                EventDocumentContext context = eventContextCreator.createContext(codeLensParams);
                return YQLPlusCodeLens.codeLens(context);
            } catch(InvalidContextException ignore) {
                // Ignore
            } catch (Exception e) {
                logger.error("Error during code lens request: " + e.getMessage());
            }
            return List.of();
        });
    }

    @Override
    public CompletableFuture resolveCodeLens(CodeLens codeLens) {
        return null;
    }

    @Override
    public CompletableFuture> formatting(DocumentFormattingParams documentFormattingParams) {
        return null;
    }

    @Override
    public CompletableFuture> rangeFormatting(DocumentRangeFormattingParams documentRangeFormattingParams) {
        return null;
    }

    @Override
    public CompletableFuture> onTypeFormatting(DocumentOnTypeFormattingParams documentOnTypeFormattingParams) {
        return null;
    }

    @Override
    public CompletableFuture> prepareRename(PrepareRenameParams params) {

        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {
                return SchemaPrepareRename.prepareRename(eventContextCreator.createContext(params));
            } catch(InvalidContextException ignore) {
                // Ignore
            }
            return null;
        });
	}

    @Override
    public CompletableFuture rename(RenameParams params) {

        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {
                return SchemaRename.rename(eventContextCreator.createContext(params), params.getNewName());
            } catch(InvalidContextException ignore) {
                // Ignore
            }
            return null;
        });
    }

    @Override
    public void didOpen(DidOpenTextDocumentParams params) {
        TextDocumentItem document = params.getTextDocument();

        SchemaDocumentScheduler scheduler = eventContextCreator.scheduler;

        scheduler.openDocument(document);
    }

    @Override
    public void didChange(DidChangeTextDocumentParams params) {
        var document = params.getTextDocument();
        SchemaDocumentScheduler scheduler = eventContextCreator.scheduler;

        var contentChanges = params.getContentChanges();
        for (int i = 0; i < contentChanges.size(); i++) {
            try {
                scheduler.updateFile(document.getUri(), contentChanges.get(i).getText());
            } catch(Exception e) {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                PrintStream logger = new PrintStream(outputStream);

                e.printStackTrace(logger);

                schemaMessageHandler.logMessage(MessageType.Error, 
                    "Updating file " + document.getUri() + " failed with error: " + outputStream.toString() 
                );
            }
        }
    }

    @Override
    public void didClose(DidCloseTextDocumentParams params) {
        TextDocumentIdentifier documentIdentifier = params.getTextDocument();
        SchemaDocumentScheduler scheduler = eventContextCreator.scheduler;

        scheduler.closeDocument(documentIdentifier.getUri());
    }

    @Override
    public void didSave(DidSaveTextDocumentParams didSaveTextDocumentParams) {

    }

    @Override
    public CompletableFuture> documentHighlight(DocumentHighlightParams params) {

        return CompletableFutures.computeAsync((cancelChecker) -> {
            return new ArrayList();
        });
    }

    @Override
    public CompletableFuture semanticTokensFull(SemanticTokensParams params) {
        return CompletableFutures.computeAsync((cancelChecker) -> {
            try {
                EventDocumentContext context = eventContextCreator.createContext(params);
                if (context.document.getDocumentType() == DocumentType.YQL) {
                    return YQLPlusSemanticTokens.getSemanticTokens(context);
                }
                return SchemaSemanticTokens.getSemanticTokens(context);
                 
            } catch (InvalidContextException ex) {
                // ignore
            } catch (CancellationException ignore) {
                // Ignore cancellation exception
            } catch (Exception e) {
                logger.error(e.getMessage());;
            }

            return new SemanticTokens(new ArrayList<>());
        });
    }

    public CompletableFuture> semanticTokensFullDelta(SemanticTokensDeltaParams params) {
        return null;
    }

    @Override
    public CompletableFuture hover(HoverParams params) {
        return CompletableFutures.computeAsync((cancelChecker) -> {

            try {

                return SchemaHover.getHover(eventContextCreator.createContext(params));

            } catch (InvalidContextException ex) {
                // ignore
            } catch (CancellationException ignore) {
                // Ignore
            } catch (Exception e) {
                logger.error(e.getMessage());
            }

            return null; 
        });
    }

    @Override
    public CompletableFuture, List>> definition(DefinitionParams params) {
        return CompletableFutures.computeAsync((cancelChecker) -> {
    
            try {
    
                return Either.forLeft(SchemaDefinition.getDefinition(eventContextCreator.createContext(params)));
    
            } catch (InvalidContextException ex) {
                // ignore
            } catch (CancellationException ignore) {
                // Ignore
            } catch (Exception e) {
                logger.error(e);
            }
    
            return Either.forLeft(new ArrayList());
        });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy