vscode-go: add inlay hint settings to extension config

Adding the inlay hint settings to the go configuration
allows for toggling inlay hints from settings.json or
the settings UI.

For golang/vscode-go#1631.

Change-Id: Iccf2ff3db89d195f694883403d4a25160d66e7ff
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/413678
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/docs/settings.md b/docs/settings.md
index cdb61ac..110641a 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -278,6 +278,41 @@
 Infer GOPATH from the workspace root. This is ignored when using Go Modules.
 
 Default: `false`
+### `go.inlayHints.assignVariableTypes`
+
+Enable/disable inlay hints for variable types in assign statements.
+
+Default: `false`
+### `go.inlayHints.compositeLiteralFields`
+
+Enable/disable inlay hints for composite literal field names.
+
+Default: `false`
+### `go.inlayHints.compositeLiteralTypes`
+
+Enable/disable inlay hints for composite literal types.
+
+Default: `false`
+### `go.inlayHints.constantValues`
+
+Enable/disable inlay hints for constant values.
+
+Default: `false`
+### `go.inlayHints.functionTypeParameters`
+
+Enable/disable inlay hints for implicit type parameters on generic functions.
+
+Default: `false`
+### `go.inlayHints.parameterNames`
+
+Enable/disable inlay hints for parameter names.
+
+Default: `false`
+### `go.inlayHints.rangeVariableTypes`
+
+Enable/disable inlay hints for variable types in range statements.
+
+Default: `false`
 ### `go.installDependenciesWhenBuilding`
 
 If true, then `-i` flag will be passed to `go build` everytime the code is compiled. Since Go 1.10, setting this may be unnecessary unless you are in GOPATH mode and do not use the language server.
diff --git a/package.json b/package.json
index 1e3a54c..e5c5981 100644
--- a/package.json
+++ b/package.json
@@ -2043,6 +2043,41 @@
           "scope": "resource",
           "type": "boolean"
         },
+        "go.inlayHints.assignVariableTypes": {
+          "type": "boolean",
+          "description": "Enable/disable inlay hints for variable types in assign statements.",
+          "default": false
+        },
+        "go.inlayHints.compositeLiteralFields": {
+          "type": "boolean",
+          "description": "Enable/disable inlay hints for composite literal field names.",
+          "default": false
+        },
+        "go.inlayHints.compositeLiteralTypes": {
+          "type": "boolean",
+          "description": "Enable/disable inlay hints for composite literal types.",
+          "default": false
+        },
+        "go.inlayHints.constantValues": {
+          "type": "boolean",
+          "description": "Enable/disable inlay hints for constant values.",
+          "default": false
+        },
+        "go.inlayHints.functionTypeParameters": {
+          "type": "boolean",
+          "description": "Enable/disable inlay hints for implicit type parameters on generic functions.",
+          "default": false
+        },
+        "go.inlayHints.parameterNames": {
+          "type": "boolean",
+          "description": "Enable/disable inlay hints for parameter names.",
+          "default": false
+        },
+        "go.inlayHints.rangeVariableTypes": {
+          "type": "boolean",
+          "description": "Enable/disable inlay hints for variable types in range statements.",
+          "default": false
+        },
         "gopls": {
           "type": "object",
           "markdownDescription": "Configure the default Go language server ('gopls'). In most cases, configuring this section is unnecessary. See [the documentation](https://github.com/golang/tools/blob/master/gopls/doc/settings.md) for all available settings.",
diff --git a/src/language/goLanguageServer.ts b/src/language/goLanguageServer.ts
index 4ca8354..83bee23 100644
--- a/src/language/goLanguageServer.ts
+++ b/src/language/goLanguageServer.ts
@@ -664,6 +664,7 @@
 	if (buildFlags.length > 0 && goplsWorkspaceConfig['build.buildFlags'] === undefined) {
 		goplsWorkspaceConfig['build.buildFlags'] = buildFlags;
 	}
+
 	return goplsWorkspaceConfig;
 }
 
@@ -684,6 +685,7 @@
 	workspaceConfig = filterGoplsDefaultConfigValues(workspaceConfig, resource);
 	// note: workspaceConfig is a modifiable, valid object.
 	workspaceConfig = passGoConfigToGoplsConfigValues(workspaceConfig, getGoConfig(resource));
+	workspaceConfig = await passInlayHintConfigToGopls(cfg, workspaceConfig, getGoConfig(resource));
 
 	// Only modify the user's configurations for the Nightly.
 	if (!extensionInfo.isPreview) {
@@ -695,6 +697,19 @@
 	return workspaceConfig;
 }
 
+async function passInlayHintConfigToGopls(cfg: LanguageServerConfig, goplsConfig: any, goConfig: any) {
+	const goplsVersion = await getLocalGoplsVersion(cfg);
+	if (!goplsVersion) return;
+	const version = semver.parse(goplsVersion.version);
+	if ((version?.compare('0.8.4') ?? 1) > 0) {
+		const { inlayHints } = goConfig;
+		if (inlayHints) {
+			goplsConfig['ui.inlayhint.hints'] = { ...inlayHints };
+		}
+	}
+	return goplsConfig;
+}
+
 // createTestCodeLens adds the go.test.cursor and go.debug.cursor code lens
 function createTestCodeLens(lens: vscode.CodeLens): vscode.CodeLens[] {
 	// CodeLens argument signature in gopls is [fileName: string, testFunctions: string[], benchFunctions: string[]],