sync: merge microsoft/vscode-go@f3dd04b into master

Change-Id: I818414713f9e6f1561ddaef5d741c7c3ef2592c9
diff --git a/.travis.yml b/.travis.yml
index b454685..54cf743 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -54,6 +54,7 @@
   - go get -u -v github.com/zmb3/gogetdoc
   - go get -u -v golang.org/x/lint/golint
   - go get -u -v golang.org/x/tools/cmd/gorename
+  - GO111MODULE=on go get golang.org/x/tools/gopls
 
 script:
   - npm run lint
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 481c0d9..ac1e019 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -44,7 +44,7 @@
 				"--extensionDevelopmentPath=${workspaceFolder}",
 				"--extensionTestsPath=${workspaceFolder}/out/test/integration/index",
 				"--timeout",
-				"999999",
+				"999999"
 			],
 			"stopOnEntry": false,
 			"sourceMaps": true,
@@ -54,6 +54,27 @@
 			"preLaunchTask": "npm: watch"
 		},
 		{
+			"name": "Launch Extension Tests with Gopls",
+			"type": "extensionHost",
+			"request": "launch",
+			"runtimeExecutable": "${execPath}",
+			// the workspace path should be GOPATH
+			"args": [
+				"--disable-extensions",
+				"--extensionDevelopmentPath=${workspaceFolder}",
+				"--extensionTestsPath=${workspaceFolder}/out/test/gopls/index",
+				"--user-data-dir", "${workspaceFolder}/test/gopls/testfixtures/src/workspace",
+				"--timeout", "999999",
+				"${workspaceFolder}/test/gopls/testfixtures/src/workspace"  // gopls requires a workspace to work with.
+			],
+			"stopOnEntry": false,
+			"sourceMaps": true,
+			"outFiles": [
+				"${workspaceFolder}/out/test/**/*.js"
+			],
+			"preLaunchTask": "npm: watch",
+		},
+		{
 			"type": "node",
 			"request": "launch",
 			"name": "Launch Unit Tests",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40010f2..e6305a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,34 @@
+## 0.14.2 - Coming Soon...
+
+* [Hyang-Ah Hana Kim (@hyangah)](https://github.com/hyangah)
+    * Allow debugging when having multiple versions of Go. Fixes [Bug 3152](https://github.com/Microsoft/vscode-go/issues/3152) with [PR 3159](https://github.com/Microsoft/vscode-go/pull/3159)
+    * Fix bug introduced in the last update where there is no prompt to install/update `gopls`. Fixes [Bug 3194](https://github.com/Microsoft/vscode-go/issues/3194) with [PR 3197](https://github.com/Microsoft/vscode-go/pull/3197)
+
+* [@tom-shan](https://github.com/tom-shan)
+    * Fix placeholder in the debug configuration snippet for debugging single file. Fixes [Bug 3154](https://github.com/Microsoft/vscode-go/issues/3154) with [PR 3155](https://github.com/Microsoft/vscode-go/pull/3155)
+
+* [Rebecca Stambler (@stamblerre)](https://github.com/stamblerre)
+    * When using the language server, drop support for disabling `format` and `highlight` features. [PR 3156](https://github.com/Microsoft/vscode-go/pull/3156)
+
+* [Mike Patnode (@mpatnode)](https://github.com/mpatnode)
+    * Add note to use WSL 2 for debugging to work in Windows Subsystem for Linux. [PR 3167](https://github.com/Microsoft/vscode-go/pull/3167)
+
+* [mo2zie (@stdupp)](https://github.com/stdupp)
+    * Fix the `Go: Fill struct` to work correctly when file has multi byte characters. [PR 2611](https://github.com/Microsoft/vscode-go/pull/2611)
+
+* [Kegsay @Kegsay](https://github.com/Kegsay)
+    * Invalidate applied code coverage on file save instead of on file change. Fixes [Bug 2551](https://github.com/Microsoft/vscode-go/issues/2551) with [PR 2853](https://github.com/Microsoft/vscode-go/pull/2853)
+
+* [Felipe Munhoz (@fnmunhoz)](https://github.com/fnmunhoz)
+    * Allow setting breakpoints on a file from the module cache. [PR 3079](https://github.com/Microsoft/vscode-go/pull/3079)
+
+* [@neclepsio](https://github.com/neclepsio)
+    * Fix bug where gopls does not start behind a blocking proxy. Fixes [Bug 3204](https://github.com/Microsoft/vscode-go/issues/3204) with [PR 3205](https://github.com/Microsoft/vscode-go/pull/3205)
+
+* [@polinasok](https://github.com/https://github.com/polinasok)
+    * Improve the error message seen when debugging for "bad access". [PR 3196](https://github.com/Microsoft/vscode-go/pull/3196)
+
+
 ## 0.14.1 - 15th April, 2020
 
 * [Ramya Rao (@ramya-rao-a)](https://github.com/ramya-rao-a)
diff --git a/package-lock.json b/package-lock.json
index 1750715..3d865ca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -75,6 +75,12 @@
       "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
       "dev": true
     },
+    "@types/deep-equal": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@types/deep-equal/-/deep-equal-1.0.1.tgz",
+      "integrity": "sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg==",
+      "dev": true
+    },
     "@types/events": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -114,9 +120,9 @@
       "dev": true
     },
     "@types/node": {
-      "version": "13.11.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.1.tgz",
-      "integrity": "sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==",
+      "version": "13.13.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.0.tgz",
+      "integrity": "sha512-WE4IOAC6r/yBZss1oQGM5zs2D7RuKR6Q+w+X2SouPofnWn+LbCqClRyhO3ZE7Ix8nmFgo/oVuuE01cJT2XB13A==",
       "dev": true
     },
     "@types/semver": {
@@ -220,6 +226,11 @@
         "sprintf-js": "~1.0.2"
       }
     },
+    "array-filter": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
+      "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
+    },
     "asn1": {
       "version": "0.2.4",
       "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
@@ -268,6 +279,14 @@
       "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
       "dev": true
     },
+    "available-typed-arrays": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz",
+      "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==",
+      "requires": {
+        "array-filter": "^1.0.0"
+      }
+    },
     "aws-sign2": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -510,11 +529,37 @@
       "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
       "dev": true
     },
+    "deep-equal": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.2.tgz",
+      "integrity": "sha512-kX0bjV7tdMuhrhzKPEnVwqfQCuf+IEfN+4Xqv4eKd75xGRyn8yzdQ9ujPY6a221rgJKyQC4KBu1PibDTpa6m9w==",
+      "requires": {
+        "es-abstract": "^1.17.5",
+        "es-get-iterator": "^1.1.0",
+        "is-arguments": "^1.0.4",
+        "is-date-object": "^1.0.2",
+        "is-regex": "^1.0.5",
+        "isarray": "^2.0.5",
+        "object-is": "^1.0.2",
+        "object-keys": "^1.1.1",
+        "regexp.prototype.flags": "^1.3.0",
+        "side-channel": "^1.0.2",
+        "which-boxed-primitive": "^1.0.1",
+        "which-collection": "^1.0.1",
+        "which-typed-array": "^1.1.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+          "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
+        }
+      }
+    },
     "define-properties": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
       "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
-      "dev": true,
       "requires": {
         "object-keys": "^1.0.12"
       }
@@ -576,7 +621,6 @@
       "version": "1.17.5",
       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
       "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
-      "dev": true,
       "requires": {
         "es-to-primitive": "^1.2.1",
         "function-bind": "^1.1.1",
@@ -591,11 +635,31 @@
         "string.prototype.trimright": "^2.1.1"
       }
     },
+    "es-get-iterator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz",
+      "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==",
+      "requires": {
+        "es-abstract": "^1.17.4",
+        "has-symbols": "^1.0.1",
+        "is-arguments": "^1.0.4",
+        "is-map": "^2.0.1",
+        "is-set": "^2.0.1",
+        "is-string": "^1.0.5",
+        "isarray": "^2.0.5"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+          "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
+        }
+      }
+    },
     "es-to-primitive": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
       "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
-      "dev": true,
       "requires": {
         "is-callable": "^1.1.4",
         "is-date-object": "^1.0.1",
@@ -697,6 +761,11 @@
         "is-buffer": "~2.0.3"
       }
     },
+    "foreach": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+    },
     "forever-agent": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -740,8 +809,7 @@
     "function-bind": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
     "get-caller-file": {
       "version": "2.0.5",
@@ -810,7 +878,6 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
       "requires": {
         "function-bind": "^1.1.1"
       }
@@ -824,8 +891,7 @@
     "has-symbols": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
-      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
-      "dev": true
+      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
     },
     "he": {
       "version": "1.2.0",
@@ -912,6 +978,16 @@
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
       "dev": true
     },
+    "is-arguments": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+      "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
+    },
+    "is-bigint": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.0.tgz",
+      "integrity": "sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g=="
+    },
     "is-binary-path": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -921,6 +997,11 @@
         "binary-extensions": "^2.0.0"
       }
     },
+    "is-boolean-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.1.tgz",
+      "integrity": "sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ=="
+    },
     "is-buffer": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
@@ -930,14 +1011,12 @@
     "is-callable": {
       "version": "1.1.5",
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
-      "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
-      "dev": true
+      "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q=="
     },
     "is-date-object": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
-      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
-      "dev": true
+      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
     },
     "is-extglob": {
       "version": "2.1.1",
@@ -960,35 +1039,74 @@
         "is-extglob": "^2.1.1"
       }
     },
