tools/generate.go: update gopls and dlv-dap versions in generate

Both gopls and dlv-dap have frequent updates, so we frequently need
to change the latest versions to keep our users up to date.

This updates the generate script to also update the versions in
src/goTools.ts.

Updates golang/vscode-go#1403

Change-Id: Ic6de1ce8cbe9c97d89f48c4b689271d75be5bb17
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/319029
Trust: Suzy Mueller <suzmue@golang.org>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/src/goStatus.ts b/src/goStatus.ts
index 937c4ee..2968297 100644
--- a/src/goStatus.ts
+++ b/src/goStatus.ts
@@ -19,7 +19,7 @@
 } from './goLanguageServer';
 import { isGoFile } from './goMode';
 import { getModFolderPath, isModSupported } from './goModules';
-import { allToolsInformation } from './goTools';
+import { allToolsInformation } from './goToolsInformation';
 import { getGoVersion } from './util';
 
 export const outputChannel = vscode.window.createOutputChannel('Go');
diff --git a/src/goTools.ts b/src/goTools.ts
index 5c04b9c..cb68bd0 100644
--- a/src/goTools.ts
+++ b/src/goTools.ts
@@ -13,6 +13,7 @@
 import util = require('util');
 import { getFormatTool, usingCustomFormatTool } from './goFormat';
 import { goLiveErrorsEnabled } from './goLiveErrors';
+import { allToolsInformation } from './goToolsInformation';
 import { getBinPath, GoVersion } from './util';
 
 export interface Tool {
@@ -214,259 +215,20 @@
 	return !features || features['diagnostics'] === true;
 }
 
