validate method
void
validate()
Implementation
void validate() {
if (name.isEmpty || symbolCount <= 0 || stateCount <= 0) {
throw const FormatException('Invalid empty Tree-sitter language table');
}
if (symbols.length < symbolCount || lexModes.length != stateCount) {
throw const FormatException('Tree-sitter table count mismatch');
}
if ((publicSymbolMap.isNotEmpty &&
publicSymbolMap.length != nodeKindCount) ||
publicSymbolMap.any(
(symbol) => symbol < 0 || symbol >= nodeKindCount,
)) {
throw const FormatException('Tree-sitter public-symbol map mismatch');
}
if (maxReservedWordSetSize < 0 ||
(maxReservedWordSetSize == 0 && reservedWords.isNotEmpty) ||
(maxReservedWordSetSize > 0 &&
reservedWords.length % maxReservedWordSetSize != 0) ||
reservedWords.any((symbol) => symbol < 0 || symbol >= symbolCount)) {
throw const FormatException('Tree-sitter reserved-word table mismatch');
}
if ((fieldCount == 0
? fieldNames.isNotEmpty || fieldMapSlices.isNotEmpty
: fieldNames.length != fieldCount + 1 ||
fieldMapSlices.length != productionIdCount) ||
fieldMapEntries.any(
(entry) => entry.fieldId <= 0 || entry.fieldId >= fieldNames.length,
) ||
fieldMapSlices.any(
(slice) =>
slice.index < 0 ||
slice.length < 0 ||
slice.index + slice.length > fieldMapEntries.length,
)) {
throw const FormatException('Tree-sitter field-map count mismatch');
}
if ((aliasSequences.isNotEmpty &&
aliasSequences.length != productionIdCount) ||
aliasSequences.any(
(sequence) =>
sequence.any((symbol) => symbol < 0 || symbol >= symbols.length),
)) {
throw const FormatException('Tree-sitter alias-sequence mismatch');
}
if ((nonTerminalAliasMap.isNotEmpty &&
nonTerminalAliasMap.length != symbolCount) ||
nonTerminalAliasMap.any(
(aliases) =>
aliases.any((symbol) => symbol < 0 || symbol >= symbols.length),
)) {
throw const FormatException(
'Tree-sitter non-terminal alias-map mismatch',
);
}
final hasFullParseTable = parseTable.length == stateCount;
if (!hasFullParseTable &&
(parseTable.length != largeStateCount ||
smallParseTableMap.length != stateCount - largeStateCount)) {
throw const FormatException('Tree-sitter parse-state count mismatch');
}
if (externalSymbols.length != externalTokenCount) {
throw const FormatException('Tree-sitter external-symbol count mismatch');
}
if ((primaryStateIds.isNotEmpty && primaryStateIds.length != stateCount) ||
primaryStateIds.any((state) => state < 0 || state >= stateCount)) {
throw const FormatException('Tree-sitter primary-state count mismatch');
}
if (supertypeMapSlices.length > symbolCount ||
supertypeSymbols.any(
(symbol) => symbol < 0 || symbol >= symbols.length,
) ||
supertypeMapEntries.any(
(symbol) => symbol < 0 || symbol >= symbols.length,
) ||
supertypeMapSlices.any(
(slice) =>
slice.index < 0 ||
slice.length < 0 ||
slice.index + slice.length > supertypeMapEntries.length,
)) {
throw const FormatException('Tree-sitter supertype-map mismatch');
}
if (externalTokenCount > 0) {
if (externalLexStates.isEmpty ||
externalLexStates.any((row) => row.length != externalTokenCount) ||
!externalLexStates.any((row) => row.any((value) => value))) {
throw const FormatException(
'Tree-sitter external-lex-state table mismatch',
);
}
if (lexModes.any(
(mode) => mode.externalLexState >= externalLexStates.length,
)) {
throw const FormatException(
'Tree-sitter lex mode references a missing external state',
);
}
}
}