+    "is-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz",
+      "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw=="
+    },
     "is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
       "dev": true
     },
+    "is-number-object": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz",
+      "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw=="
+    },
     "is-regex": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
       "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
-      "dev": true,
       "requires": {
         "has": "^1.0.3"
       }
     },
+    "is-set": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz",
+      "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA=="
+    },
+    "is-string": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+      "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ=="
+    },
     "is-symbol": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
       "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
-      "dev": true,
       "requires": {
         "has-symbols": "^1.0.1"
       }
     },
+    "is-typed-array": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.3.tgz",
+      "integrity": "sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ==",
+      "requires": {
+        "available-typed-arrays": "^1.0.0",
+        "es-abstract": "^1.17.4",
+        "foreach": "^2.0.5",
+        "has-symbols": "^1.0.1"
+      }
+    },
     "is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
       "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
     },
+    "is-weakmap": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
+      "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA=="
+    },
+    "is-weakset": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.1.tgz",
+      "integrity": "sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw=="
+    },
     "isarray": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
@@ -1039,6 +1157,13 @@
         "jsonparse": "1.x.x",
         "lodash": "3.x.x",
         "object-assign": "4.x"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+        }
       }
     },
     "json-schema": {
@@ -1099,9 +1224,10 @@
       }
     },
     "lodash": {
-      "version": "3.10.1",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
-      "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+      "version": "4.17.15",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+      "dev": true
     },
     "lodash.get": {
       "version": "4.4.2",
@@ -1291,20 +1417,26 @@
     "object-inspect": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
-      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
-      "dev": true
+      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
+    },
+    "object-is": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
+      "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
     },
     "object-keys": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "dev": true
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
     },
     "object.assign": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
       "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
