vscode-go: update to LSP 3.17 and vscode-languageclient v8.0.0

Fixes golang/vscode-go#2225.

Change-Id: I576ab3e1d306d3f805e603d5770d1ca56f605b69
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/406297
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/package-lock.json b/package-lock.json
index 4a37ffe..51af64f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,8 +19,8 @@
         "vscode-debugadapter": "1.45.0",
         "vscode-debugadapter-testsupport": "1.45.0",
         "vscode-debugprotocol": "1.45.0",
-        "vscode-languageclient": "7.0.0",
-        "vscode-languageserver-protocol": "3.16.0",
+        "vscode-languageclient": "8.0.1",
+        "vscode-languageserver-protocol": "3.17.1",
         "vscode-uri": "3.0.3",
         "web-request": "1.0.7"
       },
@@ -5493,24 +5493,24 @@
       "integrity": "sha512-xU6XtdKJ0waWIt79Zt4WVyIQ3oDkhilku9Shbv7Vc4KXEr/npsf8dhinyIZXSIlH2lzJiE3imp1xbYpyRTIrhg=="
     },
     "node_modules/vscode-jsonrpc": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
-      "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz",
+      "integrity": "sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ==",
       "engines": {
-        "node": ">=8.0.0 || >=10.0.0"
+        "node": ">=14.0.0"
       }
     },
     "node_modules/vscode-languageclient": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
-      "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.0.1.tgz",
+      "integrity": "sha512-9XoE+HJfaWvu7Y75H3VmLo5WLCtsbxEgEhrLPqwt7eyoR49lUIyyrjb98Yfa50JCMqF2cePJAEVI6oe2o1sIhw==",
       "dependencies": {
         "minimatch": "^3.0.4",
-        "semver": "^7.3.4",
-        "vscode-languageserver-protocol": "3.16.0"
+        "semver": "^7.3.5",
+        "vscode-languageserver-protocol": "3.17.1"
       },
       "engines": {
-        "vscode": "^1.52.0"
+        "vscode": "^1.67.0"
       }
     },
     "node_modules/vscode-languageclient/node_modules/semver": {
@@ -5528,18 +5528,18 @@
       }
     },
     "node_modules/vscode-languageserver-protocol": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
-      "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
+      "version": "3.17.1",
+      "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz",
+      "integrity": "sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg==",
       "dependencies": {
-        "vscode-jsonrpc": "6.0.0",
-        "vscode-languageserver-types": "3.16.0"
+        "vscode-jsonrpc": "8.0.1",
+        "vscode-languageserver-types": "3.17.1"
       }
     },
     "node_modules/vscode-languageserver-types": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
-      "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
+      "version": "3.17.1",
+      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz",
+      "integrity": "sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ=="
     },
     "node_modules/vscode-uri": {
       "version": "3.0.3",
@@ -9907,18 +9907,18 @@
       "integrity": "sha512-xU6XtdKJ0waWIt79Zt4WVyIQ3oDkhilku9Shbv7Vc4KXEr/npsf8dhinyIZXSIlH2lzJiE3imp1xbYpyRTIrhg=="
     },
     "vscode-jsonrpc": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
-      "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg=="
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz",
+      "integrity": "sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ=="
     },
     "vscode-languageclient": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
-      "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.0.1.tgz",
+      "integrity": "sha512-9XoE+HJfaWvu7Y75H3VmLo5WLCtsbxEgEhrLPqwt7eyoR49lUIyyrjb98Yfa50JCMqF2cePJAEVI6oe2o1sIhw==",
       "requires": {
         "minimatch": "^3.0.4",
-        "semver": "^7.3.4",
-        "vscode-languageserver-protocol": "3.16.0"
+        "semver": "^7.3.5",
+        "vscode-languageserver-protocol": "3.17.1"
       },
       "dependencies": {
         "semver": {
@@ -9932,18 +9932,18 @@
       }
     },
     "vscode-languageserver-protocol": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
-      "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
+      "version": "3.17.1",
+      "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz",
+      "integrity": "sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg==",
       "requires": {
-        "vscode-jsonrpc": "6.0.0",
-        "vscode-languageserver-types": "3.16.0"
+        "vscode-jsonrpc": "8.0.1",
+        "vscode-languageserver-types": "3.17.1"
       }
     },
     "vscode-languageserver-types": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
