1#include "./language.h"
  2#include "./subtree.h"
  3#include "./error_costs.h"
  4#include <string.h>
  5
  6uint32_t ts_language_symbol_count(const TSLanguage *self) {
  7  return self->symbol_count + self->alias_count;
  8}
  9
 10uint32_t ts_language_state_count(const TSLanguage *self) {
 11  return self->state_count;
 12}
 13
 14uint32_t ts_language_version(const TSLanguage *self) {
 15  return self->version;
 16}
 17
 18uint32_t ts_language_field_count(const TSLanguage *self) {
 19  return self->field_count;
 20}
 21
 22void ts_language_table_entry(
 23  const TSLanguage *self,
 24  TSStateId state,
 25  TSSymbol symbol,
 26  TableEntry *result
 27) {
 28  if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat) {
 29    result->action_count = 0;
 30    result->is_reusable = false;
 31    result->actions = NULL;
 32  } else {
 33    assert(symbol < self->token_count);
 34    uint32_t action_index = ts_language_lookup(self, state, symbol);
 35    const TSParseActionEntry *entry = &self->parse_actions[action_index];
 36    result->action_count = entry->entry.count;
 37    result->is_reusable = entry->entry.reusable;
 38    result->actions = (const TSParseAction *)(entry + 1);
 39  }
 40}
 41
 42TSSymbolMetadata ts_language_symbol_metadata(
 43  const TSLanguage *self,
 44  TSSymbol symbol
 45) {
 46  if (symbol == ts_builtin_sym_error)  {
 47    return (TSSymbolMetadata) {.visible = true, .named = true};
 48  } else if (symbol == ts_builtin_sym_error_repeat) {
 49    return (TSSymbolMetadata) {.visible = false, .named = false};
 50  } else {
 51    return self->symbol_metadata[symbol];
 52  }
 53}
 54
 55TSSymbol ts_language_public_symbol(
 56  const TSLanguage *self,
 57  TSSymbol symbol
 58) {
 59  if (symbol == ts_builtin_sym_error) return symbol;
 60  return self->public_symbol_map[symbol];
 61}
 62
 63TSStateId ts_language_next_state(
 64  const TSLanguage *self,
 65  TSStateId state,
 66  TSSymbol symbol
 67) {
 68  if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat) {
 69    return 0;
 70  } else if (symbol < self->token_count) {
 71    uint32_t count;
 72    const TSParseAction *actions = ts_language_actions(self, state, symbol, &count);
 73    if (count > 0) {
 74      TSParseAction action = actions[count - 1];
 75      if (action.type == TSParseActionTypeShift) {
 76        return action.shift.extra ? state : action.shift.state;
 77      }
 78    }
 79    return 0;
 80  } else {
 81    return ts_language_lookup(self, state, symbol);
 82  }
 83}
 84
 85const char *ts_language_symbol_name(
 86  const TSLanguage *self,
 87  TSSymbol symbol
 88) {
 89  if (symbol == ts_builtin_sym_error) {
 90    return "ERROR";
 91  } else if (symbol == ts_builtin_sym_error_repeat) {
 92    return "_ERROR";
 93  } else if (symbol < ts_language_symbol_count(self)) {
 94    return self->symbol_names[symbol];
 95  } else {
 96    return NULL;
 97  }
 98}
 99
100TSSymbol ts_language_symbol_for_name(
101  const TSLanguage *self,
102  const char *string,
103  uint32_t length,
104  bool is_named
105) {
106  if (!strncmp(string, "ERROR", length)) return ts_builtin_sym_error;
107  uint16_t count = (uint16_t)ts_language_symbol_count(self);
108  for (TSSymbol i = 0; i < count; i++) {
109    TSSymbolMetadata metadata = ts_language_symbol_metadata(self, i);
110    if ((!metadata.visible && !metadata.supertype) || metadata.named != is_named) continue;
111    const char *symbol_name = self->symbol_names[i];
112    if (!strncmp(symbol_name, string, length) && !symbol_name[length]) {
113      return self->public_symbol_map[i];
114    }
115  }
116  return 0;
117}
118
119TSSymbolType ts_language_symbol_type(
120  const TSLanguage *self,
121  TSSymbol symbol
122) {
123  TSSymbolMetadata metadata = ts_language_symbol_metadata(self, symbol);
124  if (metadata.named && metadata.visible) {
125    return TSSymbolTypeRegular;
126  } else if (metadata.visible) {
127    return TSSymbolTypeAnonymous;
128  } else {
129    return TSSymbolTypeAuxiliary;
130  }
131}
132
133const char *ts_language_field_name_for_id(
134  const TSLanguage *self,
135  TSFieldId id
136) {
137  uint32_t count = ts_language_field_count(self);
138  if (count && id <= count) {
139    return self->field_names[id];
140  } else {
141    return NULL;
142  }
143}
144
145TSFieldId ts_language_field_id_for_name(
146  const TSLanguage *self,
147  const char *name,
148  uint32_t name_length
149) {
150  uint16_t count = (uint16_t)ts_language_field_count(self);
151  for (TSSymbol i = 1; i < count + 1; i++) {
152    switch (strncmp(name, self->field_names[i], name_length)) {
153      case 0:
154        if (self->field_names[i][name_length] == 0) return i;
155        break;
156      case -1:
157        return 0;
158      default:
159        break;
160    }
161  }
162  return 0;
163}
164
165TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state) {
166  if (state >= self->state_count) return NULL;
167  LookaheadIterator *iterator = ts_malloc(sizeof(LookaheadIterator));
168  *iterator = ts_language_lookaheads(self, state);
169  return (TSLookaheadIterator *)iterator;
170}
171
172void ts_lookahead_iterator_delete(TSLookaheadIterator *self) {
173  ts_free(self);
174}
175
176bool ts_lookahead_iterator_reset_state(TSLookaheadIterator * self, TSStateId state) {
177  LookaheadIterator *iterator = (LookaheadIterator *)self;
178  if (state >= iterator->language->state_count) return false;
179  *iterator = ts_language_lookaheads(iterator->language, state);
180  return true;
181}
182
183const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self) {
184  const LookaheadIterator *iterator = (const LookaheadIterator *)self;
185  return iterator->language;
186}
187
188bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state) {
189  if (state >= language->state_count) return false;
190  LookaheadIterator *iterator = (LookaheadIterator *)self;
191  *iterator = ts_language_lookaheads(language, state);
192  return true;
193}
194
195bool ts_lookahead_iterator_next(TSLookaheadIterator *self) {
196  LookaheadIterator *iterator = (LookaheadIterator *)self;
197  return ts_lookahead_iterator__next(iterator);
198}
199
200TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) {
201  const LookaheadIterator *iterator = (const LookaheadIterator *)self;
202  return iterator->symbol;
203}
204
205const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) {
206  const LookaheadIterator *iterator = (const LookaheadIterator *)self;
207  return ts_language_symbol_name(iterator->language, iterator->symbol);
208}