-      "dev": true,
       "requires": {
         "define-properties": "^1.1.2",
         "function-bind": "^1.1.1",
@@ -1423,6 +1555,15 @@
         "picomatch": "^2.0.4"
       }
     },
+    "regexp.prototype.flags": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+      "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      }
+    },
     "request": {
       "version": "2.88.2",
       "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -1463,9 +1604,9 @@
       "dev": true
     },
     "resolve": {
-      "version": "1.16.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.0.tgz",
-      "integrity": "sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA==",
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz",
+      "integrity": "sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig==",
       "dev": true,
       "requires": {
         "path-parse": "^1.0.6"
@@ -1506,6 +1647,15 @@
       "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz",
       "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="
     },
+    "side-channel": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz",
+      "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==",
+      "requires": {
+        "es-abstract": "^1.17.0-next.1",
+        "object-inspect": "^1.7.0"
+      }
+    },
     "sinon": {
       "version": "9.0.2",
       "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.2.tgz",
@@ -1579,7 +1729,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
       "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
-      "dev": true,
       "requires": {
         "define-properties": "^1.1.3",
         "es-abstract": "^1.17.5"
@@ -1589,7 +1738,6 @@
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
       "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
-      "dev": true,
       "requires": {
         "define-properties": "^1.1.3",
         "es-abstract": "^1.17.5",
@@ -1600,7 +1748,6 @@
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
       "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
-      "dev": true,
       "requires": {
         "define-properties": "^1.1.3",
         "es-abstract": "^1.17.5",
@@ -1611,7 +1758,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
       "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
-      "dev": true,
       "requires": {
         "define-properties": "^1.1.3",
         "es-abstract": "^1.17.5"
@@ -1790,12 +1936,12 @@
       "integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A=="
     },
     "vscode-languageclient": {
-      "version": "6.1.3",
-      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.1.3.tgz",
-      "integrity": "sha512-YciJxk08iU5LmWu7j5dUt9/1OLjokKET6rME3cI4BRpiF6HZlusm2ZwPt0MYJ0lV5y43sZsQHhyon2xBg4ZJVA==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.1.0.tgz",
+      "integrity": "sha512-Tcp0VoOaa0YzxL4nEfK9tsmcy76Eo8jNLvFQZwh2c8oMm02luL8uGYPLQNAiZ3XGgegfcwiQFZMqbW7DNV0vxA==",
       "requires": {
         "semver": "^6.3.0",
-        "vscode-languageserver-protocol": "^3.15.3"
+        "vscode-languageserver-protocol": "^3.15.2"
       },
       "dependencies": {
         "semver": {
@@ -1862,12 +2008,48 @@
         "isexe": "^2.0.0"
       }
     },
+    "which-boxed-primitive": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz",
+      "integrity": "sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==",
+      "requires": {
+        "is-bigint": "^1.0.0",
+        "is-boolean-object": "^1.0.0",
+        "is-number-object": "^1.0.3",
+        "is-string": "^1.0.4",
+        "is-symbol": "^1.0.2"
+      }
+    },
+    "which-collection": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
+      "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+      "requires": {
+        "is-map": "^2.0.1",
+        "is-set": "^2.0.1",
+        "is-weakmap": "^2.0.1",
+        "is-weakset": "^2.0.1"
+      }
+    },
     "which-module": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
       "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
       "dev": true
     },
+    "which-typed-array": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.2.tgz",
+      "integrity": "sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ==",
+      "requires": {
+        "available-typed-arrays": "^1.0.2",
+        "es-abstract": "^1.17.5",
+        "foreach": "^2.0.5",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.1",
+        "is-typed-array": "^1.1.3"
+      }
+    },
     "wide-align": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
@@ -1993,14 +2175,6 @@
         "flat": "^4.1.0",
         "lodash": "^4.17.15",
         "yargs": "^13.3.0"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        }
       }
     }
   }
diff --git a/package.json b/package.json
index 2ec6eda..d4f6d54 100644
--- a/package.json
+++ b/package.json
@@ -53,8 +53,9 @@
     "vscode-debugadapter": "^1.40.0",
     "vscode-debugprotocol": "^1.40.0",
     "vscode-extension-telemetry": "^0.1.2",
-    "vscode-languageclient": "^6.1.3",
-    "web-request": "^1.0.7"
+    "vscode-languageclient": "6.1.0",
+    "web-request": "^1.0.7",
+    "deep-equal": "^2.0.2"
   },
   "devDependencies": {
     "@types/fs-extra": "^8.1.0",
@@ -71,7 +72,8 @@
     "sinon": "^9.0.2",
     "tslint": "^6.1.1",
     "typescript": "^3.8.3",
-    "vscode-test": "^1.3.0"
+    "vscode-test": "^1.3.0",
+    "@types/deep-equal": "^1.0.1"
   },
   "engines": {
     "vscode": "^1.41.0"
diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts
index 4181998..687b61b 100644
--- a/src/debugAdapter/goDebug.ts
+++ b/src/debugAdapter/goDebug.ts
@@ -1833,21 +1833,19 @@
 		}
 
 		let errorMessage = err.toString();
-		// Handle unpropagated fatalpanic errors with a more user friendly message:
+		// Use a more user friendly message for an unpropagated SIGSEGV (EXC_BAD_ACCESS)
+		// signal that delve is unable to send back to the target process to be
+		// handled as a panic.
 		// https://github.com/microsoft/vscode-go/issues/1903#issuecomment-460126884
 		// https://github.com/go-delve/delve/issues/852