-export const allToolsInformation: { [key: string]: Tool } = {
-	'gocode': {
-		name: 'gocode',
-		importPath: 'github.com/mdempsky/gocode',
-		modulePath: 'github.com/mdempsky/gocode',
-		isImportant: true,
-		replacedByGopls: true,
-		description: 'Auto-completion, does not work with modules',
-		close: async (env: NodeJS.Dict<string>): Promise<string> => {
-			const toolBinPath = getBinPath('gocode');
-			if (!path.isAbsolute(toolBinPath)) {
-				return '';
-			}
-			try {
-				const execFile = util.promisify(cp.execFile);
-				const { stderr } = await execFile(toolBinPath, ['close'], { env, timeout: 10000 }); // give 10sec.
-				if (stderr.indexOf("rpc: can't find service Server.") > -1) {
-					return 'Installing gocode aborted as existing process cannot be closed. Please kill the running process for gocode and try again.';
-				}
-			} catch (err) {
-				// This may fail if gocode isn't already running.
-				console.log(`gocode close failed: ${err}`);
-			}
-			return '';
-		}
-	},
-	'gocode-gomod': {
-		name: 'gocode-gomod',
-		importPath: 'github.com/stamblerre/gocode',
-		modulePath: 'github.com/stamblerre/gocode',
-		isImportant: true,
-		replacedByGopls: true,
-		description: 'Auto-completion, works with modules',
-		minimumGoVersion: semver.coerce('1.11')
-	},
-	'gopkgs': {
-		name: 'gopkgs',
-		importPath: 'github.com/uudashr/gopkgs/v2/cmd/gopkgs',
-		modulePath: 'github.com/uudashr/gopkgs/v2',
-		replacedByGopls: false, // TODO(github.com/golang/vscode-go/issues/258): disable Add Import command.
-		isImportant: true,
-		description: 'Auto-completion of unimported packages & Add Import feature'
-	},
-	'go-outline': {
-		name: 'go-outline',
-		importPath: 'github.com/ramya-rao-a/go-outline',
-		modulePath: 'github.com/ramya-rao-a/go-outline',
-		replacedByGopls: false, // TODO(github.com/golang/vscode-go/issues/1020): replace with Gopls.
-		isImportant: true,
-		description: 'Go to symbol in file' // GoDocumentSymbolProvider, used by 'run test' codelens
-	},
-	'go-symbols': {
-		name: 'go-symbols',
-		importPath: 'github.com/acroca/go-symbols',
-		modulePath: 'github.com/acroca/go-symbols',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Go to symbol in workspace'
-	},
-	'guru': {
-		name: 'guru',
-		importPath: 'golang.org/x/tools/cmd/guru',
-		modulePath: 'golang.org/x/tools',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Find all references and Go to implementation of symbols'
-	},
-	'gorename': {
-		name: 'gorename',
-		importPath: 'golang.org/x/tools/cmd/gorename',
-		modulePath: 'golang.org/x/tools',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Rename symbols'
-	},
-	'gomodifytags': {
-		name: 'gomodifytags',
-		importPath: 'github.com/fatih/gomodifytags',
-		modulePath: 'github.com/fatih/gomodifytags',
-		replacedByGopls: false,
-		isImportant: false,
-		description: 'Modify tags on structs'
-	},
-	'goplay': {
-		name: 'goplay',
-		importPath: 'github.com/haya14busa/goplay/cmd/goplay',
-		modulePath: 'github.com/haya14busa/goplay',
-		replacedByGopls: false,
-		isImportant: false,
-		description: 'The Go playground'
-	},
-	'impl': {
-		name: 'impl',
-		importPath: 'github.com/josharian/impl',
-		modulePath: 'github.com/josharian/impl',
-		replacedByGopls: false,
-		isImportant: false,
-		description: 'Stubs for interfaces'
-	},
-	'gotype-live': {
-		name: 'gotype-live',
-		importPath: 'github.com/tylerb/gotype-live',
-		modulePath: 'github.com/tylerb/gotype-live',
-		replacedByGopls: true, // TODO(github.com/golang/vscode-go/issues/1021): recommend users to turn off.
-		isImportant: false,
-		description: 'Show errors as you type'
-	},
-	'godef': {
-		name: 'godef',
-		importPath: 'github.com/rogpeppe/godef',
-		modulePath: 'github.com/rogpeppe/godef',
-		replacedByGopls: true,
-		isImportant: true,
-		description: 'Go to definition'
-	},
-	'gogetdoc': {
-		name: 'gogetdoc',
-		importPath: 'github.com/zmb3/gogetdoc',
-		modulePath: 'github.com/zmb3/gogetdoc',
-		replacedByGopls: true,
-		isImportant: true,
-		description: 'Go to definition & text shown on hover'
-	},
-	'gofumports': {
-		name: 'gofumports',
-		importPath: 'mvdan.cc/gofumpt/gofumports',
-		modulePath: 'mvdan.cc/gofumpt',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Formatter'
-	},
-	'gofumpt': {
-		name: 'gofumpt',
-		importPath: 'mvdan.cc/gofumpt',
-		modulePath: 'mvdan.cc/gofumpt',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Formatter'
-	},
-	'goimports': {
-		name: 'goimports',
-		importPath: 'golang.org/x/tools/cmd/goimports',
-		modulePath: 'golang.org/x/tools',
-		replacedByGopls: true,
-		isImportant: true,
-		description: 'Formatter'
-	},
-	'goreturns': {
-		name: 'goreturns',
-		importPath: 'github.com/sqs/goreturns',
-		modulePath: 'github.com/sqs/goreturns',
-		replacedByGopls: true,
-		isImportant: true,
-		description: 'Formatter'
-	},
-	'goformat': {
-		name: 'goformat',
-		importPath: 'winterdrache.de/goformat/goformat',
-		modulePath: 'winterdrache.de/goformat/goformat',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Formatter'
-	},
-	'gotests': {
-		name: 'gotests',
-		importPath: 'github.com/cweill/gotests/gotests',
-		modulePath: 'github.com/cweill/gotests',
-		replacedByGopls: false,
-		isImportant: false,
-		description: 'Generate unit tests',
-		minimumGoVersion: semver.coerce('1.9')
-	},
-	// TODO(github.com/golang/vscode-go/issues/189): consider disabling lint when gopls is turned on.
-	'golint': {
-		name: 'golint',
-		importPath: 'golang.org/x/lint/golint',
-		modulePath: 'golang.org/x/lint',
-		replacedByGopls: false,
-		isImportant: false,
-		description: 'Linter',
-		minimumGoVersion: semver.coerce('1.9')
-	},
-	'staticcheck': {
-		name: 'staticcheck',
-		importPath: 'honnef.co/go/tools/cmd/staticcheck',
-		modulePath: 'honnef.co/go/tools',
-		replacedByGopls: false,
-		isImportant: true,
-		description: 'Linter'
-	},
-	'golangci-lint': {
-		name: 'golangci-lint',
-		importPath: 'github.com/golangci/golangci-lint/cmd/golangci-lint',
-		modulePath: 'github.com/golangci/golangci-lint',
-		replacedByGopls: false,
-		isImportant: true,
-		description: 'Linter'
-	},
-	'revive': {
-		name: 'revive',
-		importPath: 'github.com/mgechev/revive',
-		modulePath: 'github.com/mgechev/revive',
-		isImportant: true,
-		description: 'Linter'
-	},
-	'gopls': {
-		name: 'gopls',
-		importPath: 'golang.org/x/tools/gopls',
-		modulePath: 'golang.org/x/tools/gopls',
-		replacedByGopls: false, // lol
-		isImportant: true,
-		description: 'Language Server from Google',
-		usePrereleaseInPreviewMode: true,
-		minimumGoVersion: semver.coerce('1.12'),
-		latestVersion: semver.coerce('0.6.8'),
-		latestVersionTimestamp: moment('2021-03-17', 'YYYY-MM-DD'),
-		latestPrereleaseVersion: semver.coerce('0.6.8'),
-		latestPrereleaseVersionTimestamp: moment('2021-03-17', 'YYYY-MM-DD')
-	},
-	'dlv': {
-		name: 'dlv',
-		importPath: 'github.com/go-delve/delve/cmd/dlv',
-		modulePath: 'github.com/go-delve/delve',
-		replacedByGopls: false,
-		isImportant: true,
-		description: 'Go debugger (Delve)'
-	},
-	'dlv-dap': {
-		name: 'dlv-dap',
-		importPath: 'github.com/go-delve/delve/cmd/dlv',
-		modulePath: 'github.com/go-delve/delve',
-		replacedByGopls: false,
-		isImportant: false,
-		description: 'Go debugger (Delve built for DAP experiment)',
-		defaultVersion: 'master', // Always build from the master.
-		minimumGoVersion: semver.coerce('1.14'), // last 3 versions per delve policy
-		latestVersion: semver.parse('1.6.1-0.20210504195617-c5d58f494a26'),
-		latestVersionTimestamp: moment('2021-05-04', 'YYYY-MM-DD')
-	},
-	'fillstruct': {
-		name: 'fillstruct',
-		importPath: 'github.com/davidrjenni/reftools/cmd/fillstruct',
-		modulePath: 'github.com/davidrjenni/reftools',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Fill structs with defaults'
-	},
-	'godoctor': {
-		name: 'godoctor',
-		importPath: 'github.com/godoctor/godoctor',
-		modulePath: 'github.com/godoctor/godoctor',
-		replacedByGopls: true,
-		isImportant: false,
-		description: 'Extract to functions and variables'
+export const gocodeClose = async (env: NodeJS.Dict<string>): Promise<string> => {
+	const toolBinPath = getBinPath('gocode');
+	if (!path.isAbsolute(toolBinPath)) {
+		return '';
 	}
+	try {
+		const execFile = util.promisify(cp.execFile);
+		const { stderr } = await execFile(toolBinPath, ['close'], { env, timeout: 10000 }); // give 10sec.
+		if (stderr.indexOf("rpc: can't find service Server.") > -1) {
+			return 'Installing gocode aborted as existing process cannot be closed. Please kill the running process for gocode and try again.';
+		}
+	} catch (err) {
+		// This may fail if gocode isn't already running.
+		console.log(`gocode close failed: ${err}`);
+	}
+	return '';
 };
diff --git a/src/goToolsInformation.ts b/src/goToolsInformation.ts
new file mode 100644
index 0000000..6913adf
--- /dev/null
+++ b/src/goToolsInformation.ts
@@ -0,0 +1,246 @@
+// <!-- Everything below this line is generated. DO NOT EDIT. -->
+
+import moment = require('moment');
+import semver = require('semver');
+import { gocodeClose, Tool } from './goTools';
+
+export const allToolsInformation: { [key: string]: Tool } = {
+	'gocode': {
+		name: 'gocode',
+		importPath: 'github.com/mdempsky/gocode',
+		modulePath: 'github.com/mdempsky/gocode',
+		isImportant: true,
+		replacedByGopls: true,
+		description: 'Auto-completion, does not work with modules',
+		close: gocodeClose
+	},
+	'gocode-gomod': {
+		name: 'gocode-gomod',
+		importPath: 'github.com/stamblerre/gocode',
+		modulePath: 'github.com/stamblerre/gocode',
+		isImportant: true,
+		replacedByGopls: true,
+		description: 'Auto-completion, works with modules',
+		minimumGoVersion: semver.coerce('1.11')
+	},
+	'gopkgs': {
+		name: 'gopkgs',
+		importPath: 'github.com/uudashr/gopkgs/v2/cmd/gopkgs',
+		modulePath: 'github.com/uudashr/gopkgs/v2',
+		replacedByGopls: false, // TODO(github.com/golang/vscode-go/issues/258): disable Add Import command.
+		isImportant: true,
+		description: 'Auto-completion of unimported packages & Add Import feature'
+	},
+	'go-outline': {
+		name: 'go-outline',
+		importPath: 'github.com/ramya-rao-a/go-outline',
+		modulePath: 'github.com/ramya-rao-a/go-outline',
+		replacedByGopls: false, // TODO(github.com/golang/vscode-go/issues/1020): replace with Gopls.
+		isImportant: true,
+		description: 'Go to symbol in file' // GoDocumentSymbolProvider, used by 'run test' codelens
+	},
+	'go-symbols': {
+		name: 'go-symbols',
+		importPath: 'github.com/acroca/go-symbols',
+		modulePath: 'github.com/acroca/go-symbols',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Go to symbol in workspace'
+	},
+	'guru': {
+		name: 'guru',
+		importPath: 'golang.org/x/tools/cmd/guru',
+		modulePath: 'golang.org/x/tools',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Find all references and Go to implementation of symbols'
+	},
+	'gorename': {
+		name: 'gorename',
+		importPath: 'golang.org/x/tools/cmd/gorename',
+		modulePath: 'golang.org/x/tools',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Rename symbols'
+	},
+	'gomodifytags': {
+		name: 'gomodifytags',
+		importPath: 'github.com/fatih/gomodifytags',
+		modulePath: 'github.com/fatih/gomodifytags',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Modify tags on structs'
+	},
+	'goplay': {
+		name: 'goplay',
+		importPath: 'github.com/haya14busa/goplay/cmd/goplay',
+		modulePath: 'github.com/haya14busa/goplay',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'The Go playground'
+	},
+	'impl': {
+		name: 'impl',
+		importPath: 'github.com/josharian/impl',
+		modulePath: 'github.com/josharian/impl',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Stubs for interfaces'
+	},
+	'gotype-live': {
+		name: 'gotype-live',
+		importPath: 'github.com/tylerb/gotype-live',
+		modulePath: 'github.com/tylerb/gotype-live',
+		replacedByGopls: true, // TODO(github.com/golang/vscode-go/issues/1021): recommend users to turn off.
+		isImportant: false,
+		description: 'Show errors as you type'
+	},
+	'godef': {
+		name: 'godef',
+		importPath: 'github.com/rogpeppe/godef',
+		modulePath: 'github.com/rogpeppe/godef',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Go to definition'
+	},
+	'gogetdoc': {
+		name: 'gogetdoc',
+		importPath: 'github.com/zmb3/gogetdoc',
+		modulePath: 'github.com/zmb3/gogetdoc',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Go to definition & text shown on hover'
+	},
+	'gofumports': {
+		name: 'gofumports',
+		importPath: 'mvdan.cc/gofumpt/gofumports',
+		modulePath: 'mvdan.cc/gofumpt',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Formatter'
+	},
+	'gofumpt': {
+		name: 'gofumpt',
+		importPath: 'mvdan.cc/gofumpt',
+		modulePath: 'mvdan.cc/gofumpt',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Formatter'
+	},
+	'goimports': {
+		name: 'goimports',
+		importPath: 'golang.org/x/tools/cmd/goimports',
+		modulePath: 'golang.org/x/tools',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Formatter'
+	},
+	'goreturns': {
+		name: 'goreturns',
+		importPath: 'github.com/sqs/goreturns',
+		modulePath: 'github.com/sqs/goreturns',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Formatter'
+	},
+	'goformat': {
+		name: 'goformat',
+		importPath: 'winterdrache.de/goformat/goformat',
+		modulePath: 'winterdrache.de/goformat/goformat',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Formatter'
+	},
+	'gotests': {
+		name: 'gotests',
+		importPath: 'github.com/cweill/gotests/gotests',
+		modulePath: 'github.com/cweill/gotests',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Generate unit tests',
+		minimumGoVersion: semver.coerce('1.9')
+	},
+	// TODO(github.com/golang/vscode-go/issues/189): consider disabling lint when gopls is turned on.
+	'golint': {
+		name: 'golint',
+		importPath: 'golang.org/x/lint/golint',
+		modulePath: 'golang.org/x/lint',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Linter',
+		minimumGoVersion: semver.coerce('1.9')
+	},
+	'staticcheck': {
+		name: 'staticcheck',
+		importPath: 'honnef.co/go/tools/cmd/staticcheck',
+		modulePath: 'honnef.co/go/tools',
+		replacedByGopls: false,
+		isImportant: true,
+		description: 'Linter'
+	},
+	'golangci-lint': {
+		name: 'golangci-lint',
+		importPath: 'github.com/golangci/golangci-lint/cmd/golangci-lint',
+		modulePath: 'github.com/golangci/golangci-lint',
+		replacedByGopls: false,
+		isImportant: true,
+		description: 'Linter'
+	},
+	'revive': {
+		name: 'revive',
+		importPath: 'github.com/mgechev/revive',
+		modulePath: 'github.com/mgechev/revive',
+		isImportant: true,
+		description: 'Linter'
+	},
+	'gopls': {
+		name: 'gopls',
+		importPath: 'golang.org/x/tools/gopls',
+		modulePath: 'golang.org/x/tools/gopls',
+		replacedByGopls: false, // lol
+		isImportant: true,
+		description: 'Language Server from Google',
+		usePrereleaseInPreviewMode: true,
+		minimumGoVersion: semver.coerce('1.12'),
+		latestVersion: semver.parse('v0.6.11'),
+		latestVersionTimestamp: moment('2021-05-04', 'YYYY-MM-DD'),
+		latestPrereleaseVersion: semver.parse('v0.6.11'),
+		latestPrereleaseVersionTimestamp: moment('2021-05-04', 'YYYY-MM-DD')
+	},
+	'dlv': {
+		name: 'dlv',
+		importPath: 'github.com/go-delve/delve/cmd/dlv',
+		modulePath: 'github.com/go-delve/delve',
+		replacedByGopls: false,
+		isImportant: true,
+		description: 'Go debugger (Delve)'
+	},
+	'dlv-dap': {
+		name: 'dlv-dap',
+		importPath: 'github.com/go-delve/delve/cmd/dlv',
+		modulePath: 'github.com/go-delve/delve',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Go debugger (Delve built for DAP experiment)',
+		defaultVersion: 'master', // Always build from the master.
+		minimumGoVersion: semver.coerce('1.14'), // last 3 versions per delve policy
+		latestVersion: semver.parse('v1.6.1-0.20210513025838-66782f9b2731'),
+		latestVersionTimestamp: moment('2021-05-13', 'YYYY-MM-DD')
+	},
+	'fillstruct': {
+		name: 'fillstruct',
+		importPath: 'github.com/davidrjenni/reftools/cmd/fillstruct',
+		modulePath: 'github.com/davidrjenni/reftools',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Fill structs with defaults'
+	},
+	'godoctor': {
+		name: 'godoctor',
+		importPath: 'github.com/godoctor/godoctor',
+		modulePath: 'github.com/godoctor/godoctor',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Extract to functions and variables'
+	}
+};
diff --git a/test/integration/install.test.ts b/test/integration/install.test.ts
index 85dd96c..c4875f5 100644
--- a/test/integration/install.test.ts
+++ b/test/integration/install.test.ts
@@ -8,7 +8,7 @@
 import * as assert from 'assert';
 import * as config from '../../src/config';
 import { inspectGoToolVersion, installTools } from '../../src/goInstallTools';
-import { allToolsInformation, getConfiguredTools, getTool, getToolAtVersion } from '../../src/goTools';
+import { getConfiguredTools, getTool, getToolAtVersion } from '../../src/goTools';
 import { getBinPath, getGoVersion, GoVersion, rmdirRecursive } from '../../src/util';
 import { correctBinname } from '../../src/utils/pathUtils';
 import cp = require('child_process');
@@ -20,6 +20,7 @@
 import util = require('util');
 import vscode = require('vscode');
 import { isInPreviewMode } from '../../src/goLanguageServer';
+import { allToolsInformation } from '../../src/goToolsInformation';
 
 interface installationTestCase {
 	name: string;
diff --git a/tools/allTools.ts.in b/tools/allTools.ts.in
new file mode 100644
index 0000000..33d46b7
--- /dev/null
+++ b/tools/allTools.ts.in
@@ -0,0 +1,244 @@
+import moment = require('moment');
+import semver = require('semver');
+import { gocodeClose, Tool } from './goTools';
+
+export const allToolsInformation: { [key: string]: Tool } = {
+	'gocode': {
+		name: 'gocode',
+		importPath: 'github.com/mdempsky/gocode',
+		modulePath: 'github.com/mdempsky/gocode',
+		isImportant: true,
+		replacedByGopls: true,
+		description: 'Auto-completion, does not work with modules',
+		close: gocodeClose
+	},
+	'gocode-gomod': {
+		name: 'gocode-gomod',
+		importPath: 'github.com/stamblerre/gocode',
+		modulePath: 'github.com/stamblerre/gocode',
+		isImportant: true,
+		replacedByGopls: true,
+		description: 'Auto-completion, works with modules',
+		minimumGoVersion: semver.coerce('1.11')
+	},
+	'gopkgs': {
+		name: 'gopkgs',
+		importPath: 'github.com/uudashr/gopkgs/v2/cmd/gopkgs',
+		modulePath: 'github.com/uudashr/gopkgs/v2',
+		replacedByGopls: false, // TODO(github.com/golang/vscode-go/issues/258): disable Add Import command.
+		isImportant: true,
+		description: 'Auto-completion of unimported packages & Add Import feature'
+	},
+	'go-outline': {
+		name: 'go-outline',
+		importPath: 'github.com/ramya-rao-a/go-outline',
+		modulePath: 'github.com/ramya-rao-a/go-outline',
+		replacedByGopls: false, // TODO(github.com/golang/vscode-go/issues/1020): replace with Gopls.
+		isImportant: true,
+		description: 'Go to symbol in file' // GoDocumentSymbolProvider, used by 'run test' codelens
+	},
+	'go-symbols': {
+		name: 'go-symbols',
+		importPath: 'github.com/acroca/go-symbols',
+		modulePath: 'github.com/acroca/go-symbols',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Go to symbol in workspace'
+	},
+	'guru': {
+		name: 'guru',
+		importPath: 'golang.org/x/tools/cmd/guru',
+		modulePath: 'golang.org/x/tools',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Find all references and Go to implementation of symbols'
+	},
+	'gorename': {
+		name: 'gorename',
+		importPath: 'golang.org/x/tools/cmd/gorename',
+		modulePath: 'golang.org/x/tools',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Rename symbols'
+	},
+	'gomodifytags': {
+		name: 'gomodifytags',
+		importPath: 'github.com/fatih/gomodifytags',
+		modulePath: 'github.com/fatih/gomodifytags',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Modify tags on structs'
+	},
+	'goplay': {
+		name: 'goplay',
+		importPath: 'github.com/haya14busa/goplay/cmd/goplay',
+		modulePath: 'github.com/haya14busa/goplay',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'The Go playground'
+	},
+	'impl': {
+		name: 'impl',
+		importPath: 'github.com/josharian/impl',
+		modulePath: 'github.com/josharian/impl',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Stubs for interfaces'
+	},
+	'gotype-live': {
+		name: 'gotype-live',
+		importPath: 'github.com/tylerb/gotype-live',
+		modulePath: 'github.com/tylerb/gotype-live',
+		replacedByGopls: true, // TODO(github.com/golang/vscode-go/issues/1021): recommend users to turn off.
+		isImportant: false,
+		description: 'Show errors as you type'
+	},
+	'godef': {
+		name: 'godef',
+		importPath: 'github.com/rogpeppe/godef',
+		modulePath: 'github.com/rogpeppe/godef',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Go to definition'
+	},
+	'gogetdoc': {
+		name: 'gogetdoc',
+		importPath: 'github.com/zmb3/gogetdoc',
+		modulePath: 'github.com/zmb3/gogetdoc',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Go to definition & text shown on hover'
+	},
+	'gofumports': {
+		name: 'gofumports',
+		importPath: 'mvdan.cc/gofumpt/gofumports',
+		modulePath: 'mvdan.cc/gofumpt',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Formatter'
+	},
+	'gofumpt': {
+		name: 'gofumpt',
+		importPath: 'mvdan.cc/gofumpt',
+		modulePath: 'mvdan.cc/gofumpt',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Formatter'
+	},
+	'goimports': {
+		name: 'goimports',
+		importPath: 'golang.org/x/tools/cmd/goimports',
+		modulePath: 'golang.org/x/tools',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Formatter'
+	},
+	'goreturns': {
+		name: 'goreturns',
+		importPath: 'github.com/sqs/goreturns',
+		modulePath: 'github.com/sqs/goreturns',
+		replacedByGopls: true,
+		isImportant: true,
+		description: 'Formatter'
+	},
+	'goformat': {
+		name: 'goformat',
+		importPath: 'winterdrache.de/goformat/goformat',
+		modulePath: 'winterdrache.de/goformat/goformat',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Formatter'
+	},
+	'gotests': {
+		name: 'gotests',
+		importPath: 'github.com/cweill/gotests/gotests',
+		modulePath: 'github.com/cweill/gotests',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Generate unit tests',
+		minimumGoVersion: semver.coerce('1.9')
+	},
+	// TODO(github.com/golang/vscode-go/issues/189): consider disabling lint when gopls is turned on.
+	'golint': {
+		name: 'golint',
+		importPath: 'golang.org/x/lint/golint',
+		modulePath: 'golang.org/x/lint',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Linter',
+		minimumGoVersion: semver.coerce('1.9')
+	},
+	'staticcheck': {
+		name: 'staticcheck',
+		importPath: 'honnef.co/go/tools/cmd/staticcheck',
+		modulePath: 'honnef.co/go/tools',
+		replacedByGopls: false,
+		isImportant: true,
+		description: 'Linter'
+	},
+	'golangci-lint': {
+		name: 'golangci-lint',
+		importPath: 'github.com/golangci/golangci-lint/cmd/golangci-lint',
+		modulePath: 'github.com/golangci/golangci-lint',
+		replacedByGopls: false,
+		isImportant: true,
+		description: 'Linter'
+	},
+	'revive': {
+		name: 'revive',
+		importPath: 'github.com/mgechev/revive',
+		modulePath: 'github.com/mgechev/revive',
+		isImportant: true,
+		description: 'Linter'
+	},
+	'gopls': {
+		name: 'gopls',
+		importPath: 'golang.org/x/tools/gopls',
+		modulePath: 'golang.org/x/tools/gopls',
+		replacedByGopls: false, // lol
+		isImportant: true,
+		description: 'Language Server from Google',
+		usePrereleaseInPreviewMode: true,
+		minimumGoVersion: semver.coerce('1.12'),
+		latestVersion: semver.parse('%s'),
+		latestVersionTimestamp: moment('%s', 'YYYY-MM-DD'),
+		latestPrereleaseVersion: semver.parse('%s'),
+		latestPrereleaseVersionTimestamp: moment('%s', 'YYYY-MM-DD')
+	},
+	'dlv': {
+		name: 'dlv',
+		importPath: 'github.com/go-delve/delve/cmd/dlv',
+		modulePath: 'github.com/go-delve/delve',
+		replacedByGopls: false,
+		isImportant: true,
+		description: 'Go debugger (Delve)'
+	},
+	'dlv-dap': {
+		name: 'dlv-dap',
+		importPath: 'github.com/go-delve/delve/cmd/dlv',
+		modulePath: 'github.com/go-delve/delve',
+		replacedByGopls: false,
+		isImportant: false,
+		description: 'Go debugger (Delve built for DAP experiment)',
+		defaultVersion: 'master', // Always build from the master.
+		minimumGoVersion: semver.coerce('1.14'), // last 3 versions per delve policy
+		latestVersion: semver.parse('%s'),
+		latestVersionTimestamp: moment('%s', 'YYYY-MM-DD')
+	},
+	'fillstruct': {
+		name: 'fillstruct',
+		importPath: 'github.com/davidrjenni/reftools/cmd/fillstruct',
+		modulePath: 'github.com/davidrjenni/reftools',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Fill structs with defaults'
+	},
+	'godoctor': {
+		name: 'godoctor',
+		importPath: 'github.com/godoctor/godoctor',
+		modulePath: 'github.com/godoctor/godoctor',
+		replacedByGopls: true,
+		isImportant: false,
+		description: 'Extract to functions and variables'
+	}
+};
\ No newline at end of file
diff --git a/tools/generate.go b/tools/generate.go
index 9999738..87e9379 100644
--- a/tools/generate.go
+++ b/tools/generate.go
@@ -20,6 +20,7 @@
 	"io/ioutil"
 	"log"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"sort"
 	"strings"
@@ -28,8 +29,9 @@
 )
 
 var (
-	writeFlag               = flag.Bool("w", true, "Write new file contents to disk.")
-	updateGoplsSettingsFlag = flag.Bool("gopls", false, "Update gopls settings in package.json. This is disabled by default because 'jq' tool is needed for generation.")
+	writeFlag                    = flag.Bool("w", true, "Write new file contents to disk.")
+	updateGoplsSettingsFlag      = flag.Bool("gopls", false, "Update gopls settings in package.json. This is disabled by default because 'jq' tool is needed for generation.")
+	updateLatestToolVersionsFlag = flag.Bool("tools", false, "Update the latest versions of tools in src/src/goToolsInformation.ts. This is disabled by default because the latest versions may change frequently and should not block a release.")
 
 	debugFlag = flag.Bool("debug", false, "If true, enable extra logging and skip deletion of intermediate files.")
 )
@@ -65,6 +67,13 @@
 	MarkdownEnumDescriptions   []string               `json:"markdownEnumDescriptions,omitempty"`
 }
 
+type moduleVersion struct {
+	Path     string   `json:",omitempty"`
+	Version  string   `json:",omitempty"`
+	Time     string   `json:",omitempty"`
+	Versions []string `json:",omitempty"`
+}
+
 func main() {
 	flag.Parse()
 
@@ -105,11 +114,21 @@
 		if len(split) == 1 {
 			log.Fatalf("expected to find %q in %s, not found", gen, filename)
 		}
-		s := bytes.Join([][]byte{
-			bytes.TrimSpace(split[0]),
-			gen,
-			toAdd,
-		}, []byte("\n\n"))
+		var s []byte
+		if strings.HasSuffix(filename, ".ts") {
+			s = bytes.Join([][]byte{
+				split[0],
+				gen,
+				[]byte("\n\n"),
+				toAdd,
+			}, []byte{})
+		} else {
+			s = bytes.Join([][]byte{
+				bytes.TrimSpace(split[0]),
+				gen,
+				toAdd,
+			}, []byte("\n\n"))
+		}
 		newContent := append(s, '\n')
 
 		// Return early if the contents are unchanged.
@@ -177,6 +196,85 @@
 	writeGoplsSettingsSection(b, goplsProperty)
 
 	rewrite(filepath.Join(dir, "docs", "settings.md"), b.Bytes())
+
+	// Only update the latest tool versions if the flag is set.
+	if !*updateLatestToolVersionsFlag {
+		return
+	}
+
+	// Clear so that we can rewrite src/goToolsInformation.ts.
+	b.Reset()
+
+	// Check for latest dlv-dap version.
+	dlvVersion, err := listModuleVersion("github.com/go-delve/delve@master")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Check for the latest gopls version.
+	versions, err := listAllModuleVersions("golang.org/x/tools/gopls")
+	if err != nil {
+		log.Fatal(err)
+	}
+	latestIndex := len(versions.Versions) - 1
+	latestPre := versions.Versions[latestIndex]
+	// We need to find the last version that was not a pre-release.
+	var latest string
+	for latest = versions.Versions[latestIndex]; latestIndex >= 0; latestIndex-- {
+		if !strings.Contains(latest, "pre") {
+			break
+		}
+	}
+
+	goplsVersion, err := listModuleVersion(fmt.Sprintf("golang.org/x/tools/gopls@%s", latest))
+	if err != nil {
+		log.Fatal(err)
+	}
+	goplsVersionPre, err := listModuleVersion(fmt.Sprintf("golang.org/x/tools/gopls@%s", latestPre))
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	allToolsFile := filepath.Join(dir, "tools", "allTools.ts.in")
+
+	// Find the package.json file.
+	data, err = ioutil.ReadFile(allToolsFile)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// TODO(suzmue): change input to json and avoid magic string printing.
+	toolsString := fmt.Sprintf(string(data), goplsVersion.Version, goplsVersion.Time[:len("YYYY-MM-DD")], goplsVersionPre.Version, goplsVersionPre.Time[:len("YYYY-MM-DD")], dlvVersion.Version, dlvVersion.Time[:len("YYYY-MM-DD")])
+
+	// Write tools section.
+	b.WriteString(toolsString)
+	rewrite(filepath.Join(dir, "src", "goToolsInformation.ts"), b.Bytes())
+}
+
+func listModuleVersion(path string) (moduleVersion, error) {
+	output, err := exec.Command("go", "list", "-m", "-json", path).Output()
+	if err != nil {
+		return moduleVersion{}, err
+	}
+	var version moduleVersion
+	err = json.Unmarshal(output, &version)
+	if err != nil {
+		return moduleVersion{}, err
+	}
+	return version, nil
+}
+
+func listAllModuleVersions(path string) (moduleVersion, error) {
+	output, err := exec.Command("go", "list", "-m", "-json", "-versions", path).Output()
+	if err != nil {
+		return moduleVersion{}, err
+	}
+	var version moduleVersion
+	err = json.Unmarshal(output, &version)
+	if err != nil {
+		return moduleVersion{}, err
+	}
+	return version, nil
 }
 
 func writeProperty(b *bytes.Buffer, heading string, p Property) {