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