-      "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
+      "version": "3.17.1",
+      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz",
+      "integrity": "sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ=="
     },
     "vscode-uri": {
       "version": "3.0.3",
diff --git a/package.json b/package.json
index 0e15131..c008717 100644
--- a/package.json
+++ b/package.json
@@ -59,8 +59,8 @@
     "vscode-debugadapter": "1.45.0",
     "vscode-debugadapter-testsupport": "1.45.0",
     "vscode-debugprotocol": "1.45.0",
-    "vscode-languageclient": "7.0.0",
-    "vscode-languageserver-protocol": "3.16.0",
+    "vscode-languageclient": "8.0.1",
+    "vscode-languageserver-protocol": "3.17.1",
     "vscode-uri": "3.0.3",
     "web-request": "1.0.7"
   },
diff --git a/src/commands/startLanguageServer.ts b/src/commands/startLanguageServer.ts
index 2957fdc..466cbdf 100644
--- a/src/commands/startLanguageServer.ts
+++ b/src/commands/startLanguageServer.ts
@@ -4,7 +4,6 @@
  *--------------------------------------------------------*/
 
 import * as vscode from 'vscode';
-import deepEqual from 'deep-equal';
 
 import { CommandFactory } from '.';
 import { getGoConfig } from '../config';
@@ -50,13 +49,8 @@
 			}
 			// If the client has already been started, make sure to clear existing
 			// diagnostics and stop it.
-			let cleanStop = true;
 			if (goCtx.languageClient) {
-				cleanStop = await stopLanguageClient(goCtx);
-				if (goCtx.languageServerDisposable) {
-					goCtx.languageServerDisposable.dispose();
-					goCtx.languageServerDisposable = undefined;
-				}
+				await stopLanguageClient(goCtx);
 			}
 
 			// Before starting the language server, make sure to deregister any
@@ -96,23 +90,9 @@
 				return;
 			}
 