-		// This affects macOS only although we're agnostic of the OS at this stage, only handle the error
+		// This affects macOS only although we're agnostic of the OS at this stage.
 		if (errorMessage === 'bad access') {
+			// Reuse the panic message from the Go runtime.
 			errorMessage =
-				'unpropagated fatalpanic: signal SIGSEGV (EXC_BAD_ACCESS). This fatalpanic is not traceable on macOS, see https://github.com/go-delve/delve/issues/852';
+				`runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation]\nUnable to propogate EXC_BAD_ACCESS signal to target process and panic (see https://github.com/go-delve/delve/issues/852)`;
 		}
 
 		logError(message + ' - ' + errorMessage);
-
-		if (errorMessage === 'bad access') {
-			logError('WARNING: this stack might not be from the expected active goroutine');
-		}
-
 		this.dumpStacktrace();
 	}
 
diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index 60ccce9..60a7144 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -543,9 +543,7 @@
 			(tool) =>
 				new Promise<Tool>((resolve, reject) => {
 					const toolPath = getBinPath(tool.name);
-					fs.exists(toolPath, (exists) => {
-						resolve(exists ? null : tool);
-					});
+					resolve(path.isAbsolute(toolPath) ? null : tool);
 				})
 		)
 	).then((res) => {
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index 909ac7a..746969c 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -6,6 +6,7 @@
 'use strict';
 
 import cp = require('child_process');
+import deepEqual = require('deep-equal');
 import moment = require('moment');
 import path = require('path');
 import semver = require('semver');
@@ -13,36 +14,24 @@
 import vscode = require('vscode');
 import {
 	Command,
-	FormattingOptions,
 	HandleDiagnosticsSignature,
 	LanguageClient,
 	ProvideCompletionItemsSignature,
-	ProvideDocumentFormattingEditsSignature,
 	ProvideDocumentLinksSignature,
 	RevealOutputChannelOn
 } from 'vscode-languageclient';
 import WebRequest = require('web-request');
-import { GoDefinitionProvider } from './goDeclaration';
-import { GoHoverProvider } from './goExtraInfo';
-import { GoDocumentFormattingEditProvider } from './goFormat';
-import { GoImplementationProvider } from './goImplementations';
 import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
-import { parseLiveFile } from './goLiveErrors';
-import { GO_MODE } from './goMode';
-import { GoDocumentSymbolProvider } from './goOutline';
 import { getToolFromToolPath } from './goPath';
-import { GoReferenceProvider } from './goReferences';
-import { GoRenameProvider } from './goRename';
-import { GoSignatureHelpProvider } from './goSignature';
-import { GoCompletionItemProvider } from './goSuggest';
-import { GoWorkspaceSymbolProvider } from './goSymbol';
 import { getTool, Tool } from './goTools';
-import { GoTypeDefinitionProvider } from './goTypeDefinition';
 import { getBinPath, getCurrentGoPath, getGoConfig, getToolsEnvVars } from './util';
 
 interface LanguageServerConfig {
+	serverName: string;
+	path: string;
 	enabled: boolean;
 	flags: string[];
+	env: any;
 	features: {
 		diagnostics: boolean;
 		documentLink: boolean;
@@ -50,48 +39,91 @@
 	checkForUpdates: boolean;
 }
 
-// registerLanguageFeatures registers providers for all the language features.
-// It looks to either the language server or the standard providers for these features.
-export async function registerLanguageFeatures(ctx: vscode.ExtensionContext) {
+// Global variables used for management of the language client.
+// They are global so that the server can be easily restarted with
+// new configurations.
+let languageClient: LanguageClient;
+let languageServerDisposable: vscode.Disposable;
+let latestConfig: LanguageServerConfig;
+let serverOutputChannel: vscode.OutputChannel;
+
+// startLanguageServer starts the language server (if enabled), returning
+// true on success.
+export async function registerLanguageFeatures(ctx: vscode.ExtensionContext): Promise<boolean> {
 	// Subscribe to notifications for changes to the configuration of the language server.
 	ctx.subscriptions.push(vscode.workspace.onDidChangeConfiguration((e) => watchLanguageServerConfiguration(e)));
 
 	const config = parseLanguageServerConfig();
-
-	// If the user has not enabled the language server,
-	// register the default language features and return.
 	if (!config.enabled) {
-		registerUsualProviders(ctx);
-		return;
+		return false;
 	}
 
-	// The user has opted into the language server.
-	const languageServerToolPath = getLanguageServerToolPath();
-	const toolName = getToolFromToolPath(languageServerToolPath);
-	if (!toolName) {
-		// language server binary is not installed yet.
-		// Return immediately. The information messages such as
-		// offering to install missing tools, and suggesting to
-		// reload the window after installing the language server
-		// should be presented by now.
-		return;
-	}
-	const env = getToolsEnvVars();
+	// Support a command to restart the language server, if it's enabled.
+	ctx.subscriptions.push(vscode.commands.registerCommand('go.languageserver.restart', () => {
+		return startLanguageServer(ctx, parseLanguageServerConfig());
+	}));
 
-	// If installed, check. The user may not have the most up-to-date version of the language server.
-	const tool = getTool(toolName);
-	const versionToUpdate = await shouldUpdateLanguageServer(tool, languageServerToolPath, config.checkForUpdates);
-
-	if (versionToUpdate) {
-		promptForUpdatingTool(toolName, versionToUpdate);
+	// If the language server is gopls, we can check if the user needs to
+	// update their gopls version.
+	if (config.serverName === 'gopls') {
+		const tool = getTool(config.serverName);
+		if (!tool) {
+			return false;
+		}
+		const versionToUpdate = await shouldUpdateLanguageServer(tool, config.path, config.checkForUpdates);
+		if (versionToUpdate) {
+			promptForUpdatingTool(tool.name);
+		}
 	}
 
-	const c = new LanguageClient(
-		toolName,
+	// This function handles the case when the server isn't started yet,
+	// so we can call it to start the language server.
+	return startLanguageServer(ctx, config);
+}
+
+async function startLanguageServer(ctx: vscode.ExtensionContext, config: LanguageServerConfig): Promise<boolean> {
+	// If the client has already been started, make sure to clear existing
+	// diagnostics and stop it.
+	if (languageClient) {
+		if (languageClient.diagnostics) {
+			languageClient.diagnostics.clear();
+		}
+		await languageClient.stop();
+		if (languageServerDisposable) {
+			languageServerDisposable.dispose();
+		}
+	}
+
+	// Check if we should recreate the language client. This may be necessary
+	// if the user has changed settings in their config.
+	if (!deepEqual(latestConfig, config)) {
+		// Track the latest config used to start the language server.
+		latestConfig = config;
+
+		// If the user has not enabled or installed the language server, return.
+		if (!config.enabled || !config.path) {
+			return false;
+		}
+		buildLanguageClient(config);
+	}
+
+	languageServerDisposable = languageClient.start();
+	ctx.subscriptions.push(languageServerDisposable);
+
+	return true;
+}
+
+function buildLanguageClient(config: LanguageServerConfig) {
+	// Reuse the same output channel for each instance of the server.
+	if (!serverOutputChannel) {
+		serverOutputChannel = vscode.window.createOutputChannel(config.serverName);
+	}
+	languageClient = new LanguageClient(
+		config.serverName,
 		{
-			command: languageServerToolPath,
+			command: config.path,
 			args: ['-mode=stdio', ...config.flags],
-			options: { env }
+			options: { env: config.env },
 		},
 		{
 			initializationOptions: {},
@@ -102,6 +134,7 @@
 					(uri.scheme ? uri : uri.with({ scheme: 'file' })).toString(),
 				protocol2Code: (uri: string) => vscode.Uri.parse(uri)
 			},
+			outputChannel: serverOutputChannel,
 			revealOutputChannelOn: RevealOutputChannelOn.Never,
 			middleware: {
 				handleDiagnostics: (
@@ -179,30 +212,14 @@
 			}
 		}
 	);
-
-	c.onReady().then(() => {
-		const capabilities = c.initializeResult && c.initializeResult.capabilities;
+	languageClient.onReady().then(() => {
+		const capabilities = languageClient.initializeResult && languageClient.initializeResult.capabilities;
 		if (!capabilities) {
 			return vscode.window.showErrorMessage(
 				'The language server is not able to serve any features at the moment.'
 			);
 		}
 	});
-
-	let languageServerDisposable = c.start();
-	ctx.subscriptions.push(languageServerDisposable);
-
-	ctx.subscriptions.push(
-		vscode.commands.registerCommand('go.languageserver.restart', async () => {
-			if (c.diagnostics) {
-				c.diagnostics.clear();
-			}
-			await c.stop();
-			languageServerDisposable.dispose();
-			languageServerDisposable = c.start();
-			ctx.subscriptions.push(languageServerDisposable);
-		})
-	);
 }
 
 function watchLanguageServerConfiguration(e: vscode.ConfigurationChangeEvent) {
@@ -242,8 +259,12 @@
 
 export function parseLanguageServerConfig(): LanguageServerConfig {
 	const goConfig = getGoConfig();
-
-	const config = {
+	const toolsEnv = getToolsEnvVars();
+	const languageServerPath = getLanguageServerToolPath();
+	const languageServerName = getToolFromToolPath(languageServerPath);
+	return {
+		serverName: languageServerName,
+		path: languageServerPath,
 		enabled: goConfig['useLanguageServer'],
 		flags: goConfig['languageServerFlags'] || [],
 		features: {
@@ -252,9 +273,9 @@
 			diagnostics: goConfig['languageServerExperimentalFeatures']['diagnostics'],
 			documentLink: goConfig['languageServerExperimentalFeatures']['documentLink']
 		},
+		env: toolsEnv,
 		checkForUpdates: goConfig['useGoProxyToCheckForToolUpdates']
 	};
-	return config;
 }
 
 /**
@@ -298,9 +319,10 @@
 		if (alternateTools['go-langserver']) {
 			vscode.window.showErrorMessage(`Support for "go-langserver" has been deprecated.
 The recommended language server is gopls. Delete the alternate tool setting for "go-langserver" to use gopls, or change "go-langserver" to "gopls" in your settings.json and reload the VS Code window.`);
+			return;
 		}
-		return;
 	}
+
 	// Prompt the user to install gopls.
 	promptForMissingTool('gopls');
 }
@@ -313,28 +335,6 @@
 	return vscode.workspace.workspaceFolders.find((x) => tempGopath !== getCurrentGoPath(x.uri)) ? false : true;
 }
 
-// registerUsualProviders registers the language feature providers if the language server is not enabled.
-function registerUsualProviders(ctx: vscode.ExtensionContext) {
-	const provider = new GoCompletionItemProvider(ctx.globalState);
-	ctx.subscriptions.push(provider);
-	ctx.subscriptions.push(vscode.languages.registerCompletionItemProvider(GO_MODE, provider, '.', '"'));
-	ctx.subscriptions.push(vscode.languages.registerHoverProvider(GO_MODE, new GoHoverProvider()));
-	ctx.subscriptions.push(vscode.languages.registerDefinitionProvider(GO_MODE, new GoDefinitionProvider()));
-	ctx.subscriptions.push(vscode.languages.registerReferenceProvider(GO_MODE, new GoReferenceProvider()));
-	ctx.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(GO_MODE, new GoDocumentSymbolProvider()));
-	ctx.subscriptions.push(vscode.languages.registerWorkspaceSymbolProvider(new GoWorkspaceSymbolProvider()));
-	ctx.subscriptions.push(
-		vscode.languages.registerSignatureHelpProvider(GO_MODE, new GoSignatureHelpProvider(), '(', ',')
-	);
-	ctx.subscriptions.push(vscode.languages.registerImplementationProvider(GO_MODE, new GoImplementationProvider()));
-	ctx.subscriptions.push(
-		vscode.languages.registerDocumentFormattingEditProvider(GO_MODE, new GoDocumentFormattingEditProvider())
-	);
-	ctx.subscriptions.push(vscode.languages.registerTypeDefinitionProvider(GO_MODE, new GoTypeDefinitionProvider()));
-	ctx.subscriptions.push(vscode.languages.registerRenameProvider(GO_MODE, new GoRenameProvider()));
-	vscode.workspace.onDidChangeTextDocument(parseLiveFile, null, ctx.subscriptions);
-}
-
 const acceptGoplsPrerelease = true;  // For nightly, we accept the prerelease version.
 const defaultLatestVersion = semver.coerce('0.3.1');
 const defaultLatestVersionTime = moment('2020-02-04', 'YYYY-MM-DD');
@@ -454,7 +454,9 @@
 			includePrerelease: true,
 			loose: true
 		});
-		versions.push(parsed);
+		if (parsed) {
+			versions.push(parsed);
+		}
 	}
 	if (versions.length === 0) {
 		return null;
diff --git a/src/goMain.ts b/src/goMain.ts
index b5ac805..7f34b11 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -21,11 +21,15 @@
 	updateCodeCoverageDecorators
 } from './goCover';
 import { GoDebugConfigurationProvider } from './goDebugConfiguration';
+import { GoDefinitionProvider } from './goDeclaration';
 import { extractFunction, extractVariable } from './goDoctor';
+import { GoHoverProvider } from './goExtraInfo';
 import { runFillStruct } from './goFillStruct';
+import { GoDocumentFormattingEditProvider } from './goFormat';
 import * as goGenerateTests from './goGenerateTests';
 import { goGetPackage } from './goGetPackage';
 import { implCursor } from './goImpl';
+import { GoImplementationProvider } from './goImplementations';
 import { addImport, addImportToWorkspace } from './goImport';
 import { installCurrentPackage } from './goInstall';
 import {
@@ -37,16 +41,24 @@
 } from './goInstallTools';
 import { registerLanguageFeatures } from './goLanguageServer';
 import { lintCode } from './goLint';
+import { parseLiveFile } from './goLiveErrors';
 import { GO_MODE } from './goMode';
 import { addTags, removeTags } from './goModifytags';
 import { GO111MODULE, isModSupported } from './goModules';
+import { GoDocumentSymbolProvider } from './goOutline';
 import { clearCacheForTools, fileExists } from './goPath';
 import { playgroundCommand } from './goPlayground';
+import { GoReferenceProvider } from './goReferences';
 import { GoReferencesCodeLensProvider } from './goReferencesCodelens';
+import { GoRenameProvider } from './goRename';
 import { GoRunTestCodeLensProvider } from './goRunTestCodelens';
+import { GoSignatureHelpProvider } from './goSignature';
 import { outputChannel, showHideStatus } from './goStatus';
+import { GoCompletionItemProvider } from './goSuggest';
+import { GoWorkspaceSymbolProvider } from './goSymbol';
 import { testAtCursor, testCurrentFile, testCurrentPackage, testPrevious, testWorkspace } from './goTest';
 import { getConfiguredTools } from './goTools';
+import { GoTypeDefinitionProvider } from './goTypeDefinition';
 import { vetCode } from './goVet';
 import {
 	getFromGlobalState,
@@ -134,7 +146,10 @@
 
 		// This handles all of the configurations and registrations for the language server.
 		// It also registers the necessary language feature providers that the language server may not support.
-		await registerLanguageFeatures(ctx);
+		const ok = await registerLanguageFeatures(ctx);
+		if (!ok) {
+			registerUsualProviders(ctx);
+		}
 
 		if (
 			vscode.window.activeTextEditor &&
@@ -607,6 +622,28 @@
 	);
 }
 
+// registerUsualProviders registers the language feature providers if the language server is not enabled.
+function registerUsualProviders(ctx: vscode.ExtensionContext) {
+	const provider = new GoCompletionItemProvider(ctx.globalState);
+	ctx.subscriptions.push(provider);
+	ctx.subscriptions.push(vscode.languages.registerCompletionItemProvider(GO_MODE, provider, '.', '"'));
+	ctx.subscriptions.push(vscode.languages.registerHoverProvider(GO_MODE, new GoHoverProvider()));
+	ctx.subscriptions.push(vscode.languages.registerDefinitionProvider(GO_MODE, new GoDefinitionProvider()));
+	ctx.subscriptions.push(vscode.languages.registerReferenceProvider(GO_MODE, new GoReferenceProvider()));
+	ctx.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(GO_MODE, new GoDocumentSymbolProvider()));
+	ctx.subscriptions.push(vscode.languages.registerWorkspaceSymbolProvider(new GoWorkspaceSymbolProvider()));
+	ctx.subscriptions.push(
+		vscode.languages.registerSignatureHelpProvider(GO_MODE, new GoSignatureHelpProvider(), '(', ',')
+	);
+	ctx.subscriptions.push(vscode.languages.registerImplementationProvider(GO_MODE, new GoImplementationProvider()));
+	ctx.subscriptions.push(
+		vscode.languages.registerDocumentFormattingEditProvider(GO_MODE, new GoDocumentFormattingEditProvider())
+	);
+	ctx.subscriptions.push(vscode.languages.registerTypeDefinitionProvider(GO_MODE, new GoTypeDefinitionProvider()));
+	ctx.subscriptions.push(vscode.languages.registerRenameProvider(GO_MODE, new GoRenameProvider()));
+	vscode.workspace.onDidChangeTextDocument(parseLiveFile, null, ctx.subscriptions);
+}
+
 function addOnChangeTextDocumentListeners(ctx: vscode.ExtensionContext) {
 	vscode.workspace.onDidChangeTextDocument(trackCodeCoverageRemovalOnFileChange, null, ctx.subscriptions);
 	vscode.workspace.onDidChangeTextDocument(removeTestStatus, null, ctx.subscriptions);
diff --git a/test/gopls/extension.test.ts b/test/gopls/extension.test.ts
new file mode 100644
index 0000000..3d59143
--- /dev/null
+++ b/test/gopls/extension.test.ts
@@ -0,0 +1,135 @@
+import * as assert from 'assert';
+import cp = require('child_process');
+import * as fs from 'fs-extra';
+import * as path from 'path';
+import * as vscode from 'vscode';
+import { updateGoPathGoRootFromConfig } from '../../src/goInstallTools';
+import { extensionId } from '../../src/telemetry';
+import { getCurrentGoPath } from '../../src/util';
+
+// Env is a collection of test related variables
+// that define the test environment such as vscode workspace.
+class Env {
+
+	// Currently gopls requires a workspace and does not work in a single-file mode.
+	// Code in test environment does not support dynamically adding folders.
+	// tslint:disable-next-line:max-line-length
+	// https://github.com/microsoft/vscode/blob/890f62dfd9f3e70198931f788c5c332b3e8b7ad7/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts#L281
+	//
+	// So, when we start the gopls tests, we start the test extension host with a
+	// dummy workspace, ${projectDir}/test/gopls/testfixtures/src/workspace
+	// (see test/runTest.ts and launch.json).
+	// Then copy necessary files to the workspace using Env.reset() from the
+	// fixturesRoot directory.
+	public workspaceDir: string;
+	public fixturesRoot: string;
+
+	public extension: vscode.Extension<any>;
+
+	constructor(projectDir: string) {
+		if (!projectDir) {
+			assert.fail('project directory cannot be determined');
+		}
+		this.workspaceDir = path.resolve(projectDir, 'test/gopls/testfixtures/src/workspace');
+		this.fixturesRoot = path.resolve(projectDir, 'test/fixtures');
+		this.extension = vscode.extensions.getExtension(extensionId);
+
+		// Ensure the vscode extension host is configured as expected.
+		const workspaceFolder = path.resolve(vscode.workspace.workspaceFolders[0].uri.fsPath);
+		if (this.workspaceDir !== workspaceFolder) {
+			assert.fail(`specified workspaceDir: ${this.workspaceDir} does not match the workspace folder: ${workspaceFolder}`);
+		}
+	}
+
+	public async setup() {
+		const wscfg = vscode.workspace.getConfiguration('go');
+		if (!wscfg.get('useLanguageServer')) {
+			wscfg.update('useLanguageServer', true, vscode.ConfigurationTarget.Workspace);
+		}
+
+		await this.reset();
+		await this.extension.activate();
+		await sleep(2000);  // allow extension host + gopls to start.
+	}
+
+	public async reset(fixtureDirName?: string) {  // name of the fixtures subdirectory to use.
+		try {
+			// clean everything except the .gitignore file
+			// needed to keep the empty directory in vcs.
+			await fs.readdir(this.workspaceDir).then((files) => {
+				return Promise.all(
+					files.filter((filename) => filename !== '.gitignore').map((file) => {
+						fs.remove(path.resolve(this.workspaceDir, file));
+					}));
+				});
+
+			if (!fixtureDirName) {
+				return;
+			}
+			const src = path.resolve(this.fixturesRoot, fixtureDirName);
+			const dst = this.workspaceDir;
+			await fs.copy(src, dst, { recursive: true });
+		} catch (err) {
+			assert.fail(err);
+		}
+	}
+
+	// openDoc opens the file in the workspace with the given path (paths
+	// are the path elements of a file).
+	public async openDoc(...paths: string[]) {
+		const uri = vscode.Uri.file(path.resolve(this.workspaceDir, ...paths));
+		const doc = await vscode.workspace.openTextDocument(uri);
+		return { uri, doc };
+	}
+}
+
+async function sleep(ms: number) {
+	return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+suite('Go Extension Tests With Gopls', function() {
+	this.timeout(1000000);
+	const projectDir = path.join(__dirname, '..', '..', '..');
+	const env = new Env(projectDir);
+
+	suiteSetup(async () => { await env.setup(); });
+	suiteTeardown(async () => { await env.reset(); });
+
+	test('HoverProvider', async () => {
+		await env.reset('gogetdocTestData');
+		const { uri, doc } = await env.openDoc('test.go');
+
+		// TODO(hyangah): find a way to wait for the language server to complete processing.
+
+		const testCases: [string, vscode.Position, string | null, string | null][] = [
+			// [new vscode.Position(3,3), '/usr/local/go/src/fmt'],
+			['keyword', new vscode.Position(0, 3), null, null], // keyword
+			['inside a string', new vscode.Position(23, 14), null, null], // inside a string
+			['just a }', new vscode.Position(20, 0), null, null], // just a }
+			['inside a number', new vscode.Position(28, 16), null, null], // inside a number
+			['func main()', new vscode.Position(22, 5), 'func main()', null],
+			['import "math"', new vscode.Position(40, 23), 'package math', '`math` on'],
+			['func Println()', new vscode.Position(19, 6), 'func fmt.Println(a ...interface{}) (n int, err error)', 'Println formats '],
+			['func print()', new vscode.Position(23, 4), 'func print(txt string)', 'This is an unexported function ']
+		];
+
+		const promises = testCases.map(async ([name, position, expectedSignature, expectedDoc]) => {
+			const hovers = await vscode.commands.executeCommand(
+				'vscode.executeHoverProvider', uri, position) as vscode.Hover[];
+
+			if (expectedSignature === null && expectedDoc === null) {
+				assert.equal(hovers.length, 0, `check hovers over ${name} failed: unexpected non-empty hover message.`);
+				return;
+			}
+
+			const hover = hovers[0];
+			assert.equal(hover.contents.length, 1, `check hovers over ${name} failed: unexpected number of hover messages.`);
+			const gotMessage = (<vscode.MarkdownString>hover.contents[0]).value;
+			assert.ok(
+				gotMessage.includes('```go\n' + expectedSignature + '\n```')
+				&& (!expectedDoc || gotMessage.includes(expectedDoc)),
+				`check hovers over ${name} failed: got ${gotMessage}`);
+		});
+		return Promise.all(promises);
+	});
+});
diff --git a/test/gopls/index.ts b/test/gopls/index.ts
new file mode 100644
index 0000000..1aa3b7f
--- /dev/null
+++ b/test/gopls/index.ts
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------
+ * Copyright (C) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------*/
+import * as glob from 'glob';
+import * as Mocha from 'mocha';
+import * as path from 'path';
+export function run(): Promise<void> {
+	// Create the mocha test
+	const mocha = new Mocha({
+		ui: 'tdd'
+	});
+	mocha.useColors(true);
+
+	const testsRoot = path.resolve(__dirname, '..');
+
+	return new Promise((c, e) => {
+		glob('gopls/**.test.js', { cwd: testsRoot }, (err, files) => {
+			if (err) {
+				return e(err);
+			}
+
+			// Add files to the test suite
+			files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)));
+
+			try {
+				// Run the mocha test
+				mocha.run((failures) => {
+					if (failures > 0) {
+						e(new Error(`${failures} tests failed.`));
+					} else {
+						c();
+					}
+				});
+			} catch (err) {
+				e(err);
+			}
+		});
+	});
+}
diff --git a/test/gopls/testfixtures/src/workspace/.gitignore b/test/gopls/testfixtures/src/workspace/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/test/gopls/testfixtures/src/workspace/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/test/runTest.ts b/test/runTest.ts
index 82f76e3..ee29d48 100644
--- a/test/runTest.ts
+++ b/test/runTest.ts
@@ -1,13 +1,14 @@
+import * as fs from 'fs-extra';
 import * as path from 'path';
-
 import { runTests } from 'vscode-test';
+import { extensionId } from '../src/telemetry';
 
 async function main() {
-	try {
 		// The folder containing the Extension Manifest package.json
 		// Passed to `--extensionDevelopmentPath`
-		const extensionDevelopmentPath = path.resolve(__dirname, '../../');
+	const extensionDevelopmentPath = path.resolve(__dirname, '../../');
 
+	try {
 		// The path to the extension test script
 		// Passed to --extensionTestsPath
 		const extensionTestsPath = path.resolve(__dirname, './integration/index');
@@ -15,9 +16,31 @@
 		// Download VS Code, unzip it and run the integration test
 		await runTests({ extensionDevelopmentPath, extensionTestsPath });
 	} catch (err) {
-		console.error('Failed to run tests');
+		console.error('Failed to run integration tests' + err);
 		process.exit(1);
 	}
+
+	// Integration tests using gopls.
+	try {
+		// Currently gopls requires a workspace. Code in test environment does not support
+		// dynamically adding folders.
+		// tslint:disable-next-line:max-line-length
+		// https://github.com/microsoft/vscode/blob/890f62dfd9f3e70198931f788c5c332b3e8b7ad7/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts#L281
+		// So, we start the test extension host with a dummy workspace (test/gopls/testfixtures/src/workspace)
+		// and copy necessary files to the workspace.
+		const ws = path.resolve(extensionDevelopmentPath, 'test/gopls/testfixtures/src/workspace');
+
+		await runTests({
+			extensionDevelopmentPath,
+			extensionTestsPath: path.resolve(__dirname, './gopls/index'),
+			launchArgs: [
+				'--disable-extensions',  // disable all other extensions
+				ws  // dummy workspace to start with
+			],
+		});
+	} catch (err) {
+		console.error('Failed to run gopls tests' + err);
+	}
 }
 
 main();