'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); exports.SchemaCoordinateLexer = void 0; var _syntaxError = require('../error/syntaxError.js'); var _ast = require('./ast.js'); var _characterClasses = require('./characterClasses.js'); var _lexer = require('./lexer.js'); var _tokenKind = require('./tokenKind.js'); /** * Given a Source schema coordinate, creates a Lexer for that source. * A SchemaCoordinateLexer is a stateful stream generator in that every time * it is advanced, it returns the next token in the Source. Assuming the * source lexes, the final Token emitted by the lexer will be of kind * EOF, after which the lexer will repeatedly return the same EOF token * whenever called. */ class SchemaCoordinateLexer { /** * The previously focused non-ignored token. */ /** * The currently focused non-ignored token. */ /** * The (1-indexed) line containing the current token. * Since a schema coordinate may not contain newline, this value is always 1. */ line = 1; /** * The character offset at which the current line begins. * Since a schema coordinate may not contain newline, this value is always 0. */ lineStart = 0; constructor(source) { const startOfFileToken = new _ast.Token( _tokenKind.TokenKind.SOF, 0, 0, 0, 0, ); this.source = source; this.lastToken = startOfFileToken; this.token = startOfFileToken; } get [Symbol.toStringTag]() { return 'SchemaCoordinateLexer'; } /** * Advances the token stream to the next non-ignored token. */ advance() { this.lastToken = this.token; const token = (this.token = this.lookahead()); return token; } /** * Looks ahead and returns the next non-ignored token, but does not change * the current Lexer token. */ lookahead() { let token = this.token; if (token.kind !== _tokenKind.TokenKind.EOF) { // Read the next token and form a link in the token linked-list. const nextToken = readNextToken(this, token.end); // @ts-expect-error next is only mutable during parsing. token.next = nextToken; // @ts-expect-error prev is only mutable during parsing. nextToken.prev = token; token = nextToken; } return token; } } /** * Gets the next token from the source starting at the given position. */ exports.SchemaCoordinateLexer = SchemaCoordinateLexer; function readNextToken(lexer, start) { const body = lexer.source.body; const bodyLength = body.length; const position = start; if (position < bodyLength) { const code = body.charCodeAt(position); switch (code) { case 0x002e: // . return (0, _lexer.createToken)( lexer, _tokenKind.TokenKind.DOT, position, position + 1, ); case 0x0028: // ( return (0, _lexer.createToken)( lexer, _tokenKind.TokenKind.PAREN_L, position, position + 1, ); case 0x0029: // ) return (0, _lexer.createToken)( lexer, _tokenKind.TokenKind.PAREN_R, position, position + 1, ); case 0x003a: // : return (0, _lexer.createToken)( lexer, _tokenKind.TokenKind.COLON, position, position + 1, ); case 0x0040: // @ return (0, _lexer.createToken)( lexer, _tokenKind.TokenKind.AT, position, position + 1, ); } // Name if ((0, _characterClasses.isNameStart)(code)) { return (0, _lexer.readName)(lexer, position); } throw (0, _syntaxError.syntaxError)( lexer.source, position, `Invalid character: ${(0, _lexer.printCodePointAt)(lexer, position)}.`, ); } return (0, _lexer.createToken)( lexer, _tokenKind.TokenKind.EOF, bodyLength, bodyLength, ); }