brack_language_server/
server.rs

1use std::str::from_utf8;
2
3use anyhow::{anyhow, Result};
4use lsp_types::{ClientCapabilities, Diagnostic, Position, Range};
5use serde_json::{from_str, json, Value};
6use tokio::io::{stdin, stdout, AsyncReadExt, AsyncWriteExt};
7
8pub struct LanguageServer {
9    client_capabilities: ClientCapabilities,
10}
11
12impl LanguageServer {
13    pub fn new() -> Self {
14        Self {
15            client_capabilities: ClientCapabilities::default(),
16        }
17    }
18
19    async fn send_message(&self, msg: &str) -> Result<()> {
20        let mut output = stdout();
21        output
22            .write_all(format!("Content-Length: {}\r\n\r\n{}", msg.len(), msg).as_bytes())
23            .await?;
24        output.flush().await?;
25        Ok(())
26    }
27
28    async fn log_message(&self, message: &str) -> Result<()> {
29        let response = json!({
30            "jsonrpc": "2.0",
31            "method": "window/logMessage",
32            "params": {
33                "type": 3,
34                "message": message
35            }
36        })
37        .to_string();
38        self.send_message(&response).await
39    }
40
41    async fn send_error_response(&self, id: Option<i64>, code: i32, message: &str) -> Result<()> {
42        let response = json!({
43            "jsonrpc": "2.0",
44            "id": id,
45            "error": {
46                "code": code,
47                "message": message,
48            }
49        })
50        .to_string();
51        self.send_message(&response).await
52    }
53
54    async fn send_invalid_request_response(&self) -> Result<()> {
55        self.send_error_response(None, -32600, "received an invalid request")
56            .await
57    }
58
59    async fn send_method_not_found_response(&self, id: i64, method: &str) -> Result<()> {
60        self.send_error_response(Some(id), -32601, &format!("{} is not supported", method))
61            .await
62    }
63
64    #[allow(dead_code)]
65    async fn send_parse_error_response(&self) -> Result<()> {
66        self.send_error_response(None, -32700, "received an invalid JSON")
67            .await
68    }
69
70    async fn send_publish_diagnostics(
71        &self,
72        uri: &str,
73        diagnostics: &Vec<Diagnostic>,
74    ) -> Result<()> {
75        // check client_capabilities.text_document.publish_diagnostics
76        if self
77            .client_capabilities
78            .text_document
79            .as_ref()
80            .and_then(|td| td.publish_diagnostics.as_ref())
81            .is_none()
82        {
83            return Ok(());
84        }
85
86        let response = json!({
87            "jsonrpc": "2.0",
88            "method": "textDocument/publishDiagnostics",
89            "params": {
90                "uri": uri,
91                "diagnostics": json!(diagnostics),
92            }
93        })
94        .to_string();
95        self.send_message(&response).await
96    }
97
98    async fn handle_request(&mut self, msg: &Value, id: i64, method: &str) -> Result<()> {
99        match method {
100            "initialize" => {
101                self.log_message("Brack Language Server is initializing...")
102                    .await?;
103                self.client_capabilities = serde_json::from_value(
104                    msg.get("params")
105                        .ok_or_else(|| anyhow!("No params"))?
106                        .get("capabilities")
107                        .ok_or_else(|| anyhow!("No capabilities"))?
108                        .clone(),
109                )?;
110
111                // for debugging
112                // self.log_message(&format!(
113                //     "Client capabilities : {:?}",
114                //     self.client_capabilities
115                // ))
116                // .await?;
117
118                let response = json!({
119                    "jsonrpc": "2.0",
120                    "id": id,
121                    "result": { "capabilities": {
122                        "textDocumentSync": 1,
123                    } }
124                })
125                .to_string();
126                self.send_message(&response).await
127            }
128            _ => self.send_method_not_found_response(id, method).await,
129        }
130    }
131
132    async fn handle_response(&self, _: &Value, _: i64) -> Result<()> {
133        Ok(())
134    }
135
136    async fn handle_notification_text_document_did_open(&self, msg: &Value) -> Result<()> {
137        let text_document = msg
138            .get("params")
139            .ok_or_else(|| anyhow!("No params"))?
140            .get("textDocument")
141            .ok_or_else(|| anyhow!("No textDocument"))?;
142        let uri = text_document
143            .get("uri")
144            .and_then(|uri| uri.as_str())
145            .ok_or_else(|| anyhow!("No uri"))?;
146        let _ = text_document
147            .get("text")
148            .and_then(|text| text.as_str())
149            .ok_or_else(|| anyhow!("No text"))?;
150        self.log_message(&format!("Did open {}", uri)).await?;
151
152        Ok(())
153    }
154
155    async fn handle_notification_text_document_did_change(&self, msg: &Value) -> Result<()> {
156        let uri = msg
157            .get("params")
158            .ok_or_else(|| anyhow!("No params"))?
159            .get("textDocument")
160            .ok_or_else(|| anyhow!("No textDocument"))?
161            .get("uri")
162            .and_then(|uri| uri.as_str())
163            .ok_or_else(|| anyhow!("No uri"))?;
164        let index = msg
165            .get("params")
166            .ok_or_else(|| anyhow!("No params"))?
167            .get("contentChanges")
168            .and_then(|content_changes| content_changes.as_array())
169            .and_then(|content_changes| content_changes.len().checked_sub(1))
170            .ok_or_else(|| anyhow!("No contentChanges"))?;
171        let _ = msg
172            .get("params")
173            .ok_or_else(|| anyhow!("No params"))?
174            .get("contentChanges")
175            .and_then(|content_changes| content_changes.get(index))
176            .and_then(|content_change| content_change.get("text"))
177            .and_then(|text| text.as_str())
178            .ok_or_else(|| anyhow!("No text"))?;
179        self.log_message(&format!("Did change {}", uri)).await?;
180
181        let diagnostics = vec![Diagnostic {
182            range: Range {
183                start: Position {
184                    line: 0,
185                    character: 0,
186                },
187                end: Position {
188                    line: 0,
189                    character: 3,
190                },
191            },
192            message: "This is a test diagnostic message 2!".to_string(),
193            ..Default::default()
194        }];
195        self.log_message(&format!("{:?}", diagnostics)).await?;
196        self.send_publish_diagnostics(uri, &diagnostics).await
197    }
198
199    async fn handle_notification(&mut self, msg: &Value, method: &str) -> Result<()> {
200        match method {
201            "initialized" => {
202                self.log_message("Brack Language Server has been initialized!")
203                    .await?;
204                Ok(())
205            }
206            "textDocument/didOpen" => self.handle_notification_text_document_did_open(msg).await,
207            "textDocument/didChange" => {
208                self.handle_notification_text_document_did_change(msg).await
209            }
210            _ => Ok(()),
211        }
212    }
213
214    async fn dispatch(&mut self, msg: Value) -> Result<()> {
215        match (
216            msg.get("id").and_then(|i| i.as_i64()),
217            msg.get("method").and_then(|m| m.as_str()),
218        ) {
219            (Some(id), Some(method)) => self.handle_request(&msg, id, method).await,
220            (Some(id), None) => self.handle_response(&msg, id).await,
221            (None, Some(method)) => self.handle_notification(&msg, method).await,
222            _ => self.send_invalid_request_response().await,
223        }
224    }
225
226    pub async fn run(&mut self) -> Result<()> {
227        let mut stdin = stdin();
228        let mut buffer = Vec::new();
229
230        loop {
231            let mut tmp_buffer = [0; 1024];
232
233            let chunk = stdin.read(&mut tmp_buffer).await?;
234
235            if chunk == 0 {
236                break;
237            }
238            buffer.extend_from_slice(&tmp_buffer[..chunk]);
239
240            let buffer_string = from_utf8(&buffer)?;
241            if !buffer_string.contains("\r\n\r\n") {
242                continue;
243            }
244
245            let splitted_buffer = buffer_string.split("\r\n\r\n").collect::<Vec<&str>>();
246            let header_string = splitted_buffer[0];
247
248            let mut content_length = -1;
249            let header_length = header_string.len() + 4;
250            for line in header_string.split("\r\n") {
251                let splitted_line = line.split(": ").collect::<Vec<&str>>();
252                let key = splitted_line[0];
253                let value = splitted_line[1];
254                if key == "Content-Length" {
255                    content_length = value.parse::<i32>()?;
256                }
257            }
258
259            if content_length == -1 {
260                continue;
261            }
262            let total_length = header_length + content_length as usize;
263
264            if buffer.len() < total_length {
265                continue;
266            }
267
268            let msg: Value = from_str(&buffer_string[header_length..total_length])?;
269            self.dispatch(msg).await?;
270            buffer.drain(0..total_length);
271        }
272
273        Ok(())
274    }
275}