extension/src/language: separate interactive client capability injection

Moving the interactive refactoring related client capability from
the Go language client to interactive language client.

The Go language client extends interactive language client and
the interactive extends the library language client. Each language
client will call "super.fillInitializeParams" before injecting
related language client capabilities.

Change-Id: I855764ffa57697bc37438565766b3ee94f768f23
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/780820
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Hongxiang Jiang <hxjiang@golang.org>
Reviewed-by: Madeline Kalil <mkalil@google.com>
diff --git a/extension/src/language/form.ts b/extension/src/language/form.ts
index e62a910..0f655d9 100644
--- a/extension/src/language/form.ts
+++ b/extension/src/language/form.ts
@@ -5,6 +5,7 @@
  *--------------------------------------------------------*/
 
 import * as vscode from 'vscode';
+import { InitializeParams } from 'vscode-languageserver-protocol';
 import { LanguageClient, RequestType, ServerOptions, LanguageClientOptions } from 'vscode-languageclient/node';
 
 // ----------------------------------------------------------------------------
@@ -294,6 +295,25 @@
 	}
 
 	/**
+	 * Fills in the LSP initialize parameters during the handshake, and registers
+	 * client capabilities to support interactive refactoring prompts.
+	 *
+	 * @important Subclasses overriding this method must:
+	 * 1. Call `super.fillInitializeParams(params)` first to preserve base client
+	 *    configurations.
+	 * 2. Amend or merge properties into `params.capabilities.experimental`
+	 *    rather than overwriting the entire field, to prevent erasing the
+	 * 		interactive capabilities.
+	 */
+	protected fillInitializeParams(params: InitializeParams): void {
+		super.fillInitializeParams(params);
+
+		const experimental = params.capabilities.experimental || {};
+		experimental.interactiveInputTypes = ['bool', 'file', 'enum', 'lazyEnum', 'number', 'string'];
+		params.capabilities.experimental = experimental;
+	}
+
+	/**
 	 * MAX_RETRY defined the maximum number of user collection allowed for when
 	 * resolving a command.
 	 */
diff --git a/extension/src/language/goLanguageServer.ts b/extension/src/language/goLanguageServer.ts
index 8ca63ce..f6d30e3 100644
--- a/extension/src/language/goLanguageServer.ts
+++ b/extension/src/language/goLanguageServer.ts
@@ -14,7 +14,7 @@
 import semver = require('semver');
 import util = require('util');
 import vscode = require('vscode');
-import { InitializeParams, LSPObject } from 'vscode-languageserver-protocol';
+import { InitializeParams } from 'vscode-languageserver-protocol';
 import {
 	CancellationToken,
 	CloseAction,
@@ -363,10 +363,9 @@
 		// library. Experimental capabilities not used by vscode-languageserver-node
 		// can be used for custom communication between vscode-go and gopls.
 		// See https://github.com/microsoft/vscode-languageserver-node/issues/1607
-		const experimental: LSPObject = {
-			progressMessageStyles: ['log'],
-			interactiveInputTypes: ['bool', 'file', 'enum', 'lazyEnum', 'number', 'string']
-		};
+		const experimental = (params.capabilities.experimental as any) || {};
+		experimental.progressMessageStyles = ['log'];
+
 		params.capabilities.experimental = experimental;
 	}
 }