1#include "api.h"
  2#include "./alloc.h"
  3#include "./tree_cursor.h"
  4#include "./language.h"
  5#include "./tree.h"
  6
  7typedef struct {
  8  Subtree parent;
  9  const TSTree *tree;
 10  Length position;
 11  uint32_t child_index;
 12  uint32_t structural_child_index;
 13  uint32_t descendant_index;
 14  const TSSymbol *alias_sequence;
 15} CursorChildIterator;
 16
 17// CursorChildIterator
 18
 19static inline bool ts_tree_cursor_is_entry_visible(const TreeCursor *self, uint32_t index) {
 20  TreeCursorEntry *entry = &self->stack.contents[index];
 21  if (index == 0 || ts_subtree_visible(*entry->subtree)) {
 22    return true;
 23  } else if (!ts_subtree_extra(*entry->subtree)) {
 24    TreeCursorEntry *parent_entry = &self->stack.contents[index - 1];
 25    return ts_language_alias_at(
 26      self->tree->language,
 27      parent_entry->subtree->ptr->production_id,
 28      entry->structural_child_index
 29    );
 30  } else {
 31    return false;
 32  }
 33}
 34
 35static inline CursorChildIterator ts_tree_cursor_iterate_children(const TreeCursor *self) {
 36  TreeCursorEntry *last_entry = array_back(&self->stack);
 37  if (ts_subtree_child_count(*last_entry->subtree) == 0) {
 38    return (CursorChildIterator) {NULL_SUBTREE, self->tree, length_zero(), 0, 0, 0, NULL};
 39  }
 40  const TSSymbol *alias_sequence = ts_language_alias_sequence(
 41    self->tree->language,
 42    last_entry->subtree->ptr->production_id
 43  );
 44
 45  uint32_t descendant_index = last_entry->descendant_index;
 46  if (ts_tree_cursor_is_entry_visible(self, self->stack.size - 1)) {
 47    descendant_index += 1;
 48  }
 49
 50  return (CursorChildIterator) {
 51    .tree = self->tree,
 52    .parent = *last_entry->subtree,
 53    .position = last_entry->position,
 54    .child_index = 0,
 55    .structural_child_index = 0,
 56    .descendant_index = descendant_index,
 57    .alias_sequence = alias_sequence,
 58  };
 59}
 60
 61static inline bool ts_tree_cursor_child_iterator_next(
 62  CursorChildIterator *self,
 63  TreeCursorEntry *result,
 64  bool *visible
 65) {
 66  if (!self->parent.ptr || self->child_index == self->parent.ptr->child_count) return false;
 67  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
 68  *result = (TreeCursorEntry) {
 69    .subtree = child,
 70    .position = self->position,
 71    .child_index = self->child_index,
 72    .structural_child_index = self->structural_child_index,
 73    .descendant_index = self->descendant_index,
 74  };
 75  *visible = ts_subtree_visible(*child);
 76  bool extra = ts_subtree_extra(*child);
 77  if (!extra) {
 78    if (self->alias_sequence) {
 79      *visible |= self->alias_sequence[self->structural_child_index];
 80    }
 81    self->structural_child_index++;
 82  }
 83
 84  self->descendant_index += ts_subtree_visible_descendant_count(*child);
 85  if (*visible) {
 86    self->descendant_index += 1;
 87  }
 88
 89  self->position = length_add(self->position, ts_subtree_size(*child));
 90  self->child_index++;
 91
 92  if (self->child_index < self->parent.ptr->child_count) {
 93    Subtree next_child = ts_subtree_children(self->parent)[self->child_index];
 94    self->position = length_add(self->position, ts_subtree_padding(next_child));
 95  }
 96
 97  return true;
 98}
 99
