1#![deny(missing_debug_implementations)]
77#![deny(missing_docs)]
78#![deny(unsafe_code)]
79#![deny(clippy::print_stdout)]
88#![allow(clippy::mutable_key_type)]
89#![allow(clippy::new_without_default)]
90#![allow(clippy::module_inception)]
91#![allow(deprecated)]
92#![allow(unused_imports)]
93
94pub extern crate lsp_types_max;
95pub use lsp_types_max as lsp_types;
96
97#[allow(missing_docs)]
98#[allow(missing_debug_implementations)]
99pub mod closure_channel;
100
101#[allow(missing_docs)]
102#[allow(missing_debug_implementations)]
103pub mod agent;
104
105#[allow(missing_docs)]
106#[allow(missing_debug_implementations)]
107pub mod runtime;
108
109#[allow(missing_docs)]
110#[allow(missing_debug_implementations)]
111pub mod andon;
112
113#[allow(missing_docs)]
114#[allow(missing_debug_implementations)]
115pub mod live;
116
117#[allow(missing_docs)]
118#[allow(missing_debug_implementations)]
119pub mod client;
120
121pub use agent as max_agent;
122pub use andon as max_andon;
123pub use live as max_live;
124pub use runtime as max_runtime;
125
126pub extern crate lsp_max_protocol as max_protocol;
127
128pub use async_trait::async_trait;
130
131pub use self::service::progress::{
132 Bounded, Cancellable, NotCancellable, OngoingProgress, Progress, Unbounded,
133};
134pub use self::service::{Client, ClientSocket, ExitedError, LspService, LspServiceBuilder};
135pub use self::transport::{Loopback, Server};
136
137use lsp_types_max::*;
138
139use self::jsonrpc::{Error, Result};
140
141pub mod ast {
143 pub use lsp_max_ast::*;
144}
145
146pub mod jsonrpc;
147
148mod codec;
149pub mod language_server;
151pub mod service;
152mod transport;
153pub use language_server::LanguageServer;
154
155pub use lsp_max_lsif as lsif;
156
157mod composition;
158pub use composition::{ComposedServer, CompositionState, SharedCompositionState, SourceHealth};
159
160pub mod diagnostics;
162pub mod gate;
164pub mod workspace_edit;
166
167pub mod rule_pack_server;
169pub use rule_pack_server::{
170 glob_matches, ClassifiedFindings, Finding, Rule, RulePack, RulePackServer,
171 ValidatedRulePackSet, WorkspaceIndex,
172};
173
174pub mod coverage;
176
177pub mod primitives;
179
180pub mod pipeline;
182
183pub(crate) use diagnostics::update_diagnostics;
184
185pub(crate) fn rfc3339_now() -> String {
187 use std::time::{SystemTime, UNIX_EPOCH};
188 let mut s = SystemTime::now()
189 .duration_since(UNIX_EPOCH)
190 .unwrap_or_default()
191 .as_secs();
192 let sec = s % 60;
193 s /= 60;
194 let min = s % 60;
195 s /= 60;
196 let hour = s % 24;
197 s /= 24;
198 let mut year = 1970u64;
199 loop {
200 let leap = if (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) {
201 1
202 } else {
203 0
204 };
205 let days = 365 + leap;
206 if s < days {
207 break;
208 }
209 s -= days;
210 year += 1;
211 }
212 let leap = if (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) {
213 1
214 } else {
215 0
216 };
217 const MONTH_DAYS: [u64; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
218 let mut month = 1u64;
219 for (i, &d) in MONTH_DAYS.iter().enumerate() {
220 let d = if i == 1 { d + leap } else { d };
221 if s < d {
222 month = i as u64 + 1;
223 break;
224 }
225 s -= d;
226 }
227 let day = s + 1;
228 format!("{year:04}-{month:02}-{day:02}T{hour:02}:{min:02}:{sec:02}Z")
229}
230
231fn _assert_object_safe() {
232 fn assert_impl<T: LanguageServer>() {}
233 assert_impl::<Box<dyn LanguageServer>>();
234}
235
236use std::collections::HashMap;
237use std::sync::{Mutex, OnceLock};
238
239#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
241#[allow(dead_code)]
242pub struct SnapshotRecord {
243 #[allow(dead_code)]
245 pub id: max_protocol::SnapshotId,
246 pub capability_vector: max_protocol::MaxCapabilityVector,
248 pub diagnostics: Vec<max_protocol::MaxDiagnostic>,
250 pub actions: Vec<max_protocol::MaxCodeAction>,
252 pub conformance_vector: max_protocol::ConformanceVector,
254 pub receipts: Vec<max_protocol::Receipt>,
256}
257
258#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
260pub struct ServerRegistry {
261 pub client_capabilities: Option<ClientCapabilities>,
263 pub server_capabilities: Option<ServerCapabilities>,
265 pub diagnostics: HashMap<String, max_protocol::MaxDiagnostic>,
267 pub repair_plans: HashMap<String, Vec<max_protocol::MaxCodeAction>>,
269 pub gates: HashMap<String, bool>,
271 pub receipts: HashMap<String, max_protocol::Receipt>,
273 pub snapshots: HashMap<String, SnapshotRecord>,
275 #[serde(default)]
277 pub cleared_diagnostics: std::collections::HashSet<String>,
278 pub current_state: crate::service::State,
280 pub document_versions: HashMap<url::Url, i32>,
282 pub root_path: std::path::PathBuf,
284 #[serde(default)]
287 pub action_seq: u64,
288 #[serde(default)]
291 pub conformance_delta_log:
292 std::collections::VecDeque<crate::max_runtime::ConformanceDeltaEntry>,
293}
294
295pub static REGISTRY: OnceLock<Mutex<ServerRegistry>> = OnceLock::new();
297
298pub static MESH: OnceLock<Mutex<crate::max_runtime::AutonomicMesh>> = OnceLock::new();
300
301pub fn get_registry() -> &'static Mutex<ServerRegistry> {
303 REGISTRY.get_or_init(|| {
304 let diagnostics = HashMap::new();
305 let repair_plans = HashMap::new();
306 let mut gates = HashMap::new();
307 gates.insert("gate-state-check".to_string(), false);
308
309 Mutex::new(ServerRegistry {
310 client_capabilities: None,
311 server_capabilities: None,
312 diagnostics,
313 repair_plans,
314 gates,
315 receipts: HashMap::new(),
316 snapshots: HashMap::new(),
317 cleared_diagnostics: std::collections::HashSet::new(),
318 current_state: crate::service::State::Uninitialized,
319 document_versions: HashMap::new(),
320 root_path: std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")),
321 action_seq: 0,
322 conformance_delta_log: std::collections::VecDeque::new(),
323 })
324 })
325}
326
327pub(crate) fn lock_registry() -> Result<std::sync::MutexGuard<'static, ServerRegistry>> {
328 get_registry().lock().map_err(|_| Error::internal_error())
329}
330
331fn build_standard_mesh() -> crate::max_runtime::AutonomicMesh {
332 let mut mesh = crate::max_runtime::AutonomicMesh::new();
333 mesh.register_hook(Box::new(crate::max_runtime::IntakeDiagnosticHook));
334 mesh.register_hook(Box::new(crate::max_runtime::IntakeClearHook));
335 mesh.register_hook(Box::new(
336 crate::max_runtime::CustomerRequestClassifierHook::new(),
337 ));
338 mesh.register_hook(Box::new(crate::max_runtime::PolicyEvaluationHook::new()));
339 mesh.register_hook(Box::new(crate::max_runtime::ReceiptRoutingHook::new()));
340 mesh
341}
342
343pub(crate) fn lock_mesh(
344) -> Result<std::sync::MutexGuard<'static, crate::max_runtime::AutonomicMesh>> {
345 MESH.get_or_init(|| Mutex::new(build_standard_mesh()))
346 .lock()
347 .map_err(|_| Error::internal_error())
348}
349
350pub fn reset_registry_for_tests() {
353 if let Ok(mut reg) = get_registry().lock() {
354 reg.client_capabilities = None;
355 reg.server_capabilities = None;
356 reg.diagnostics.clear();
357 reg.repair_plans.clear();
358 reg.gates.clear();
359 reg.gates.insert("gate-state-check".to_string(), false);
360 reg.receipts.clear();
361 reg.snapshots.clear();
362 reg.cleared_diagnostics.clear();
363 reg.current_state = crate::service::State::Uninitialized;
364 reg.document_versions.clear();
365 reg.root_path = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
366 reg.action_seq = 0;
367 reg.conformance_delta_log.clear();
368 }
369}
370
371pub(crate) fn sha256(data: &[u8]) -> String {
372 let mut h = [
373 0x6a09e667u32,
374 0xbb67ae85u32,
375 0x3c6ef372u32,
376 0xa54ff53au32,
377 0x510e527fu32,
378 0x9b05688cu32,
379 0x1f83d9abu32,
380 0x5be0cd19u32,
381 ];
382 let k = [
383 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
384 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
385 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
386 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
387 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
388 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
389 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
390 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
391 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
392 0xc67178f2,
393 ];
394
395 let mut padded = data.to_vec();
396 let bit_len = (data.len() as u64) * 8;
397 padded.push(0x80);
398 while (padded.len() + 8) % 64 != 0 {
399 padded.push(0);
400 }
401 padded.extend_from_slice(&bit_len.to_be_bytes());
402
403 for chunk in padded.chunks_exact(64) {
404 let mut w = [0u32; 64];
405 for i in 0..16 {
406 w[i] = u32::from_be_bytes([
407 chunk[i * 4],
408 chunk[i * 4 + 1],
409 chunk[i * 4 + 2],
410 chunk[i * 4 + 3],
411 ]);
412 }
413 for i in 16..64 {
414 let s0 = w[i - 15].rotate_right(7) ^ w[i - 15].rotate_right(18) ^ (w[i - 15] >> 3);
415 let s1 = w[i - 2].rotate_right(17) ^ w[i - 2].rotate_right(19) ^ (w[i - 2] >> 10);
416 w[i] = w[i - 16]
417 .wrapping_add(s0)
418 .wrapping_add(w[i - 7])
419 .wrapping_add(s1);
420 }
421
422 let mut a = h[0];
423 let mut b = h[1];
424 let mut c = h[2];
425 let mut d = h[3];
426 let mut e = h[4];
427 let mut f = h[5];
428 let mut g = h[6];
429 let mut h_val = h[7];
430
431 for i in 0..64 {
432 let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25);
433 let ch = (e & f) ^ ((!e) & g);
434 let temp1 = h_val
435 .wrapping_add(s1)
436 .wrapping_add(ch)
437 .wrapping_add(k[i])
438 .wrapping_add(w[i]);
439 let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22);
440 let maj = (a & b) ^ (a & c) ^ (b & c);
441 let temp2 = s0.wrapping_add(maj);
442
443 h_val = g;
444 g = f;
445 f = e;
446 e = d.wrapping_add(temp1);
447 d = c;
448 c = b;
449 b = a;
450 a = temp1.wrapping_add(temp2);
451 }
452
453 h[0] = h[0].wrapping_add(a);
454 h[1] = h[1].wrapping_add(b);
455 h[2] = h[2].wrapping_add(c);
456 h[3] = h[3].wrapping_add(d);
457 h[4] = h[4].wrapping_add(e);
458 h[5] = h[5].wrapping_add(f);
459 h[6] = h[6].wrapping_add(g);
460 h[7] = h[7].wrapping_add(h_val);
461 }
462
463 let mut result = String::new();
464 for &val in &h {
465 result.push_str(&format!("{:08x}", val));
466 }
467 result
468}