Skip to main content

tree_sitter/
lib.rs

1// code-gauge-allow-file fileNcss 852 -- core Parser, Language, Tree, Node, and TreeCursor bindings share private wrappers
2#![cfg_attr(not(any(test, doctest)), doc = include_str!("./README.md"))]
3#![cfg_attr(not(feature = "std"), no_std)]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5
6pub mod ffi;
7mod lookahead;
8mod sexp;
9mod util;
10
11pub use lookahead::LookaheadIterator;
12#[doc(hidden)]
13pub use sexp::format_sexp;
14
15#[cfg(any(
16    not(feature = "std"),
17    all(target_arch = "wasm32", target_os = "unknown")
18))]
19extern crate alloc;
20#[cfg(not(feature = "std"))]
21use alloc::{
22    boxed::Box,
23    string::{String, ToString},
24    vec::Vec,
25};
26use core::{
27    ffi::{CStr, c_char, c_void},
28    fmt, hash, iter,
29    marker::PhantomData,
30    num::NonZeroU16,
31    ops::{ControlFlow, Deref},
32    ptr::{self, NonNull},
33    slice, str,
34};
35#[cfg(feature = "std")]
36use std::error;
37#[cfg(all(unix, feature = "std"))]
38use std::os::fd::AsRawFd;
39#[cfg(all(windows, feature = "std"))]
40use std::os::windows::io::AsRawHandle;
41
42use tree_sitter_language::LanguageFn;
43
44#[cfg(feature = "wasm")]
45mod wasm_language;
46#[cfg(feature = "wasm")]
47#[cfg_attr(docsrs, doc(cfg(feature = "wasm")))]
48pub use wasm_language::*;
49
50#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
51mod wasm_allocator;
52
53/// The latest ABI version that the current version of the library supports.
54///
55/// The CLI of this fork assigns it to each generated language. Its upper 16
56/// bits (`0x5742`, "WB") tag the fork and its lower 16 bits count the fork's
57/// ABI revisions, so that it never equals an ABI version of upstream
58/// Tree-sitter: the library rejects languages generated by upstream's CLI, and
59/// upstream's library rejects languages generated by this fork's CLI.
60#[doc(alias = "TREE_SITTER_LANGUAGE_VERSION")]
61pub const LANGUAGE_VERSION: usize = ffi::TREE_SITTER_LANGUAGE_VERSION as usize;
62
63/// The earliest ABI version that is supported by the current version of the
64/// library. Its parse tables are a subset of those of [`LANGUAGE_VERSION`], so
65/// the library loads both.
66#[doc(alias = "TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION")]
67pub const MIN_COMPATIBLE_LANGUAGE_VERSION: usize =
68    ffi::TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION as usize;
69
70pub const PARSER_HEADER: &str = include_str!("../src/parser.h");
71
72/// An opaque object that defines how to parse a particular language. The code
73/// for each `Language` is generated by the Tree-sitter CLI.
74#[doc(alias = "TSLanguage")]
75#[derive(Debug, PartialEq, Eq, Hash)]
76#[repr(transparent)]
77pub struct Language(pub(crate) *const ffi::TSLanguage);
78
79pub struct LanguageRef<'a>(
80    pub(crate) *const ffi::TSLanguage,
81    pub(crate) PhantomData<&'a ()>,
82);
83
84/// The metadata associated with a language.
85///
86/// Currently, this metadata can be used to check the [Semantic Version](https://semver.org/)
87/// of the language.
88#[doc(alias = "TSLanguageMetadata")]
89pub struct LanguageMetadata {
90    pub major_version: u8,
91    pub minor_version: u8,
92    pub patch_version: u8,
93}
94
95impl From<ffi::TSLanguageMetadata> for LanguageMetadata {
96    fn from(val: ffi::TSLanguageMetadata) -> Self {
97        Self {
98            major_version: val.major_version,
99            minor_version: val.minor_version,
100            patch_version: val.patch_version,
101        }
102    }
103}
104
105/// A tree that represents the syntactic structure of a source code file.
106#[doc(alias = "TSTree")]
107pub struct Tree(NonNull<ffi::TSTree>);
108
109/// A position in a multi-line text document, in terms of rows and columns.
110///
111/// Rows and columns are zero-based.
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
113pub struct Point {
114    pub row: usize,
115    pub column: usize,
116}
117
118/// A range of positions in a multi-line text document, both in terms of bytes
119/// and of rows and columns.
120#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
121pub struct Range {
122    pub start_byte: usize,
123    pub end_byte: usize,
124    pub start_point: Point,
125    pub end_point: Point,
126}
127
128/// A summary of a change to a text document.
129#[derive(Clone, Copy, Debug, PartialEq, Eq)]
130pub struct InputEdit {
131    pub start_byte: usize,
132    pub old_end_byte: usize,
133    pub new_end_byte: usize,
134    pub start_position: Point,
135    pub old_end_position: Point,
136    pub new_end_position: Point,
137}
138
139impl InputEdit {
140    /// Edit a point to keep it in-sync with source code that has been edited.
141    ///
142    /// This function updates a single point's byte offset and row/column position
143    /// based on this edit operation. This is useful for editing points without
144    /// requiring a tree or node instance.
145    #[doc(alias = "ts_point_edit")]
146    pub fn edit_point(&self, point: &mut Point, byte: &mut usize) {
147        let edit = self.into();
148        let mut ts_point = (*point).into();
149        let mut ts_byte = *byte as u32;
150
151        unsafe {
152            ffi::ts_point_edit(
153                core::ptr::addr_of_mut!(ts_point),
154                core::ptr::addr_of_mut!(ts_byte),
155                &raw const edit,
156            );
157        }
158
159        *point = ts_point.into();
160        *byte = ts_byte as usize;
161    }
162
163    /// Edit a range to keep it in-sync with source code that has been edited.
164    ///
165    /// This function updates a range's start and end positions based on this edit
166    /// operation. This is useful for editing ranges without requiring a tree
167    /// or node instance.
168    #[doc(alias = "ts_range_edit")]
169    pub fn edit_range(&self, range: &mut Range) {
170        let edit = self.into();
171        let mut ts_range = (*range).into();
172
173        unsafe {
174            ffi::ts_range_edit(core::ptr::addr_of_mut!(ts_range), &raw const edit);
175        }
176
177        *range = ts_range.into();
178    }
179}
180
181/// A single node within a syntax [`Tree`].
182#[doc(alias = "TSNode")]
183#[derive(Clone, Copy)]
184#[repr(transparent)]
185pub struct Node<'tree>(ffi::TSNode, PhantomData<&'tree ()>);
186
187/// A stateful object that this is used to produce a [`Tree`] based on some
188/// source code.
189#[doc(alias = "TSParser")]
190pub struct Parser(NonNull<ffi::TSParser>);
191
192/// A stateful object that is passed into a [`ParseProgressCallback`]
193/// to pass in the current state of the parser.
194pub struct ParseState(NonNull<ffi::TSParseState>);
195
196impl ParseState {
197    #[must_use]
198    pub const fn current_byte_offset(&self) -> usize {
199        unsafe { self.0.as_ref() }.current_byte_offset as usize
200    }
201
202    #[must_use]
203    pub const fn has_error(&self) -> bool {
204        unsafe { self.0.as_ref() }.has_error
205    }
206}
207
208#[derive(Default)]
209pub struct ParseOptions<'a> {
210    pub progress_callback: Option<ParseProgressCallback<'a>>,
211}
212
213impl<'a> ParseOptions<'a> {
214    #[must_use]
215    pub fn new() -> Self {
216        Self::default()
217    }
218
219    #[must_use]
220    pub fn progress_callback<F: FnMut(&ParseState) -> ControlFlow<()>>(
221        mut self,
222        callback: &'a mut F,
223    ) -> Self {
224        self.progress_callback = Some(callback);
225        self
226    }
227
228    /// Create a new `ParseOptions` with a shorter lifetime, borrowing from this one.
229    ///
230    /// This is useful when you need to reuse parse options multiple times, e.g., calling
231    /// [`Parser::parse_with_options`] multiple times with the same options.
232    #[must_use]
233    pub fn reborrow(&mut self) -> ParseOptions {
234        ParseOptions {
235            progress_callback: match &mut self.progress_callback {
236                Some(cb) => Some(*cb),
237                None => None,
238            },
239        }
240    }
241}
242
243/// A type of log message.
244#[derive(Debug, PartialEq, Eq)]
245pub enum LogType {
246    Parse,
247    Lex,
248}
249
250type FieldId = NonZeroU16;
251
252/// A callback that receives log messages during parsing.
253type Logger = Box<dyn FnMut(LogType, &str) + Send + 'static>;
254
255/// A callback that receives log messages during parsing, with relaxed constraints.
256type UnsafeLogger<'a> = Box<dyn FnMut(LogType, &str) + Send + 'a>;
257
258/// A callback that receives the parse state during parsing.
259type ParseProgressCallback<'a> = &'a mut dyn FnMut(&ParseState) -> ControlFlow<()>;
260
261pub trait Decode {
262    /// A callback that decodes the next code point from the input slice. It should return the code
263    /// point, and how many bytes were decoded.
264    fn decode(bytes: &[u8]) -> (i32, u32);
265}
266
267/// A stateful object for walking a syntax [`Tree`] efficiently.
268#[doc(alias = "TSTreeCursor")]
269pub struct TreeCursor<'tree>(ffi::TSTreeCursor, PhantomData<&'tree ()>);
270
271/// An error that occurred when trying to assign a [`Language`] to a [`Parser`].
272/// If the `wasm` feature is enabled, this can also indicate a failure to load
273/// the Wasm store.
274#[derive(Debug, PartialEq, Eq)]
275pub enum LanguageError {
276    Version(usize),
277    NotParseable,
278    #[cfg(feature = "wasm")]
279    Wasm,
280}
281
282/// An error that occurred in [`Parser::set_included_ranges`].
283#[derive(Debug, PartialEq, Eq)]
284pub struct IncludedRangesError(pub usize);
285
286impl Language {
287    #[must_use]
288    pub fn new(builder: LanguageFn) -> Self {
289        Self(unsafe { builder.into_raw()().cast() })
290    }
291
292    /// Check whether this language can be assigned to a parser.
293    ///
294    /// When Tree-sitter is compiled to WebAssembly, languages obtained from a
295    /// syntax tree can be used for parsing only within the same WebAssembly
296    /// instance that created the tree. In other instances, such languages can
297    /// still be used to inspect syntax trees.
298    #[doc(alias = "ts_language_is_parseable")]
299    #[must_use]
300    pub fn is_parseable(&self) -> bool {
301        unsafe { ffi::ts_language_is_parseable(self.0) }
302    }
303
304    /// Get the name of this language. This returns `None` for a language with
305    /// another ABI version.
306    #[doc(alias = "ts_language_name")]
307    #[must_use]
308    pub fn name(&self) -> Option<&str> {
309        let ptr = unsafe { ffi::ts_language_name(self.0) };
310        (!ptr.is_null()).then(|| unsafe { CStr::from_ptr(ptr) }.to_str().unwrap())
311    }
312
313    /// Get the ABI version number of this [`Language`].
314    ///
315    /// The library loads only languages whose number is from
316    /// [`MIN_COMPATIBLE_LANGUAGE_VERSION`] to [`LANGUAGE_VERSION`], which the CLI
317    /// of this fork assigns. Any other number comes from a parser
318    /// that another CLI generated.
319    #[doc(alias = "ts_language_abi_version")]
320    #[must_use]
321    pub fn abi_version(&self) -> usize {
322        unsafe { ffi::ts_language_abi_version(self.0) as usize }
323    }
324
325    /// Get the metadata for this language. This information is generated by the
326    /// CLI, and relies on the language author providing the correct metadata in
327    /// the language's `tree-sitter.json` file. This returns `None` for a
328    /// language with another ABI version.
329    ///
330    /// See also [`LanguageMetadata`].
331    #[doc(alias = "ts_language_metadata")]
332    #[must_use]
333    pub fn metadata(&self) -> Option<LanguageMetadata> {
334        unsafe {
335            let ptr = ffi::ts_language_metadata(self.0);
336            (!ptr.is_null()).then(|| (*ptr).into())
337        }
338    }
339
340    /// Get the number of distinct node types in this language.
341    #[doc(alias = "ts_language_symbol_count")]
342    #[must_use]
343    pub fn node_kind_count(&self) -> usize {
344        unsafe { ffi::ts_language_symbol_count(self.0) as usize }
345    }
346
347    /// Get the number of valid states in this language.
348    #[doc(alias = "ts_language_state_count")]
349    #[must_use]
350    pub fn parse_state_count(&self) -> usize {
351        unsafe { ffi::ts_language_state_count(self.0) as usize }
352    }
353
354    /// Get a list of all supertype symbols for the language. The list is empty
355    /// for a language with another ABI version.
356    #[doc(alias = "ts_language_supertypes")]
357    #[must_use]
358    pub fn supertypes(&self) -> &[u16] {
359        let mut length = 0u32;
360        unsafe {
361            let ptr = ffi::ts_language_supertypes(self.0, core::ptr::addr_of_mut!(length));
362            if length == 0 {
363                &[]
364            } else {
365                slice::from_raw_parts(ptr.cast_mut(), length as usize)
366            }
367        }
368    }
369
370    /// Get a list of all subtype symbols for a given supertype symbol. The list
371    /// is empty for a language with another ABI version.
372    #[doc(alias = "ts_language_supertype_map")]
373    #[must_use]
374    pub fn subtypes_for_supertype(&self, supertype: u16) -> &[u16] {
375        unsafe {
376            let mut length = 0u32;
377            let ptr = ffi::ts_language_subtypes(self.0, supertype, core::ptr::addr_of_mut!(length));
378            if length == 0 {
379                &[]
380            } else {
381                slice::from_raw_parts(ptr.cast_mut(), length as usize)
382            }
383        }
384    }
385
386    /// Get the name of the node kind for the given numerical id.
387    #[doc(alias = "ts_language_symbol_name")]
388    #[must_use]
389    pub fn node_kind_for_id(&self, id: u16) -> Option<&str> {
390        let ptr = unsafe { ffi::ts_language_symbol_name(self.0, id) };
391        (!ptr.is_null()).then(|| unsafe { CStr::from_ptr(ptr) }.to_str().unwrap())
392    }
393
394    /// Get the numeric id for the given node kind.
395    #[doc(alias = "ts_language_symbol_for_name")]
396    #[must_use]
397    pub fn id_for_node_kind(&self, kind: &str, named: bool) -> u16 {
398        unsafe {
399            ffi::ts_language_symbol_for_name(
400                self.0,
401                kind.as_bytes().as_ptr().cast::<c_char>(),
402                kind.len() as u32,
403                named,
404            )
405        }
406    }
407
408    /// Check whether `id` can be used to index this language's symbol tables.
409    ///
410    /// `ts_symbol_metadata` holds one entry per grammar symbol plus one per alias,
411    /// so [`Self::node_kind_count`] is an exact bound. `ERROR` and `_ERROR` sit
412    /// at the top of the `u16` range and are handled by the C library before any
413    /// table lookup.
414    fn node_kind_id_is_valid(&self, id: u16) -> bool {
415        (id as usize) < self.node_kind_count() || id >= u16::MAX - 1
416    }
417
418    /// Check if the node type for the given numerical id is named (as opposed
419    /// to an anonymous node type).
420    #[must_use]
421    pub fn node_kind_is_named(&self, id: u16) -> bool {
422        self.node_kind_id_is_valid(id)
423            && unsafe { ffi::ts_language_symbol_type(self.0, id) == ffi::TSSymbolTypeRegular }
424    }
425
426    /// Check if the node type for the given numerical id is visible (as opposed
427    /// to a hidden node type).
428    #[must_use]
429    pub fn node_kind_is_visible(&self, id: u16) -> bool {
430        self.node_kind_id_is_valid(id)
431            && unsafe { ffi::ts_language_symbol_type(self.0, id) <= ffi::TSSymbolTypeAnonymous }
432    }
433
434    /// Check if the node type for the given numerical id is a supertype.
435    #[must_use]
436    pub fn node_kind_is_supertype(&self, id: u16) -> bool {
437        self.node_kind_id_is_valid(id)
438            && unsafe { ffi::ts_language_symbol_type(self.0, id) == ffi::TSSymbolTypeSupertype }
439    }
440
441    /// Get the number of distinct field names in this language.
442    #[doc(alias = "ts_language_field_count")]
443    #[must_use]
444    pub fn field_count(&self) -> usize {
445        unsafe { ffi::ts_language_field_count(self.0) as usize }
446    }
447
448    /// Get the field name for the given numerical id.
449    #[doc(alias = "ts_language_field_name_for_id")]
450    #[must_use]
451    pub fn field_name_for_id(&self, field_id: u16) -> Option<&str> {
452        let ptr = unsafe { ffi::ts_language_field_name_for_id(self.0, field_id) };
453        (!ptr.is_null()).then(|| unsafe { CStr::from_ptr(ptr) }.to_str().unwrap())
454    }
455
456    /// Get the numerical id for the given field name.
457    #[doc(alias = "ts_language_field_id_for_name")]
458    #[must_use]
459    pub fn field_id_for_name(&self, field_name: impl AsRef<[u8]>) -> Option<FieldId> {
460        let field_name = field_name.as_ref();
461        let id = unsafe {
462            ffi::ts_language_field_id_for_name(
463                self.0,
464                field_name.as_ptr().cast::<c_char>(),
465                field_name.len() as u32,
466            )
467        };
468        FieldId::new(id)
469    }
470
471    /// Get the next parse state. Combine this with
472    /// [`lookahead_iterator`](Language::lookahead_iterator) to
473    /// generate completion suggestions or valid symbols in error nodes.
474    ///
475    /// Example:
476    /// ```ignore
477    /// let state = language.next_state(node.parse_state(), node.grammar_id());
478    /// ```
479    #[doc(alias = "ts_language_next_state")]
480    #[must_use]
481    pub fn next_state(&self, state: u16, id: u16) -> u16 {
482        unsafe { ffi::ts_language_next_state(self.0, state, id) }
483    }
484
485    /// Create a new lookahead iterator for this language and parse state.
486    ///
487    /// This returns `None` if state is invalid for this language.
488    ///
489    /// Iterating [`LookaheadIterator`] will yield valid symbols in the given
490    /// parse state. A newly created iterator is not positioned on a symbol, so
491    /// [`LookaheadIterator::current_symbol`] returns `None` until the first
492    /// [`Iterator::next`] call.
493    ///
494    /// The iterator retains the language, so the language may be dropped while
495    /// the iterator is still in use.
496    ///
497    /// Lookahead iterators can be useful to generate suggestions and improve
498    /// syntax error diagnostics. To get symbols valid in an `ERROR` node, use the
499    /// lookahead iterator on its first leaf node state. For a missing node, use
500    /// the node's [`parse_state`](Node::parse_state). Keep in mind that lookahead
501    /// symbols are valid in that parse state, but are not necessarily valid
502    /// continuations in the context of the actual following token or guaranteed
503    /// to be considered during error recovery.
504    #[doc(alias = "ts_lookahead_iterator_new")]
505    #[must_use]
506    pub fn lookahead_iterator(&self, state: u16) -> Option<LookaheadIterator> {
507        let ptr = unsafe { ffi::ts_lookahead_iterator_new(self.0, state) };
508        (!ptr.is_null()).then(|| unsafe { LookaheadIterator::from_raw(ptr) })
509    }
510}
511
512impl From<LanguageFn> for Language {
513    fn from(value: LanguageFn) -> Self {
514        Self::new(value)
515    }
516}
517
518impl Clone for Language {
519    fn clone(&self) -> Self {
520        unsafe { Self(ffi::ts_language_copy(self.0)) }
521    }
522}
523
524impl Drop for Language {
525    fn drop(&mut self) {
526        unsafe { ffi::ts_language_delete(self.0) }
527    }
528}
529
530impl Deref for LanguageRef<'_> {
531    type Target = Language;
532
533    fn deref(&self) -> &Self::Target {
534        unsafe { &*(core::ptr::addr_of!(self.0).cast::<Language>()) }
535    }
536}
537
538impl Default for Parser {
539    fn default() -> Self {
540        Self::new()
541    }
542}
543
544impl Parser {
545    /// Create a new parser.
546    #[doc(alias = "ts_parser_new")]
547    #[must_use]
548    pub fn new() -> Self {
549        unsafe {
550            let parser = ffi::ts_parser_new();
551            Self(NonNull::new_unchecked(parser))
552        }
553    }
554
555    /// Set the language that the parser should use for parsing.
556    ///
557    /// Returns a Result indicating whether or not the language was successfully
558    /// assigned. Assignment fails if the language cannot be used for parsing,
559    /// or if it was generated with an incompatible version of the Tree-sitter
560    /// CLI. Check this using [`Language::is_parseable`] and
561    /// [`Language::abi_version`].
562    #[doc(alias = "ts_parser_set_language")]
563    pub fn set_language(&mut self, language: &Language) -> Result<(), LanguageError> {
564        let version = language.abi_version();
565        if (MIN_COMPATIBLE_LANGUAGE_VERSION..=LANGUAGE_VERSION).contains(&version) {
566            if !language.is_parseable() {
567                return Err(LanguageError::NotParseable);
568            }
569            #[cfg_attr(
570                not(feature = "wasm"),
571                expect(unused_variables, reason = "only used when wasm feature is enabled")
572            )]
573            let success = unsafe { ffi::ts_parser_set_language(self.0.as_ptr(), language.0) };
574            #[cfg(feature = "wasm")]
575            if !success {
576                return Err(LanguageError::Wasm);
577            }
578            Ok(())
579        } else {
580            Err(LanguageError::Version(version))
581        }
582    }
583
584    /// Get the parser's current language.
585    #[doc(alias = "ts_parser_language")]
586    #[must_use]
587    pub fn language(&self) -> Option<LanguageRef<'_>> {
588        let ptr = unsafe { ffi::ts_parser_language(self.0.as_ptr()) };
589        (!ptr.is_null()).then_some(LanguageRef(ptr, PhantomData))
590    }
591
592    /// Get the parser's current logger.
593    #[doc(alias = "ts_parser_logger")]
594    #[must_use]
595    pub fn logger(&self) -> Option<&Logger> {
596        let logger = unsafe { ffi::ts_parser_logger(self.0.as_ptr()) };
597        unsafe { logger.payload.cast::<Logger>().as_ref() }
598    }
599
600    /// Set the logging callback that the parser should use during parsing.
601    ///
602    /// To log through a callback that borrows non-`'static` data, see
603    /// [`set_logger_unchecked`](Parser::set_logger_unchecked).
604    #[doc(alias = "ts_parser_set_logger")]
605    pub fn set_logger(&mut self, logger: Option<Logger>) {
606        // SAFETY: `Logger` is `Send + 'static`
607        unsafe { self.set_logger_unchecked(logger) };
608    }
609
610    /// Set the logging callback, allowing the callback to borrow non-`'static`
611    /// data. See [`set_logger`](Parser::set_logger).
612    ///
613    /// # Safety
614    ///
615    /// Any data borrowed by `logger` must remain valid until the logger is
616    /// removed. Equivalently, the parser must not be used to parse once the
617    /// borrowed data has gone out of scope.
618    pub unsafe fn set_logger_unchecked(&mut self, logger: Option<UnsafeLogger<'_>>) {
619        let prev_logger = unsafe { ffi::ts_parser_logger(self.0.as_ptr()) };
620        if !prev_logger.payload.is_null() {
621            drop(unsafe { Box::from_raw(prev_logger.payload.cast::<Logger>()) });
622        }
623
624        let c_logger = if let Some(logger) = logger {
625            let container = Box::new(logger);
626
627            unsafe extern "C" fn log(
628                payload: *mut c_void,
629                c_log_type: ffi::TSLogType,
630                c_message: *const c_char,
631            ) {
632                unsafe {
633                    let callback = payload.cast::<Logger>().as_mut().unwrap();
634                    if let Ok(message) = CStr::from_ptr(c_message).to_str() {
635                        let log_type = if c_log_type == ffi::TSLogTypeParse {
636                            LogType::Parse
637                        } else {
638                            LogType::Lex
639                        };
640                        callback(log_type, message);
641                    }
642                }
643            }
644
645            let raw_container = Box::into_raw(container);
646
647            ffi::TSLogger {
648                payload: raw_container.cast::<c_void>(),
649                log: Some(log),
650            }
651        } else {
652            ffi::TSLogger {
653                payload: ptr::null_mut(),
654                log: None,
655            }
656        };
657
658        unsafe { ffi::ts_parser_set_logger(self.0.as_ptr(), c_logger) };
659    }
660
661    /// Set the destination to which the parser should write debugging graphs
662    /// during parsing. The graphs are formatted in the DOT language. You may
663    /// want to pipe these graphs directly to a `dot(1)` process in order to
664    /// generate SVG output.
665    #[doc(alias = "ts_parser_print_dot_graphs")]
666    #[cfg(not(target_os = "wasi"))]
667    #[cfg(feature = "std")]
668    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
669    pub fn print_dot_graphs(
670        &mut self,
671        #[cfg(unix)] file: &impl AsRawFd,
672        #[cfg(windows)] file: &impl AsRawHandle,
673    ) {
674        #[cfg(unix)]
675        {
676            let fd = file.as_raw_fd();
677            unsafe {
678                ffi::ts_parser_print_dot_graphs(self.0.as_ptr(), ffi::_ts_dup(fd));
679            }
680        }
681
682        #[cfg(windows)]
683        {
684            let handle = file.as_raw_handle();
685            unsafe {
686                ffi::ts_parser_print_dot_graphs(self.0.as_ptr(), ffi::_ts_dup(handle));
687            }
688        }
689    }
690
691    /// Stop the parser from printing debugging graphs while parsing.
692    #[doc(alias = "ts_parser_print_dot_graphs")]
693    #[cfg(not(target_os = "wasi"))]
694    #[cfg(feature = "std")]
695    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
696    pub fn stop_printing_dot_graphs(&mut self) {
697        unsafe { ffi::ts_parser_print_dot_graphs(self.0.as_ptr(), -1) }
698    }
699
700    /// Parse a slice of UTF8 text.
701    ///
702    /// # Arguments:
703    /// * `text` The UTF8-encoded text to parse.
704    /// * `old_tree` A previous syntax tree parsed from the same document. If the text of the
705    ///   document has changed since `old_tree` was created, then you must edit `old_tree` to match
706    ///   the new text using [`Tree::edit`].
707    ///
708    /// Returns a [`Tree`] if parsing succeeded, or `None` if:
709    ///  * The parser has not yet had a language assigned with [`Parser::set_language`]
710    #[doc(alias = "ts_parser_parse")]
711    pub fn parse(&mut self, text: impl AsRef<[u8]>, old_tree: Option<&Tree>) -> Option<Tree> {
712        let bytes = text.as_ref();
713        if let Ok(len) = u32::try_from(bytes.len()) {
714            return unsafe {
715                self.parse_raw_bytes(
716                    (bytes.as_ptr().cast::<c_char>(), len),
717                    old_tree,
718                    ffi::TSInputEncodingUTF8,
719                )
720            };
721        }
722        let len = bytes.len();
723        self.parse_with_options(
724            &mut |i, _| {
725                if i < len {
726                    &bytes[i..]
727                } else {
728                    Default::default()
729                }
730            },
731            old_tree,
732            None,
733        )
734    }
735
736    /// Parse text provided in chunks by a callback.
737    ///
738    /// # Arguments:
739    /// * `callback` A function that takes a byte offset and position and returns a slice of
740    ///   UTF8-encoded text starting at that byte offset and position. The slices can be of any
741    ///   length. If the given position is at the end of the text, the callback should return an
742    ///   empty slice.
743    /// * `old_tree` A previous syntax tree parsed from the same document. If the text of the
744    ///   document has changed since `old_tree` was created, then you must edit `old_tree` to match
745    ///   the new text using [`Tree::edit`].
746    /// * `options` Options for parsing the text. This can be used to set a progress callback.
747    pub fn parse_with_options<T: AsRef<[u8]>, F: FnMut(usize, Point) -> T>(
748        &mut self,
749        callback: &mut F,
750        old_tree: Option<&Tree>,
751        options: Option<ParseOptions>,
752    ) -> Option<Tree> {
753        self.parse_chunks::<0, u8, T, F>(
754            callback,
755            old_tree,
756            (options, ffi::TSInputEncodingUTF8, None),
757        )
758    }
759
760    /// Parse a slice of UTF16 little-endian text.
761    ///
762    /// # Arguments:
763    /// * `text` The UTF16-encoded text to parse.
764    /// * `old_tree` A previous syntax tree parsed from the same document. If the text of the
765    ///   document has changed since `old_tree` was created, then you must edit `old_tree` to match
766    ///   the new text using [`Tree::edit`].
767    pub fn parse_utf16_le(
768        &mut self,
769        input: impl AsRef<[u16]>,
770        old_tree: Option<&Tree>,
771    ) -> Option<Tree> {
772        self.parse_utf16_slice::<true>(input.as_ref(), old_tree)
773    }
774
775    /// Parse UTF16 little-endian text provided in chunks by a callback.
776    ///
777    /// # Arguments:
778    /// * `callback` A function that takes a code point offset and position and returns a slice of
779    ///   UTF16-encoded text starting at that byte offset and position. The slices can be of any
780    ///   length. If the given position is at the end of the text, the callback should return an
781    ///   empty slice.
782    /// * `old_tree` A previous syntax tree parsed from the same document. If the text of the
783    ///   document has changed since `old_tree` was created, then you must edit `old_tree` to match
784    ///   the new text using [`Tree::edit`].
785    /// * `options` Options for parsing the text. This can be used to set a progress callback.
786    pub fn parse_utf16_le_with_options<T: AsRef<[u16]>, F: FnMut(usize, Point) -> T>(
787        &mut self,
788        callback: &mut F,
789        old_tree: Option<&Tree>,
790        options: Option<ParseOptions>,
791    ) -> Option<Tree> {
792        self.parse_utf16_with_options::<true, T, F>(callback, old_tree, options)
793    }
794
795    /// Parse a slice of UTF16 big-endian text.
796    ///
797    /// # Arguments:
798    /// * `text` The UTF16-encoded text to parse.
799    /// * `old_tree` A previous syntax tree parsed from the same document. If the text of the
800    ///   document has changed since `old_tree` was created, then you must edit `old_tree` to match
801    ///   the new text using [`Tree::edit`].
802    pub fn parse_utf16_be(
803        &mut self,
804        input: impl AsRef<[u16]>,
805        old_tree: Option<&Tree>,
806    ) -> Option<Tree> {
807        self.parse_utf16_slice::<false>(input.as_ref(), old_tree)
808    }
809
810    /// Parse UTF16 big-endian text provided in chunks by a callback.
811    ///
812    /// # Arguments:
813    /// * `callback` A function that takes a code point offset and position and returns a slice of
814    ///   UTF16-encoded text starting at that byte offset and position. The slices can be of any
815    ///   length. If the given position is at the end of the text, the callback should return an
816    ///   empty slice.
817    /// * `old_tree` A previous syntax tree parsed from the same document. If the text of the
818    ///   document has changed since `old_tree` was created, then you must edit `old_tree` to match
819    ///   the new text using [`Tree::edit`].
820    /// * `options` Options for parsing the text. This can be used to set a progress callback.
821    pub fn parse_utf16_be_with_options<T: AsRef<[u16]>, F: FnMut(usize, Point) -> T>(
822        &mut self,
823        callback: &mut F,
824        old_tree: Option<&Tree>,
825        options: Option<ParseOptions>,
826    ) -> Option<Tree> {
827        self.parse_utf16_with_options::<false, T, F>(callback, old_tree, options)
828    }
829
830    /// Parse text provided in chunks by a callback using a custom encoding.
831    /// This is useful for parsing text in encodings that are not UTF-8 or UTF-16.
832    ///
833    /// # Arguments:
834    /// * `callback` A function that takes a byte offset and position and returns a slice of text
835    ///   starting at that byte offset and position. The slices can be of any length. If the given
836    ///   position is at the end of the text, the callback should return an empty slice.
837    /// * `old_tree` A previous syntax tree parsed from the same document. If the text of the
838    ///   document has changed since `old_tree` was created, then you must edit `old_tree` to match
839    ///   the new text using [`Tree::edit`].
840    /// * `options` Options for parsing the text. This can be used to set a progress callback.
841    ///
842    /// Additionally, you must set the generic parameter [`D`] to a type that implements the
843    /// [`Decode`] trait. This trait has a single method, [`decode`](Decode::decode), which takes a
844    /// slice of bytes and returns a tuple of the code point and the number of bytes consumed.
845    /// The `decode` method should return `-1` for the code point if decoding fails.
846    pub fn parse_custom_encoding<D: Decode, T: AsRef<[u8]>, F: FnMut(usize, Point) -> T>(
847        &mut self,
848        callback: &mut F,
849        old_tree: Option<&Tree>,
850        options: Option<ParseOptions>,
851    ) -> Option<Tree> {
852        unsafe extern "C" fn decode_fn<D: Decode>(
853            data: *const u8,
854            len: u32,
855            code_point: *mut i32,
856        ) -> u32 {
857            unsafe {
858                let (c, len) = D::decode(core::slice::from_raw_parts(data, len as usize));
859                if let Some(code_point) = code_point.as_mut() {
860                    *code_point = c;
861                }
862                len
863            }
864        }
865
866        self.parse_chunks::<0, u8, T, F>(
867            callback,
868            old_tree,
869            (options, ffi::TSInputEncodingCustom, Some(decode_fn::<D>)),
870        )
871    }
872
873    fn parse_utf16_slice<const LE: bool>(
874        &mut self,
875        code_points: &[u16],
876        old_tree: Option<&Tree>,
877    ) -> Option<Tree> {
878        let encoding = if LE {
879            ffi::TSInputEncodingUTF16LE
880        } else {
881            ffi::TSInputEncodingUTF16BE
882        };
883        if let Some(byte_len) = code_points
884            .len()
885            .checked_mul(2)
886            .and_then(|n| u32::try_from(n).ok())
887        {
888            return unsafe {
889                self.parse_raw_bytes(
890                    (code_points.as_ptr().cast::<c_char>(), byte_len),
891                    old_tree,
892                    encoding,
893                )
894            };
895        }
896        let len = code_points.len();
897        self.parse_utf16_with_options::<LE, _, _>(
898            &mut |i, _| if i < len { &code_points[i..] } else { &[] },
899            old_tree,
900            None,
901        )
902    }
903
904    fn parse_utf16_with_options<const LE: bool, T: AsRef<[u16]>, F: FnMut(usize, Point) -> T>(
905        &mut self,
906        callback: &mut F,
907        old_tree: Option<&Tree>,
908        options: Option<ParseOptions>,
909    ) -> Option<Tree> {
910        let encoding = if LE {
911            ffi::TSInputEncodingUTF16LE
912        } else {
913            ffi::TSInputEncodingUTF16BE
914        };
915        self.parse_chunks::<1, u16, T, F>(callback, old_tree, (options, encoding, None))
916    }
917
918    fn parse_chunks<const UNIT_SHIFT: u32, U, T: AsRef<[U]>, F: FnMut(usize, Point) -> T>(
919        &mut self,
920        callback: &mut F,
921        old_tree: Option<&Tree>,
922        (options, encoding, decode): (
923            Option<ParseOptions>,
924            ffi::TSInputEncoding,
925            ffi::TSDecodeFunction,
926        ),
927    ) -> Option<Tree> {
928        type Payload<'a, F, T> = (&'a mut F, Option<T>);
929
930        unsafe extern "C" fn read<
931            const UNIT_SHIFT: u32,
932            U,
933            T: AsRef<[U]>,
934            F: FnMut(usize, Point) -> T,
935        >(
936            payload: *mut c_void,
937            byte_offset: u32,
938            position: ffi::TSPoint,
939            bytes_read: *mut u32,
940        ) -> *const c_char {
941            unsafe {
942                let (callback, text) = payload.cast::<Payload<F, T>>().as_mut().unwrap();
943                *text = Some(callback(
944                    (byte_offset as usize) >> UNIT_SHIFT,
945                    Point {
946                        row: position.row as usize,
947                        column: (position.column as usize) >> UNIT_SHIFT,
948                    },
949                ));
950                let slice = text.as_ref().unwrap().as_ref();
951                *bytes_read =
952                    (slice.len().min((u32::MAX as usize) >> UNIT_SHIFT) << UNIT_SHIFT) as u32;
953                slice.as_ptr().cast::<c_char>()
954            }
955        }
956
957        // Hold the returned chunk in `payload` across the next C read so callbacks may return owned buffers.
958        let mut payload: Payload<F, T> = (callback, None);
959        let c_input = ffi::TSInput {
960            payload: ptr::addr_of_mut!(payload).cast::<c_void>(),
961            read: Some(read::<UNIT_SHIFT, U, T, F>),
962            encoding,
963            decode,
964        };
965        unsafe { self.parse_c_input(c_input, old_tree, options) }
966    }
967
968    unsafe fn parse_raw_bytes(
969        &mut self,
970        (bytes, byte_len): (*const c_char, u32),
971        old_tree: Option<&Tree>,
972        encoding: ffi::TSInputEncoding,
973    ) -> Option<Tree> {
974        let c_old_tree = old_tree.map_or(ptr::null(), |t| t.0.as_ptr().cast_const());
975        let c_new_tree = unsafe {
976            ffi::ts_parser_parse_string_encoding(
977                self.0.as_ptr(),
978                c_old_tree,
979                bytes,
980                byte_len,
981                encoding,
982            )
983        };
984        NonNull::new(c_new_tree).map(Tree)
985    }
986
987    unsafe fn parse_c_input(
988        &mut self,
989        c_input: ffi::TSInput,
990        old_tree: Option<&Tree>,
991        options: Option<ParseOptions>,
992    ) -> Option<Tree> {
993        unsafe extern "C" fn progress(state: *mut ffi::TSParseState) -> bool {
994            unsafe {
995                let callback = (*state)
996                    .payload
997                    .cast::<ParseProgressCallback>()
998                    .as_mut()
999                    .unwrap();
1000                match callback(&ParseState::from_raw(state)) {
1001                    ControlFlow::Continue(()) => false,
1002                    ControlFlow::Break(()) => true,
1003                }
1004            }
1005        }
1006
1007        let mut callback_ptr;
1008        let parse_options = if let Some(cb) = options.and_then(|o| o.progress_callback) {
1009            callback_ptr = cb;
1010            ffi::TSParseOptions {
1011                payload: core::ptr::addr_of_mut!(callback_ptr).cast::<c_void>(),
1012                progress_callback: Some(progress),
1013            }
1014        } else {
1015            ffi::TSParseOptions {
1016                payload: ptr::null_mut(),
1017                progress_callback: None,
1018            }
1019        };
1020
1021        let c_old_tree = old_tree.map_or(ptr::null_mut(), |t| t.0.as_ptr());
1022        let c_new_tree = unsafe {
1023            ffi::ts_parser_parse_with_options(self.0.as_ptr(), c_old_tree, c_input, parse_options)
1024        };
1025        NonNull::new(c_new_tree).map(Tree)
1026    }
1027
1028    /// Instruct the parser to start the next parse from the beginning.
1029    ///
1030    /// If the parser previously failed because of a callback, then by default,
1031    /// it will resume where it left off on the next call to [`parse`](Parser::parse)
1032    /// or other parsing functions. If you don't want to resume, and instead intend to use
1033    /// this parser to parse some other document, you must call `reset` first.
1034    #[doc(alias = "ts_parser_reset")]
1035    pub fn reset(&mut self) {
1036        unsafe { ffi::ts_parser_reset(self.0.as_ptr()) }
1037    }
1038
1039    /// Set the ranges of text that the parser should include when parsing.
1040    ///
1041    /// By default, the parser will always include entire documents. This
1042    /// function allows you to parse only a *portion* of a document but
1043    /// still return a syntax tree whose ranges match up with the document
1044    /// as a whole. You can also pass multiple disjoint ranges.
1045    ///
1046    /// If `ranges` is empty, then the entire document will be parsed.
1047    /// Otherwise, the given ranges must be ordered from earliest to latest
1048    /// in the document, and they must not overlap. That is, the following
1049    /// must hold for all `i` < `length - 1`:
1050    /// ```text
1051    ///     ranges[i].end_byte <= ranges[i + 1].start_byte
1052    /// ```
1053    /// If this requirement is not satisfied, method will return
1054    /// [`IncludedRangesError`] error with an offset in the passed ranges
1055    /// slice pointing to a first incorrect range.
1056    #[doc(alias = "ts_parser_set_included_ranges")]
1057    pub fn set_included_ranges(&mut self, ranges: &[Range]) -> Result<(), IncludedRangesError> {
1058        let ts_ranges = ranges.iter().copied().map(Into::into).collect::<Vec<_>>();
1059        let result = unsafe {
1060            ffi::ts_parser_set_included_ranges(
1061                self.0.as_ptr(),
1062                ts_ranges.as_ptr(),
1063                ts_ranges.len() as u32,
1064            )
1065        };
1066
1067        if result {
1068            Ok(())
1069        } else {
1070            let mut prev_end_byte = 0;
1071            for (i, range) in ranges.iter().enumerate() {
1072                if range.start_byte < prev_end_byte || range.end_byte < range.start_byte {
1073                    return Err(IncludedRangesError(i));
1074                }
1075                prev_end_byte = range.end_byte;
1076            }
1077            Err(IncludedRangesError(0))
1078        }
1079    }
1080
1081    /// Get the ranges of text that the parser will include when parsing.
1082    #[doc(alias = "ts_parser_included_ranges")]
1083    #[must_use]
1084    pub fn included_ranges(&self) -> Vec<Range> {
1085        let mut count = 0u32;
1086        unsafe {
1087            let ptr =
1088                ffi::ts_parser_included_ranges(self.0.as_ptr(), core::ptr::addr_of_mut!(count));
1089            let ranges = slice::from_raw_parts(ptr, count as usize);
1090            ranges.iter().copied().map(Into::into).collect()
1091        }
1092    }
1093}
1094
1095impl Drop for Parser {
1096    fn drop(&mut self) {
1097        #[cfg(feature = "std")]
1098        #[cfg(not(target_os = "wasi"))]
1099        {
1100            self.stop_printing_dot_graphs();
1101        }
1102        self.set_logger(None);
1103        unsafe { ffi::ts_parser_delete(self.0.as_ptr()) }
1104    }
1105}
1106
1107#[cfg(windows)]
1108unsafe extern "C" {
1109    fn _open_osfhandle(osfhandle: isize, flags: core::ffi::c_int) -> core::ffi::c_int;
1110}
1111
1112impl Tree {
1113    /// Get the root node of the syntax tree.
1114    #[doc(alias = "ts_tree_root_node")]
1115    #[must_use]
1116    pub fn root_node(&self) -> Node {
1117        Node::new(unsafe { ffi::ts_tree_root_node(self.0.as_ptr()) }).unwrap()
1118    }
1119
1120    /// Get the root node of the syntax tree, but with its position shifted
1121    /// forward by the given offset.
1122    #[doc(alias = "ts_tree_root_node_with_offset")]
1123    #[must_use]
1124    pub fn root_node_with_offset(&self, offset_bytes: usize, offset_extent: Point) -> Node {
1125        Node::new(unsafe {
1126            ffi::ts_tree_root_node_with_offset(
1127                self.0.as_ptr(),
1128                offset_bytes as u32,
1129                offset_extent.into(),
1130            )
1131        })
1132        .unwrap()
1133    }
1134
1135    /// Get the language that was used to parse the syntax tree.
1136    ///
1137    /// When Tree-sitter is compiled to WebAssembly, this returns the original
1138    /// language if the tree is being accessed from the same WebAssembly
1139    /// instance that created it. Otherwise, this returns a copy of the language
1140    /// that can be used to inspect the tree but cannot be assigned to a parser.
1141    #[doc(alias = "ts_tree_language")]
1142    #[must_use]
1143    pub fn language(&self) -> LanguageRef {
1144        LanguageRef(
1145            unsafe { ffi::ts_tree_language(self.0.as_ptr()) },
1146            PhantomData,
1147        )
1148    }
1149
1150    /// Edit the syntax tree to keep it in sync with source code that has been
1151    /// edited.
1152    ///
1153    /// You must describe the edit both in terms of byte offsets and in terms of
1154    /// row/column coordinates.
1155    #[doc(alias = "ts_tree_edit")]
1156    pub fn edit(&mut self, edit: &InputEdit) {
1157        let edit = edit.into();
1158        unsafe { ffi::ts_tree_edit(self.0.as_ptr(), &raw const edit) };
1159    }
1160
1161    /// Create a new [`TreeCursor`] starting from the root of the tree.
1162    #[must_use]
1163    pub fn walk(&self) -> TreeCursor {
1164        self.root_node().walk()
1165    }
1166
1167    /// Compare this old edited syntax tree to a new syntax tree representing
1168    /// the same document, returning a sequence of ranges whose syntactic
1169    /// structure has changed.
1170    ///
1171    /// For this to work correctly, this syntax tree must have been edited such
1172    /// that its ranges match up to the new tree. Generally, you'll want to
1173    /// call this method right after calling one of the [`Parser::parse`]
1174    /// functions. Call it on the old tree that was passed to parse, and
1175    /// pass the new tree that was returned from `parse`.
1176    #[doc(alias = "ts_tree_get_changed_ranges")]
1177    pub fn changed_ranges(&self, other: &Self) -> impl ExactSizeIterator<Item = Range> {
1178        let mut count = 0u32;
1179        unsafe {
1180            let ptr = ffi::ts_tree_get_changed_ranges(
1181                self.0.as_ptr(),
1182                other.0.as_ptr(),
1183                core::ptr::addr_of_mut!(count),
1184            );
1185            util::CBufferIter::new(ptr, count as usize).map(Into::into)
1186        }
1187    }
1188
1189    /// Get the included ranges that were used to parse the syntax tree.
1190    #[doc(alias = "ts_tree_included_ranges")]
1191    #[must_use]
1192    pub fn included_ranges(&self) -> Vec<Range> {
1193        let mut count = 0u32;
1194        unsafe {
1195            let ptr = ffi::ts_tree_included_ranges(self.0.as_ptr(), core::ptr::addr_of_mut!(count));
1196            let ranges = slice::from_raw_parts(ptr, count as usize);
1197            let result = ranges.iter().copied().map(Into::into).collect();
1198            ts_free(ptr.cast::<c_void>());
1199            result
1200        }
1201    }
1202
1203    /// Print a graph of the tree to the given file descriptor.
1204    /// The graph is formatted in the DOT language. You may want to pipe this
1205    /// graph directly to a `dot(1)` process in order to generate SVG
1206    /// output.
1207    #[doc(alias = "ts_tree_print_dot_graph")]
1208    #[cfg(not(target_os = "wasi"))]
1209    #[cfg(feature = "std")]
1210    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1211    pub fn print_dot_graph(
1212        &self,
1213        #[cfg(unix)] file: &impl AsRawFd,
1214        #[cfg(windows)] file: &impl AsRawHandle,
1215    ) {
1216        #[cfg(unix)]
1217        {
1218            let fd = file.as_raw_fd();
1219            unsafe { ffi::ts_tree_print_dot_graph(self.0.as_ptr(), fd) }
1220        }
1221
1222        #[cfg(windows)]
1223        {
1224            let handle = file.as_raw_handle();
1225            let fd = unsafe { _open_osfhandle(handle as isize, 0) };
1226            unsafe { ffi::ts_tree_print_dot_graph(self.0.as_ptr(), fd) }
1227        }
1228    }
1229}
1230
1231impl fmt::Debug for Tree {
1232    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1233        write!(f, "{{Tree {:?}}}", self.root_node())
1234    }
1235}
1236
1237impl Drop for Tree {
1238    fn drop(&mut self) {
1239        unsafe { ffi::ts_tree_delete(self.0.as_ptr()) }
1240    }
1241}
1242
1243impl Clone for Tree {
1244    fn clone(&self) -> Self {
1245        unsafe { Self(NonNull::new_unchecked(ffi::ts_tree_copy(self.0.as_ptr()))) }
1246    }
1247}
1248
1249impl<'tree> Node<'tree> {
1250    fn new(node: ffi::TSNode) -> Option<Self> {
1251        (!node.id.is_null()).then_some(Node(node, PhantomData))
1252    }
1253
1254    /// Get a numeric id for this node that is unique.
1255    ///
1256    /// Within a given syntax tree, no two nodes have the same id. However:
1257    ///
1258    /// - If a new tree is created based on an older tree, and a node from the old tree is reused in
1259    ///   the process, then that node will have the same id in both trees.
1260    ///
1261    /// - A node not marked as having changes does not guarantee it was reused.
1262    ///
1263    /// - If a node is marked as having changed in the old tree, it will not be reused.
1264    #[must_use]
1265    pub fn id(&self) -> usize {
1266        self.0.id as usize
1267    }
1268
1269    /// Get this node's type as a numerical id.
1270    #[doc(alias = "ts_node_symbol")]
1271    #[must_use]
1272    pub fn kind_id(&self) -> u16 {
1273        unsafe { ffi::ts_node_symbol(self.0) }
1274    }
1275
1276    /// Get the node's type as a numerical id as it appears in the grammar
1277    /// ignoring aliases.
1278    #[doc(alias = "ts_node_grammar_symbol")]
1279    #[must_use]
1280    pub fn grammar_id(&self) -> u16 {
1281        unsafe { ffi::ts_node_grammar_symbol(self.0) }
1282    }
1283
1284    /// Get this node's type as a string.
1285    #[doc(alias = "ts_node_type")]
1286    #[must_use]
1287    pub fn kind(&self) -> &'tree str {
1288        let ptr = unsafe { ffi::ts_node_type(self.0) };
1289        assert!(!ptr.is_null());
1290        unsafe { CStr::from_ptr(ptr) }.to_str().unwrap()
1291    }
1292
1293    /// Get this node's symbol name as it appears in the grammar ignoring
1294    /// aliases as a string.
1295    #[doc(alias = "ts_node_grammar_type")]
1296    #[must_use]
1297    pub fn grammar_name(&self) -> &'tree str {
1298        let ptr = unsafe { ffi::ts_node_grammar_type(self.0) };
1299        assert!(!ptr.is_null());
1300        unsafe { CStr::from_ptr(ptr) }.to_str().unwrap()
1301    }
1302
1303    /// Get the [`Language`] that was used to parse this node's syntax tree.
1304    ///
1305    /// When Tree-sitter is compiled to WebAssembly, this returns the original
1306    /// language if the node is being accessed from the same WebAssembly
1307    /// instance that created its tree. Otherwise, this returns a copy of the
1308    /// language that can be used to inspect the tree but cannot be assigned to
1309    /// a parser.
1310    #[doc(alias = "ts_node_language")]
1311    #[must_use]
1312    pub fn language(&self) -> LanguageRef<'tree> {
1313        LanguageRef(unsafe { ffi::ts_node_language(self.0) }, PhantomData)
1314    }
1315
1316    /// Check if this node is *named*.
1317    ///
1318    /// Named nodes correspond to named rules in the grammar, whereas
1319    /// *anonymous* nodes correspond to string literals in the grammar.
1320    #[doc(alias = "ts_node_is_named")]
1321    #[must_use]
1322    pub fn is_named(&self) -> bool {
1323        unsafe { ffi::ts_node_is_named(self.0) }
1324    }
1325
1326    /// Check if this node is *extra*.
1327    ///
1328    /// Extra nodes represent things like comments, which are not required by the
1329    /// grammar, but can appear anywhere.
1330    #[doc(alias = "ts_node_is_extra")]
1331    #[must_use]
1332    pub fn is_extra(&self) -> bool {
1333        unsafe { ffi::ts_node_is_extra(self.0) }
1334    }
1335
1336    /// Check if this node has been edited.
1337    #[doc(alias = "ts_node_has_changes")]
1338    #[must_use]
1339    pub fn has_changes(&self) -> bool {
1340        unsafe { ffi::ts_node_has_changes(self.0) }
1341    }
1342
1343    /// Check if this node represents a syntax error or contains any syntax
1344    /// errors anywhere within it.
1345    #[doc(alias = "ts_node_has_error")]
1346    #[must_use]
1347    pub fn has_error(&self) -> bool {
1348        unsafe { ffi::ts_node_has_error(self.0) }
1349    }
1350
1351    /// Check if this node represents a syntax error.
1352    ///
1353    /// Syntax errors represent parts of the code that could not be incorporated
1354    /// into a valid syntax tree.
1355    #[doc(alias = "ts_node_is_error")]
1356    #[must_use]
1357    pub fn is_error(&self) -> bool {
1358        unsafe { ffi::ts_node_is_error(self.0) }
1359    }
1360
1361    /// Get the parse state immediately before this node.
1362    ///
1363    /// For a missing node, this is the state from the recovery path that was
1364    /// selected by the parser. It can be used with
1365    /// [`Language::lookahead_iterator`] to inspect the symbols that are valid in
1366    /// that state. This does not necessarily include every symbol that could be
1367    /// recovered by inserting a missing node, because the recovery process can
1368    /// consider multiple stack versions.
1369    #[doc(alias = "ts_node_parse_state")]
1370    #[must_use]
1371    pub fn parse_state(&self) -> u16 {
1372        unsafe { ffi::ts_node_parse_state(self.0) }
1373    }
1374
1375    /// Get the parse state after this node.
1376    #[doc(alias = "ts_node_next_parse_state")]
1377    #[must_use]
1378    pub fn next_parse_state(&self) -> u16 {
1379        unsafe { ffi::ts_node_next_parse_state(self.0) }
1380    }
1381
1382    /// Check if this node is *missing*.
1383    ///
1384    /// Missing nodes are inserted by the parser in order to recover from
1385    /// certain kinds of syntax errors.
1386    #[doc(alias = "ts_node_is_missing")]
1387    #[must_use]
1388    pub fn is_missing(&self) -> bool {
1389        unsafe { ffi::ts_node_is_missing(self.0) }
1390    }
1391
1392    /// Get the byte offset where this node starts.
1393    #[doc(alias = "ts_node_start_byte")]
1394    #[must_use]
1395    pub fn start_byte(&self) -> usize {
1396        unsafe { ffi::ts_node_start_byte(self.0) as usize }
1397    }
1398
1399    /// Get the byte offset where this node ends.
1400    #[doc(alias = "ts_node_end_byte")]
1401    #[must_use]
1402    pub fn end_byte(&self) -> usize {
1403        unsafe { ffi::ts_node_end_byte(self.0) as usize }
1404    }
1405
1406    /// Get the byte range of source code that this node represents.
1407    #[must_use]
1408    pub fn byte_range(&self) -> core::ops::Range<usize> {
1409        self.start_byte()..self.end_byte()
1410    }
1411
1412    /// Get the range of source code that this node represents, both in terms of
1413    /// raw bytes and of row/column coordinates.
1414    #[must_use]
1415    pub fn range(&self) -> Range {
1416        Range {
1417            start_byte: self.start_byte(),
1418            end_byte: self.end_byte(),
1419            start_point: self.start_position(),
1420            end_point: self.end_position(),
1421        }
1422    }
1423
1424    /// Get this node's start position in terms of rows and columns.
1425    #[doc(alias = "ts_node_start_point")]
1426    #[must_use]
1427    pub fn start_position(&self) -> Point {
1428        let result = unsafe { ffi::ts_node_start_point(self.0) };
1429        result.into()
1430    }
1431
1432    /// Get this node's end position in terms of rows and columns.
1433    #[doc(alias = "ts_node_end_point")]
1434    #[must_use]
1435    pub fn end_position(&self) -> Point {
1436        let result = unsafe { ffi::ts_node_end_point(self.0) };
1437        result.into()
1438    }
1439
1440    /// Get the node's child at the given index, where zero represents the first
1441    /// child.
1442    ///
1443    /// This method is fairly fast, but its cost is technically log(i), so if
1444    /// you might be iterating over a long list of children, you should use
1445    /// [`Node::children`] instead.
1446    #[doc(alias = "ts_node_child")]
1447    #[must_use]
1448    pub fn child(&self, i: u32) -> Option<Self> {
1449        Self::new(unsafe { ffi::ts_node_child(self.0, i) })
1450    }
1451
1452    /// Get this node's number of children.
1453    #[doc(alias = "ts_node_child_count")]
1454    #[must_use]
1455    pub fn child_count(&self) -> u32 {
1456        unsafe { ffi::ts_node_child_count(self.0) }
1457    }
1458
1459    /// Get this node's *named* child at the given index.
1460    ///
1461    /// See also [`Node::is_named`].
1462    /// This method is fairly fast, but its cost is technically log(i), so if
1463    /// you might be iterating over a long list of children, you should use
1464    /// [`Node::named_children`] instead.
1465    #[doc(alias = "ts_node_named_child")]
1466    #[must_use]
1467    pub fn named_child(&self, i: u32) -> Option<Self> {
1468        Self::new(unsafe { ffi::ts_node_named_child(self.0, i) })
1469    }
1470
1471    /// Get this node's number of *named* children.
1472    ///
1473    /// See also [`Node::is_named`].
1474    #[doc(alias = "ts_node_named_child_count")]
1475    #[must_use]
1476    pub fn named_child_count(&self) -> usize {
1477        unsafe { ffi::ts_node_named_child_count(self.0) as usize }
1478    }
1479
1480    /// Get the first child with the given field name.
1481    ///
1482    /// If multiple children may have the same field name, access them using
1483    /// [`children_by_field_name`](Node::children_by_field_name)
1484    #[doc(alias = "ts_node_child_by_field_name")]
1485    #[must_use]
1486    pub fn child_by_field_name(&self, field_name: impl AsRef<[u8]>) -> Option<Self> {
1487        let field_name = field_name.as_ref();
1488        Self::new(unsafe {
1489            ffi::ts_node_child_by_field_name(
1490                self.0,
1491                field_name.as_ptr().cast::<c_char>(),
1492                field_name.len() as u32,
1493            )
1494        })
1495    }
1496
1497    /// Get this node's child with the given numerical field id.
1498    ///
1499    /// See also [`child_by_field_name`](Node::child_by_field_name). You can
1500    /// convert a field name to an id using [`Language::field_id_for_name`].
1501    #[doc(alias = "ts_node_child_by_field_id")]
1502    #[must_use]
1503    pub fn child_by_field_id(&self, field_id: u16) -> Option<Self> {
1504        Self::new(unsafe { ffi::ts_node_child_by_field_id(self.0, field_id) })
1505    }
1506
1507    /// Get the field name of this node's child at the given index.
1508    #[doc(alias = "ts_node_field_name_for_child")]
1509    #[must_use]
1510    pub fn field_name_for_child(&self, child_index: u32) -> Option<&'tree str> {
1511        unsafe {
1512            let ptr = ffi::ts_node_field_name_for_child(self.0, child_index);
1513            (!ptr.is_null()).then(|| CStr::from_ptr(ptr).to_str().unwrap())
1514        }
1515    }
1516
1517    /// Get the field name of this node's named child at the given index.
1518    #[must_use]
1519    pub fn field_name_for_named_child(&self, named_child_index: u32) -> Option<&'tree str> {
1520        unsafe {
1521            let ptr = ffi::ts_node_field_name_for_named_child(self.0, named_child_index);
1522            (!ptr.is_null()).then(|| CStr::from_ptr(ptr).to_str().unwrap())
1523        }
1524    }
1525
1526    /// Iterate over this node's children.
1527    ///
1528    /// A [`TreeCursor`] is used to retrieve the children efficiently. Obtain
1529    /// a [`TreeCursor`] by calling [`Tree::walk`] or [`Node::walk`]. To avoid
1530    /// unnecessary allocations, you should reuse the same cursor for
1531    /// subsequent calls to this method.
1532    ///
1533    /// If you're walking the tree recursively, you may want to use the
1534    /// [`TreeCursor`] APIs directly instead.
1535    pub fn children<'cursor>(
1536        &self,
1537        cursor: &'cursor mut TreeCursor<'tree>,
1538    ) -> impl ExactSizeIterator<Item = Node<'tree>> + 'cursor {
1539        cursor.reset(*self);
1540        cursor.goto_first_child();
1541        (0..self.child_count()).map(move |_| {
1542            let result = cursor.node();
1543            cursor.goto_next_sibling();
1544            result
1545        })
1546    }
1547
1548    /// Iterate over this node's named children.
1549    ///
1550    /// See also [`Node::children`].
1551    pub fn named_children<'cursor>(
1552        &self,
1553        cursor: &'cursor mut TreeCursor<'tree>,
1554    ) -> impl ExactSizeIterator<Item = Node<'tree>> + 'cursor {
1555        cursor.reset(*self);
1556        cursor.goto_first_child();
1557        (0..self.named_child_count()).map(move |_| {
1558            while !cursor.node().is_named() {
1559                if !cursor.goto_next_sibling() {
1560                    break;
1561                }
1562            }
1563            let result = cursor.node();
1564            cursor.goto_next_sibling();
1565            result
1566        })
1567    }
1568
1569    /// Iterate over this node's children with a given field name.
1570    ///
1571    /// See also [`Node::children`].
1572    pub fn children_by_field_name<'cursor>(
1573        &self,
1574        field_name: &str,
1575        cursor: &'cursor mut TreeCursor<'tree>,
1576    ) -> impl Iterator<Item = Node<'tree>> + 'cursor {
1577        let field_id = self.language().field_id_for_name(field_name);
1578        let mut done = field_id.is_none();
1579        if !done {
1580            cursor.reset(*self);
1581            cursor.goto_first_child();
1582        }
1583        iter::from_fn(move || {
1584            if !done {
1585                while cursor.field_id() != field_id {
1586                    if !cursor.goto_next_sibling() {
1587                        return None;
1588                    }
1589                }
1590                let result = cursor.node();
1591                if !cursor.goto_next_sibling() {
1592                    done = true;
1593                }
1594                return Some(result);
1595            }
1596            None
1597        })
1598    }
1599
1600    /// Iterate over this node's children with a given field id.
1601    ///
1602    /// See also [`Node::children_by_field_name`].
1603    pub fn children_by_field_id<'cursor>(
1604        &self,
1605        field_id: FieldId,
1606        cursor: &'cursor mut TreeCursor<'tree>,
1607    ) -> impl Iterator<Item = Node<'tree>> + 'cursor {
1608        cursor.reset(*self);
1609        cursor.goto_first_child();
1610        let mut done = false;
1611        iter::from_fn(move || {
1612            if !done {
1613                while cursor.field_id() != Some(field_id) {
1614                    if !cursor.goto_next_sibling() {
1615                        return None;
1616                    }
1617                }
1618                let result = cursor.node();
1619                if !cursor.goto_next_sibling() {
1620                    done = true;
1621                }
1622                return Some(result);
1623            }
1624            None
1625        })
1626    }
1627
1628    /// Get this node's immediate parent.
1629    /// Prefer [`child_with_descendant`](Node::child_with_descendant)
1630    /// for iterating over this node's ancestors.
1631    #[doc(alias = "ts_node_parent")]
1632    #[must_use]
1633    pub fn parent(&self) -> Option<Self> {
1634        Self::new(unsafe { ffi::ts_node_parent(self.0) })
1635    }
1636
1637    /// Get the node that contains `descendant`.
1638    ///
1639    /// Note that this can return `descendant` itself.
1640    #[doc(alias = "ts_node_child_with_descendant")]
1641    #[must_use]
1642    pub fn child_with_descendant(&self, descendant: Self) -> Option<Self> {
1643        Self::new(unsafe { ffi::ts_node_child_with_descendant(self.0, descendant.0) })
1644    }
1645
1646    /// Get this node's next sibling.
1647    #[doc(alias = "ts_node_next_sibling")]
1648    #[must_use]
1649    pub fn next_sibling(&self) -> Option<Self> {
1650        Self::new(unsafe { ffi::ts_node_next_sibling(self.0) })
1651    }
1652
1653    /// Get this node's previous sibling.
1654    #[doc(alias = "ts_node_prev_sibling")]
1655    #[must_use]
1656    pub fn prev_sibling(&self) -> Option<Self> {
1657        Self::new(unsafe { ffi::ts_node_prev_sibling(self.0) })
1658    }
1659
1660    /// Get this node's next named sibling.
1661    #[doc(alias = "ts_node_next_named_sibling")]
1662    #[must_use]
1663    pub fn next_named_sibling(&self) -> Option<Self> {
1664        Self::new(unsafe { ffi::ts_node_next_named_sibling(self.0) })
1665    }
1666
1667    /// Get this node's previous named sibling.
1668    #[doc(alias = "ts_node_prev_named_sibling")]
1669    #[must_use]
1670    pub fn prev_named_sibling(&self) -> Option<Self> {
1671        Self::new(unsafe { ffi::ts_node_prev_named_sibling(self.0) })
1672    }
1673
1674    /// Get this node's first child that contains or starts after the given byte offset.
1675    #[doc(alias = "ts_node_first_child_for_byte")]
1676    #[must_use]
1677    pub fn first_child_for_byte(&self, byte: usize) -> Option<Self> {
1678        Self::new(unsafe { ffi::ts_node_first_child_for_byte(self.0, byte as u32) })
1679    }
1680
1681    /// Get this node's first named child that contains or starts after the given byte offset.
1682    #[doc(alias = "ts_node_first_named_child_for_point")]
1683    #[must_use]
1684    pub fn first_named_child_for_byte(&self, byte: usize) -> Option<Self> {
1685        Self::new(unsafe { ffi::ts_node_first_named_child_for_byte(self.0, byte as u32) })
1686    }
1687
1688    /// Get the node's number of descendants, including one for the node itself.
1689    #[doc(alias = "ts_node_descendant_count")]
1690    #[must_use]
1691    pub fn descendant_count(&self) -> usize {
1692        unsafe { ffi::ts_node_descendant_count(self.0) as usize }
1693    }
1694
1695    /// Get the smallest node within this node that spans the given byte range.
1696    #[doc(alias = "ts_node_descendant_for_byte_range")]
1697    #[must_use]
1698    pub fn descendant_for_byte_range(&self, start: usize, end: usize) -> Option<Self> {
1699        Self::new(unsafe {
1700            ffi::ts_node_descendant_for_byte_range(self.0, start as u32, end as u32)
1701        })
1702    }
1703
1704    /// Get the smallest named node within this node that spans the given byte range.
1705    #[doc(alias = "ts_node_named_descendant_for_byte_range")]
1706    #[must_use]
1707    pub fn named_descendant_for_byte_range(&self, start: usize, end: usize) -> Option<Self> {
1708        Self::new(unsafe {
1709            ffi::ts_node_named_descendant_for_byte_range(self.0, start as u32, end as u32)
1710        })
1711    }
1712
1713    /// Get the smallest node within this node that spans the given point range.
1714    #[doc(alias = "ts_node_descendant_for_point_range")]
1715    #[must_use]
1716    pub fn descendant_for_point_range(&self, start: Point, end: Point) -> Option<Self> {
1717        Self::new(unsafe {
1718            ffi::ts_node_descendant_for_point_range(self.0, start.into(), end.into())
1719        })
1720    }
1721
1722    /// Get the smallest named node within this node that spans the given point range.
1723    #[doc(alias = "ts_node_named_descendant_for_point_range")]
1724    #[must_use]
1725    pub fn named_descendant_for_point_range(&self, start: Point, end: Point) -> Option<Self> {
1726        Self::new(unsafe {
1727            ffi::ts_node_named_descendant_for_point_range(self.0, start.into(), end.into())
1728        })
1729    }
1730
1731    /// Get an S-expression representing the node.
1732    #[doc(alias = "ts_node_string")]
1733    #[must_use]
1734    pub fn to_sexp(&self) -> String {
1735        let c_string = unsafe { ffi::ts_node_string(self.0) };
1736        let result = unsafe { CStr::from_ptr(c_string) }
1737            .to_str()
1738            .unwrap()
1739            .to_string();
1740        unsafe { ts_free(c_string.cast::<c_void>()) };
1741        result
1742    }
1743
1744    pub fn utf8_text<'a>(&self, source: &'a [u8]) -> Result<&'a str, str::Utf8Error> {
1745        str::from_utf8(&source[self.start_byte()..self.end_byte()])
1746    }
1747
1748    #[must_use]
1749    pub fn utf16_text<'a>(&self, source: &'a [u16]) -> &'a [u16] {
1750        &source[self.start_byte() / 2..self.end_byte() / 2]
1751    }
1752
1753    /// Create a new [`TreeCursor`] starting from this node.
1754    ///
1755    /// Note that the given node is considered the root of the cursor,
1756    /// and the cursor cannot walk outside this node.
1757    #[doc(alias = "ts_tree_cursor_new")]
1758    #[must_use]
1759    pub fn walk(&self) -> TreeCursor<'tree> {
1760        TreeCursor(unsafe { ffi::ts_tree_cursor_new(self.0) }, PhantomData)
1761    }
1762
1763    /// Edit this node to keep it in-sync with source code that has been edited.
1764    ///
1765    /// This function is only rarely needed. When you edit a syntax tree with
1766    /// the [`Tree::edit`] method, all of the nodes that you retrieve from
1767    /// the tree afterward will already reflect the edit. You only need to
1768    /// use [`Node::edit`] when you have a specific [`Node`] instance that
1769    /// you want to keep and continue to use after an edit.
1770    #[doc(alias = "ts_node_edit")]
1771    pub fn edit(&mut self, edit: &InputEdit) {
1772        let edit = edit.into();
1773        unsafe { ffi::ts_node_edit(core::ptr::addr_of_mut!(self.0), &raw const edit) }
1774    }
1775}
1776
1777impl PartialEq for Node<'_> {
1778    fn eq(&self, other: &Self) -> bool {
1779        core::ptr::eq(self.0.id, other.0.id)
1780    }
1781}
1782
1783impl Eq for Node<'_> {}
1784
1785impl hash::Hash for Node<'_> {
1786    fn hash<H: hash::Hasher>(&self, state: &mut H) {
1787        self.0.id.hash(state);
1788        self.0.context[0].hash(state);
1789        self.0.context[1].hash(state);
1790        self.0.context[2].hash(state);
1791        self.0.context[3].hash(state);
1792    }
1793}
1794
1795impl fmt::Debug for Node<'_> {
1796    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1797        write!(
1798            f,
1799            "{{Node {} {} - {}}}",
1800            self.kind(),
1801            self.start_position(),
1802            self.end_position()
1803        )
1804    }
1805}
1806
1807impl fmt::Display for Node<'_> {
1808    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1809        if !f.alternate() {
1810            return f.write_str(&self.to_sexp());
1811        }
1812        let c_string = unsafe { ts_node_string_pretty(self.0, f.width().unwrap_or(0)) };
1813        let result = unsafe { CStr::from_ptr(c_string) }
1814            .to_str()
1815            .unwrap()
1816            .to_string();
1817        unsafe { ts_free(c_string.cast::<c_void>()) };
1818        f.write_str(&result)
1819    }
1820}
1821
1822impl<'tree> TreeCursor<'tree> {
1823    /// Get the tree cursor's current [`Node`].
1824    #[doc(alias = "ts_tree_cursor_current_node")]
1825    #[must_use]
1826    pub fn node(&self) -> Node<'tree> {
1827        Node(
1828            unsafe { ffi::ts_tree_cursor_current_node(&raw const self.0) },
1829            PhantomData,
1830        )
1831    }
1832
1833    /// Get the numerical field id of this tree cursor's current node.
1834    ///
1835    /// See also [`field_name`](TreeCursor::field_name).
1836    #[doc(alias = "ts_tree_cursor_current_field_id")]
1837    #[must_use]
1838    pub fn field_id(&self) -> Option<FieldId> {
1839        let id = unsafe { ffi::ts_tree_cursor_current_field_id(&raw const self.0) };
1840        FieldId::new(id)
1841    }
1842
1843    /// Get the field name of this tree cursor's current node.
1844    #[doc(alias = "ts_tree_cursor_current_field_name")]
1845    #[must_use]
1846    pub fn field_name(&self) -> Option<&'tree str> {
1847        unsafe {
1848            let ptr = ffi::ts_tree_cursor_current_field_name(&raw const self.0);
1849            (!ptr.is_null()).then(|| CStr::from_ptr(ptr).to_str().unwrap())
1850        }
1851    }
1852
1853    /// Get the depth of the cursor's current node relative to the original
1854    /// node that the cursor was constructed with.
1855    #[doc(alias = "ts_tree_cursor_current_depth")]
1856    #[must_use]
1857    pub fn depth(&self) -> u32 {
1858        unsafe { ffi::ts_tree_cursor_current_depth(&raw const self.0) }
1859    }
1860
1861    /// Get the index of the cursor's current node out of all of the
1862    /// descendants of the original node that the cursor was constructed with
1863    #[doc(alias = "ts_tree_cursor_current_descendant_index")]
1864    #[must_use]
1865    pub fn descendant_index(&self) -> usize {
1866        unsafe { ffi::ts_tree_cursor_current_descendant_index(&raw const self.0) as usize }
1867    }
1868
1869    /// Move this cursor to the first child of its current node.
1870    ///
1871    /// This returns `true` if the cursor successfully moved, and returns
1872    /// `false` if there were no children.
1873    #[doc(alias = "ts_tree_cursor_goto_first_child")]
1874    pub fn goto_first_child(&mut self) -> bool {
1875        unsafe { ffi::ts_tree_cursor_goto_first_child(&raw mut self.0) }
1876    }
1877
1878    /// Move this cursor to the last child of its current node.
1879    ///
1880    /// This returns `true` if the cursor successfully moved, and returns
1881    /// `false` if there were no children.
1882    ///
1883    /// Note that this function may be slower than
1884    /// [`goto_first_child`](TreeCursor::goto_first_child) because it needs to
1885    /// iterate through all the children to compute the child's position.
1886    #[doc(alias = "ts_tree_cursor_goto_last_child")]
1887    pub fn goto_last_child(&mut self) -> bool {
1888        unsafe { ffi::ts_tree_cursor_goto_last_child(&raw mut self.0) }
1889    }
1890
1891    /// Move this cursor to the parent of its current node.
1892    ///
1893    /// This returns `true` if the cursor successfully moved, and returns
1894    /// `false` if there was no parent node (the cursor was already on the
1895    /// root node).
1896    ///
1897    /// Note that the node the cursor was constructed with is considered the root
1898    /// of the cursor, and the cursor cannot walk outside this node.
1899    #[doc(alias = "ts_tree_cursor_goto_parent")]
1900    pub fn goto_parent(&mut self) -> bool {
1901        unsafe { ffi::ts_tree_cursor_goto_parent(&raw mut self.0) }
1902    }
1903
1904    /// Move this cursor to the next sibling of its current node.
1905    ///
1906    /// This returns `true` if the cursor successfully moved, and returns
1907    /// `false` if there was no next sibling node.
1908    ///
1909    /// Note that the node the cursor was constructed with is considered the root
1910    /// of the cursor, and the cursor cannot walk outside this node.
1911    #[doc(alias = "ts_tree_cursor_goto_next_sibling")]
1912    pub fn goto_next_sibling(&mut self) -> bool {
1913        unsafe { ffi::ts_tree_cursor_goto_next_sibling(&raw mut self.0) }
1914    }
1915
1916    /// Move the cursor to the node that is the nth descendant of
1917    /// the original node that the cursor was constructed with, where
1918    /// zero represents the original node itself.
1919    #[doc(alias = "ts_tree_cursor_goto_descendant")]
1920    pub fn goto_descendant(&mut self, descendant_index: usize) {
1921        unsafe { ffi::ts_tree_cursor_goto_descendant(&raw mut self.0, descendant_index as u32) }
1922    }
1923
1924    /// Move this cursor to the previous sibling of its current node.
1925    ///
1926    /// This returns `true` if the cursor successfully moved, and returns
1927    /// `false` if there was no previous sibling node.
1928    ///
1929    /// Note, that this function may be slower than
1930    /// [`goto_next_sibling`](TreeCursor::goto_next_sibling) due to how node
1931    /// positions are stored. In the worst case, this will need to iterate
1932    /// through all the children up to the previous sibling node to recalculate
1933    /// its position. Also note that the node the cursor was constructed with is
1934    /// considered the root of the cursor, and the cursor cannot walk outside this node.
1935    #[doc(alias = "ts_tree_cursor_goto_previous_sibling")]
1936    pub fn goto_previous_sibling(&mut self) -> bool {
1937        unsafe { ffi::ts_tree_cursor_goto_previous_sibling(&raw mut self.0) }
1938    }
1939
1940    /// Move this cursor to the first child of its current node that contains or
1941    /// starts after the given byte offset.
1942    ///
1943    /// This returns the index of the child node if one was found, and returns
1944    /// `None` if no such child was found.
1945    #[doc(alias = "ts_tree_cursor_goto_first_child_for_byte")]
1946    pub fn goto_first_child_for_byte(&mut self, index: usize) -> Option<usize> {
1947        let result =
1948            unsafe { ffi::ts_tree_cursor_goto_first_child_for_byte(&raw mut self.0, index as u32) };
1949        result.try_into().ok()
1950    }
1951
1952    /// Move this cursor to the first child of its current node that contains or
1953    /// starts after the given byte offset.
1954    ///
1955    /// This returns the index of the child node if one was found, and returns
1956    /// `None` if no such child was found.
1957    #[doc(alias = "ts_tree_cursor_goto_first_child_for_point")]
1958    pub fn goto_first_child_for_point(&mut self, point: Point) -> Option<usize> {
1959        let result = unsafe {
1960            ffi::ts_tree_cursor_goto_first_child_for_point(&raw mut self.0, point.into())
1961        };
1962        result.try_into().ok()
1963    }
1964
1965    /// Re-initialize this tree cursor to start at the original node that the
1966    /// cursor was constructed with.
1967    #[doc(alias = "ts_tree_cursor_reset")]
1968    pub fn reset(&mut self, node: Node<'tree>) {
1969        unsafe { ffi::ts_tree_cursor_reset(&raw mut self.0, node.0) };
1970    }
1971
1972    /// Re-initialize a tree cursor to the same position as another cursor.
1973    ///
1974    /// Unlike [`reset`](TreeCursor::reset), this will not lose parent
1975    /// information and allows reusing already created cursors.
1976    #[doc(alias = "ts_tree_cursor_reset_to")]
1977    pub fn reset_to(&mut self, cursor: &Self) {
1978        unsafe { ffi::ts_tree_cursor_reset_to(&raw mut self.0, &raw const cursor.0) };
1979    }
1980}
1981
1982impl Clone for TreeCursor<'_> {
1983    fn clone(&self) -> Self {
1984        TreeCursor(
1985            unsafe { ffi::ts_tree_cursor_copy(&raw const self.0) },
1986            PhantomData,
1987        )
1988    }
1989}
1990
1991impl Drop for TreeCursor<'_> {
1992    fn drop(&mut self) {
1993        unsafe { ffi::ts_tree_cursor_delete(&raw mut self.0) }
1994    }
1995}
1996
1997impl Point {
1998    #[must_use]
1999    pub const fn new(row: usize, column: usize) -> Self {
2000        Self { row, column }
2001    }
2002}
2003
2004impl fmt::Display for Point {
2005    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2006        write!(f, "({}, {})", self.row, self.column)
2007    }
2008}
2009
2010impl From<Point> for ffi::TSPoint {
2011    fn from(val: Point) -> Self {
2012        Self {
2013            row: val.row as u32,
2014            column: val.column as u32,
2015        }
2016    }
2017}
2018
2019impl From<ffi::TSPoint> for Point {
2020    fn from(point: ffi::TSPoint) -> Self {
2021        Self {
2022            row: point.row as usize,
2023            column: point.column as usize,
2024        }
2025    }
2026}
2027
2028impl From<Range> for ffi::TSRange {
2029    fn from(val: Range) -> Self {
2030        Self {
2031            start_byte: val.start_byte as u32,
2032            end_byte: val.end_byte as u32,
2033            start_point: val.start_point.into(),
2034            end_point: val.end_point.into(),
2035        }
2036    }
2037}
2038
2039impl From<ffi::TSRange> for Range {
2040    fn from(range: ffi::TSRange) -> Self {
2041        Self {
2042            start_byte: range.start_byte as usize,
2043            end_byte: range.end_byte as usize,
2044            start_point: range.start_point.into(),
2045            end_point: range.end_point.into(),
2046        }
2047    }
2048}
2049
2050impl From<&InputEdit> for ffi::TSInputEdit {
2051    fn from(val: &InputEdit) -> Self {
2052        Self {
2053            start_byte: val.start_byte as u32,
2054            old_end_byte: val.old_end_byte as u32,
2055            new_end_byte: val.new_end_byte as u32,
2056            start_point: val.start_position.into(),
2057            old_end_point: val.old_end_position.into(),
2058            new_end_point: val.new_end_position.into(),
2059        }
2060    }
2061}
2062
2063impl fmt::Display for IncludedRangesError {
2064    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2065        write!(f, "Incorrect range by index: {}", self.0)
2066    }
2067}
2068
2069impl fmt::Display for LanguageError {
2070    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2071        match self {
2072            Self::Version(version) => {
2073                write!(
2074                    f,
2075                    "Incompatible language version {version:#x}. Expected {LANGUAGE_VERSION:#x}",
2076                )
2077            }
2078            Self::NotParseable => {
2079                write!(f, "Language cannot be used for parsing.")
2080            }
2081            #[cfg(feature = "wasm")]
2082            Self::Wasm => {
2083                write!(f, "Failed to load the Wasm store.")
2084            }
2085        }
2086    }
2087}
2088
2089pub fn wasm_stdlib_symbols() -> impl Iterator<Item = &'static str> {
2090    const WASM_STDLIB_SYMBOLS: &str = include_str!(concat!(env!("OUT_DIR"), "/stdlib-symbols.txt"));
2091
2092    WASM_STDLIB_SYMBOLS
2093        .lines()
2094        .map(|s| s.trim_matches(|c| c == '"' || c == ','))
2095}
2096
2097unsafe extern "C" {
2098    fn ts_node_string_pretty(node: ffi::TSNode, initial_indent_level: usize) -> *mut c_char;
2099    static mut ts_current_free: unsafe extern "C" fn(ptr: *mut c_void);
2100}
2101
2102/// Frees a pointer that was returned by a tree-sitter C API using whichever `free`
2103/// function is currently installed via [`set_allocator`] or [`ffi::ts_set_allocator`].
2104#[inline]
2105unsafe fn ts_free(ptr: *mut c_void) {
2106    let f = unsafe { core::ptr::addr_of!(ts_current_free).read() };
2107    unsafe { f(ptr) };
2108}
2109
2110/// A complete set of memory allocation functions for the core C library.
2111#[derive(Copy, Clone)]
2112pub struct Allocator {
2113    pub malloc: unsafe extern "C" fn(size: usize) -> *mut c_void,
2114    pub calloc: unsafe extern "C" fn(nmemb: usize, size: usize) -> *mut c_void,
2115    pub realloc: unsafe extern "C" fn(ptr: *mut c_void, size: usize) -> *mut c_void,
2116    pub free: unsafe extern "C" fn(ptr: *mut c_void),
2117}
2118
2119/// Replaces the memory allocation functions used by the core C library.
2120///
2121/// Pass `Some` to install an allocator, or `None` to restore libc defaults.
2122///
2123/// # Safety
2124///
2125/// All of the following must hold:
2126///
2127/// - The four functions must belong to a single allocator family.
2128///
2129/// - The functions must not return null for non-zero allocs.
2130///
2131/// - Returned pointers must satisfy the alignment that libc `malloc` provides.
2132///
2133/// - Call this before any other tree-sitter API call, and do not call it again
2134///   while live tree-sitter objects exist.
2135///
2136/// - This function is not thread-safe.
2137#[doc(alias = "ts_set_allocator")]
2138pub unsafe fn set_allocator(allocator: Option<Allocator>) {
2139    let (m, c, r, f) = match allocator {
2140        Some(a) => (
2141            Some(a.malloc),
2142            Some(a.calloc),
2143            Some(a.realloc),
2144            Some(a.free),
2145        ),
2146        None => (None, None, None, None),
2147    };
2148    unsafe { ffi::ts_set_allocator(m, c, r, f) };
2149}
2150
2151#[cfg(feature = "std")]
2152#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
2153impl error::Error for IncludedRangesError {}
2154#[cfg(feature = "std")]
2155#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
2156impl error::Error for LanguageError {}
2157
2158#[cfg(not(target_family = "wasm"))]
2159unsafe impl Send for Language {}
2160#[cfg(not(target_family = "wasm"))]
2161unsafe impl Sync for Language {}
2162
2163unsafe impl Send for Node<'_> {}
2164unsafe impl Sync for Node<'_> {}
2165
2166#[cfg(not(target_family = "wasm"))]
2167unsafe impl Send for Parser {}
2168#[cfg(not(target_family = "wasm"))]
2169unsafe impl Sync for Parser {}
2170
2171unsafe impl Send for Tree {}
2172unsafe impl Sync for Tree {}
2173
2174unsafe impl Send for TreeCursor<'_> {}
2175unsafe impl Sync for TreeCursor<'_> {}