tree_sitter_c2rust/
lib.rs

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