jellybean_tree_sitter/
lib.rs

1#![doc = include_str!("./README.md")]
2
3pub mod ffi;
4mod util;
5
6#[cfg(unix)]
7use std::os::unix::io::AsRawFd;
8
9use std::{
10    char, error,
11    ffi::CStr,
12    fmt, hash, iter,
13    marker::PhantomData,
14    mem::MaybeUninit,
15    num::NonZeroU16,
16    ops,
17    os::raw::{c_char, c_void},
18    ptr::{self, NonNull},
19    slice, str,
20    sync::atomic::AtomicUsize,
21    u16,
22};
23
24/// The latest ABI version that is supported by the current version of the
25/// library.
26///
27/// When Languages are generated by the Tree-sitter CLI, they are
28/// assigned an ABI version number that corresponds to the current CLI version.
29/// The Tree-sitter library is generally backwards-compatible with languages
30/// generated using older CLI versions, but is not forwards-compatible.
31#[doc(alias = "TREE_SITTER_LANGUAGE_VERSION")]
32pub const LANGUAGE_VERSION: usize = ffi::TREE_SITTER_LANGUAGE_VERSION as usize;
33
34/// The earliest ABI version that is supported by the current version of the
35/// library.
36#[doc(alias = "TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION")]
37pub const MIN_COMPATIBLE_LANGUAGE_VERSION: usize =
38    ffi::TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION as usize;
39
40pub const PARSER_HEADER: &'static str = include_str!("../include/tree_sitter/parser.h");
41
42/// An opaque object that defines how to parse a particular language. The code for each
43/// `Language` is generated by the Tree-sitter CLI.
44#[doc(alias = "TSLanguage")]
45#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
46#[repr(transparent)]
47pub struct Language(*const ffi::TSLanguage);
48
49/// A tree that represents the syntactic structure of a source code file.
50#[doc(alias = "TSTree")]
51pub struct Tree(NonNull<ffi::TSTree>);
52
53/// A position in a multi-line text document, in terms of rows and columns.
54///
55/// Rows and columns are zero-based.
56#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
57pub struct Point {
58    pub row: usize,
59    pub column: usize,
60}
61
62/// A range of positions in a multi-line text document, both in terms of bytes and of
63/// rows and columns.
64#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
65pub struct Range {
66    pub start_byte: usize,
67    pub end_byte: usize,
68    pub start_point: Point,
69    pub end_point: Point,
70}
71
72/// A summary of a change to a text document.
73#[derive(Clone, Copy, Debug, PartialEq, Eq)]
74pub struct InputEdit {
75    pub start_byte: usize,
76    pub old_end_byte: usize,
77    pub new_end_byte: usize,
78    pub start_position: Point,
79    pub old_end_position: Point,
80    pub new_end_position: Point,
81}
82
83/// A single node within a syntax [`Tree`].
84#[doc(alias = "TSNode")]
85#[derive(Clone, Copy)]
86#[repr(transparent)]
87pub struct Node<'tree>(ffi::TSNode, PhantomData<&'tree ()>);
88
89/// A stateful object that this is used to produce a [`Tree`] based on some source code.
90#[doc(alias = "TSParser")]
91pub struct Parser(NonNull<ffi::TSParser>);
92
93/// A stateful object that is used to look up symbols valid in a specific parse state
94#[doc(alias = "TSLookaheadIterator")]
95pub struct LookaheadIterator(NonNull<ffi::TSLookaheadIterator>);
96struct LookaheadNamesIterator<'a>(&'a mut LookaheadIterator);
97
98/// A type of log message.
99#[derive(Debug, PartialEq, Eq)]
100pub enum LogType {
101    Parse,
102    Lex,
103}
104
105type FieldId = NonZeroU16;
106
107/// A callback that receives log messages during parser.
108type Logger<'a> = Box<dyn FnMut(LogType, &str) + 'a>;
109
110/// A stateful object for walking a syntax [`Tree`] efficiently.
111#[doc(alias = "TSTreeCursor")]
112pub struct TreeCursor<'cursor>(ffi::TSTreeCursor, PhantomData<&'cursor ()>);
113
114/// A set of patterns that match nodes in a syntax tree.
115#[doc(alias = "TSQuery")]
116#[derive(Debug)]
117pub struct Query {
118    ptr: NonNull<ffi::TSQuery>,
119    metadata: QueryMetadata,
120}
121
122#[derive(Debug, Default, Clone)]
123#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
124pub struct SerializableQuery(Vec<u8>, QueryMetadata);
125
126#[derive(Debug, Default, Clone)]
127#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
128pub struct QueryMetadata {
129    capture_names: Box<[String]>,
130    capture_quantifiers: Box<[Box<[CaptureQuantifier]>]>,
131    text_predicates: Box<[Box<[TextPredicateCapture]>]>,
132    property_settings: Box<[Box<[QueryProperty]>]>,
133    property_predicates: Box<[Box<[(QueryProperty, bool)]>]>,
134    general_predicates: Box<[Box<[QueryPredicate]>]>,
135}
136
137/// A quantifier for captures
138#[derive(Debug, PartialEq, Eq, Clone, Copy)]
139#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
140pub enum CaptureQuantifier {
141    Zero,
142    ZeroOrOne,
143    ZeroOrMore,
144    One,
145    OneOrMore,
146}
147
148impl From<ffi::TSQuantifier> for CaptureQuantifier {
149    fn from(value: ffi::TSQuantifier) -> Self {
150        match value {
151            ffi::TSQuantifierZero => CaptureQuantifier::Zero,
152            ffi::TSQuantifierZeroOrOne => CaptureQuantifier::ZeroOrOne,
153            ffi::TSQuantifierZeroOrMore => CaptureQuantifier::ZeroOrMore,
154            ffi::TSQuantifierOne => CaptureQuantifier::One,
155            ffi::TSQuantifierOneOrMore => CaptureQuantifier::OneOrMore,
156            _ => panic!("Unrecognized quantifier: {}", value),
157        }
158    }
159}
160
161/// A stateful object for executing a [`Query`] on a syntax [`Tree`].
162#[doc(alias = "TSQueryCursor")]
163pub struct QueryCursor {
164    ptr: NonNull<ffi::TSQueryCursor>,
165}
166
167/// A key-value pair associated with a particular pattern in a [`Query`].
168#[derive(Debug, PartialEq, Eq, Clone)]
169#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
170pub struct QueryProperty {
171    pub key: Box<str>,
172    pub value: Option<Box<str>>,
173    pub capture_id: Option<usize>,
174}
175
176#[derive(Debug, PartialEq, Eq, Clone)]
177#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
178pub enum QueryPredicateArg {
179    Capture(u32),
180    String(Box<str>),
181}
182
183/// A key-value pair associated with a particular pattern in a [`Query`].
184#[derive(Debug, PartialEq, Eq, Clone)]
185#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
186pub struct QueryPredicate {
187    pub operator: Box<str>,
188    pub args: Box<[QueryPredicateArg]>,
189}
190
191/// A match of a [`Query`] to a particular set of [`Node`]s.
192pub struct QueryMatch<'cursor, 'tree> {
193    pub pattern_index: usize,
194    pub captures: &'cursor [QueryCapture<'tree>],
195    id: u32,
196    cursor: *mut ffi::TSQueryCursor,
197}
198
199/// A sequence of [`QueryMatch`]es associated with a given [`QueryCursor`].
200pub struct QueryMatches<'query, 'cursor, T: TextProvider<I>, I: AsRef<[u8]>> {
201    ptr: *mut ffi::TSQueryCursor,
202    query: &'query Query,
203    text_provider: T,
204    buffer1: Vec<u8>,
205    buffer2: Vec<u8>,
206    _phantom: PhantomData<(&'cursor (), I)>,
207}
208
209/// A sequence of [`QueryCapture`]s associated with a given [`QueryCursor`].
210pub struct QueryCaptures<'query, 'cursor, T: TextProvider<I>, I: AsRef<[u8]>> {
211    ptr: *mut ffi::TSQueryCursor,
212    query: &'query Query,
213    text_provider: T,
214    buffer1: Vec<u8>,
215    buffer2: Vec<u8>,
216    _phantom: PhantomData<(&'cursor (), I)>,
217}
218
219pub trait TextProvider<I>
220where
221    I: AsRef<[u8]>,
222{
223    type I: Iterator<Item = I>;
224    fn text(&mut self, node: Node) -> Self::I;
225}
226
227/// A particular [`Node`] that has been captured with a particular name within a [`Query`].
228#[derive(Clone, Copy, Debug)]
229#[repr(C)]
230pub struct QueryCapture<'tree> {
231    pub node: Node<'tree>,
232    pub index: u32,
233}
234
235/// An error that occurred when trying to assign an incompatible [`Language`] to a [`Parser`].
236#[derive(Debug, PartialEq, Eq)]
237pub struct LanguageError {
238    version: usize,
239}
240
241/// An error that occured during (de)serialization
242#[derive(Debug, PartialEq, Eq)]
243pub enum SerializationError {
244    LanguageError(LanguageError),
245    AllocationError,
246    DeserializationError(QueryError),
247}
248
249/// An error that occurred in [`Parser::set_included_ranges`].
250#[derive(Debug, PartialEq, Eq)]
251pub struct IncludedRangesError(pub usize);
252
253/// An error that occurred when trying to create a [`Query`].
254#[derive(Debug, PartialEq, Eq)]
255pub struct QueryError {
256    pub row: usize,
257    pub column: usize,
258    pub offset: usize,
259    pub message: String,
260    pub kind: QueryErrorKind,
261}
262
263#[derive(Debug, PartialEq, Eq)]
264pub enum QueryErrorKind {
265    Syntax,
266    NodeType,
267    Field,
268    Capture,
269    Predicate,
270    Structure,
271    Language,
272}
273
274#[derive(Debug, Clone)]
275/// The first item is the capture index
276/// The next is capture specific, depending on what item is expected
277/// The first bool is if the capture is positive
278/// The last item is a bool signifying whether or not it's meant to match
279/// any or all captures
280#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
281enum TextPredicateCapture {
282    EqString(u32, Box<str>, bool, bool),
283    EqCapture(u32, u32, bool, bool),
284    MatchString(
285        u32,
286        #[cfg_attr(feature = "serde", serde(with = "serde_regex"))]
287        regex::bytes::Regex,
288        bool, bool
289    ),
290    AnyString(u32, Box<[Box<str>]>, bool),
291}
292
293// TODO: Remove this struct at at some point. If `core::str::lossy::Utf8Lossy`
294// is ever stabilized.
295pub struct LossyUtf8<'a> {
296    bytes: &'a [u8],
297    in_replacement: bool,
298}
299
300impl Language {
301    /// Get the ABI version number that indicates which version of the Tree-sitter CLI
302    /// that was used to generate this [`Language`].
303    #[doc(alias = "ts_language_version")]
304    pub fn version(&self) -> usize {
305        unsafe { ffi::ts_language_version(self.0) as usize }
306    }
307
308    /// Get the number of distinct node types in this language.
309    #[doc(alias = "ts_language_symbol_count")]
310    pub fn node_kind_count(&self) -> usize {
311        unsafe { ffi::ts_language_symbol_count(self.0) as usize }
312    }
313
314    /// Get the number of valid states in this language.
315    #[doc(alias = "ts_language_state_count")]
316    pub fn parse_state_count(&self) -> usize {
317        unsafe { ffi::ts_language_state_count(self.0) as usize }
318    }
319
320    /// Get the name of the node kind for the given numerical id.
321    #[doc(alias = "ts_language_symbol_name")]
322    pub fn node_kind_for_id(&self, id: u16) -> Option<&'static str> {
323        let ptr = unsafe { ffi::ts_language_symbol_name(self.0, id) };
324        (!ptr.is_null()).then(|| unsafe { CStr::from_ptr(ptr) }.to_str().unwrap())
325    }
326
327    /// Get the numeric id for the given node kind.
328    #[doc(alias = "ts_language_symbol_for_name")]
329    pub fn id_for_node_kind(&self, kind: &str, named: bool) -> u16 {
330        unsafe {
331            ffi::ts_language_symbol_for_name(
332                self.0,
333                kind.as_bytes().as_ptr() as *const c_char,
334                kind.len() as u32,
335                named,
336            )
337        }
338    }
339
340    /// Check if the node type for the given numerical id is named (as opposed
341    /// to an anonymous node type).
342    pub fn node_kind_is_named(&self, id: u16) -> bool {
343        unsafe { ffi::ts_language_symbol_type(self.0, id) == ffi::TSSymbolTypeRegular }
344    }
345
346    #[doc(alias = "ts_language_symbol_type")]
347    pub fn node_kind_is_visible(&self, id: u16) -> bool {
348        unsafe { ffi::ts_language_symbol_type(self.0, id) <= ffi::TSSymbolTypeAnonymous }
349    }
350
351    /// Get the number of distinct field names in this language.
352    #[doc(alias = "ts_language_field_count")]
353    pub fn field_count(&self) -> usize {
354        unsafe { ffi::ts_language_field_count(self.0) as usize }
355    }
356
357    /// Get the field names for the given numerical id.
358    #[doc(alias = "ts_language_field_name_for_id")]
359    pub fn field_name_for_id(&self, field_id: u16) -> Option<&'static str> {
360        let ptr = unsafe { ffi::ts_language_field_name_for_id(self.0, field_id) };
361        (!ptr.is_null()).then(|| unsafe { CStr::from_ptr(ptr) }.to_str().unwrap())
362    }
363
364    /// Get the numerical id for the given field name.
365    #[doc(alias = "ts_language_field_id_for_name")]
366    pub fn field_id_for_name(&self, field_name: impl AsRef<[u8]>) -> Option<FieldId> {
367        let field_name = field_name.as_ref();
368        let id = unsafe {
369            ffi::ts_language_field_id_for_name(
370                self.0,
371                field_name.as_ptr() as *const c_char,
372                field_name.len() as u32,
373            )
374        };
375        FieldId::new(id)
376    }
377
378    /// Get the next parse state. Combine this with
379    /// [`lookahead_iterator`](Language::lookahead_iterator) to
380    /// generate completion suggestions or valid symbols in error nodes.
381    ///
382    /// Example:
383    /// ```
384    /// let state = language.next_state(node.parse_state(), node.grammar_id());
385    /// ```
386    #[doc(alias = "ts_language_next_state")]
387    pub fn next_state(&self, state: u16, id: u16) -> u16 {
388        unsafe { ffi::ts_language_next_state(self.0, state, id) }
389    }
390
391    /// Create a new lookahead iterator for this language and parse state.
392    ///
393    /// This returns `None` if state is invalid for this language.
394    ///
395    /// Iterating [`LookaheadIterator`] will yield valid symbols in the given
396    /// parse state. Newly created lookahead iterators will return the `ERROR`
397    /// symbol from [`LookaheadIterator::current_symbol`].
398    ///
399    /// Lookahead iterators can be useful to generate suggestions and improve
400    /// syntax error diagnostics. To get symbols valid in an ERROR node, use the
401    /// lookahead iterator on its first leaf node state. For `MISSING` nodes, a
402    /// lookahead iterator created on the previous non-extra leaf node may be
403    /// appropriate.
404    #[doc(alias = "ts_lookahead_iterator_new")]
405    pub fn lookahead_iterator(&self, state: u16) -> Option<LookaheadIterator> {
406        let ptr = unsafe { ffi::ts_lookahead_iterator_new(self.0, state) };
407        (!ptr.is_null()).then(|| unsafe { LookaheadIterator::from_raw(ptr) })
408    }
409}
410
411impl Parser {
412    /// Create a new parser.
413    pub fn new() -> Parser {
414        unsafe {
415            let parser = ffi::ts_parser_new();
416            Parser(NonNull::new_unchecked(parser))
417        }
418    }
419
420    /// Set the language that the parser should use for parsing.
421    ///
422    /// Returns a Result indicating whether or not the language was successfully
423    /// assigned. True means assignment succeeded. False means there was a version
424    /// mismatch: the language was generated with an incompatible version of the
425    /// Tree-sitter CLI. Check the language's version using [`Language::version`]
426    /// and compare it to this library's [`LANGUAGE_VERSION`](LANGUAGE_VERSION) and
427    /// [`MIN_COMPATIBLE_LANGUAGE_VERSION`](MIN_COMPATIBLE_LANGUAGE_VERSION) constants.
428    #[doc(alias = "ts_parser_set_language")]
429    pub fn set_language(&mut self, language: Language) -> Result<(), LanguageError> {
430        let version = language.version();
431        if version < MIN_COMPATIBLE_LANGUAGE_VERSION || version > LANGUAGE_VERSION {
432            Err(LanguageError { version })
433        } else {
434            unsafe {
435                ffi::ts_parser_set_language(self.0.as_ptr(), language.0);
436            }
437            Ok(())
438        }
439    }
440
441    /// Get the parser's current language.
442    #[doc(alias = "ts_parser_language")]
443    pub fn language(&self) -> Option<Language> {
444        let ptr = unsafe { ffi::ts_parser_language(self.0.as_ptr()) };
445        (!ptr.is_null()).then(|| Language(ptr))
446    }
447
448    /// Get the parser's current logger.
449    #[doc(alias = "ts_parser_logger")]
450    pub fn logger(&self) -> Option<&Logger> {
451        let logger = unsafe { ffi::ts_parser_logger(self.0.as_ptr()) };
452        unsafe { (logger.payload as *mut Logger).as_ref() }
453    }
454
455    /// Set the logging callback that a parser should use during parsing.
456    #[doc(alias = "ts_parser_set_logger")]
457    pub fn set_logger(&mut self, logger: Option<Logger>) {
458        let prev_logger = unsafe { ffi::ts_parser_logger(self.0.as_ptr()) };
459        if !prev_logger.payload.is_null() {
460            drop(unsafe { Box::from_raw(prev_logger.payload as *mut Logger) });
461        }
462
463        let c_logger;
464        if let Some(logger) = logger {
465            let container = Box::new(logger);
466
467            unsafe extern "C" fn log(
468                payload: *mut c_void,
469                c_log_type: ffi::TSLogType,
470                c_message: *const c_char,
471            ) {
472                let callback = (payload as *mut Logger).as_mut().unwrap();
473                if let Ok(message) = CStr::from_ptr(c_message).to_str() {
474                    let log_type = if c_log_type == ffi::TSLogTypeParse {
475                        LogType::Parse
476                    } else {
477                        LogType::Lex
478                    };
479                    callback(log_type, message);
480                }
481            }
482
483            let raw_container = Box::into_raw(container);
484
485            c_logger = ffi::TSLogger {
486                payload: raw_container as *mut c_void,
487                log: Some(log),
488            };
489        } else {
490            c_logger = ffi::TSLogger {
491                payload: ptr::null_mut(),
492                log: None,
493            };
494        }
495
496        unsafe { ffi::ts_parser_set_logger(self.0.as_ptr(), c_logger) };
497    }
498
499    /// Set the destination to which the parser should write debugging graphs
500    /// during parsing. The graphs are formatted in the DOT language. You may want
501    /// to pipe these graphs directly to a `dot(1)` process in order to generate
502    /// SVG output.
503    #[cfg(unix)]
504    #[doc(alias = "ts_parser_print_dot_graphs")]
505    pub fn print_dot_graphs(&mut self, file: &impl AsRawFd) {
506        let fd = file.as_raw_fd();
507        unsafe { ffi::ts_parser_print_dot_graphs(self.0.as_ptr(), ffi::dup(fd)) }
508    }
509
510    /// Stop the parser from printing debugging graphs while parsing.
511    #[doc(alias = "ts_parser_print_dot_graphs")]
512    pub fn stop_printing_dot_graphs(&mut self) {
513        unsafe { ffi::ts_parser_print_dot_graphs(self.0.as_ptr(), -1) }
514    }
515
516    /// Parse a slice of UTF8 text.
517    ///
518    /// # Arguments:
519    /// * `text` The UTF8-encoded text to parse.
520    /// * `old_tree` A previous syntax tree parsed from the same document.
521    ///   If the text of the document has changed since `old_tree` was
522    ///   created, then you must edit `old_tree` to match the new text using
523    ///   [`Tree::edit`].
524    ///
525    /// Returns a [`Tree`] if parsing succeeded, or `None` if:
526    ///  * The parser has not yet had a language assigned with [`Parser::set_language`]
527    ///  * The timeout set with [`Parser::set_timeout_micros`] expired
528    ///  * The cancellation flag set with [`Parser::set_cancellation_flag`] was flipped
529    #[doc(alias = "ts_parser_parse")]
530    pub fn parse(&mut self, text: impl AsRef<[u8]>, old_tree: Option<&Tree>) -> Option<Tree> {
531        let bytes = text.as_ref();
532        let len = bytes.len();
533        self.parse_with(
534            &mut |i, _| (i < len).then(|| &bytes[i..]).unwrap_or_default(),
535            old_tree,
536        )
537    }
538
539    /// Parse a slice of UTF16 text.
540    ///
541    /// # Arguments:
542    /// * `text` The UTF16-encoded text to parse.
543    /// * `old_tree` A previous syntax tree parsed from the same document.
544    ///   If the text of the document has changed since `old_tree` was
545    ///   created, then you must edit `old_tree` to match the new text using
546    ///   [`Tree::edit`].
547    pub fn parse_utf16(
548        &mut self,
549        input: impl AsRef<[u16]>,
550        old_tree: Option<&Tree>,
551    ) -> Option<Tree> {
552        let code_points = input.as_ref();
553        let len = code_points.len();
554        self.parse_utf16_with(
555            &mut |i, _| (i < len).then(|| &code_points[i..]).unwrap_or_default(),
556            old_tree,
557        )
558    }
559
560    /// Parse UTF8 text provided in chunks by a callback.
561    ///
562    /// # Arguments:
563    /// * `callback` A function that takes a byte offset and position and
564    ///   returns a slice of UTF8-encoded text starting at that byte offset
565    ///   and position. The slices can be of any length. If the given position
566    ///   is at the end of the text, the callback should return an empty slice.
567    /// * `old_tree` A previous syntax tree parsed from the same document.
568    ///   If the text of the document has changed since `old_tree` was
569    ///   created, then you must edit `old_tree` to match the new text using
570    ///   [`Tree::edit`].
571    pub fn parse_with<T: AsRef<[u8]>, F: FnMut(usize, Point) -> T>(
572        &mut self,
573        callback: &mut F,
574        old_tree: Option<&Tree>,
575    ) -> Option<Tree> {
576        // A pointer to this payload is passed on every call to the `read` C function.
577        // The payload contains two things:
578        // 1. A reference to the rust `callback`.
579        // 2. The text that was returned from the previous call to `callback`.
580        //    This allows the callback to return owned values like vectors.
581        let mut payload: (&mut F, Option<T>) = (callback, None);
582
583        // This C function is passed to Tree-sitter as the input callback.
584        unsafe extern "C" fn read<T: AsRef<[u8]>, F: FnMut(usize, Point) -> T>(
585            payload: *mut c_void,
586            byte_offset: u32,
587            position: ffi::TSPoint,
588            bytes_read: *mut u32,
589        ) -> *const c_char {
590            let (callback, text) = (payload as *mut (&mut F, Option<T>)).as_mut().unwrap();
591            *text = Some(callback(byte_offset as usize, position.into()));
592            let slice = text.as_ref().unwrap().as_ref();
593            *bytes_read = slice.len() as u32;
594            return slice.as_ptr() as *const c_char;
595        }
596
597        let c_input = ffi::TSInput {
598            payload: &mut payload as *mut (&mut F, Option<T>) as *mut c_void,
599            read: Some(read::<T, F>),
600            encoding: ffi::TSInputEncodingUTF8,
601        };
602
603        let c_old_tree = old_tree.map_or(ptr::null_mut(), |t| t.0.as_ptr());
604        unsafe {
605            let c_new_tree = ffi::ts_parser_parse(self.0.as_ptr(), c_old_tree, c_input);
606            NonNull::new(c_new_tree).map(Tree)
607        }
608    }
609
610    /// Parse UTF16 text provided in chunks by a callback.
611    ///
612    /// # Arguments:
613    /// * `callback` A function that takes a code point offset and position and
614    ///   returns a slice of UTF16-encoded text starting at that byte offset
615    ///   and position. The slices can be of any length. If the given position
616    ///   is at the end of the text, the callback should return an empty slice.
617    /// * `old_tree` A previous syntax tree parsed from the same document.
618    ///   If the text of the document has changed since `old_tree` was
619    ///   created, then you must edit `old_tree` to match the new text using
620    ///   [`Tree::edit`].
621    pub fn parse_utf16_with<T: AsRef<[u16]>, F: FnMut(usize, Point) -> T>(
622        &mut self,
623        callback: &mut F,
624        old_tree: Option<&Tree>,
625    ) -> Option<Tree> {
626        // A pointer to this payload is passed on every call to the `read` C function.
627        // The payload contains two things:
628        // 1. A reference to the rust `callback`.
629        // 2. The text that was returned from the previous call to `callback`.
630        //    This allows the callback to return owned values like vectors.
631        let mut payload: (&mut F, Option<T>) = (callback, None);
632
633        // This C function is passed to Tree-sitter as the input callback.
634        unsafe extern "C" fn read<T: AsRef<[u16]>, F: FnMut(usize, Point) -> T>(
635            payload: *mut c_void,
636            byte_offset: u32,
637            position: ffi::TSPoint,
638            bytes_read: *mut u32,
639        ) -> *const c_char {
640            let (callback, text) = (payload as *mut (&mut F, Option<T>)).as_mut().unwrap();
641            *text = Some(callback(
642                (byte_offset / 2) as usize,
643                Point {
644                    row: position.row as usize,
645                    column: position.column as usize / 2,
646                },
647            ));
648            let slice = text.as_ref().unwrap().as_ref();
649            *bytes_read = slice.len() as u32 * 2;
650            slice.as_ptr() as *const c_char
651        }
652
653        let c_input = ffi::TSInput {
654            payload: &mut payload as *mut (&mut F, Option<T>) as *mut c_void,
655            read: Some(read::<T, F>),
656            encoding: ffi::TSInputEncodingUTF16,
657        };
658
659        let c_old_tree = old_tree.map_or(ptr::null_mut(), |t| t.0.as_ptr());
660        unsafe {
661            let c_new_tree = ffi::ts_parser_parse(self.0.as_ptr(), c_old_tree, c_input);
662            NonNull::new(c_new_tree).map(Tree)
663        }
664    }
665
666    /// Instruct the parser to start the next parse from the beginning.
667    ///
668    /// If the parser previously failed because of a timeout or a cancellation, then by default, it
669    /// will resume where it left off on the next call to [`parse`](Parser::parse) or other parsing
670    /// functions. If you don't want to resume, and instead intend to use this parser to parse some
671    /// other document, you must call `reset` first.
672    #[doc(alias = "ts_parser_reset")]
673    pub fn reset(&mut self) {
674        unsafe { ffi::ts_parser_reset(self.0.as_ptr()) }
675    }
676
677    /// Get the duration in microseconds that parsing is allowed to take.
678    ///
679    /// This is set via [`set_timeout_micros`](Parser::set_timeout_micros).
680    #[doc(alias = "ts_parser_timeout_micros")]
681    pub fn timeout_micros(&self) -> u64 {
682        unsafe { ffi::ts_parser_timeout_micros(self.0.as_ptr()) }
683    }
684
685    /// Set the maximum duration in microseconds that parsing should be allowed to
686    /// take before halting.
687    ///
688    /// If parsing takes longer than this, it will halt early, returning `None`.
689    /// See [`parse`](Parser::parse) for more information.
690    #[doc(alias = "ts_parser_set_timeout_micros")]
691    pub fn set_timeout_micros(&mut self, timeout_micros: u64) {
692        unsafe { ffi::ts_parser_set_timeout_micros(self.0.as_ptr(), timeout_micros) }
693    }
694
695    /// Set the ranges of text that the parser should include when parsing.
696    ///
697    /// By default, the parser will always include entire documents. This function
698    /// allows you to parse only a *portion* of a document but still return a syntax
699    /// tree whose ranges match up with the document as a whole. You can also pass
700    /// multiple disjoint ranges.
701    ///
702    /// If `ranges` is empty, then the entire document will be parsed. Otherwise,
703    /// the given ranges must be ordered from earliest to latest in the document,
704    /// and they must not overlap. That is, the following must hold for all
705    /// `i` < `length - 1`:
706    /// ```text
707    ///     ranges[i].end_byte <= ranges[i + 1].start_byte
708    /// ```
709    /// If this requirement is not satisfied, method will return IncludedRangesError
710    /// error with an offset in the passed ranges slice pointing to a first incorrect range.
711    #[doc(alias = "ts_parser_set_included_ranges")]
712    pub fn set_included_ranges(&mut self, ranges: &[Range]) -> Result<(), IncludedRangesError> {
713        let ts_ranges: Vec<ffi::TSRange> =
714            ranges.iter().cloned().map(|range| range.into()).collect();
715        let result = unsafe {
716            ffi::ts_parser_set_included_ranges(
717                self.0.as_ptr(),
718                ts_ranges.as_ptr(),
719                ts_ranges.len() as u32,
720            )
721        };
722
723        if result {
724            Ok(())
725        } else {
726            let mut prev_end_byte = 0;
727            for (i, range) in ranges.iter().enumerate() {
728                if range.start_byte < prev_end_byte || range.end_byte < range.start_byte {
729                    return Err(IncludedRangesError(i));
730                }
731                prev_end_byte = range.end_byte;
732            }
733            Err(IncludedRangesError(0))
734        }
735    }
736
737    /// Get the parser's current cancellation flag pointer.
738    #[doc(alias = "ts_parser_cancellation_flag")]
739    pub unsafe fn cancellation_flag(&self) -> Option<&AtomicUsize> {
740        (ffi::ts_parser_cancellation_flag(self.0.as_ptr()) as *const AtomicUsize).as_ref()
741    }
742
743    /// Set the parser's current cancellation flag pointer.
744    ///
745    /// If a pointer is assigned, then the parser will periodically read from
746    /// this pointer during parsing. If it reads a non-zero value, it will halt early,
747    /// returning `None`. See [`parse`](Parser::parse) for more information.
748    #[doc(alias = "ts_parser_set_cancellation_flag")]
749    pub unsafe fn set_cancellation_flag(&mut self, flag: Option<&AtomicUsize>) {
750        if let Some(flag) = flag {
751            ffi::ts_parser_set_cancellation_flag(
752                self.0.as_ptr(),
753                flag as *const AtomicUsize as *const usize,
754            );
755        } else {
756            ffi::ts_parser_set_cancellation_flag(self.0.as_ptr(), ptr::null());
757        }
758    }
759}
760
761impl Drop for Parser {
762    fn drop(&mut self) {
763        self.stop_printing_dot_graphs();
764        self.set_logger(None);
765        unsafe { ffi::ts_parser_delete(self.0.as_ptr()) }
766    }
767}
768
769impl Tree {
770    /// Get the root node of the syntax tree.
771    #[doc(alias = "ts_tree_root_node")]
772    pub fn root_node(&self) -> Node {
773        Node::new(unsafe { ffi::ts_tree_root_node(self.0.as_ptr()) }).unwrap()
774    }
775
776    /// Get the root node of the syntax tree, but with its position shifted
777    /// forward by the given offset.
778    #[doc(alias = "ts_tree_root_node_with_offset")]
779    pub fn root_node_with_offset(&self, offset_bytes: usize, offset_extent: Point) -> Node {
780        Node::new(unsafe {
781            ffi::ts_tree_root_node_with_offset(
782                self.0.as_ptr(),
783                offset_bytes as u32,
784                offset_extent.into(),
785            )
786        })
787        .unwrap()
788    }
789
790    /// Get the language that was used to parse the syntax tree.
791    #[doc(alias = "ts_tree_language")]
792    pub fn language(&self) -> Language {
793        Language(unsafe { ffi::ts_tree_language(self.0.as_ptr()) })
794    }
795
796    /// Edit the syntax tree to keep it in sync with source code that has been
797    /// edited.
798    ///
799    /// You must describe the edit both in terms of byte offsets and in terms of
800    /// row/column coordinates.
801    #[doc(alias = "ts_tree_edit")]
802    pub fn edit(&mut self, edit: &InputEdit) {
803        let edit = edit.into();
804        unsafe { ffi::ts_tree_edit(self.0.as_ptr(), &edit) };
805    }
806
807    /// Create a new [`TreeCursor`] starting from the root of the tree.
808    pub fn walk(&self) -> TreeCursor {
809        self.root_node().walk()
810    }
811
812    /// Compare this old edited syntax tree to a new syntax tree representing the same
813    /// document, returning a sequence of ranges whose syntactic structure has changed.
814    ///
815    /// For this to work correctly, this syntax tree must have been edited such that its
816    /// ranges match up to the new tree. Generally, you'll want to call this method right
817    /// after calling one of the [`Parser::parse`] functions. Call it on the old tree that
818    /// was passed to parse, and pass the new tree that was returned from `parse`.
819    #[doc(alias = "ts_tree_get_changed_ranges")]
820    pub fn changed_ranges(&self, other: &Tree) -> impl ExactSizeIterator<Item = Range> {
821        let mut count = 0u32;
822        unsafe {
823            let ptr = ffi::ts_tree_get_changed_ranges(
824                self.0.as_ptr(),
825                other.0.as_ptr(),
826                &mut count as *mut u32,
827            );
828            util::CBufferIter::new(ptr, count as usize).map(|r| r.into())
829        }
830    }
831
832    /// Get the included ranges that were used to parse the syntax tree.
833    pub fn included_ranges(&self) -> Vec<Range> {
834        let mut count = 0u32;
835        unsafe {
836            let ptr = ffi::ts_tree_included_ranges(self.0.as_ptr(), &mut count as *mut u32);
837            let ranges = slice::from_raw_parts(ptr, count as usize);
838            let result = ranges.iter().copied().map(|range| range.into()).collect();
839            (FREE_FN)(ptr as *mut c_void);
840            result
841        }
842    }
843
844    /// Print a graph of the tree to the given file descriptor.
845    /// The graph is formatted in the DOT language. You may want to pipe this graph
846    /// directly to a `dot(1)` process in order to generate SVG output.
847    #[cfg(unix)]
848    #[doc(alias = "ts_tree_print_dot_graph")]
849    pub fn print_dot_graph(&self, file: &impl AsRawFd) {
850        let fd = file.as_raw_fd();
851        unsafe { ffi::ts_tree_print_dot_graph(self.0.as_ptr(), fd) }
852    }
853}
854
855impl fmt::Debug for Tree {
856    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
857        write!(f, "{{Tree {:?}}}", self.root_node())
858    }
859}
860
861impl Drop for Tree {
862    fn drop(&mut self) {
863        unsafe { ffi::ts_tree_delete(self.0.as_ptr()) }
864    }
865}
866
867impl Clone for Tree {
868    fn clone(&self) -> Tree {
869        unsafe { Tree(NonNull::new_unchecked(ffi::ts_tree_copy(self.0.as_ptr()))) }
870    }
871}
872
873impl<'tree> Node<'tree> {
874    fn new(node: ffi::TSNode) -> Option<Self> {
875        (!node.id.is_null()).then(|| Node(node, PhantomData))
876    }
877
878    /// Get a numeric id for this node that is unique.
879    ///
880    /// Within a given syntax tree, no two nodes have the same id. However, if
881    /// a new tree is created based on an older tree, and a node from the old
882    /// tree is reused in the process, then that node will have the same id in
883    /// both trees.
884    pub fn id(&self) -> usize {
885        self.0.id as usize
886    }
887
888    /// Get this node's type as a numerical id.
889    #[doc(alias = "ts_node_symbol")]
890    pub fn kind_id(&self) -> u16 {
891        unsafe { ffi::ts_node_symbol(self.0) }
892    }
893
894    /// Get the node's type as a numerical id as it appears in the grammar
895    /// ignoring aliases.
896    #[doc(alias = "ts_node_grammar_symbol")]
897    pub fn grammar_id(&self) -> u16 {
898        unsafe { ffi::ts_node_grammar_symbol(self.0) }
899    }
900
901    /// Get this node's type as a string.
902    #[doc(alias = "ts_node_type")]
903    pub fn kind(&self) -> &'static str {
904        unsafe { CStr::from_ptr(ffi::ts_node_type(self.0)) }
905            .to_str()
906            .unwrap()
907    }
908
909    /// Get this node's symbol name as it appears in the grammar ignoring
910    /// aliases as a string.
911    #[doc(alias = "ts_node_grammar_type")]
912    pub fn grammar_name(&self) -> &'static str {
913        unsafe { CStr::from_ptr(ffi::ts_node_grammar_type(self.0)) }
914            .to_str()
915            .unwrap()
916    }
917
918    /// Get the [`Language`] that was used to parse this node's syntax tree.
919    #[doc(alias = "ts_node_language")]
920    pub fn language(&self) -> Language {
921        Language(unsafe { ffi::ts_node_language(self.0) })
922    }
923
924    /// Check if this node is *named*.
925    ///
926    /// Named nodes correspond to named rules in the grammar, whereas *anonymous* nodes
927    /// correspond to string literals in the grammar.
928    #[doc(alias = "ts_node_is_named")]
929    pub fn is_named(&self) -> bool {
930        unsafe { ffi::ts_node_is_named(self.0) }
931    }
932
933    /// Check if this node is *extra*.
934    ///
935    /// Extra nodes represent things like comments, which are not required the grammar,
936    /// but can appear anywhere.
937    #[doc(alias = "ts_node_is_extra")]
938    pub fn is_extra(&self) -> bool {
939        unsafe { ffi::ts_node_is_extra(self.0) }
940    }
941
942    /// Check if this node has been edited.
943    #[doc(alias = "ts_node_has_changes")]
944    pub fn has_changes(&self) -> bool {
945        unsafe { ffi::ts_node_has_changes(self.0) }
946    }
947
948    /// Check if this node represents a syntax error or contains any syntax errors anywhere
949    /// within it.
950    #[doc(alias = "ts_node_has_error")]
951    pub fn has_error(&self) -> bool {
952        unsafe { ffi::ts_node_has_error(self.0) }
953    }
954
955    /// Check if this node represents a syntax error.
956    ///
957    /// Syntax errors represent parts of the code that could not be incorporated into a
958    /// valid syntax tree.
959    #[doc(alias = "ts_node_is_error")]
960    pub fn is_error(&self) -> bool {
961        unsafe { ffi::ts_node_is_error(self.0) }
962    }
963
964    /// Get this node's parse state.
965    #[doc(alias = "ts_node_parse_state")]
966    pub fn parse_state(&self) -> u16 {
967        unsafe { ffi::ts_node_parse_state(self.0) }
968    }
969
970    /// Get the parse state after this node.
971    #[doc(alias = "ts_node_next_parse_state")]
972    pub fn next_parse_state(&self) -> u16 {
973        unsafe { ffi::ts_node_next_parse_state(self.0) }
974    }
975
976    /// Check if this node is *missing*.
977    ///
978    /// Missing nodes are inserted by the parser in order to recover from certain kinds of
979    /// syntax errors.
980    #[doc(alias = "ts_node_is_missing")]
981    pub fn is_missing(&self) -> bool {
982        unsafe { ffi::ts_node_is_missing(self.0) }
983    }
984
985    /// Get the byte offsets where this node starts.
986    #[doc(alias = "ts_node_start_byte")]
987    pub fn start_byte(&self) -> usize {
988        unsafe { ffi::ts_node_start_byte(self.0) as usize }
989    }
990
991    /// Get the byte offsets where this node end.
992    #[doc(alias = "ts_node_end_byte")]
993    pub fn end_byte(&self) -> usize {
994        unsafe { ffi::ts_node_end_byte(self.0) as usize }
995    }
996
997    /// Get the byte range of source code that this node represents.
998    pub fn byte_range(&self) -> std::ops::Range<usize> {
999        self.start_byte()..self.end_byte()
1000    }
1001
1002    /// Get the range of source code that this node represents, both in terms of raw bytes
1003    /// and of row/column coordinates.
1004    pub fn range(&self) -> Range {
1005        Range {
1006            start_byte: self.start_byte(),
1007            end_byte: self.end_byte(),
1008            start_point: self.start_position(),
1009            end_point: self.end_position(),
1010        }
1011    }
1012
1013    /// Get this node's start position in terms of rows and columns.
1014    #[doc(alias = "ts_node_start_point")]
1015    pub fn start_position(&self) -> Point {
1016        let result = unsafe { ffi::ts_node_start_point(self.0) };
1017        result.into()
1018    }
1019
1020    /// Get this node's end position in terms of rows and columns.
1021    #[doc(alias = "ts_node_end_point")]
1022    pub fn end_position(&self) -> Point {
1023        let result = unsafe { ffi::ts_node_end_point(self.0) };
1024        result.into()
1025    }
1026
1027    /// Get the node's child at the given index, where zero represents the first
1028    /// child.
1029    ///
1030    /// This method is fairly fast, but its cost is technically log(i), so you
1031    /// if you might be iterating over a long list of children, you should use
1032    /// [`Node::children`] instead.
1033    #[doc(alias = "ts_node_child")]
1034    pub fn child(&self, i: usize) -> Option<Self> {
1035        Self::new(unsafe { ffi::ts_node_child(self.0, i as u32) })
1036    }
1037
1038    /// Get this node's number of children.
1039    #[doc(alias = "ts_node_child_count")]
1040    pub fn child_count(&self) -> usize {
1041        unsafe { ffi::ts_node_child_count(self.0) as usize }
1042    }
1043
1044    /// Get this node's *named* child at the given index.
1045    ///
1046    /// See also [`Node::is_named`].
1047    /// This method is fairly fast, but its cost is technically log(i), so you
1048    /// if you might be iterating over a long list of children, you should use
1049    /// [`Node::named_children`] instead.
1050    #[doc(alias = "ts_node_named_child")]
1051    pub fn named_child(&self, i: usize) -> Option<Self> {
1052        Self::new(unsafe { ffi::ts_node_named_child(self.0, i as u32) })
1053    }
1054
1055    /// Get this node's number of *named* children.
1056    ///
1057    /// See also [`Node::is_named`].
1058    #[doc(alias = "ts_node_named_child_count")]
1059    pub fn named_child_count(&self) -> usize {
1060        unsafe { ffi::ts_node_named_child_count(self.0) as usize }
1061    }
1062
1063    /// Get the first child with the given field name.
1064    ///
1065    /// If multiple children may have the same field name, access them using
1066    /// [`children_by_field_name`](Node::children_by_field_name)
1067    #[doc(alias = "ts_node_child_by_field_name")]
1068    pub fn child_by_field_name(&self, field_name: impl AsRef<[u8]>) -> Option<Self> {
1069        let field_name = field_name.as_ref();
1070        Self::new(unsafe {
1071            ffi::ts_node_child_by_field_name(
1072                self.0,
1073                field_name.as_ptr() as *const c_char,
1074                field_name.len() as u32,
1075            )
1076        })
1077    }
1078
1079    /// Get this node's child with the given numerical field id.
1080    ///
1081    /// See also [`child_by_field_name`](Node::child_by_field_name). You can convert a field name to
1082    /// an id using [`Language::field_id_for_name`].
1083    #[doc(alias = "ts_node_child_by_field_id")]
1084    pub fn child_by_field_id(&self, field_id: u16) -> Option<Self> {
1085        Self::new(unsafe { ffi::ts_node_child_by_field_id(self.0, field_id) })
1086    }
1087
1088    /// Get the field name of this node's child at the given index.
1089    #[doc(alias = "ts_node_field_name_for_child")]
1090    pub fn field_name_for_child(&self, child_index: u32) -> Option<&'static str> {
1091        unsafe {
1092            let ptr = ffi::ts_node_field_name_for_child(self.0, child_index);
1093            (!ptr.is_null()).then(|| CStr::from_ptr(ptr).to_str().unwrap())
1094        }
1095    }
1096
1097    /// Iterate over this node's children.
1098    ///
1099    /// A [`TreeCursor`] is used to retrieve the children efficiently. Obtain
1100    /// a [`TreeCursor`] by calling [`Tree::walk`] or [`Node::walk`]. To avoid unnecessary
1101    /// allocations, you should reuse the same cursor for subsequent calls to
1102    /// this method.
1103    ///
1104    /// If you're walking the tree recursively, you may want to use the [`TreeCursor`]
1105    /// APIs directly instead.
1106    pub fn children<'cursor>(
1107        &self,
1108        cursor: &'cursor mut TreeCursor<'tree>,
1109    ) -> impl ExactSizeIterator<Item = Node<'tree>> + 'cursor {
1110        cursor.reset(*self);
1111        cursor.goto_first_child();
1112        (0..self.child_count()).into_iter().map(move |_| {
1113            let result = cursor.node();
1114            cursor.goto_next_sibling();
1115            result
1116        })
1117    }
1118
1119    /// Iterate over this node's named children.
1120    ///
1121    /// See also [`Node::children`].
1122    pub fn named_children<'cursor>(
1123        &self,
1124        cursor: &'cursor mut TreeCursor<'tree>,
1125    ) -> impl ExactSizeIterator<Item = Node<'tree>> + 'cursor {
1126        cursor.reset(*self);
1127        cursor.goto_first_child();
1128        (0..self.named_child_count()).into_iter().map(move |_| {
1129            while !cursor.node().is_named() {
1130                if !cursor.goto_next_sibling() {
1131                    break;
1132                }
1133            }
1134            let result = cursor.node();
1135            cursor.goto_next_sibling();
1136            result
1137        })
1138    }
1139
1140    /// Iterate over this node's children with a given field name.
1141    ///
1142    /// See also [`Node::children`].
1143    pub fn children_by_field_name<'cursor>(
1144        &self,
1145        field_name: &str,
1146        cursor: &'cursor mut TreeCursor<'tree>,
1147    ) -> impl Iterator<Item = Node<'tree>> + 'cursor {
1148        let field_id = self.language().field_id_for_name(field_name);
1149        let mut done = field_id.is_none();
1150        if !done {
1151            cursor.reset(*self);
1152            cursor.goto_first_child();
1153        }
1154        iter::from_fn(move || {
1155            if !done {
1156                while cursor.field_id() != field_id {
1157                    if !cursor.goto_next_sibling() {
1158                        return None;
1159                    }
1160                }
1161                let result = cursor.node();
1162                if !cursor.goto_next_sibling() {
1163                    done = true;
1164                }
1165                return Some(result);
1166            }
1167            None
1168        })
1169    }
1170
1171    /// Iterate over this node's children with a given field id.
1172    ///
1173    /// See also [`Node::children_by_field_name`].
1174    pub fn children_by_field_id<'cursor>(
1175        &self,
1176        field_id: FieldId,
1177        cursor: &'cursor mut TreeCursor<'tree>,
1178    ) -> impl Iterator<Item = Node<'tree>> + 'cursor {
1179        cursor.reset(*self);
1180        cursor.goto_first_child();
1181        let mut done = false;
1182        iter::from_fn(move || {
1183            if !done {
1184                while cursor.field_id() != Some(field_id) {
1185                    if !cursor.goto_next_sibling() {
1186                        return None;
1187                    }
1188                }
1189                let result = cursor.node();
1190                if !cursor.goto_next_sibling() {
1191                    done = true;
1192                }
1193                return Some(result);
1194            }
1195            None
1196        })
1197    }
1198
1199    /// Get this node's immediate parent.
1200    #[doc(alias = "ts_node_parent")]
1201    pub fn parent(&self) -> Option<Self> {
1202        Self::new(unsafe { ffi::ts_node_parent(self.0) })
1203    }
1204
1205    /// Get this node's next sibling.
1206    #[doc(alias = "ts_node_next_sibling")]
1207    pub fn next_sibling(&self) -> Option<Self> {
1208        Self::new(unsafe { ffi::ts_node_next_sibling(self.0) })
1209    }
1210
1211    /// Get this node's previous sibling.
1212    #[doc(alias = "ts_node_prev_sibling")]
1213    pub fn prev_sibling(&self) -> Option<Self> {
1214        Self::new(unsafe { ffi::ts_node_prev_sibling(self.0) })
1215    }
1216
1217    /// Get this node's next named sibling.
1218    #[doc(alias = "ts_node_next_named_sibling")]
1219    pub fn next_named_sibling(&self) -> Option<Self> {
1220        Self::new(unsafe { ffi::ts_node_next_named_sibling(self.0) })
1221    }
1222
1223    /// Get this node's previous named sibling.
1224    #[doc(alias = "ts_node_prev_named_sibling")]
1225    pub fn prev_named_sibling(&self) -> Option<Self> {
1226        Self::new(unsafe { ffi::ts_node_prev_named_sibling(self.0) })
1227    }
1228
1229    /// Get the node's number of descendants, including one for the node itself.
1230    #[doc(alias = "ts_node_descendant_count")]
1231    pub fn descendant_count(&self) -> usize {
1232        unsafe { ffi::ts_node_descendant_count(self.0) as usize }
1233    }
1234
1235    /// Get the smallest node within this node that spans the given range.
1236    #[doc(alias = "ts_node_descendant_for_byte_range")]
1237    pub fn descendant_for_byte_range(&self, start: usize, end: usize) -> Option<Self> {
1238        Self::new(unsafe {
1239            ffi::ts_node_descendant_for_byte_range(self.0, start as u32, end as u32)
1240        })
1241    }
1242
1243    /// Get the smallest named node within this node that spans the given range.
1244    #[doc(alias = "ts_node_named_descendant_for_byte_range")]
1245    pub fn named_descendant_for_byte_range(&self, start: usize, end: usize) -> Option<Self> {
1246        Self::new(unsafe {
1247            ffi::ts_node_named_descendant_for_byte_range(self.0, start as u32, end as u32)
1248        })
1249    }
1250
1251    /// Get the smallest node within this node that spans the given range.
1252    #[doc(alias = "ts_node_descendant_for_point_range")]
1253    pub fn descendant_for_point_range(&self, start: Point, end: Point) -> Option<Self> {
1254        Self::new(unsafe {
1255            ffi::ts_node_descendant_for_point_range(self.0, start.into(), end.into())
1256        })
1257    }
1258
1259    /// Get the smallest named node within this node that spans the given range.
1260    #[doc(alias = "ts_node_named_descendant_for_point_range")]
1261    pub fn named_descendant_for_point_range(&self, start: Point, end: Point) -> Option<Self> {
1262        Self::new(unsafe {
1263            ffi::ts_node_named_descendant_for_point_range(self.0, start.into(), end.into())
1264        })
1265    }
1266
1267    #[doc(alias = "ts_node_string")]
1268    pub fn to_sexp(&self) -> String {
1269        let c_string = unsafe { ffi::ts_node_string(self.0) };
1270        let result = unsafe { CStr::from_ptr(c_string) }
1271            .to_str()
1272            .unwrap()
1273            .to_string();
1274        unsafe { (FREE_FN)(c_string as *mut c_void) };
1275        result
1276    }
1277
1278    pub fn utf8_text<'a>(&self, source: &'a [u8]) -> Result<&'a str, str::Utf8Error> {
1279        str::from_utf8(&source[self.start_byte()..self.end_byte()])
1280    }
1281
1282    pub fn utf16_text<'a>(&self, source: &'a [u16]) -> &'a [u16] {
1283        &source.as_ref()[self.start_byte()..self.end_byte()]
1284    }
1285
1286    /// Create a new [`TreeCursor`] starting from this node.
1287    #[doc(alias = "ts_tree_cursor_new")]
1288    pub fn walk(&self) -> TreeCursor<'tree> {
1289        TreeCursor(unsafe { ffi::ts_tree_cursor_new(self.0) }, PhantomData)
1290    }
1291
1292    /// Edit this node to keep it in-sync with source code that has been edited.
1293    ///
1294    /// This function is only rarely needed. When you edit a syntax tree with the
1295    /// [`Tree::edit`] method, all of the nodes that you retrieve from the tree
1296    /// afterward will already reflect the edit. You only need to use [`Node::edit`]
1297    /// when you have a specific [`Node`] instance that you want to keep and continue
1298    /// to use after an edit.
1299    #[doc(alias = "ts_node_edit")]
1300    pub fn edit(&mut self, edit: &InputEdit) {
1301        let edit = edit.into();
1302        unsafe { ffi::ts_node_edit(&mut self.0 as *mut ffi::TSNode, &edit) }
1303    }
1304}
1305
1306impl PartialEq for Node<'_> {
1307    fn eq(&self, other: &Self) -> bool {
1308        self.0.id == other.0.id
1309    }
1310}
1311
1312impl Eq for Node<'_> {}
1313
1314impl hash::Hash for Node<'_> {
1315    fn hash<H: hash::Hasher>(&self, state: &mut H) {
1316        self.0.id.hash(state);
1317        self.0.context[0].hash(state);
1318        self.0.context[1].hash(state);
1319        self.0.context[2].hash(state);
1320        self.0.context[3].hash(state);
1321    }
1322}
1323
1324impl fmt::Debug for Node<'_> {
1325    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1326        write!(
1327            f,
1328            "{{Node {} {} - {}}}",
1329            self.kind(),
1330            self.start_position(),
1331            self.end_position()
1332        )
1333    }
1334}
1335
1336impl<'cursor> TreeCursor<'cursor> {
1337    /// Get the tree cursor's current [`Node`].
1338    #[doc(alias = "ts_tree_cursor_current_node")]
1339    pub fn node(&self) -> Node<'cursor> {
1340        Node(
1341            unsafe { ffi::ts_tree_cursor_current_node(&self.0) },
1342            PhantomData,
1343        )
1344    }
1345
1346    /// Get the numerical field id of this tree cursor's current node.
1347    ///
1348    /// See also [`field_name`](TreeCursor::field_name).
1349    #[doc(alias = "ts_tree_cursor_current_field_id")]
1350    pub fn field_id(&self) -> Option<FieldId> {
1351        let id = unsafe { ffi::ts_tree_cursor_current_field_id(&self.0) };
1352        FieldId::new(id)
1353    }
1354
1355    /// Get the field name of this tree cursor's current node.
1356    #[doc(alias = "ts_tree_cursor_current_field_name")]
1357    pub fn field_name(&self) -> Option<&'static str> {
1358        unsafe {
1359            let ptr = ffi::ts_tree_cursor_current_field_name(&self.0);
1360            (!ptr.is_null()).then(|| CStr::from_ptr(ptr).to_str().unwrap())
1361        }
1362    }
1363
1364    /// Get the numerical field id of this tree cursor's current node.
1365    ///
1366    /// See also [`field_name`](TreeCursor::field_name).
1367    #[doc(alias = "ts_tree_cursor_current_depth")]
1368    pub fn depth(&self) -> u32 {
1369        unsafe { ffi::ts_tree_cursor_current_depth(&self.0) }
1370    }
1371
1372    /// Get the index of the cursor's current node out of all of the
1373    /// descendants of the original node that the cursor was constructed with
1374    #[doc(alias = "ts_tree_cursor_current_descendant_index")]
1375    pub fn descendant_index(&self) -> usize {
1376        unsafe { ffi::ts_tree_cursor_current_descendant_index(&self.0) as usize }
1377    }
1378
1379    /// Move this cursor to the first child of its current node.
1380    ///
1381    /// This returns `true` if the cursor successfully moved, and returns `false`
1382    /// if there were no children.
1383    #[doc(alias = "ts_tree_cursor_goto_first_child")]
1384    pub fn goto_first_child(&mut self) -> bool {
1385        return unsafe { ffi::ts_tree_cursor_goto_first_child(&mut self.0) };
1386    }
1387
1388    /// Move this cursor to the last child of its current node.
1389    ///
1390    /// This returns `true` if the cursor successfully moved, and returns
1391    /// `false` if there were no children.
1392    ///
1393    /// Note that this function may be slower than
1394    /// [`goto_first_child`](TreeCursor::goto_first_child) because it needs to
1395    /// iterate through all the children to compute the child's position.
1396    #[doc(alias = "ts_tree_cursor_goto_last_child")]
1397    pub fn goto_last_child(&mut self) -> bool {
1398        return unsafe { ffi::ts_tree_cursor_goto_last_child(&mut self.0) };
1399    }
1400
1401    /// Move this cursor to the parent of its current node.
1402    ///
1403    /// This returns `true` if the cursor successfully moved, and returns `false`
1404    /// if there was no parent node (the cursor was already on the root node).
1405    #[doc(alias = "ts_tree_cursor_goto_parent")]
1406    pub fn goto_parent(&mut self) -> bool {
1407        return unsafe { ffi::ts_tree_cursor_goto_parent(&mut self.0) };
1408    }
1409
1410    /// Move this cursor to the next sibling of its current node.
1411    ///
1412    /// This returns `true` if the cursor successfully moved, and returns `false`
1413    /// if there was no next sibling node.
1414    #[doc(alias = "ts_tree_cursor_goto_next_sibling")]
1415    pub fn goto_next_sibling(&mut self) -> bool {
1416        return unsafe { ffi::ts_tree_cursor_goto_next_sibling(&mut self.0) };
1417    }
1418
1419    /// Move the cursor to the node that is the nth descendant of
1420    /// the original node that the cursor was constructed with, where
1421    /// zero represents the original node itself.
1422    #[doc(alias = "ts_tree_cursor_goto_descendant")]
1423    pub fn goto_descendant(&mut self, descendant_index: usize) {
1424        return unsafe {
1425            ffi::ts_tree_cursor_goto_descendant(&mut self.0, descendant_index as u32)
1426        };
1427    }
1428
1429    /// Move this cursor to the previous sibling of its current node.
1430    ///
1431    /// This returns `true` if the cursor successfully moved, and returns
1432    /// `false` if there was no previous sibling node.
1433    ///
1434    /// Note, that this function may be slower than
1435    /// [`goto_next_sibling`](TreeCursor::goto_next_sibling) due to how node
1436    /// positions are stored. In the worst case, this will need to iterate
1437    /// through all the children upto the previous sibling node to recalculate
1438    /// its position.
1439    #[doc(alias = "ts_tree_cursor_goto_previous_sibling")]
1440    pub fn goto_previous_sibling(&mut self) -> bool {
1441        return unsafe { ffi::ts_tree_cursor_goto_previous_sibling(&mut self.0) };
1442    }
1443
1444    /// Move this cursor to the first child of its current node that extends beyond
1445    /// the given byte offset.
1446    ///
1447    /// This returns the index of the child node if one was found, and returns `None`
1448    /// if no such child was found.
1449    #[doc(alias = "ts_tree_cursor_goto_first_child_for_byte")]
1450    pub fn goto_first_child_for_byte(&mut self, index: usize) -> Option<usize> {
1451        let result =
1452            unsafe { ffi::ts_tree_cursor_goto_first_child_for_byte(&mut self.0, index as u32) };
1453        (result >= 0).then_some(result as usize)
1454    }
1455
1456    /// Move this cursor to the first child of its current node that extends beyond
1457    /// the given byte offset.
1458    ///
1459    /// This returns the index of the child node if one was found, and returns `None`
1460    /// if no such child was found.
1461    #[doc(alias = "ts_tree_cursor_goto_first_child_for_point")]
1462    pub fn goto_first_child_for_point(&mut self, point: Point) -> Option<usize> {
1463        let result =
1464            unsafe { ffi::ts_tree_cursor_goto_first_child_for_point(&mut self.0, point.into()) };
1465        (result >= 0).then_some(result as usize)
1466    }
1467
1468    /// Re-initialize this tree cursor to start at a different node.
1469    #[doc(alias = "ts_tree_cursor_reset")]
1470    pub fn reset(&mut self, node: Node<'cursor>) {
1471        unsafe { ffi::ts_tree_cursor_reset(&mut self.0, node.0) };
1472    }
1473
1474    /// Re-initialize a tree cursor to the same position as another cursor.
1475    ///
1476    /// Unlike [`reset`](TreeCursor::reset), this will not lose parent information and
1477    /// allows reusing already created cursors.
1478    #[doc(alias = "ts_tree_cursor_reset_to")]
1479    pub fn reset_to(&mut self, cursor: TreeCursor<'cursor>) {
1480        unsafe { ffi::ts_tree_cursor_reset_to(&mut self.0, &cursor.0) };
1481    }
1482}
1483
1484impl Clone for TreeCursor<'_> {
1485    fn clone(&self) -> Self {
1486        TreeCursor(unsafe { ffi::ts_tree_cursor_copy(&self.0) }, PhantomData)
1487    }
1488}
1489
1490impl Drop for TreeCursor<'_> {
1491    fn drop(&mut self) {
1492        unsafe { ffi::ts_tree_cursor_delete(&mut self.0) }
1493    }
1494}
1495
1496impl LookaheadIterator {
1497    /// Get the current language of the lookahead iterator.
1498    #[doc(alias = "ts_lookahead_iterator_language")]
1499    pub fn language(&self) -> Language {
1500        Language(unsafe { ffi::ts_lookahead_iterator_language(self.0.as_ptr()) })
1501    }
1502
1503    /// Get the current symbol of the lookahead iterator.
1504    #[doc(alias = "ts_lookahead_iterator_current_symbol")]
1505    pub fn current_symbol(&self) -> u16 {
1506        unsafe { ffi::ts_lookahead_iterator_current_symbol(self.0.as_ptr()) }
1507    }
1508
1509    /// Get the current symbol name of the lookahead iterator.
1510    #[doc(alias = "ts_lookahead_iterator_current_symbol_name")]
1511    pub fn current_symbol_name(&self) -> &'static str {
1512        unsafe {
1513            CStr::from_ptr(ffi::ts_lookahead_iterator_current_symbol_name(
1514                self.0.as_ptr(),
1515            ))
1516            .to_str()
1517            .unwrap()
1518        }
1519    }
1520
1521    /// Reset the lookahead iterator.
1522    ///
1523    /// This returns `true` if the language was set successfully and `false`
1524    /// otherwise.
1525    #[doc(alias = "ts_lookahead_iterator_reset")]
1526    pub fn reset(&mut self, language: Language, state: u16) -> bool {
1527        unsafe { ffi::ts_lookahead_iterator_reset(self.0.as_ptr(), language.0, state) }
1528    }
1529
1530    /// Reset the lookahead iterator to another state.
1531    ///
1532    /// This returns `true` if the iterator was reset to the given state and `false`
1533    /// otherwise.
1534    #[doc(alias = "ts_lookahead_iterator_reset_state")]
1535    pub fn reset_state(&mut self, state: u16) -> bool {
1536        unsafe { ffi::ts_lookahead_iterator_reset_state(self.0.as_ptr(), state) }
1537    }
1538
1539    /// Iterate symbol names.
1540    pub fn iter_names(&mut self) -> impl Iterator<Item = &'static str> + '_ {
1541        LookaheadNamesIterator(self)
1542    }
1543}
1544
1545impl Iterator for LookaheadNamesIterator<'_> {
1546    type Item = &'static str;
1547
1548    #[doc(alias = "ts_lookahead_iterator_next")]
1549    fn next(&mut self) -> Option<Self::Item> {
1550        unsafe { ffi::ts_lookahead_iterator_next(self.0 .0.as_ptr()) }
1551            .then(|| self.0.current_symbol_name())
1552    }
1553}
1554
1555impl Iterator for LookaheadIterator {
1556    type Item = u16;
1557
1558    #[doc(alias = "ts_lookahead_iterator_next")]
1559    fn next(&mut self) -> Option<Self::Item> {
1560        // the first symbol is always `0` so we can safely skip it
1561        unsafe { ffi::ts_lookahead_iterator_next(self.0.as_ptr()) }.then(|| self.current_symbol())
1562    }
1563}
1564
1565impl Drop for LookaheadIterator {
1566    #[doc(alias = "ts_lookahead_iterator_delete")]
1567    fn drop(&mut self) {
1568        unsafe { ffi::ts_lookahead_iterator_delete(self.0.as_ptr()) }
1569    }
1570}
1571
1572impl Query {
1573    /// Create a new query from a string containing one or more S-expression
1574    /// patterns.
1575    ///
1576    /// The query is associated with a particular language, and can only be run
1577    /// on syntax nodes parsed with that language. References to Queries can be
1578    /// shared between multiple threads.
1579    pub fn new(language: Language, source: &str) -> Result<Self, QueryError> {
1580        let mut error_offset = 0u32;
1581        let mut error_type: ffi::TSQueryError = 0;
1582        let bytes = source.as_bytes();
1583
1584        // Compile the query.
1585        let ptr = unsafe {
1586            ffi::ts_query_new(
1587                language.0,
1588                bytes.as_ptr() as *const c_char,
1589                bytes.len() as u32,
1590                &mut error_offset as *mut u32,
1591                &mut error_type as *mut ffi::TSQueryError,
1592            )
1593        };
1594
1595        // On failure, build an error based on the error code and offset.
1596        if ptr.is_null() {
1597            if error_type == ffi::TSQueryErrorLanguage {
1598                return Err(QueryError {
1599                    row: 0,
1600                    column: 0,
1601                    offset: 0,
1602                    message: LanguageError {
1603                        version: language.version(),
1604                    }
1605                    .to_string(),
1606                    kind: QueryErrorKind::Language,
1607                });
1608            }
1609
1610            let offset = error_offset as usize;
1611            let mut line_start = 0;
1612            let mut row = 0;
1613            let mut line_containing_error = None;
1614            for line in source.split("\n") {
1615                let line_end = line_start + line.len() + 1;
1616                if line_end > offset {
1617                    line_containing_error = Some(line);
1618                    break;
1619                }
1620                line_start = line_end;
1621                row += 1;
1622            }
1623            let column = offset - line_start;
1624
1625            let kind;
1626            let message;
1627            match error_type {
1628                // Error types that report names
1629                ffi::TSQueryErrorNodeType | ffi::TSQueryErrorField | ffi::TSQueryErrorCapture => {
1630                    let suffix = source.split_at(offset).1;
1631                    let end_offset = suffix
1632                        .find(|c| !char::is_alphanumeric(c) && c != '_' && c != '-')
1633                        .unwrap_or(suffix.len());
1634                    message = suffix.split_at(end_offset).0.to_string();
1635                    kind = match error_type {
1636                        ffi::TSQueryErrorNodeType => QueryErrorKind::NodeType,
1637                        ffi::TSQueryErrorField => QueryErrorKind::Field,
1638                        ffi::TSQueryErrorCapture => QueryErrorKind::Capture,
1639                        _ => unreachable!(),
1640                    };
1641                }
1642
1643                // Error types that report positions
1644                _ => {
1645                    message = if let Some(line) = line_containing_error {
1646                        line.to_string() + "\n" + &" ".repeat(offset - line_start) + "^"
1647                    } else {
1648                        "Unexpected EOF".to_string()
1649                    };
1650                    kind = match error_type {
1651                        ffi::TSQueryErrorStructure => QueryErrorKind::Structure,
1652                        _ => QueryErrorKind::Syntax,
1653                    };
1654                }
1655            };
1656
1657            return Err(QueryError {
1658                row,
1659                column,
1660                offset,
1661                kind,
1662                message,
1663            });
1664        }
1665
1666        unsafe { Query::from_raw_parts(ptr, source) }
1667    }
1668
1669    #[doc(hidden)]
1670    unsafe fn from_raw_parts(ptr: *mut ffi::TSQuery, source: &str) -> Result<Self, QueryError> {
1671        let ptr = {
1672            struct TSQueryDrop(*mut ffi::TSQuery);
1673            impl Drop for TSQueryDrop {
1674                fn drop(&mut self) {
1675                    unsafe { ffi::ts_query_delete(self.0) }
1676                }
1677            }
1678            TSQueryDrop(ptr)
1679        };
1680
1681        let string_count = unsafe { ffi::ts_query_string_count(ptr.0) };
1682        let capture_count = unsafe { ffi::ts_query_capture_count(ptr.0) };
1683        let pattern_count = unsafe { ffi::ts_query_pattern_count(ptr.0) as usize };
1684
1685        let mut capture_names = Vec::with_capacity(capture_count as usize);
1686        let mut capture_quantifiers_vec = Vec::with_capacity(pattern_count as usize);
1687        let mut text_predicates_vec = Vec::with_capacity(pattern_count);
1688        let mut property_predicates_vec = Vec::with_capacity(pattern_count);
1689        let mut property_settings_vec = Vec::with_capacity(pattern_count);
1690        let mut general_predicates_vec = Vec::with_capacity(pattern_count);
1691
1692        // Build a vector of strings to store the capture names.
1693        for i in 0..capture_count {
1694            unsafe {
1695                let mut length = 0u32;
1696                let name = ffi::ts_query_capture_name_for_id(ptr.0, i, &mut length as *mut u32)
1697                    as *const u8;
1698                let name = slice::from_raw_parts(name, length as usize);
1699                let name = str::from_utf8_unchecked(name);
1700                capture_names.push(name.to_string());
1701            }
1702        }
1703
1704        // Build a vector to store capture qunatifiers.
1705        for i in 0..pattern_count {
1706            let mut capture_quantifiers = Vec::with_capacity(capture_count as usize);
1707            for j in 0..capture_count {
1708                unsafe {
1709                    let quantifier = ffi::ts_query_capture_quantifier_for_id(ptr.0, i as u32, j);
1710                    capture_quantifiers.push(quantifier.into());
1711                }
1712            }
1713            capture_quantifiers_vec.push(capture_quantifiers.into());
1714        }
1715
1716        // Build a vector of strings to represent literal values used in predicates.
1717        let string_values = (0..string_count)
1718            .map(|i| unsafe {
1719                let mut length = 0u32;
1720                let value =
1721                    ffi::ts_query_string_value_for_id(ptr.0, i as u32, &mut length as *mut u32)
1722                        as *const u8;
1723                let value = slice::from_raw_parts(value, length as usize);
1724                let value = str::from_utf8_unchecked(value);
1725                value
1726            })
1727            .collect::<Vec<_>>();
1728
1729        // Build a vector of predicates for each pattern.
1730        for i in 0..pattern_count {
1731            let predicate_steps = unsafe {
1732                let mut length = 0u32;
1733                let raw_predicates =
1734                    ffi::ts_query_predicates_for_pattern(ptr.0, i as u32, &mut length as *mut u32);
1735                (length > 0)
1736                    .then(|| slice::from_raw_parts(raw_predicates, length as usize))
1737                    .unwrap_or_default()
1738            };
1739
1740            let byte_offset = unsafe { ffi::ts_query_start_byte_for_pattern(ptr.0, i as u32) };
1741            let row = source
1742                .char_indices()
1743                .take_while(|(i, _)| *i < byte_offset as usize)
1744                .filter(|(_, c)| *c == '\n')
1745                .count();
1746
1747            use ffi::TSQueryPredicateStepType as T;
1748            const TYPE_DONE: T = ffi::TSQueryPredicateStepTypeDone;
1749            const TYPE_CAPTURE: T = ffi::TSQueryPredicateStepTypeCapture;
1750            const TYPE_STRING: T = ffi::TSQueryPredicateStepTypeString;
1751
1752            let mut text_predicates = Vec::new();
1753            let mut property_predicates = Vec::new();
1754            let mut property_settings = Vec::new();
1755            let mut general_predicates = Vec::new();
1756            for p in predicate_steps.split(|s| s.type_ == TYPE_DONE) {
1757                if p.is_empty() {
1758                    continue;
1759                }
1760
1761                if p[0].type_ != TYPE_STRING {
1762                    return Err(predicate_error(
1763                        row,
1764                        format!(
1765                            "Expected predicate to start with a function name. Got @{}.",
1766                            capture_names[p[0].value_id as usize],
1767                        ),
1768                    ));
1769                }
1770
1771                // Build a predicate for each of the known predicate function names.
1772                let operator_name = string_values[p[0].value_id as usize];
1773                match operator_name {
1774                    "eq?" | "not-eq?" | "any-eq?" | "any-not-eq?" => {
1775                        if p.len() != 3 {
1776                            return Err(predicate_error(
1777                                row,
1778                                format!(
1779                                "Wrong number of arguments to #eq? predicate. Expected 2, got {}.",
1780                                p.len() - 1
1781                            ),
1782                            ));
1783                        }
1784                        if p[1].type_ != TYPE_CAPTURE {
1785                            return Err(predicate_error(row, format!(
1786                                "First argument to #eq? predicate must be a capture name. Got literal \"{}\".",
1787                                string_values[p[1].value_id as usize],
1788                            )));
1789                        }
1790
1791                        let is_positive = operator_name == "eq?" || operator_name == "any-eq?";
1792                        let match_all = match operator_name {
1793                            "eq?" | "not-eq?" => true,
1794                            "any-eq?" | "any-not-eq?" => false,
1795                            _ => unreachable!(),
1796                        };
1797                        text_predicates.push(if p[2].type_ == TYPE_CAPTURE {
1798                            TextPredicateCapture::EqCapture(
1799                                p[1].value_id,
1800                                p[2].value_id,
1801                                is_positive,
1802                                match_all,
1803                            )
1804                        } else {
1805                            TextPredicateCapture::EqString(
1806                                p[1].value_id,
1807                                string_values[p[2].value_id as usize].to_string().into(),
1808                                is_positive,
1809                                match_all,
1810                            )
1811                        });
1812                    }
1813
1814                    "match?" | "not-match?" | "any-match?" | "any-not-match?" => {
1815                        if p.len() != 3 {
1816                            return Err(predicate_error(row, format!(
1817                                "Wrong number of arguments to #match? predicate. Expected 2, got {}.",
1818                                p.len() - 1
1819                            )));
1820                        }
1821                        if p[1].type_ != TYPE_CAPTURE {
1822                            return Err(predicate_error(row, format!(
1823                                "First argument to #match? predicate must be a capture name. Got literal \"{}\".",
1824                                string_values[p[1].value_id as usize],
1825                            )));
1826                        }
1827                        if p[2].type_ == TYPE_CAPTURE {
1828                            return Err(predicate_error(row, format!(
1829                                "Second argument to #match? predicate must be a literal. Got capture @{}.",
1830                                capture_names[p[2].value_id as usize],
1831                            )));
1832                        }
1833
1834                        let is_positive =
1835                            operator_name == "match?" || operator_name == "any-match?";
1836                        let match_all = match operator_name {
1837                            "match?" | "not-match?" => true,
1838                            "any-match?" | "any-not-match?" => false,
1839                            _ => unreachable!(),
1840                        };
1841                        let regex = &string_values[p[2].value_id as usize];
1842                        text_predicates.push(TextPredicateCapture::MatchString(
1843                            p[1].value_id,
1844                            regex::bytes::Regex::new(regex).map_err(|_| {
1845                                predicate_error(row, format!("Invalid regex '{}'", regex))
1846                            })?,
1847                            is_positive,
1848                            match_all,
1849                        ));
1850                    }
1851
1852                    "set!" => property_settings.push(Self::parse_property(
1853                        row,
1854                        &operator_name,
1855                        &capture_names,
1856                        &string_values,
1857                        &p[1..],
1858                    )?),
1859
1860                    "is?" | "is-not?" => property_predicates.push((
1861                        Self::parse_property(
1862                            row,
1863                            &operator_name,
1864                            &capture_names,
1865                            &string_values,
1866                            &p[1..],
1867                        )?,
1868                        operator_name == "is?",
1869                    )),
1870
1871                    "any-of?" | "not-any-of?" => {
1872                        if p.len() < 2 {
1873                            return Err(predicate_error(row, format!(
1874                                "Wrong number of arguments to #any-of? predicate. Expected at least 1, got {}.",
1875                                p.len() - 1
1876                            )));
1877                        }
1878                        if p[1].type_ != TYPE_CAPTURE {
1879                            return Err(predicate_error(row, format!(
1880                                "First argument to #any-of? predicate must be a capture name. Got literal \"{}\".",
1881                                string_values[p[1].value_id as usize],
1882                            )));
1883                        }
1884
1885                        let is_positive = operator_name == "any-of?";
1886                        let mut values = Vec::new();
1887                        for arg in &p[2..] {
1888                            if arg.type_ == TYPE_CAPTURE {
1889                                return Err(predicate_error(row, format!(
1890                                    "Arguments to #any-of? predicate must be literals. Got capture @{}.",
1891                                    capture_names[arg.value_id as usize],
1892                                )));
1893                            }
1894                            values.push(string_values[arg.value_id as usize]);
1895                        }
1896                        text_predicates.push(TextPredicateCapture::AnyString(
1897                            p[1].value_id,
1898                            values
1899                                .iter()
1900                                .map(|x| x.to_string().into())
1901                                .collect::<Vec<_>>()
1902                                .into(),
1903                            is_positive,
1904                        ));
1905                    }
1906
1907                    _ => general_predicates.push(QueryPredicate {
1908                        operator: operator_name.to_string().into(),
1909                        args: p[1..]
1910                            .iter()
1911                            .map(|a| {
1912                                if a.type_ == TYPE_CAPTURE {
1913                                    QueryPredicateArg::Capture(a.value_id)
1914                                } else {
1915                                    QueryPredicateArg::String(
1916                                        string_values[a.value_id as usize].to_string().into(),
1917                                    )
1918                                }
1919                            })
1920                            .collect(),
1921                    }),
1922                }
1923            }
1924
1925            text_predicates_vec.push(text_predicates.into());
1926            property_predicates_vec.push(property_predicates.into());
1927            property_settings_vec.push(property_settings.into());
1928            general_predicates_vec.push(general_predicates.into());
1929        }
1930
1931        let result = Query {
1932            ptr: unsafe { NonNull::new_unchecked(ptr.0) },
1933            metadata: QueryMetadata {
1934                capture_names: capture_names.into(),
1935                capture_quantifiers: capture_quantifiers_vec.into(),
1936                text_predicates: text_predicates_vec.into(),
1937                property_predicates: property_predicates_vec.into(),
1938                property_settings: property_settings_vec.into(),
1939                general_predicates: general_predicates_vec.into(),
1940            },
1941        };
1942
1943        std::mem::forget(ptr);
1944
1945        Ok(result)
1946    }
1947
1948    /// Get the byte offset where the given pattern starts in the query's source.
1949    #[doc(alias = "ts_query_start_byte_for_pattern")]
1950    pub fn start_byte_for_pattern(&self, pattern_index: usize) -> usize {
1951        if pattern_index >= self.text_predicates.len() {
1952            panic!(
1953                "Pattern index is {} but the pattern count is {}",
1954                pattern_index,
1955                self.text_predicates.len(),
1956            );
1957        }
1958        unsafe {
1959            ffi::ts_query_start_byte_for_pattern(self.ptr.as_ptr(), pattern_index as u32) as usize
1960        }
1961    }
1962
1963    /// Get the number of patterns in the query.
1964    #[doc(alias = "ts_query_pattern_count")]
1965    pub fn pattern_count(&self) -> usize {
1966        unsafe { ffi::ts_query_pattern_count(self.ptr.as_ptr()) as usize }
1967    }
1968
1969    /// Get the names of the captures used in the query.
1970    pub fn capture_names(&self) -> &[String] {
1971        &self.capture_names
1972    }
1973
1974    /// Get the quantifiers of the captures used in the query.
1975    pub fn capture_quantifiers(&self, index: usize) -> &[CaptureQuantifier] {
1976        &self.capture_quantifiers[index]
1977    }
1978
1979    /// Get the index for a given capture name.
1980    pub fn capture_index_for_name(&self, name: &str) -> Option<u32> {
1981        self.capture_names
1982            .iter()
1983            .position(|n| *n == name)
1984            .map(|ix| ix as u32)
1985    }
1986
1987    /// Get the properties that are checked for the given pattern index.
1988    ///
1989    /// This includes predicates with the operators `is?` and `is-not?`.
1990    pub fn property_predicates(&self, index: usize) -> &[(QueryProperty, bool)] {
1991        &self.property_predicates[index]
1992    }
1993
1994    /// Get the properties that are set for the given pattern index.
1995    ///
1996    /// This includes predicates with the operator `set!`.
1997    pub fn property_settings(&self, index: usize) -> &[QueryProperty] {
1998        &self.property_settings[index]
1999    }
2000
2001    /// Get the other user-defined predicates associated with the given index.
2002    ///
2003    /// This includes predicate with operators other than:
2004    /// * `match?`
2005    /// * `eq?` and `not-eq?`
2006    /// * `is?` and `is-not?`
2007    /// * `set!`
2008    pub fn general_predicates(&self, index: usize) -> &[QueryPredicate] {
2009        &self.general_predicates[index]
2010    }
2011
2012    /// Disable a certain capture within a query.
2013    ///
2014    /// This prevents the capture from being returned in matches, and also avoids any
2015    /// resource usage associated with recording the capture.
2016    #[doc(alias = "ts_query_disable_capture")]
2017    pub fn disable_capture(&mut self, name: &str) {
2018        unsafe {
2019            ffi::ts_query_disable_capture(
2020                self.ptr.as_ptr(),
2021                name.as_bytes().as_ptr() as *const c_char,
2022                name.len() as u32,
2023            );
2024        }
2025    }
2026
2027    /// Disable a certain pattern within a query.
2028    ///
2029    /// This prevents the pattern from matching, and also avoids any resource usage
2030    /// associated with the pattern.
2031    #[doc(alias = "ts_query_disable_pattern")]
2032    pub fn disable_pattern(&mut self, index: usize) {
2033        unsafe { ffi::ts_query_disable_pattern(self.ptr.as_ptr(), index as u32) }
2034    }
2035
2036    /// Check if a given pattern within a query has a single root node.
2037    #[doc(alias = "ts_query_is_pattern_rooted")]
2038    pub fn is_pattern_rooted(&self, index: usize) -> bool {
2039        unsafe { ffi::ts_query_is_pattern_rooted(self.ptr.as_ptr(), index as u32) }
2040    }
2041
2042    /// Check if a given pattern within a query has a single root node.
2043    #[doc(alias = "ts_query_is_pattern_non_local")]
2044    pub fn is_pattern_non_local(&self, index: usize) -> bool {
2045        unsafe { ffi::ts_query_is_pattern_non_local(self.ptr.as_ptr(), index as u32) }
2046    }
2047
2048    /// Check if a given step in a query is 'definite'.
2049    ///
2050    /// A query step is 'definite' if its parent pattern will be guaranteed to match
2051    /// successfully once it reaches the step.
2052    #[doc(alias = "ts_query_is_pattern_guaranteed_at_step")]
2053    pub fn is_pattern_guaranteed_at_step(&self, byte_offset: usize) -> bool {
2054        unsafe {
2055            ffi::ts_query_is_pattern_guaranteed_at_step(self.ptr.as_ptr(), byte_offset as u32)
2056        }
2057    }
2058
2059    fn parse_property(
2060        row: usize,
2061        function_name: &str,
2062        capture_names: &[String],
2063        string_values: &[&str],
2064        args: &[ffi::TSQueryPredicateStep],
2065    ) -> Result<QueryProperty, QueryError> {
2066        if args.len() == 0 || args.len() > 3 {
2067            return Err(predicate_error(
2068                row,
2069                format!(
2070                    "Wrong number of arguments to {} predicate. Expected 1 to 3, got {}.",
2071                    function_name,
2072                    args.len(),
2073                ),
2074            ));
2075        }
2076
2077        let mut capture_id = None;
2078        let mut key = None;
2079        let mut value = None;
2080
2081        for arg in args {
2082            if arg.type_ == ffi::TSQueryPredicateStepTypeCapture {
2083                if capture_id.is_some() {
2084                    return Err(predicate_error(
2085                        row,
2086                        format!(
2087                            "Invalid arguments to {} predicate. Unexpected second capture name @{}",
2088                            function_name, capture_names[arg.value_id as usize]
2089                        ),
2090                    ));
2091                }
2092                capture_id = Some(arg.value_id as usize);
2093            } else if key.is_none() {
2094                key = Some(&string_values[arg.value_id as usize]);
2095            } else if value.is_none() {
2096                value = Some(string_values[arg.value_id as usize]);
2097            } else {
2098                return Err(predicate_error(
2099                    row,
2100                    format!(
2101                        "Invalid arguments to {} predicate. Unexpected third argument @{}",
2102                        function_name, string_values[arg.value_id as usize]
2103                    ),
2104                ));
2105            }
2106        }
2107
2108        if let Some(key) = key {
2109            Ok(QueryProperty::new(key, value, capture_id))
2110        } else {
2111            return Err(predicate_error(
2112                row,
2113                format!(
2114                    "Invalid arguments to {} predicate. Missing key argument",
2115                    function_name,
2116                ),
2117            ));
2118        }
2119    }
2120
2121    /// Convert `self` into a serializable version of itself.
2122    #[doc(alias = "ts_query_serialize")]
2123    pub fn serializable(mut self) -> Result<SerializableQuery, SerializationError> {
2124        let mut size: usize = 0;
2125        let ptr = unsafe { ffi::ts_query_serialize(self.ptr.as_ptr(), &mut size) };
2126        if ptr.is_null() {
2127            Err(SerializationError::AllocationError)
2128        } else {
2129            let slice = unsafe { slice::from_raw_parts(ptr as *const u8, size) };
2130            let vec = slice.to_vec();
2131            unsafe { (FREE_FN)(ptr as *mut c_void) };
2132            let metadata = std::mem::replace(&mut self.metadata, QueryMetadata::default());
2133            Ok(SerializableQuery(vec, metadata))
2134        }
2135    }
2136
2137    /// Deserialize the serializable version of a query.
2138    #[doc(alias = "ts_query_deserialize")]
2139    pub fn deserialize(
2140        data: SerializableQuery,
2141        language: Language,
2142    ) -> Result<Self, SerializationError> {
2143        let version = language.version();
2144        if version < MIN_COMPATIBLE_LANGUAGE_VERSION || version > LANGUAGE_VERSION {
2145            Err(SerializationError::LanguageError(LanguageError { version }))
2146        } else {
2147            let ptr = unsafe {
2148                let data_ptr = data.0.as_slice().as_ptr() as *const c_char;
2149                ffi::ts_query_deserialize(data_ptr, language.0)
2150            };
2151            if ptr.is_null() {
2152                Err(SerializationError::AllocationError)
2153            } else {
2154                Ok(Query {
2155                    ptr: unsafe { NonNull::new_unchecked(ptr) },
2156                    metadata: data.1,
2157                })
2158            }
2159        }
2160    }
2161}
2162
2163impl QueryCursor {
2164    /// Create a new cursor for executing a given query.
2165    ///
2166    /// The cursor stores the state that is needed to iteratively search for matches.
2167    #[doc(alias = "ts_query_cursor_new")]
2168    pub fn new() -> Self {
2169        QueryCursor {
2170            ptr: unsafe { NonNull::new_unchecked(ffi::ts_query_cursor_new()) },
2171        }
2172    }
2173
2174    /// Return the maximum number of in-progress matches for this cursor.
2175    #[doc(alias = "ts_query_cursor_match_limit")]
2176    pub fn match_limit(&self) -> u32 {
2177        unsafe { ffi::ts_query_cursor_match_limit(self.ptr.as_ptr()) }
2178    }
2179
2180    /// Set the maximum number of in-progress matches for this cursor.  The limit must be > 0 and
2181    /// <= 65536.
2182    #[doc(alias = "ts_query_cursor_set_match_limit")]
2183    pub fn set_match_limit(&mut self, limit: u32) {
2184        unsafe {
2185            ffi::ts_query_cursor_set_match_limit(self.ptr.as_ptr(), limit);
2186        }
2187    }
2188
2189    /// Check if, on its last execution, this cursor exceeded its maximum number of
2190    /// in-progress matches.
2191    #[doc(alias = "ts_query_cursor_did_exceed_match_limit")]
2192    pub fn did_exceed_match_limit(&self) -> bool {
2193        unsafe { ffi::ts_query_cursor_did_exceed_match_limit(self.ptr.as_ptr()) }
2194    }
2195
2196    /// Iterate over all of the matches in the order that they were found.
2197    ///
2198    /// Each match contains the index of the pattern that matched, and a list of captures.
2199    /// Because multiple patterns can match the same set of nodes, one match may contain
2200    /// captures that appear *before* some of the captures from a previous match.
2201    #[doc(alias = "ts_query_cursor_exec")]
2202    pub fn matches<'query, 'tree, T: TextProvider<I>, I: AsRef<[u8]>>(
2203        &mut self,
2204        query: &'query Query,
2205        node: Node<'tree>,
2206        text_provider: T,
2207    ) -> QueryMatches<'query, 'tree, T, I> {
2208        let ptr = self.ptr.as_ptr();
2209        unsafe { ffi::ts_query_cursor_exec(ptr, query.ptr.as_ptr(), node.0) };
2210        QueryMatches {
2211            ptr,
2212            query,
2213            text_provider,
2214            buffer1: Default::default(),
2215            buffer2: Default::default(),
2216            _phantom: PhantomData,
2217        }
2218    }
2219
2220    /// Iterate over all of the individual captures in the order that they appear.
2221    ///
2222    /// This is useful if you don't care about which pattern matched, and just want a single,
2223    /// ordered sequence of captures.
2224    #[doc(alias = "ts_query_cursor_exec")]
2225    pub fn captures<'query, 'tree, T: TextProvider<I>, I: AsRef<[u8]>>(
2226        &mut self,
2227        query: &'query Query,
2228        node: Node<'tree>,
2229        text_provider: T,
2230    ) -> QueryCaptures<'query, 'tree, T, I> {
2231        let ptr = self.ptr.as_ptr();
2232        unsafe { ffi::ts_query_cursor_exec(ptr, query.ptr.as_ptr(), node.0) };
2233        QueryCaptures {
2234            ptr,
2235            query,
2236            text_provider,
2237            buffer1: Default::default(),
2238            buffer2: Default::default(),
2239            _phantom: PhantomData,
2240        }
2241    }
2242
2243    /// Set the range in which the query will be executed, in terms of byte offsets.
2244    #[doc(alias = "ts_query_cursor_set_byte_range")]
2245    pub fn set_byte_range(&mut self, range: ops::Range<usize>) -> &mut Self {
2246        unsafe {
2247            ffi::ts_query_cursor_set_byte_range(
2248                self.ptr.as_ptr(),
2249                range.start as u32,
2250                range.end as u32,
2251            );
2252        }
2253        self
2254    }
2255
2256    /// Set the range in which the query will be executed, in terms of rows and columns.
2257    #[doc(alias = "ts_query_cursor_set_point_range")]
2258    pub fn set_point_range(&mut self, range: ops::Range<Point>) -> &mut Self {
2259        unsafe {
2260            ffi::ts_query_cursor_set_point_range(
2261                self.ptr.as_ptr(),
2262                range.start.into(),
2263                range.end.into(),
2264            );
2265        }
2266        self
2267    }
2268
2269    /// Set the maximum start depth for a query cursor.
2270    ///
2271    /// This prevents cursors from exploring children nodes at a certain depth.
2272    /// Note if a pattern includes many children, then they will still be checked.
2273    ///
2274    /// The zero max start depth value can be used as a special behavior and
2275    /// it helps to destructure a subtree by staying on a node and using captures
2276    /// for interested parts. Note that the zero max start depth only limit a search
2277    /// depth for a pattern's root node but other nodes that are parts of the pattern
2278    /// may be searched at any depth what defined by the pattern structure.
2279    ///
2280    /// Set to `None` to remove the maximum start depth.
2281    #[doc(alias = "ts_query_cursor_set_max_start_depth")]
2282    pub fn set_max_start_depth(&mut self, max_start_depth: Option<u32>) -> &mut Self {
2283        unsafe {
2284            ffi::ts_query_cursor_set_max_start_depth(
2285                self.ptr.as_ptr(),
2286                max_start_depth.unwrap_or(u32::MAX),
2287            );
2288        }
2289        self
2290    }
2291}
2292
2293impl<'tree> QueryMatch<'_, 'tree> {
2294    pub fn id(&self) -> u32 {
2295        self.id
2296    }
2297
2298    #[doc(alias = "ts_query_cursor_remove_match")]
2299    pub fn remove(self) {
2300        unsafe { ffi::ts_query_cursor_remove_match(self.cursor, self.id) }
2301    }
2302
2303    pub fn nodes_for_capture_index(
2304        &self,
2305        capture_ix: u32,
2306    ) -> impl Iterator<Item = Node<'tree>> + '_ {
2307        self.captures
2308            .iter()
2309            .filter_map(move |capture| (capture.index == capture_ix).then_some(capture.node))
2310    }
2311
2312    fn new(m: ffi::TSQueryMatch, cursor: *mut ffi::TSQueryCursor) -> Self {
2313        QueryMatch {
2314            cursor,
2315            id: m.id,
2316            pattern_index: m.pattern_index as usize,
2317            captures: (m.capture_count > 0)
2318                .then(|| unsafe {
2319                    slice::from_raw_parts(
2320                        m.captures as *const QueryCapture<'tree>,
2321                        m.capture_count as usize,
2322                    )
2323                })
2324                .unwrap_or_default(),
2325        }
2326    }
2327
2328    fn satisfies_text_predicates<I: AsRef<[u8]>>(
2329        &self,
2330        query: &Query,
2331        buffer1: &mut Vec<u8>,
2332        buffer2: &mut Vec<u8>,
2333        text_provider: &mut impl TextProvider<I>,
2334    ) -> bool {
2335        struct NodeText<'a, T> {
2336            buffer: &'a mut Vec<u8>,
2337            first_chunk: Option<T>,
2338        }
2339        impl<'a, T: AsRef<[u8]>> NodeText<'a, T> {
2340            fn new(buffer: &'a mut Vec<u8>) -> Self {
2341                Self {
2342                    buffer,
2343                    first_chunk: None,
2344                }
2345            }
2346
2347            fn get_text(&mut self, chunks: &mut impl Iterator<Item = T>) -> &[u8] {
2348                self.first_chunk = chunks.next();
2349                if let Some(next_chunk) = chunks.next() {
2350                    self.buffer.clear();
2351                    self.buffer
2352                        .extend_from_slice(self.first_chunk.as_ref().unwrap().as_ref());
2353                    self.buffer.extend_from_slice(next_chunk.as_ref());
2354                    for chunk in chunks {
2355                        self.buffer.extend_from_slice(chunk.as_ref());
2356                    }
2357                    self.buffer.as_slice()
2358                } else if let Some(ref first_chunk) = self.first_chunk {
2359                    first_chunk.as_ref()
2360                } else {
2361                    Default::default()
2362                }
2363            }
2364        }
2365
2366        let mut node_text1 = NodeText::new(buffer1);
2367        let mut node_text2 = NodeText::new(buffer2);
2368
2369        query.text_predicates[self.pattern_index]
2370            .iter()
2371            .all(|predicate| match predicate {
2372                TextPredicateCapture::EqCapture(i, j, is_positive, match_all_nodes) => {
2373                    let mut nodes_1 = self.nodes_for_capture_index(*i);
2374                    let mut nodes_2 = self.nodes_for_capture_index(*j);
2375                    while let (Some(node1), Some(node2)) = (nodes_1.next(), nodes_2.next()) {
2376                        let mut text1 = text_provider.text(node1);
2377                        let mut text2 = text_provider.text(node2);
2378                        let text1 = node_text1.get_text(&mut text1);
2379                        let text2 = node_text2.get_text(&mut text2);
2380                        if (text1 == text2) != *is_positive && *match_all_nodes {
2381                            return false;
2382                        }
2383                        if (text1 == text2) == *is_positive && !*match_all_nodes {
2384                            return true;
2385                        }
2386                    }
2387                    nodes_1.next().is_none() && nodes_2.next().is_none()
2388                }
2389                TextPredicateCapture::EqString(i, s, is_positive, match_all_nodes) => {
2390                    let nodes = self.nodes_for_capture_index(*i);
2391                    for node in nodes {
2392                        let mut text = text_provider.text(node);
2393                        let text = node_text1.get_text(&mut text);
2394                        if (text == s.as_bytes()) != *is_positive && *match_all_nodes {
2395                            return false;
2396                        }
2397                        if (text == s.as_bytes()) == *is_positive && !*match_all_nodes {
2398                            return true;
2399                        }
2400                    }
2401                    true
2402                }
2403                TextPredicateCapture::MatchString(i, r, is_positive, match_all_nodes) => {
2404                    let nodes = self.nodes_for_capture_index(*i);
2405                    for node in nodes {
2406                        let mut text = text_provider.text(node);
2407                        let text = node_text1.get_text(&mut text);
2408                        if (r.is_match(text)) != *is_positive && *match_all_nodes {
2409                            return false;
2410                        }
2411                        if (r.is_match(text)) == *is_positive && !*match_all_nodes {
2412                            return true;
2413                        }
2414                    }
2415                    true
2416                }
2417                TextPredicateCapture::AnyString(i, v, is_positive) => {
2418                    let nodes = self.nodes_for_capture_index(*i);
2419                    for node in nodes {
2420                        let mut text = text_provider.text(node);
2421                        let text = node_text1.get_text(&mut text);
2422                        if (v.iter().any(|s| text == s.as_bytes())) != *is_positive {
2423                            return false;
2424                        }
2425                    }
2426                    true
2427                }
2428            })
2429    }
2430}
2431
2432impl std::ops::Deref for Query {
2433    type Target = QueryMetadata;
2434
2435    fn deref(&self) -> &Self::Target {
2436        &self.metadata
2437    }
2438}
2439
2440impl std::ops::DerefMut for Query {
2441    fn deref_mut(&mut self) -> &mut Self::Target {
2442        &mut self.metadata
2443    }
2444}
2445
2446impl QueryProperty {
2447    pub fn new(key: &str, value: Option<&str>, capture_id: Option<usize>) -> Self {
2448        QueryProperty {
2449            capture_id,
2450            key: key.to_string().into(),
2451            value: value.map(|s| s.to_string().into()),
2452        }
2453    }
2454}
2455
2456impl<'query, 'tree: 'query, T: TextProvider<I>, I: AsRef<[u8]>> Iterator
2457    for QueryMatches<'query, 'tree, T, I>
2458{
2459    type Item = QueryMatch<'query, 'tree>;
2460
2461    fn next(&mut self) -> Option<Self::Item> {
2462        unsafe {
2463            loop {
2464                let mut m = MaybeUninit::<ffi::TSQueryMatch>::uninit();
2465                if ffi::ts_query_cursor_next_match(self.ptr, m.as_mut_ptr()) {
2466                    let result = QueryMatch::new(m.assume_init(), self.ptr);
2467                    if result.satisfies_text_predicates(
2468                        self.query,
2469                        &mut self.buffer1,
2470                        &mut self.buffer2,
2471                        &mut self.text_provider,
2472                    ) {
2473                        return Some(result);
2474                    }
2475                } else {
2476                    return None;
2477                }
2478            }
2479        }
2480    }
2481}
2482
2483impl<'query, 'tree: 'query, T: TextProvider<I>, I: AsRef<[u8]>> Iterator
2484    for QueryCaptures<'query, 'tree, T, I>
2485{
2486    type Item = (QueryMatch<'query, 'tree>, usize);
2487
2488    fn next(&mut self) -> Option<Self::Item> {
2489        unsafe {
2490            loop {
2491                let mut capture_index = 0u32;
2492                let mut m = MaybeUninit::<ffi::TSQueryMatch>::uninit();
2493                if ffi::ts_query_cursor_next_capture(
2494                    self.ptr,
2495                    m.as_mut_ptr(),
2496                    &mut capture_index as *mut u32,
2497                ) {
2498                    let result = QueryMatch::new(m.assume_init(), self.ptr);
2499                    if result.satisfies_text_predicates(
2500                        self.query,
2501                        &mut self.buffer1,
2502                        &mut self.buffer2,
2503                        &mut self.text_provider,
2504                    ) {
2505                        return Some((result, capture_index as usize));
2506                    } else {
2507                        result.remove();
2508                    }
2509                } else {
2510                    return None;
2511                }
2512            }
2513        }
2514    }
2515}
2516
2517impl<T: TextProvider<I>, I: AsRef<[u8]>> QueryMatches<'_, '_, T, I> {
2518    #[doc(alias = "ts_query_cursor_set_byte_range")]
2519    pub fn set_byte_range(&mut self, range: ops::Range<usize>) {
2520        unsafe {
2521            ffi::ts_query_cursor_set_byte_range(self.ptr, range.start as u32, range.end as u32);
2522        }
2523    }
2524
2525    #[doc(alias = "ts_query_cursor_set_point_range")]
2526    pub fn set_point_range(&mut self, range: ops::Range<Point>) {
2527        unsafe {
2528            ffi::ts_query_cursor_set_point_range(self.ptr, range.start.into(), range.end.into());
2529        }
2530    }
2531}
2532
2533impl<T: TextProvider<I>, I: AsRef<[u8]>> QueryCaptures<'_, '_, T, I> {
2534    #[doc(alias = "ts_query_cursor_set_byte_range")]
2535    pub fn set_byte_range(&mut self, range: ops::Range<usize>) {
2536        unsafe {
2537            ffi::ts_query_cursor_set_byte_range(self.ptr, range.start as u32, range.end as u32);
2538        }
2539    }
2540
2541    #[doc(alias = "ts_query_cursor_set_point_range")]
2542    pub fn set_point_range(&mut self, range: ops::Range<Point>) {
2543        unsafe {
2544            ffi::ts_query_cursor_set_point_range(self.ptr, range.start.into(), range.end.into());
2545        }
2546    }
2547}
2548
2549impl fmt::Debug for QueryMatch<'_, '_> {
2550    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2551        write!(
2552            f,
2553            "QueryMatch {{ id: {}, pattern_index: {}, captures: {:?} }}",
2554            self.id, self.pattern_index, self.captures
2555        )
2556    }
2557}
2558
2559impl<F, R, I> TextProvider<I> for F
2560where
2561    F: FnMut(Node) -> R,
2562    R: Iterator<Item = I>,
2563    I: AsRef<[u8]>,
2564{
2565    type I = R;
2566
2567    fn text(&mut self, node: Node) -> Self::I {
2568        (self)(node)
2569    }
2570}
2571
2572impl<'a> TextProvider<&'a [u8]> for &'a [u8] {
2573    type I = iter::Once<&'a [u8]>;
2574
2575    fn text(&mut self, node: Node) -> Self::I {
2576        iter::once(&self[node.byte_range()])
2577    }
2578}
2579
2580impl PartialEq for Query {
2581    fn eq(&self, other: &Self) -> bool {
2582        self.ptr == other.ptr
2583    }
2584}
2585
2586impl Drop for Query {
2587    fn drop(&mut self) {
2588        unsafe { ffi::ts_query_delete(self.ptr.as_ptr()) }
2589    }
2590}
2591
2592impl Drop for QueryCursor {
2593    fn drop(&mut self) {
2594        unsafe { ffi::ts_query_cursor_delete(self.ptr.as_ptr()) }
2595    }
2596}
2597
2598impl Point {
2599    pub fn new(row: usize, column: usize) -> Self {
2600        Point { row, column }
2601    }
2602}
2603
2604impl fmt::Display for Point {
2605    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2606        write!(f, "({}, {})", self.row, self.column)
2607    }
2608}
2609
2610impl Into<ffi::TSPoint> for Point {
2611    fn into(self) -> ffi::TSPoint {
2612        ffi::TSPoint {
2613            row: self.row as u32,
2614            column: self.column as u32,
2615        }
2616    }
2617}
2618
2619impl From<ffi::TSPoint> for Point {
2620    fn from(point: ffi::TSPoint) -> Self {
2621        Self {
2622            row: point.row as usize,
2623            column: point.column as usize,
2624        }
2625    }
2626}
2627
2628impl Into<ffi::TSRange> for Range {
2629    fn into(self) -> ffi::TSRange {
2630        ffi::TSRange {
2631            start_byte: self.start_byte as u32,
2632            end_byte: self.end_byte as u32,
2633            start_point: self.start_point.into(),
2634            end_point: self.end_point.into(),
2635        }
2636    }
2637}
2638
2639impl From<ffi::TSRange> for Range {
2640    fn from(range: ffi::TSRange) -> Self {
2641        Self {
2642            start_byte: range.start_byte as usize,
2643            end_byte: range.end_byte as usize,
2644            start_point: range.start_point.into(),
2645            end_point: range.end_point.into(),
2646        }
2647    }
2648}
2649
2650impl Into<ffi::TSInputEdit> for &'_ InputEdit {
2651    fn into(self) -> ffi::TSInputEdit {
2652        ffi::TSInputEdit {
2653            start_byte: self.start_byte as u32,
2654            old_end_byte: self.old_end_byte as u32,
2655            new_end_byte: self.new_end_byte as u32,
2656            start_point: self.start_position.into(),
2657            old_end_point: self.old_end_position.into(),
2658            new_end_point: self.new_end_position.into(),
2659        }
2660    }
2661}
2662
2663impl<'a> LossyUtf8<'a> {
2664    pub fn new(bytes: &'a [u8]) -> Self {
2665        LossyUtf8 {
2666            bytes,
2667            in_replacement: false,
2668        }
2669    }
2670}
2671
2672impl<'a> Iterator for LossyUtf8<'a> {
2673    type Item = &'a str;
2674
2675    fn next(&mut self) -> Option<&'a str> {
2676        if self.bytes.is_empty() {
2677            return None;
2678        }
2679        if self.in_replacement {
2680            self.in_replacement = false;
2681            return Some("\u{fffd}");
2682        }
2683        match std::str::from_utf8(self.bytes) {
2684            Ok(valid) => {
2685                self.bytes = Default::default();
2686                Some(valid)
2687            }
2688            Err(error) => {
2689                if let Some(error_len) = error.error_len() {
2690                    let error_start = error.valid_up_to();
2691                    if error_start > 0 {
2692                        let result =
2693                            unsafe { std::str::from_utf8_unchecked(&self.bytes[..error_start]) };
2694                        self.bytes = &self.bytes[(error_start + error_len)..];
2695                        self.in_replacement = true;
2696                        Some(result)
2697                    } else {
2698                        self.bytes = &self.bytes[error_len..];
2699                        Some("\u{fffd}")
2700                    }
2701                } else {
2702                    None
2703                }
2704            }
2705        }
2706    }
2707}
2708
2709fn predicate_error(row: usize, message: String) -> QueryError {
2710    QueryError {
2711        kind: QueryErrorKind::Predicate,
2712        row,
2713        column: 0,
2714        offset: 0,
2715        message,
2716    }
2717}
2718
2719impl fmt::Display for IncludedRangesError {
2720    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2721        write!(f, "Incorrect range by index: {}", self.0)
2722    }
2723}
2724
2725impl fmt::Display for LanguageError {
2726    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2727        write!(
2728            f,
2729            "Incompatible language version {}. Expected minimum {}, maximum {}",
2730            self.version, MIN_COMPATIBLE_LANGUAGE_VERSION, LANGUAGE_VERSION,
2731        )
2732    }
2733}
2734
2735impl fmt::Display for QueryError {
2736    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2737        let msg = match self.kind {
2738            QueryErrorKind::Field => "Invalid field name ",
2739            QueryErrorKind::NodeType => "Invalid node type ",
2740            QueryErrorKind::Capture => "Invalid capture name ",
2741            QueryErrorKind::Predicate => "Invalid predicate: ",
2742            QueryErrorKind::Structure => "Impossible pattern:\n",
2743            QueryErrorKind::Syntax => "Invalid syntax:\n",
2744            QueryErrorKind::Language => "",
2745        };
2746        if msg.len() > 0 {
2747            write!(
2748                f,
2749                "Query error at {}:{}. {}{}",
2750                self.row + 1,
2751                self.column + 1,
2752                msg,
2753                self.message
2754            )
2755        } else {
2756            write!(f, "{}", self.message)
2757        }
2758    }
2759}
2760
2761extern "C" {
2762    fn free(ptr: *mut c_void);
2763}
2764
2765static mut FREE_FN: unsafe extern "C" fn(ptr: *mut c_void) = free;
2766
2767#[doc(alias = "ts_set_allocator")]
2768pub unsafe fn set_allocator(
2769    new_malloc: Option<unsafe extern "C" fn(usize) -> *mut c_void>,
2770    new_calloc: Option<unsafe extern "C" fn(usize, usize) -> *mut c_void>,
2771    new_realloc: Option<unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void>,
2772    new_free: Option<unsafe extern "C" fn(*mut c_void)>,
2773) {
2774    FREE_FN = new_free.unwrap_or(free);
2775    ffi::ts_set_allocator(new_malloc, new_calloc, new_realloc, new_free);
2776}
2777
2778impl error::Error for IncludedRangesError {}
2779impl error::Error for LanguageError {}
2780impl error::Error for QueryError {}
2781
2782unsafe impl Send for Language {}
2783unsafe impl Sync for Language {}
2784
2785unsafe impl Send for Node<'_> {}
2786unsafe impl Sync for Node<'_> {}
2787
2788unsafe impl Send for LookaheadIterator {}
2789unsafe impl Sync for LookaheadIterator {}
2790
2791unsafe impl Send for LookaheadNamesIterator<'_> {}
2792unsafe impl Sync for LookaheadNamesIterator<'_> {}
2793
2794unsafe impl Send for Parser {}
2795unsafe impl Sync for Parser {}
2796
2797unsafe impl Send for Query {}
2798unsafe impl Sync for Query {}
2799
2800unsafe impl Send for QueryCursor {}
2801unsafe impl Sync for QueryCursor {}
2802
2803unsafe impl Send for Tree {}
2804unsafe impl Sync for Tree {}
2805
2806unsafe impl Send for TreeCursor<'_> {}
2807unsafe impl Sync for TreeCursor<'_> {}