100// Return a position that, when `b` is added to it, yields `a`. This
101// can only be computed if `b` has zero rows. Otherwise, this function
102// returns `LENGTH_UNDEFINED`, and the caller needs to recompute
103// the position some other way.
104static inline Length length_backtrack(Length a, Length b) {
105  if (length_is_undefined(a) || b.extent.row != 0) {
106    return LENGTH_UNDEFINED;
107  }
108
109  Length result;
110  result.bytes = a.bytes - b.bytes;
111  result.extent.row = a.extent.row;
112  result.extent.column = a.extent.column - b.extent.column;
113  return result;
114}
115
116static inline bool ts_tree_cursor_child_iterator_previous(
117  CursorChildIterator *self,
118  TreeCursorEntry *result,
119  bool *visible
120) {
121  // this is mostly a reverse `ts_tree_cursor_child_iterator_next` taking into
122  // account unsigned underflow
123  if (!self->parent.ptr || (int8_t)self->child_index == -1) return false;
124  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
125  *result = (TreeCursorEntry) {
126    .subtree = child,
127    .position = self->position,
128    .child_index = self->child_index,
129    .structural_child_index = self->structural_child_index,
130  };
131  *visible = ts_subtree_visible(*child);
132  bool extra = ts_subtree_extra(*child);
133  if (!extra && self->alias_sequence) {
134    *visible |= self->alias_sequence[self->structural_child_index];
135    self->structural_child_index--;
136  }
137
138  self->position = length_backtrack(self->position, ts_subtree_padding(*child));
139  self->child_index--;
140
141  // unsigned can underflow so compare it to child_count
142  if (self->child_index < self->parent.ptr->child_count) {
143    Subtree previous_child = ts_subtree_children(self->parent)[self->child_index];
144    Length size = ts_subtree_size(previous_child);
145    self->position = length_backtrack(self->position, size);
146  }
147
148  return true;
149}
150
151// TSTreeCursor - lifecycle
152
153TSTreeCursor ts_tree_cursor_new(TSNode node) {
154  TSTreeCursor self = {NULL, NULL, {0, 0, 0}};
155  ts_tree_cursor_init((TreeCursor *)&self, node);
156  return self;
157}
158
159void ts_tree_cursor_reset(TSTreeCursor *_self, TSNode node) {
160  ts_tree_cursor_init((TreeCursor *)_self, node);
161}
162
163void ts_tree_cursor_init(TreeCursor *self, TSNode node) {
164  self->tree = node.tree;
165  self->root_alias_symbol = node.context[3];
166  array_clear(&self->stack);
167  array_push(&self->stack, ((TreeCursorEntry) {
168    .subtree = (const Subtree *)node.id,
169    .position = {
170      ts_node_start_byte(node),
171      ts_node_start_point(node)
172    },
173    .child_index = 0,
174    .structural_child_index = 0,
175    .descendant_index = 0,
176  }));
177}
178
179void ts_tree_cursor_delete(TSTreeCursor *_self) {
180  TreeCursor *self = (TreeCursor *)_self;
181  array_delete(&self->stack);
182}
183
184// TSTreeCursor - walking the tree
185
186TreeCursorStep ts_tree_cursor_goto_first_child_internal(TSTreeCursor *_self) {
187  TreeCursor *self = (TreeCursor *)_self;
188  bool visible;
189  TreeCursorEntry entry;
190  CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
191  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
192    if (visible) {
193      array_push(&self->stack, entry);
194      return TreeCursorStepVisible;
195    }
196    if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
197      array_push(&self->stack, entry);
198      return TreeCursorStepHidden;
199    }
200  }
201  return TreeCursorStepNone;
202}
203
204bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) {
205  for (;;) {
206    switch (ts_tree_cursor_goto_first_child_internal(self)) {
207      case TreeCursorStepHidden:
208        continue;
209      case TreeCursorStepVisible:
210        return true;
211      default:
212        return false;
213    }
214  }
215  return false;
216}
217
218TreeCursorStep ts_tree_cursor_goto_last_child_internal(TSTreeCursor *_self) {
219  TreeCursor *self = (TreeCursor *)_self;
220  bool visible;
221  TreeCursorEntry entry;
222  CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
223  if (!iterator.parent.ptr || iterator.parent.ptr->child_count == 0) return TreeCursorStepNone;
224
225  TreeCursorEntry last_entry = {0};
226  TreeCursorStep last_step = TreeCursorStepNone;
227  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
228    if (visible) {
229      last_entry = entry;
230      last_step = TreeCursorStepVisible;
231    }
232    else if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
233      last_entry = entry;
234      last_step = TreeCursorStepHidden;
235    }
236  }
237  if (last_entry.subtree) {
238    array_push(&self->stack, last_entry);
239    return last_step;
240  }
241
242  return TreeCursorStepNone;
243}
244
245bool ts_tree_cursor_goto_last_child(TSTreeCursor *self) {
246  for (;;) {
247    switch (ts_tree_cursor_goto_last_child_internal(self)) {
248      case TreeCursorStepHidden:
249        continue;
250      case TreeCursorStepVisible:
251        return true;
252      default:
253        return false;
254    }
255  }
256  return false;
257}
258
259static inline int64_t ts_tree_cursor_goto_first_child_for_byte_and_point(
260  TSTreeCursor *_self,
261  uint32_t goal_byte,
262  TSPoint goal_point
263) {
264  TreeCursor *self = (TreeCursor *)_self;
265  uint32_t initial_size = self->stack.size;
266  uint32_t visible_child_index = 0;
267
268  bool did_descend;
269  do {
270    did_descend = false;
271
272    bool visible;
273    TreeCursorEntry entry;
274    CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
275    while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
276      Length entry_end = length_add(entry.position, ts_subtree_size(*entry.subtree));
277      bool at_goal = entry_end.bytes >= goal_byte && point_gte(entry_end.extent, goal_point);
278      uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
279      if (at_goal) {
280        if (visible) {
281          array_push(&self->stack, entry);
282          return visible_child_index;
283        }
284        if (visible_child_count > 0) {
285          array_push(&self->stack, entry);
286          did_descend = true;
287          break;
288        }
289      } else if (visible) {
290        visible_child_index++;
291      } else {
292        visible_child_index += visible_child_count;
293      }
294    }
295  } while (did_descend);
296
297  self->stack.size = initial_size;
298  return -1;
299}
300
301int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) {
302  return ts_tree_cursor_goto_first_child_for_byte_and_point(self, goal_byte, POINT_ZERO);
303}
304
305int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) {
306  return ts_tree_cursor_goto_first_child_for_byte_and_point(self, 0, goal_point);
307}
308
309TreeCursorStep ts_tree_cursor_goto_sibling_internal(
310    TSTreeCursor *_self,
311    bool (*advance)(CursorChildIterator *, TreeCursorEntry *, bool *)) {
312  TreeCursor *self = (TreeCursor *)_self;
313  uint32_t initial_size = self->stack.size;
314
315  while (self->stack.size > 1) {
316    TreeCursorEntry entry = array_pop(&self->stack);
317    CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
318    iterator.child_index = entry.child_index;
319    iterator.structural_child_index = entry.structural_child_index;
320    iterator.position = entry.position;
321    iterator.descendant_index = entry.descendant_index;
322
323    bool visible = false;
324    advance(&iterator, &entry, &visible);
325    if (visible && self->stack.size + 1 < initial_size) break;
326
327    while (advance(&iterator, &entry, &visible)) {
328      if (visible) {
329        array_push(&self->stack, entry);
330        return TreeCursorStepVisible;
331      }
332
333      if (ts_subtree_visible_child_count(*entry.subtree)) {
334        array_push(&self->stack, entry);
335        return TreeCursorStepHidden;
336      }
337    }
338  }
339
340  self->stack.size = initial_size;
341  return TreeCursorStepNone;
342}
343
344TreeCursorStep ts_tree_cursor_goto_next_sibling_internal(TSTreeCursor *_self) {
345  return ts_tree_cursor_goto_sibling_internal(_self, ts_tree_cursor_child_iterator_next);
346}
347
348bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) {
349  switch (ts_tree_cursor_goto_next_sibling_internal(self)) {
350    case TreeCursorStepHidden:
351      ts_tree_cursor_goto_first_child(self);
352      return true;
353    case TreeCursorStepVisible:
354      return true;
355    default:
356      return false;
357  }
358}
359
360TreeCursorStep ts_tree_cursor_goto_previous_sibling_internal(TSTreeCursor *_self) {
361  // since subtracting across row loses column information, we may have to
362  // restore it
363  TreeCursor *self = (TreeCursor *)_self;
364
365  // for that, save current position before traversing
366  TreeCursorStep step = ts_tree_cursor_goto_sibling_internal(
367      _self, ts_tree_cursor_child_iterator_previous);
368  if (step == TreeCursorStepNone)
369    return step;
370
371  // if length is already valid, there's no need to recompute it
372  if (!length_is_undefined(array_back(&self->stack)->position))
373    return step;
374
375  // restore position from the parent node
376  const TreeCursorEntry *parent = &self->stack.contents[self->stack.size - 2];
377  Length position = parent->position;
378  uint32_t child_index = array_back(&self->stack)->child_index;
379  const Subtree *children = ts_subtree_children((*(parent->subtree)));
380
381  if (child_index > 0) {
382    // skip first child padding since its position should match the position of the parent
383    position = length_add(position, ts_subtree_size(children[0]));
384    for (uint32_t i = 1; i < child_index; ++i) {
385      position = length_add(position, ts_subtree_total_size(children[i]));
386    }
387    position = length_add(position, ts_subtree_padding(children[child_index]));
388  }
389
390  array_back(&self->stack)->position = position;
391
392  return step;
393}
394
395bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self) {
396  switch (ts_tree_cursor_goto_previous_sibling_internal(self)) {
397    case TreeCursorStepHidden:
398      ts_tree_cursor_goto_last_child(self);
399      return true;
400    case TreeCursorStepVisible:
401      return true;
402    default:
403      return false;
404  }
405}
406
407bool ts_tree_cursor_goto_parent(TSTreeCursor *_self) {
408  TreeCursor *self = (TreeCursor *)_self;
409  for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
410    if (ts_tree_cursor_is_entry_visible(self, i)) {
411      self->stack.size = i + 1;
412      return true;
413    }
414  }
415  return false;
416}
417
418void ts_tree_cursor_goto_descendant(
419  TSTreeCursor *_self,
420  uint32_t goal_descendant_index
421) {
422  TreeCursor *self = (TreeCursor *)_self;
423
424  // Ascend to the lowest ancestor that contains the goal node.
425  for (;;) {
426    uint32_t i = self->stack.size - 1;
427    TreeCursorEntry *entry = &self->stack.contents[i];
428    uint32_t next_descendant_index =
429      entry->descendant_index +
430      (ts_tree_cursor_is_entry_visible(self, i) ? 1 : 0) +
431      ts_subtree_visible_descendant_count(*entry->subtree);
432    if (
433      (entry->descendant_index <= goal_descendant_index) &&
434      (next_descendant_index > goal_descendant_index)
435    ) {
436      break;
437    } else if (self->stack.size <= 1) {
438      return;
439    } else {
440      self->stack.size--;
441    }
442  }
443
444  // Descend to the goal node.
445  bool did_descend = true;
446  do {
447    did_descend = false;
448    bool visible;
449    TreeCursorEntry entry;
450    CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
451    if (iterator.descendant_index > goal_descendant_index) {
452      return;
453    }
454
455    while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
456      if (iterator.descendant_index > goal_descendant_index) {
457        array_push(&self->stack, entry);
458        if (visible && entry.descendant_index == goal_descendant_index) {
459          return;
460        } else {
461          did_descend = true;
462          break;
463        }
464      }
465    }
466  } while (did_descend);
467}
468
469uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *_self) {
470  const TreeCursor *self = (const TreeCursor *)_self;
471  TreeCursorEntry *last_entry = array_back(&self->stack);
472  return last_entry->descendant_index;
473}
474
475TSNode ts_tree_cursor_current_node(const TSTreeCursor *_self) {
476  const TreeCursor *self = (const TreeCursor *)_self;
477  TreeCursorEntry *last_entry = array_back(&self->stack);
478  TSSymbol alias_symbol = self->root_alias_symbol;
479  if (self->stack.size > 1 && !ts_subtree_extra(*last_entry->subtree)) {
480    TreeCursorEntry *parent_entry = &self->stack.contents[self->stack.size - 2];
481    alias_symbol = ts_language_alias_at(
482      self->tree->language,
483      parent_entry->subtree->ptr->production_id,
484      last_entry->structural_child_index
485    );
486  }
487  return ts_node_new(
488    self->tree,
489    last_entry->subtree,
490    last_entry->position,
491    alias_symbol
492  );
493}
494
495// Private - Get various facts about the current node that are needed
496// when executing tree queries.
497void ts_tree_cursor_current_status(
498  const TSTreeCursor *_self,
499  TSFieldId *field_id,
500  bool *has_later_siblings,
501  bool *has_later_named_siblings,
502  bool *can_have_later_siblings_with_this_field,
503  TSSymbol *supertypes,
504  unsigned *supertype_count
505) {
506  const TreeCursor *self = (const TreeCursor *)_self;
507  unsigned max_supertypes = *supertype_count;
508  *field_id = 0;
509  *supertype_count = 0;
510  *has_later_siblings = false;
511  *has_later_named_siblings = false;
512  *can_have_later_siblings_with_this_field = false;
513
514  // Walk up the tree, visiting the current node and its invisible ancestors,
515  // because fields can refer to nodes through invisible *wrapper* nodes,
516  for (unsigned i = self->stack.size - 1; i > 0; i--) {
517    TreeCursorEntry *entry = &self->stack.contents[i];
518    TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
519
520    const TSSymbol *alias_sequence = ts_language_alias_sequence(
521      self->tree->language,
522      parent_entry->subtree->ptr->production_id
523    );
524
525    #define subtree_symbol(subtree, structural_child_index) \
526      ((                                                    \
527        !ts_subtree_extra(subtree) &&                       \
528        alias_sequence &&                                   \
529        alias_sequence[structural_child_index]              \
530      ) ?                                                   \
531        alias_sequence[structural_child_index] :            \
532        ts_subtree_symbol(subtree))
533
534    // Stop walking up when a visible ancestor is found.
535    TSSymbol entry_symbol = subtree_symbol(
536      *entry->subtree,
537      entry->structural_child_index
538    );
539    TSSymbolMetadata entry_metadata = ts_language_symbol_metadata(
540      self->tree->language,
541      entry_symbol
542    );
543    if (i != self->stack.size - 1 && entry_metadata.visible) break;
544
545    // Record any supertypes
546    if (entry_metadata.supertype && *supertype_count < max_supertypes) {
547      supertypes[*supertype_count] = entry_symbol;
548      (*supertype_count)++;
549    }
550
551    // Determine if the current node has later siblings.
552    if (!*has_later_siblings) {
553      unsigned sibling_count = parent_entry->subtree->ptr->child_count;
554      unsigned structural_child_index = entry->structural_child_index;
555      if (!ts_subtree_extra(*entry->subtree)) structural_child_index++;
556      for (unsigned j = entry->child_index + 1; j < sibling_count; j++) {
557        Subtree sibling = ts_subtree_children(*parent_entry->subtree)[j];
558        TSSymbolMetadata sibling_metadata = ts_language_symbol_metadata(
559          self->tree->language,
560          subtree_symbol(sibling, structural_child_index)
561        );
562        if (sibling_metadata.visible) {
563          *has_later_siblings = true;
564          if (*has_later_named_siblings) break;
565          if (sibling_metadata.named) {
566            *has_later_named_siblings = true;
567            break;
568          }
569        } else if (ts_subtree_visible_child_count(sibling) > 0) {
570          *has_later_siblings = true;
571          if (*has_later_named_siblings) break;
572          if (sibling.ptr->named_child_count > 0) {
573            *has_later_named_siblings = true;
574            break;
575          }
576        }
577        if (!ts_subtree_extra(sibling)) structural_child_index++;
578      }
579    }
580
581    #undef subtree_symbol
582
583    if (!ts_subtree_extra(*entry->subtree)) {
584      const TSFieldMapEntry *field_map, *field_map_end;
585      ts_language_field_map(
586        self->tree->language,
587        parent_entry->subtree->ptr->production_id,
588        &field_map, &field_map_end
589      );
590
591      // Look for a field name associated with the current node.
592      if (!*field_id) {
593        for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {
594          if (!map->inherited && map->child_index == entry->structural_child_index) {
595            *field_id = map->field_id;
596            break;
597          }
598        }
599      }
600
601      // Determine if the current node can have later siblings with the same field name.
602      if (*field_id) {
603        for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {
604          if (
605            map->field_id == *field_id &&
606            map->child_index > entry->structural_child_index
607          ) {
608            *can_have_later_siblings_with_this_field = true;
609            break;
610          }
611        }
612      }
613    }
614  }
615}
616
617uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *_self) {
618  const TreeCursor *self = (const TreeCursor *)_self;
619  uint32_t depth = 0;
620  for (unsigned i = 1; i < self->stack.size; i++) {
621    if (ts_tree_cursor_is_entry_visible(self, i)) {
622      depth++;
623    }
624  }
625  return depth;
626}
627
628TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self) {
629  const TreeCursor *self = (const TreeCursor *)_self;
630  for (int i = (int)self->stack.size - 2; i >= 0; i--) {
631    TreeCursorEntry *entry = &self->stack.contents[i];
632    bool is_visible = true;
633    TSSymbol alias_symbol = 0;
634    if (i > 0) {
635      TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
636      alias_symbol = ts_language_alias_at(
637        self->tree->language,
638        parent_entry->subtree->ptr->production_id,
639        entry->structural_child_index
640      );
641      is_visible = (alias_symbol != 0) || ts_subtree_visible(*entry->subtree);
642    }
643    if (is_visible) {
644      return ts_node_new(
645        self->tree,
646        entry->subtree,
647        entry->position,
648        alias_symbol
649      );
650    }
651  }
652  return ts_node_new(NULL, NULL, length_zero(), 0);
653}
654
655TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self) {
656  const TreeCursor *self = (const TreeCursor *)_self;
657
658  // Walk up the tree, visiting the current node and its invisible ancestors.
659  for (unsigned i = self->stack.size - 1; i > 0; i--) {
660    TreeCursorEntry *entry = &self->stack.contents[i];
661    TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
662
663    // Stop walking up when another visible node is found.
664    if (
665      i != self->stack.size - 1 &&
666      ts_tree_cursor_is_entry_visible(self, i)
667    ) break;
668
669    if (ts_subtree_extra(*entry->subtree)) break;
670
671    const TSFieldMapEntry *field_map, *field_map_end;
672    ts_language_field_map(
673      self->tree->language,
674      parent_entry->subtree->ptr->production_id,
675      &field_map, &field_map_end
676    );
677    for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {
678      if (!map->inherited && map->child_index == entry->structural_child_index) {
679        return map->field_id;
680      }
681    }
682  }
683  return 0;
684}
685
686const char *ts_tree_cursor_current_field_name(const TSTreeCursor *_self) {
687  TSFieldId id = ts_tree_cursor_current_field_id(_self);
688  if (id) {
689    const TreeCursor *self = (const TreeCursor *)_self;
690    return self->tree->language->field_names[id];
691  } else {
692    return NULL;
693  }
694}
695
696TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *_cursor) {
697  const TreeCursor *cursor = (const TreeCursor *)_cursor;
698  TSTreeCursor res = {NULL, NULL, {0, 0}};
699  TreeCursor *copy = (TreeCursor *)&res;
700  copy->tree = cursor->tree;
701  copy->root_alias_symbol = cursor->root_alias_symbol;
702  array_init(&copy->stack);
703  array_push_all(&copy->stack, &cursor->stack);
704  return res;
705}
706
707void ts_tree_cursor_reset_to(TSTreeCursor *_dst, const TSTreeCursor *_src) {
708  const TreeCursor *cursor = (const TreeCursor *)_src;
709  TreeCursor *copy = (TreeCursor *)_dst;
710  copy->tree = cursor->tree;
711  copy->root_alias_symbol = cursor->root_alias_symbol;
712  array_clear(&copy->stack);
713  array_push_all(&copy->stack, &cursor->stack);
714}