diff --git a/LICENSE.md b/LICENSE.md
index f49a4e1..9a8fc67 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright 2018 Nadeeshaan Gunasinghe
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/client/.vscodeignore b/client/.vscodeignore
new file mode 100644
index 0000000..d3f0107
--- /dev/null
+++ b/client/.vscodeignore
@@ -0,0 +1,8 @@
+.vscode/**
+typings/**
+out/test/**
+test/**
+src/**
+**/*.map
+.gitignore
+tsconfig.json
diff --git a/client/package.json b/client/package.json
new file mode 100644
index 0000000..b63d732
--- /dev/null
+++ b/client/package.json
@@ -0,0 +1,53 @@
+{
+ "name": "swagger-language-sever-extension",
+ "description": "VSCode Client extension for Swagger",
+ "author": "Nadeeshaan",
+ "license": "MIT",
+ "version": "0.0.1",
+ "publisher": "nadeeshaan",
+ "engines": {
+ "vscode": "^1.26.0"
+ },
+ "categories": [
+ "Other"
+ ],
+ "activationEvents": [
+ "onLanguage:yaml"
+ ],
+ "main": "./out/extension",
+ "contributes": {
+ "configuration": {
+ "type": "object",
+ "title": "Example configuration",
+ "properties": {
+ "languageServerExample.maxNumberOfProblems": {
+ "scope": "resource",
+ "type": "number",
+ "default": 100,
+ "description": "Controls the maximum number of problems produced by the server."
+ }
+ }
+ }
+ },
+ "scripts": {
+ "vscode:prepublish": "npm run compile",
+ "compile": "tsc -p ./",
+ "watch": "tsc -watch -p ./",
+ "postinstall": "node ./node_modules/vscode/bin/install",
+ "build:grammar": "tsc -p syntaxes/build && node syntaxes/build/build.js",
+ "test": "npm run compile && node ./node_modules/vscode/bin/test",
+ "clean": "rimraf server-build target",
+ "package": "npm run compile && vsce package"
+ },
+ "devDependencies": {
+ "vscode": "^1.1.5",
+ "@types/node": "^8.10.25",
+ "tslint": "^5.8.0",
+ "typescript": "^2.6.1",
+ "vsce": "^1.36.2"
+ },
+ "dependencies": {
+ "vscode": "^1.1.21",
+ "vscode-languageclient": "^4.1.4"
+ }
+}
diff --git a/client/src/extension.ts b/client/src/extension.ts
new file mode 100644
index 0000000..7d4be73
--- /dev/null
+++ b/client/src/extension.ts
@@ -0,0 +1,43 @@
+/* --------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ * ------------------------------------------------------------------------------------------ */
+'use strict';
+
+import * as path from 'path';
+
+import { workspace, Disposable, ExtensionContext } from 'vscode';
+import { LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, TransportKind } from 'vscode-languageclient';
+
+const main: string = 'StdioLauncher';
+
+export function activate(context: ExtensionContext) {
+
+ const { JAVA_HOME } = process.env;
+ console.log(`Using java from JAVA_HOME: ${JAVA_HOME}`);
+ let excecutable : string = path.join(JAVA_HOME, 'bin', 'java');
+
+ let jarPath = path.join(__dirname, '..', 'launcher', 'ls-launcher.jar');
+ const args: string[] = ['-cp', jarPath];
+ args.push('-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005,quiet=y');
+ console.log(jarPath);
+
+ let serverOptions: ServerOptions = {
+ command: excecutable,
+ args: [...args, main],
+ options: {}
+ };
+
+ // Options to control the language client
+ let clientOptions: LanguageClientOptions = {
+ // Register the server for plain text documents
+ documentSelector: [{scheme: 'file', language: 'yaml'}]
+ };
+
+ // Create the language client and start the client.
+ let disposable = new LanguageClient('languageServerExample', 'Language Server Example', serverOptions, clientOptions).start();
+
+ // Push the disposable to the context's subscriptions so that the
+ // client can be deactivated on extension deactivation
+ context.subscriptions.push(disposable);
+}
diff --git a/client/tsconfig.json b/client/tsconfig.json
new file mode 100644
index 0000000..4e6b0ca
--- /dev/null
+++ b/client/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "compilerOptions": {
+ "target": "es6",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "outDir": "out",
+ "lib": [ "es2016" ],
+ "sourceMap": true
+ },
+ "exclude": [
+ "node_modules",
+ "server"
+ ]
+}
\ No newline at end of file
diff --git a/langserver-core/pom.xml b/langserver-core/pom.xml
new file mode 100644
index 0000000..cf82ea6
--- /dev/null
+++ b/langserver-core/pom.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ swagger-language-server
+ org.swagger.ls
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ langserver-core
+ jar
+
\ No newline at end of file
diff --git a/langserver-core/src/main/java/org/swagger/langserver/DocumentManager.java b/langserver-core/src/main/java/org/swagger/langserver/DocumentManager.java
new file mode 100644
index 0000000..8b78b6d
--- /dev/null
+++ b/langserver-core/src/main/java/org/swagger/langserver/DocumentManager.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018, Nadeeshaan Gunasinghe
+ *
+ * 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.swagger.langserver;
+
+import java.nio.file.Path;
+
+/**
+ * Document Manager is responsible for maintaining the content of the documents.
+ */
+public interface DocumentManager {
+ /**
+ * Checks whether the given file is open in workspace.
+ *
+ * @param filePath Path of the file
+ * @return True if the given file is open
+ */
+ boolean isFileOpen(Path filePath);
+
+ /**
+ * Opens the given file in document manager.
+ *
+ * @param filePath Path of the file
+ * @param content Content of the file
+ */
+ void openFile(Path filePath, String content);
+
+ /**
+ * Updates given file in document manager with new content.
+ *
+ * @param filePath Path of the file
+ * @param updatedContent New content of the file
+ */
+ void updateFile(Path filePath, String updatedContent);
+
+ /**
+ * Close the given file in document manager.
+ *
+ * @param filePath Path of the file
+ */
+ void closeFile(Path filePath);
+
+ /**
+ * Gets uptodate content of the file.
+ *
+ * @param filePath Path of the file
+ * @return Content of the file
+ */
+ String getFileContent(Path filePath);
+}
diff --git a/langserver-core/src/main/java/org/swagger/langserver/DocumentManagerImpl.java b/langserver-core/src/main/java/org/swagger/langserver/DocumentManagerImpl.java
new file mode 100644
index 0000000..d18380d
--- /dev/null
+++ b/langserver-core/src/main/java/org/swagger/langserver/DocumentManagerImpl.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018, Nadeeshaan Gunasinghe
+ *
+ * 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.swagger.langserver;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Implementation of DocumentManager Interface.
+ */
+public class DocumentManagerImpl implements DocumentManager {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DocumentManagerImpl.class);
+
+ private ConcurrentHashMap documents;
+
+ private DocumentManagerImpl() {
+ this.documents = new ConcurrentHashMap<>();
+ }
+
+ private static class InnerSingleton {
+ private static final DocumentManagerImpl INSTANCE = new DocumentManagerImpl();
+ }
+
+ public static DocumentManagerImpl getInstance() {
+ return InnerSingleton.INSTANCE;
+ }
+
+ /**
+ * Checks whether the given file is open in workspace.
+ *
+ * @param filePath Path of the file
+ * @return Returns the list of opened document paths
+ */
+ @Override
+ public boolean isFileOpen(Path filePath) {
+ return getPathEntry(filePath) != null;
+ }
+
+ /**
+ * Opens the given file in document manager.
+ *
+ * @param filePath Path of the file
+ * @param content Content of the file
+ */
+ @Override
+ public void openFile(Path filePath, String content) {
+ if (isFileOpen(filePath)) {
+ LOGGER.warn("File is Already opened");
+ return;
+ }
+ this.documents.put(filePath, content);
+ }
+
+ /**
+ * Updates given file in document manager with new content.
+ *
+ * @param filePath Path of the file
+ * @param updatedContent New content of the file
+ */
+ @Override
+ public void updateFile(Path filePath, String updatedContent) {
+ Path opened = getPathEntry(filePath);
+ if (opened == null) {
+ LOGGER.error("Cannot find the file to update: " + filePath.toString());
+ return;
+ }
+
+ this.documents.put(opened, updatedContent);
+ }
+
+ /**
+ * Close the given file in document manager.
+ *
+ * @param filePath Path of the file
+ */
+ @Override
+ public void closeFile(Path filePath) {
+ Path opened = getPathEntry(filePath);
+ if (opened == null) {
+ LOGGER.warn("Cannot find open file [" + filePath.toString() + "] to close");
+ return;
+ }
+
+ this.documents.remove(opened);
+ }
+
+ /**
+ * Gets uptodate content of the file.
+ *
+ * @param filePath Path of the file
+ * @return Content of the file
+ */
+ @Override
+ public String getFileContent(Path filePath) {
+ if (!isFileOpen(filePath)) {
+ return null;
+ }
+ return documents.get(filePath);
+ }
+
+ // Private methods
+
+ /**
+ * Get the path entry for the given file path.
+ *
+ * @param filePath File Path to se
+ * @return {@link Path} Path Entry
+ */
+ private Path getPathEntry(Path filePath) {
+ return this.documents.entrySet().stream().filter(entry -> {
+ try {
+ return Files.isSameFile(entry.getKey(), filePath);
+ } catch (IOException e) {
+ LOGGER.error("Error locating File: " + e.getMessage());
+ return false;
+ }
+ }).map(Map.Entry::getKey).findFirst().orElse(null);
+ }
+}
diff --git a/langserver-core/src/main/java/org/swagger/langserver/SwaggerLanguageServer.java b/langserver-core/src/main/java/org/swagger/langserver/SwaggerLanguageServer.java
new file mode 100644
index 0000000..9960194
--- /dev/null
+++ b/langserver-core/src/main/java/org/swagger/langserver/SwaggerLanguageServer.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, Nadeeshaan Gunasinghe
+ *
+ * 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.swagger.langserver;
+
+import org.eclipse.lsp4j.CompletionOptions;
+import org.eclipse.lsp4j.InitializeParams;
+import org.eclipse.lsp4j.InitializeResult;
+import org.eclipse.lsp4j.ServerCapabilities;
+import org.eclipse.lsp4j.TextDocumentSyncKind;
+import org.eclipse.lsp4j.services.LanguageClient;
+import org.eclipse.lsp4j.services.LanguageClientAware;
+import org.eclipse.lsp4j.services.LanguageServer;
+import org.eclipse.lsp4j.services.TextDocumentService;
+import org.eclipse.lsp4j.services.WorkspaceService;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Language Server Implementation for Swagger.
+ */
+public class SwaggerLanguageServer implements LanguageServer, LanguageClientAware {
+
+ private TextDocumentService textDocumentService;
+
+ private WorkspaceService workspaceService;
+
+ private LanguageClient client;
+
+ public SwaggerLanguageServer() {
+ this.textDocumentService = new SwaggerTextDocumentService();
+ this.workspaceService = new SwaggerWorkspaceService();
+ }
+
+ @Override
+ public void connect(LanguageClient languageClient) {
+ this.client = languageClient;
+ }
+
+ @Override
+ public CompletableFuture initialize(InitializeParams initializeParams) {
+ final InitializeResult initializeResult = new InitializeResult(new ServerCapabilities());
+ initializeResult.getCapabilities().setTextDocumentSync(TextDocumentSyncKind.Full);
+ initializeResult.getCapabilities().setCompletionProvider(new CompletionOptions());
+ return CompletableFuture.supplyAsync(() -> initializeResult);
+ }
+
+ @Override
+ public CompletableFuture