tree_sitter/
lib.rs

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