public static Optional<Hover> getFileHoverInformation(String hoverDirectory, String markdownKey, Range range) {
        // avoid doing unnecessary IO operations
        if (markdownContentCache.containsKey(markdownKey)) {
            Optional<MarkupContent> mdContent = markdownContentCache.get(markdownKey);
            if (mdContent != null) {
                if (mdContent.isEmpty()) {
                    return Optional.empty();
                }
                return Optional.of(new Hover(mdContent.get(), range));
            }
        }

        if (SchemaLanguageServer.serverPath == null)return Optional.empty();
        String fileName = markdownKey + ".md";
        fileName = FileUtils.sanitizeFileName(fileName);

        Path markdownPath = SchemaLanguageServer.serverPath.resolve("hover").resolve(hoverDirectory).resolve(fileName);

        try {
            String markdown = Files.readString(markdownPath);

            MarkupContent mdContent = new MarkupContent(MarkupKind.MARKDOWN, markdown);
            Hover hover = new Hover(mdContent, range);
            markdownContentCache.put(markdownKey, Optional.of(mdContent));
            return Optional.of(hover);

        } catch(IOException ex) {
            return Optional.empty();
        }
    }
Public interface to be used by {@link SchemaCompletion}
@param function
@return Hover with empty range
integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/schema/hover/SchemaHover.java