// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_
#define SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_

#include <optional>
#include <vector>

#include "src/tint/lang/wgsl/reader/parser/token.h"

namespace tint::wgsl::reader {

/// Converts the input stream into a series of Tokens
class Lexer {
  public:
    /// Creates a new Lexer
    /// @param file the source file
    explicit Lexer(const Source::File* file);
    ~Lexer();

    /// @return the token list.
    std::vector<Token> Lex();

  private:
    /// Returns the next token in the input stream.
    /// @return Token
    Token next();

    /// Advances past blankspace and comments, if present at the current position.
    /// @returns error token, EOF, or uninitialized
    std::optional<Token> skip_blankspace_and_comments();
    /// Advances past a comment at the current position, if one exists.
    /// Returns an error if there was an unterminated block comment,
    /// or a null character was present.
    /// @returns uninitialized token on success, or error
    std::optional<Token> skip_comment();

    Token build_token_from_int_if_possible(Source source,
                                           size_t start,
                                           size_t prefix_count,
                                           int32_t base);

    std::optional<Token::Type> parse_keyword(std::string_view);

    /// The try_* methods have the following in common:
    /// - They assume there is at least one character to be consumed,
    ///   i.e. the input has not yet reached end of file.
    /// - They return an initialized token when they match and consume
    ///   a token of the specified kind.
    /// - Some can return an error token.
    /// - Otherwise they return an uninitialized token when they did not
    ///   match a token of the specfied kind.
    std::optional<Token> try_float();
    std::optional<Token> try_hex_float();
    std::optional<Token> try_hex_integer();
    std::optional<Token> try_ident();
    std::optional<Token> try_integer();
    std::optional<Token> try_punctuation();

    Source begin_source() const;
    void end_source(Source&) const;

    /// @returns view of current line
    std::string_view line() const;
    /// @returns position in current line
    size_t pos() const;
    /// @returns length of current line
    size_t length() const;
    /// @returns reference to character at `pos` within current line
    const char& at(size_t pos) const;
    /// @returns substring view at `offset` within current line of length `count`
    std::string_view substr(size_t offset, size_t count);
    /// advances current position by `offset` within current line
    void advance(size_t offset = 1);
    /// sets current position to `pos` within current line
    void set_pos(size_t pos);
    /// advances current position to next line
    void advance_line();
    /// @returns true if the end of the input has been reached.
    bool is_eof() const;
    /// @returns true if the end of the current line has been reached.
    bool is_eol() const;
    /// @returns true if there is another character on the input and
    /// it is not null.
    bool is_null() const;
    /// @param ch a character
    /// @returns true if 'ch' is a decimal digit
    bool is_digit(char ch) const;
    /// @param ch a character
    /// @returns true if 'ch' is a hexadecimal digit
    bool is_hex(char ch) const;
    /// @returns true if string at `pos` matches `substr`
    bool matches(size_t pos, std::string_view substr);
    /// @returns true if char at `pos` matches `ch`
    bool matches(size_t pos, char ch);
    /// The source file content
    Source::File const* const file_;
    /// The current location within the input
    Source::Location location_;
};

}  // namespace tint::wgsl::reader

#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_
