src/goDebugConfiguration: infer default mode property

The mode property in launch.json defaults to local for attach requests.
However, if mode property for attach requests is omitted,
configs returned by resolveDebugConfiguration() have undefined mode.

This leads to cannot unmarshal string into processId to type int error
due to skipping parseInt in resolveDebugConfigurationWithSubstitutedVariables
hook when using command:pickGoProcess.

This change fixes the issue by setting the default value.

Fixes golang/vscode-go#1929

Change-Id: Ifa6501d1db9727aacad1368a93d10e941a3de17e
GitHub-Last-Rev: 6bcf535692ff3f8c310df35b3d74bfc7db03a1ae
GitHub-Pull-Request: golang/vscode-go#1932
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/370454
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Trust: Peter Weinberger <pjw@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/src/goDebugConfiguration.ts b/src/goDebugConfiguration.ts
index bf2b1eb..dc6055c 100644
--- a/src/goDebugConfiguration.ts
+++ b/src/goDebugConfiguration.ts
@@ -141,6 +141,15 @@
 			debugConfiguration['type'] = this.defaultDebugAdapterType;
 		}
 
+		if (!debugConfiguration['mode']) {
+			if (debugConfiguration.request === 'launch') {
+				// 'auto' will decide mode by checking file extensions later
+				debugConfiguration['mode'] = 'auto';
+			} else if (debugConfiguration.request === 'attach') {
+				debugConfiguration['mode'] = 'local';
+			}
+		}
+
 		debugConfiguration['packagePathToGoModPathMap'] = packagePathToGoModPathMap;
 
 		const goConfig = getGoConfig(folder && folder.uri);
diff --git a/test/integration/goDebugConfiguration.test.ts b/test/integration/goDebugConfiguration.test.ts
index ad382ca..5f63b8c 100644
--- a/test/integration/goDebugConfiguration.test.ts
+++ b/test/integration/goDebugConfiguration.test.ts
@@ -920,3 +920,45 @@
 		assert.strictEqual(resolvedConfig['debugAdapter'], want);
 	});
 });
+
+suite('Debug Configuration Infers Default Mode Property', () => {
+	const debugConfigProvider = new GoDebugConfigurationProvider();
+	test("default mode for launch requests and test Go programs should be 'test'", () => {
+		const config = {
+			name: 'Launch',
+			type: 'go',
+			request: 'launch',
+			program: '/path/to/main_test.go'
+		};
+
+		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const resolvedConfig = config as any;
+		assert.strictEqual(resolvedConfig['mode'], 'test');
+	});
+
+	test("default mode for launch requests and non-test Go programs should be 'debug'", () => {
+		const config = {
+			name: 'Launch',
+			type: 'go',
+			request: 'launch',
+			program: '/path/to/main.go'
+		};
+
+		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const resolvedConfig = config as any;
+		assert.strictEqual(resolvedConfig['mode'], 'debug');
+	});
+
+	test("default mode for attach requests should be 'local'", () => {
+		const config = {
+			name: 'Attach',
+			type: 'go',
+			request: 'attach',
+			program: '/path/to/main.go'
+		};
+
+		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const resolvedConfig = config as any;
+		assert.strictEqual(resolvedConfig['mode'], 'local');
+	});
+});