1use std::{
4 collections::{HashMap, HashSet, VecDeque},
5 ops::Range,
6};
7
8use crate::{Error, backend::Backend, language::Registry};
9
10mod injection;
11mod stream;
12
13pub(crate) use stream::walk;
14
15#[derive(Debug, Clone, Copy)]
17pub struct Edit {
18 pub start_byte: usize,
19 pub old_end_byte: usize,
20 pub new_end_byte: usize,
21 pub start_position: (usize, usize),
22 pub old_end_position: (usize, usize),
23 pub new_end_position: (usize, usize),
24}
25
26impl Edit {
27 pub(crate) fn between(old: &str, new: &str) -> Self {
28 let mut start = old
29 .bytes()
30 .zip(new.bytes())
31 .take_while(|(a, b)| a == b)
32 .count();
33 while !old.is_char_boundary(start) || !new.is_char_boundary(start) {
34 start -= 1;
35 }
36 let mut suffix = old[start..]
37 .bytes()
38 .rev()
39 .zip(new[start..].bytes().rev())
40 .take_while(|(a, b)| a == b)
41 .count();
42 while !old.is_char_boundary(old.len() - suffix) || !new.is_char_boundary(new.len() - suffix)
43 {
44 suffix -= 1;
45 }
46 let position = |source: &str, end: usize| {
47 let prefix = &source[..end];
48 (
49 prefix.bytes().filter(|byte| *byte == b'\n').count(),
50 end - prefix.rfind('\n').map_or(0, |index| index + 1),
51 )
52 };
53 Self {
54 start_byte: start,
55 old_end_byte: old.len() - suffix,
56 new_end_byte: new.len() - suffix,
57 start_position: position(old, start),
58 old_end_position: position(old, old.len() - suffix),
59 new_end_position: position(new, new.len() - suffix),
60 }
61 }
62}
63
64pub(crate) struct Layer<T> {
65 pub language: String,
66 pub ranges: Vec<Range<usize>>,
67 pub parent: Option<usize>,
68 pub depth: usize,
69 pub tree: T,
70}
71
72pub(crate) struct LayerView<'a, T> {
74 pub language: &'a str,
75 pub ranges: &'a [Range<usize>],
76 pub depth: usize,
77 pub tree: &'a T,
78}
79
80impl<T> Layer<T> {
81 pub fn view(&self) -> LayerView<'_, T> {
82 LayerView {
83 language: &self.language,
84 ranges: &self.ranges,
85 depth: self.depth,
86 tree: &self.tree,
87 }
88 }
89
90 pub(crate) fn adjust_ranges(&mut self, edit: &Edit) -> bool {
91 for range in &mut self.ranges {
92 if edit.old_end_byte < range.start {
93 range.start = range.start - edit.old_end_byte + edit.new_end_byte;
94 range.end = range.end - edit.old_end_byte + edit.new_end_byte;
95 } else if edit.start_byte > range.start && edit.old_end_byte < range.end {
96 range.end = range.end - edit.old_end_byte + edit.new_end_byte;
97 } else if edit.start_byte <= range.end {
98 return false;
100 }
101 }
102 true
103 }
104}
105
106pub(crate) struct Syntax<B: Backend> {
108 pub layers: Vec<Layer<B::Tree>>,
109}
110
111struct ParseRequest<'a> {
112 language: &'a str,
113 ranges: Vec<Range<usize>>,
114 parent: Option<usize>,
115 previous_parent: Option<usize>,
116 depth: usize,
117}
118
119impl<B: Backend> Syntax<B> {
120 pub fn parse(
121 backend: &mut B,
122 registry: &Registry<B>,
123 name: &str,
124 source: &str,
125 previous: Option<Self>,
126 edit: Option<&Edit>,
127 ) -> Result<Self, Error> {
128 let language = registry.resolve(name)?;
129 backend.prepare_source(source)?;
130 let mut previous: HashMap<_, _> = previous
131 .into_iter()
132 .flat_map(|syntax| syntax.layers)
133 .enumerate()
134 .filter_map(|(index, mut layer)| {
135 if layer.parent.is_none() {
136 layer.ranges = std::iter::once(0..source.len()).collect();
137 } else if edit.is_some_and(|edit| !layer.adjust_ranges(edit)) {
138 return None;
139 }
140 Some((
141 (layer.parent, layer.language, layer.ranges),
142 (index, layer.tree),
143 ))
144 })
145 .collect();
146 let mut requests = VecDeque::from([ParseRequest {
147 language,
148 ranges: std::iter::once(0..source.len()).collect(),
149 parent: None,
150 previous_parent: None,
151 depth: 0,
152 }]);
153 let mut seen = HashSet::new();
154 let mut layers: Vec<Layer<B::Tree>> = Vec::new();
155
156 while let Some(request) = requests.pop_front() {
157 if request.depth > 32 {
158 return Err(Error::InjectionDepth);
159 }
160 if !seen.insert((request.language, request.ranges.clone())) {
161 continue;
162 }
163 let (raw, language) = registry.language(backend, request.language)?;
164 let previous = if request.parent.is_none() {
165 previous.remove(&(None, request.language.to_owned(), request.ranges.clone()))
166 } else {
167 request.previous_parent.and_then(|parent| {
168 previous.remove(&(
169 Some(parent),
170 request.language.to_owned(),
171 request.ranges.clone(),
172 ))
173 })
174 };
175 let previous_index = previous.as_ref().map(|(index, _)| *index);
176 let tree = backend.parse_prepared(
177 raw,
178 source,
179 &request.ranges,
180 previous.map(|(_, tree)| tree),
181 edit,
182 )?;
183 let matches = language.injections.matches(backend, &tree, source)?;
184 let index = layers.len();
185 let parent_language = request
186 .parent
187 .map(|parent| layers[parent].language.as_str());
188 for injection in injection::collect(
189 &language.injections,
190 &matches,
191 source,
192 &request.ranges,
193 request.language,
194 parent_language,
195 ) {
196 if let Some((target, _)) = registry.get(injection.language) {
197 requests.push_back(ParseRequest {
198 language: target,
199 ranges: injection.ranges,
200 parent: Some(index),
201 previous_parent: previous_index,
202 depth: request.depth + 1,
203 });
204 }
205 }
206 layers.push(Layer {
207 language: request.language.to_owned(),
208 ranges: request.ranges,
209 parent: request.parent,
210 depth: request.depth,
211 tree,
212 });
213 }
214 Ok(Self { layers })
215 }
216}