1use dap::{StartDebuggingRequestArguments, adapters::DebugTaskDefinition};
2use gpui::{AsyncApp, SharedString};
3use language::LanguageName;
4use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
5
6use crate::*;
7
8#[derive(Default, Debug)]
9pub(crate) struct GoDebugAdapter;
10
11impl GoDebugAdapter {
12 const ADAPTER_NAME: &'static str = "Delve";
13 fn request_args(&self, config: &DebugTaskDefinition) -> StartDebuggingRequestArguments {
14 let mut args = match &config.request {
15 dap::DebugRequest::Attach(attach_config) => {
16 json!({
17 "processId": attach_config.process_id,
18 })
19 }
20 dap::DebugRequest::Launch(launch_config) => json!({
21 "program": launch_config.program,
22 "cwd": launch_config.cwd,
23 "args": launch_config.args,
24 "env": launch_config.env_json()
25 }),
26 };
27
28 let map = args.as_object_mut().unwrap();
29
30 if let Some(stop_on_entry) = config.stop_on_entry {
31 map.insert("stopOnEntry".into(), stop_on_entry.into());
32 }
33
34 StartDebuggingRequestArguments {
35 configuration: args,
36 request: config.request.to_dap(),
37 }
38 }
39}
40
41#[async_trait(?Send)]
42impl DebugAdapter for GoDebugAdapter {
43 fn name(&self) -> DebugAdapterName {
44 DebugAdapterName(Self::ADAPTER_NAME.into())
45 }
46
47 fn adapter_language_name(&self) -> Option<LanguageName> {
48 Some(SharedString::new_static("Go").into())
49 }
50
51 async fn get_binary(
52 &self,
53 delegate: &Arc<dyn DapDelegate>,
54 config: &DebugTaskDefinition,
55 _user_installed_path: Option<PathBuf>,
56 _cx: &mut AsyncApp,
57 ) -> Result<DebugAdapterBinary> {
58 let delve_path = delegate
59 .which(OsStr::new("dlv"))
60 .await
61 .and_then(|p| p.to_str().map(|p| p.to_string()))
62 .ok_or(anyhow!("Dlv not found in path"))?;
63
64 let tcp_connection = config.tcp_connection.clone().unwrap_or_default();
65 let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
66
67 Ok(DebugAdapterBinary {
68 command: delve_path,
69 arguments: vec![
70 "dap".into(),
71 "--listen".into(),
72 format!("{}:{}", host, port),
73 ],
74 cwd: None,
75 envs: HashMap::default(),
76 connection: Some(adapters::TcpArguments {
77 host,
78 port,
79 timeout,
80 }),
81 request_args: self.request_args(config),
82 })
83 }
84}