tree_sitter_patched_arborium/
lib.rs

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