server/aws-lsp-json/src/language-service/jsonLanguageService.ts (60 lines of code) (raw):

import { AwsLanguageService, MutuallyExclusiveLanguageService, UriResolver } from '@aws/lsp-core/out/base' import { JSONDocument, LanguageService, getLanguageService } from 'vscode-json-languageservice' import { CompletionList, Diagnostic, FormattingOptions, Hover, Range } from 'vscode-languageserver' import { Position, TextDocument, TextEdit } from 'vscode-languageserver-textdocument' export type JsonLanguageServiceProps = { defaultSchemaUri?: string uriResolver?: UriResolver allowComments?: boolean } /** * This is a thin wrapper around the VS Code Json Language Service * https://github.com/microsoft/vscode-json-languageservice/ */ export class JsonLanguageService implements AwsLanguageService { private jsonService: LanguageService constructor(private readonly props: JsonLanguageServiceProps) { let resolveUri: (url: string) => Promise<string> if (props.uriResolver) { resolveUri = props.uriResolver } else { resolveUri = getSchema } this.jsonService = getLanguageService({ schemaRequestService: resolveUri?.bind(this), }) const schemas = props.defaultSchemaUri ? [{ fileMatch: ['*'], uri: props.defaultSchemaUri }] : undefined this.jsonService.configure({ allowComments: props.allowComments ?? true, schemas }) } public isSupported(document: TextDocument): boolean { const languageId = document.languageId // placeholder-test-json comes from the sample Visual Studio Client (Extension) in the repo // see client/visualStudio/IdesLspPoc/ContentDefinitions/JsonContentType.cs return languageId === 'json' || languageId === 'placeholder-test-json' } public doValidation(textDocument: TextDocument): Thenable<Diagnostic[]> { const jsonDocument = this.parse(textDocument) return this.jsonService.doValidation(textDocument, jsonDocument) } public doComplete(textDocument: TextDocument, position: Position): Thenable<CompletionList | null> { const jsonDocument = this.parse(textDocument) return this.jsonService.doComplete(textDocument, position, jsonDocument) } public doHover(textDocument: TextDocument, position: Position): Thenable<Hover | null> { const jsonDocument = this.parse(textDocument) return this.jsonService.doHover(textDocument, position, jsonDocument) } public format(textDocument: TextDocument, range: Range, options: FormattingOptions): TextEdit[] { return this.jsonService.format(textDocument, range, options) } private parse(textDocument: TextDocument): JSONDocument { const jsonDocument = this.jsonService.parseJSONDocument(textDocument) if (!jsonDocument) { throw new Error(`Unable to parse document with uri: ${textDocument.uri}`) } return jsonDocument } } async function getSchema(url: string) { const response = await fetch(url) const schema = await (await response.blob()).text() return schema } export function create(props: JsonLanguageServiceProps): AwsLanguageService { const jsonService = new JsonLanguageService(props) return new MutuallyExclusiveLanguageService([jsonService]) }