mz_deploy/lsp.rs
1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! LSP server for mz-deploy projects.
11//!
12//! Provides IDE integration for `.sql` files in mz-deploy projects via the
13//! Language Server Protocol (LSP). The server runs over stdio and supports
14//! nine capabilities:
15//!
16//! ## Go-to-definition
17//!
18//! Navigates from a SQL identifier (e.g., `foo` in `SELECT * FROM foo`) to the
19//! `.sql` file that defines it. Resolution uses two phases:
20//!
21//! 1. **Lexer-based identifier extraction** — Uses [`mz_sql_lexer::lexer::lex()`]
22//! to tokenize the file and find the identifier (possibly dot-qualified) at the
23//! cursor position.
24//! 2. **Project model lookup** — Resolves the identifier against the planned
25//! project model using `ObjectId::from_item_name()` conventions (1-part uses
26//! default db+schema from file path, 2-part uses default db, 3-part as-is).
27//!
28//! ## Find References
29//!
30//! Finds all project objects that depend on a given identifier. This is the
31//! inverse of go-to-definition: it answers "who uses this table/view/source?"
32//! by building the reverse dependency graph from `graph::Project`.
33//!
34//! ## Hover
35//!
36//! Shows the output schema (column names, types, nullability) for a referenced
37//! object when hovering over its identifier. Column data comes from the
38//! build artifact database (internal views) merged with `types.lock` (external
39//! dependencies). If no column data is available, the hover shows the object
40//! kind and source file path.
41//!
42//! ## Completion
43//!
44//! Two kinds of completions are provided:
45//!
46//! - **Keywords** — Static list from the lexer's keyword map, computed once at
47//! startup. Excluded when the typed prefix contains dots (qualified context).
48//! - **Object names** — Dynamic completions from the project model and external
49//! dependencies, computed per-request. Qualification level adapts to the
50//! dot-qualified prefix the user has already typed (0 dots = minimum, 1 dot =
51//! schema.object, 2+ dots = db.schema.object).
52//!
53//! ## Semantic Tokens
54//!
55//! Drives editor syntax coloring via `textDocument/semanticTokens/full`. The
56//! document is lexed with `mz_sql_lexer` and each token is mapped to a standard
57//! LSP token type (KEYWORD, STRING, NUMBER, OPERATOR, VARIABLE, PARAMETER,
58//! COMMENT). This covers Materialize-specific keywords that VS Code's built-in
59//! SQL grammar doesn't know about, so the editor's theme colors apply uniformly
60//! across the full Materialize keyword set.
61//!
62//! ## Document Symbols
63//!
64//! Returns the structural outline of a `.sql` file: the main CREATE statement
65//! as the root symbol, with supporting statements (indexes, grants, comments,
66//! unit tests) as children. Powers the editor's "Outline" view and breadcrumb
67//! navigation.
68//!
69//! ## Workspace Symbols
70//!
71//! Searches all objects in the project by name, enabling fuzzy-find across the
72//! entire workspace. Results include the object kind, file location, and a
73//! `database.schema` container label for grouping.
74//!
75//! ## Parse error diagnostics
76//!
77//! On every `didOpen` and `didChange`, the file is parsed with
78//! [`mz_sql_parser::parser::parse_statements()`]. Parse errors are converted to
79//! LSP diagnostics with correct line/column positions via a ropey `Rope`.
80//!
81//! ## Code Lens
82//!
83//! - **"Run Test"** above each `EXECUTE UNIT TEST` statement.
84//! - **"Explain"** above `CREATE MATERIALIZED VIEW` and named `CREATE INDEX`.
85//!
86//! ## Architecture
87//!
88//! ```text
89//! Editor ──stdio──▶ tower-lsp Server ──▶ Backend
90//! ├─ documents: per-file Rope (updated on change)
91//! ├─ project: graph::Project (rebuilt on save)
92//! ├─ project_cache: ProjectCache (rebuilt on save)
93//! ├─ profile_name: active connection profile
94//! └─ root: project root directory
95//! ```
96//!
97//! The project model rebuilds fully on `did_save` via `project::plan_sync()`.
98//! Parse diagnostics run per-file on every keystroke. Incremental updates may
99//! come later; the pipeline is fast enough for typical project sizes.
100
101mod code_action;
102mod code_lens;
103mod completion;
104pub mod diagnostics;
105mod document_symbol;
106pub mod functions;
107pub mod goto_definition;
108pub mod hover;
109mod references;
110mod run;
111mod semantic_tokens;
112mod server;
113mod symbol_kind;
114mod workspace_symbol;
115
116pub use run::run;