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