src/goDebugFactory: start dlv dap process early

This simplifies the code path.

Change-Id: Ia4ef6f7828dda39d70fd52aa5b0d4b8bb878b8ae
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/313049
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
diff --git a/src/goDebugFactory.ts b/src/goDebugFactory.ts
index 670e398..a970121 100644
--- a/src/goDebugFactory.ts
+++ b/src/goDebugFactory.ts
@@ -33,14 +33,15 @@
 		console.log('GoDebugAdapterDescriptorFactory.dispose');
 	}
 
-	private createDebugAdapterDescriptorDlvDap(
+	private async createDebugAdapterDescriptorDlvDap(
 		configuration: vscode.DebugConfiguration
-	): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
+	): Promise<vscode.ProviderResult<vscode.DebugAdapterDescriptor>> {
 		if (configuration.port) {
 			return new vscode.DebugAdapterServer(configuration.port, configuration.host ?? '127.0.0.1');
 		}
 		const logger = new TimestampedLogger(configuration.trace, this.outputChannel);
 		const d = new DelveDAPOutputAdapter(configuration, logger);
+		await d.startAndConnectToServer();
 		return new vscode.DebugAdapterInlineImplementation(d);
 	}
 }
@@ -195,45 +196,22 @@
 		super(logger);
 	}
 
-	private connected: Promise<void>;
 	private dlvDapServer: ChildProcess;
 	private port: number;
 	private socket: net.Socket;
-	private terminatedOnError = false;
 
 	protected async sendMessageToServer(message: vscode.DebugProtocolMessage): Promise<void> {
-		if (!this.connected) {
-			this.connected = this.startAndConnectToServer();
-		}
-		try {
-			await this.connected;
-			super.sendMessageToServer(message);
-		} catch (err) {
-			if (this.terminatedOnError) {
-				return;
-			}
-			this.terminatedOnError = true;
-			// If there was an error connecting, show an error message
-			// and send a terminated event, since we cannot start.
-			if (err) {
-				const errMsg = `Debug Error: ${err}`;
-				this.outputEvent(errMsg, 'stderr');
-				vscode.window.showErrorMessage(errMsg);
-			}
-			this.sendMessageToClient(new TerminatedEvent());
-			return;
-		}
+		super.sendMessageToServer(message);
 	}
 
 	async dispose() {
 		// NOTE: OutputEvents from here may not show up in DEBUG CONSOLE
 		// because the debug session is terminating.
 		await super.dispose();
-
-		if (this.connected === undefined) {
+		if (!this.dlvDapServer) {
 			return;
 		}
-		this.connected = undefined;
+
 		const dlvDapServer = this.dlvDapServer;
 		if (!dlvDapServer) {
 			return;
@@ -260,7 +238,7 @@
 		});
 	}
 
-	private async startAndConnectToServer() {
+	public async startAndConnectToServer() {
 		const { port, host, dlvDapServer } = await startDapServer(
 			this.config,
 			(msg) => this.outputEvent('stdout', msg),
diff --git a/test/integration/goDebug.test.ts b/test/integration/goDebug.test.ts
index 0464c10..374a3c5 100644
--- a/test/integration/goDebug.test.ts
+++ b/test/integration/goDebug.test.ts
@@ -1858,7 +1858,7 @@
 
 		const debugConfig = await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 		if (isDlvDap) {
-			dlvDapAdapter = new DelveDAPDebugAdapterOnSocket(debugConfig);
+			dlvDapAdapter = await DelveDAPDebugAdapterOnSocket.create(debugConfig);
 			const port = await dlvDapAdapter.serve();
 			await dc.start(port); // This will connect to the adapter's port.
 		}
@@ -1881,7 +1881,13 @@
 // the thin adapter for Delve DAP and the debug test support's
 // DebugClient to communicate with the adapter over a network socket.
 class DelveDAPDebugAdapterOnSocket extends proxy.DelveDAPOutputAdapter {
-	constructor(config: DebugConfiguration) {
+	static async create(config: DebugConfiguration) {
+		const d = new DelveDAPDebugAdapterOnSocket(config);
+		await d.startAndConnectToServer();
+		return d;
+	}
+
+	private constructor(config: DebugConfiguration) {
 		super(config);
 	}