-			// Check if we should recreate the language client.
-			// This may be necessary if the user has changed settings
-			// in their config, or previous session wasn't stopped cleanly.
-			if (!cleanStop || !deepEqual(goCtx.latestConfig, cfg)) {
-				// Track the latest config used to start the language server,
-				// and rebuild the language client.
-				goCtx.languageClient = await buildLanguageClient(goCtx, buildLanguageClientOption(goCtx, cfg));
-				goCtx.crashCount = 0;
-			}
-
-			const disposable = goCtx.languageClient?.start();
-			if (disposable) {
-				goCtx.languageServerDisposable = disposable;
-				ctx.subscriptions.push(goCtx.languageServerDisposable);
-			}
-			await goCtx.languageClient?.onReady();
-			goCtx.serverInfo = toServerInfo(goCtx.languageClient?.initializeResult);
+			goCtx.languageClient = await buildLanguageClient(goCtx, buildLanguageClientOption(goCtx, cfg));
+			await goCtx.languageClient.start();
+			goCtx.serverInfo = toServerInfo(goCtx.languageClient.initializeResult);
 			updateStatus(goCtx, goConfig, true);
 			console.log(`Server: ${JSON.stringify(goCtx.serverInfo, null, 2)}`);
 		} finally {
diff --git a/src/context.ts b/src/context.ts
index 05405db..27f5ff4 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -15,7 +15,6 @@
 export interface GoExtensionContext {
 	languageClient?: LanguageClient;
 	legacyLanguageService?: LegacyLanguageService;
-	languageServerDisposable?: vscode.Disposable;
 	latestConfig?: LanguageServerConfig;
 	serverOutputChannel?: vscode.OutputChannel;
 	languageServerIsRunning?: boolean;
diff --git a/src/goMain.ts b/src/goMain.ts
index 00f5f11..5043032 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -215,6 +215,7 @@
 
 export function deactivate() {
 	return Promise.all([
+		goCtx.languageClient?.stop(),
 		cancelRunningTests(),
 		killRunningPprof(),
 		Promise.resolve(cleanupTempDir()),
diff --git a/src/language/goLanguageServer.ts b/src/language/goLanguageServer.ts
index 25bd2f5..352aa38 100644
--- a/src/language/goLanguageServer.ts
+++ b/src/language/goLanguageServer.ts
@@ -26,6 +26,7 @@
 	HandleDiagnosticsSignature,
 	InitializeError,
 	InitializeResult,
+	LanguageClientOptions,
 	Message,
 	ProvideCodeLensesSignature,
 	ProvideCompletionItemsSignature,
@@ -33,7 +34,7 @@
 	ResponseError,
 	RevealOutputChannelOn
 } from 'vscode-languageclient';
-import { LanguageClient } from 'vscode-languageclient/node';
+import { LanguageClient, ServerOptions } from 'vscode-languageclient/node';
 import { getGoConfig, getGoplsConfig, extensionInfo } from '../config';
 import { toolExecutionEnvironment } from '../goEnv';
 import { GoDocumentFormattingEditProvider, usingCustomFormatTool } from './legacy/goFormat';
@@ -268,8 +269,10 @@
 };
 
 // exported for testing.
-export async function stopLanguageClient(goCtx: GoExtensionContext): Promise<boolean> {
+export async function stopLanguageClient(goCtx: GoExtensionContext) {
 	const c = goCtx.languageClient;
+	goCtx.crashCount = 0;
+	goCtx.languageClient = undefined;
 	if (!c) return false;
 
 	if (c.diagnostics) {
@@ -284,9 +287,7 @@
 		await race(c.stop(), 2000);
 	} catch (e) {
 		c.outputChannel?.appendLine(`Failed to stop client: ${e}`);
-		return false;
 	}
-	return true;
 }
 
 export function toServerInfo(res?: InitializeResult): ServerInfo | undefined {
@@ -367,7 +368,7 @@
 			command: cfg.path,
 			args: ['-mode=stdio', ...cfg.flags],
 			options: { env: cfg.env }
-		},
+		} as ServerOptions,
 		{
 			initializationOptions: goplsWorkspaceConfig,
 			documentSelector,
@@ -393,29 +394,29 @@
 				return false;
 			},
 			errorHandler: {
-				error: (error: Error, message: Message, count: number): ErrorAction => {
+				error: (error: Error, message: Message, count: number) => {
 					// Allow 5 crashes before shutdown.
 					if (count < 5) {
-						return ErrorAction.Continue;
+						return { action: ErrorAction.Continue };
 					}
 					vscode.window.showErrorMessage(
 						`Error communicating with the language server: ${error}: ${message}.`
 					);
-					return ErrorAction.Shutdown;
+					return { action: ErrorAction.Shutdown };
 				},
-				closed: (): CloseAction => {
+				closed: () => {
 					// Allow 5 crashes before shutdown.
 					const { crashCount = 0 } = goCtx;
 					goCtx.crashCount = crashCount + 1;
 					if (goCtx.crashCount < 5) {
-						return CloseAction.Restart;
+						return { action: CloseAction.Restart };
 					}
 					suggestGoplsIssueReport(
 						goCtx,
 						'The connection to gopls has been closed. The gopls server may have crashed.',
 						errorKind.crash
 					);
-					return CloseAction.DoNotRestart;
+					return { action: CloseAction.DoNotRestart };
 				}
 			},
 			middleware: {
@@ -555,19 +556,19 @@
 				},
 				// Keep track of the last file change in order to not prompt
 				// user if they are actively working.
-				didOpen: (e, next) => {
+				didOpen: async (e, next) => {
 					goCtx.lastUserAction = new Date();
 					next(e);
 				},
-				didChange: (e, next) => {
+				didChange: async (e, next) => {
 					goCtx.lastUserAction = new Date();
 					next(e);
 				},
-				didClose: (e, next) => {
+				didClose: async (e, next) => {
 					goCtx.lastUserAction = new Date();
 					next(e);
 				},
-				didSave: (e, next) => {
+				didSave: async (e, next) => {
 					goCtx.lastUserAction = new Date();
 					next(e);
 				},
@@ -601,7 +602,7 @@
 					}
 				}
 			}
-		}
+		} as LanguageClientOptions
 	);
 	return c;
 }
diff --git a/test/gopls/extension.test.ts b/test/gopls/extension.test.ts
index c08f914..3ed44b6 100644
--- a/test/gopls/extension.test.ts
+++ b/test/gopls/extension.test.ts
@@ -109,9 +109,8 @@
 		if (!this.languageClient) {
 			throw new Error('Language client not initialized.');
 		}
-		this.disposables.push(this.languageClient.start());
 
-		await this.languageClient.onReady();
+		await this.languageClient.start();
 		await this.openDoc(filePath);
 		await pkgLoadingDone;
 	}