// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_FIDL_CODEC_SEMANTIC_PARSER_H_
#define SRC_LIB_FIDL_CODEC_SEMANTIC_PARSER_H_

#include <iostream>
#include <memory>
#include <ostream>
#include <string>

#include "src/lib/fidl_codec/semantic.h"

namespace fidl_codec {

class LibraryLoader;

namespace semantic {

// Defines a location within a buffer.
class Location {
 public:
  Location(const std::string& buffer, std::string::const_iterator location)
      : buffer_(buffer), location_(location) {}

  const std::string& buffer() const { return buffer_; }
  std::string::const_iterator location() const { return location_; }

 private:
  // Reference to the buffer which contains the text we are parsing.
  const std::string& buffer_;
  // Location within this buffer.
  const std::string::const_iterator location_;
};

// Handles the parser errors.
class ParserErrors {
 public:
  explicit ParserErrors(std::ostream& os = std::cerr) : os_(os) {}

  int error_count() const { return error_count_; }
  bool has_error() const { return error_count_ > 0; }

  // Adds a global error (not associated to a location in the buffer).
  std::ostream& AddError();

  // Adds an error at the specified location.
  std::ostream& AddError(const Location& location);

 private:
  // The stream which receives the errors.
  std::ostream& os_;
  // The number of errors which have been generated.
  int error_count_ = 0;
};

// All the lexical tokens we can reduce.
enum class LexicalToken {
  // The end of the file has been found.
  kEof,
  // An identifier. If allow_dots_in_indentifiers is true, an identifier can contain dots.
  kIdentifier,
  // A left brace: {
  kLeftBrace,
  // A right brace: }
  kRightBrace,
  // Two colons: ::
  kColonColon,
  // A dot: .
  kDot,
  // The equal sign: =
  kEqual,
  // A semicolon: ;
  kSemicolon,
  // A slash: /
  kSlash
};

// Parser for the language which defines semantic rules for FIDL methods.
class SemanticParser {
 public:
  SemanticParser(LibraryLoader* library_loader, const std::string& buffer, ParserErrors* errors)
      : library_loader_(library_loader), buffer_(buffer), errors_(errors) {
    next_ = buffer_.begin();
    NextLexicalToken();
  }

  // Returns the location of the current lexical token.
  Location GetLocation() const { return Location(buffer_, current_location_); }

  // Adds an error at the current lexical token location.
  std::ostream& AddError() { return errors_->AddError(GetLocation()); }

  // Reduce the next lexical token. The parser always has a current not used yet lexical token
  // reduced by NextLexicalToken.
  void NextLexicalToken();

  // Skips text until a semicolon or a right brace are found. If a semicolon is found, the parsing
  // continues after the semicolon. If a right brace is found, the parsing continues before the
  // right brace.
  void SkipSemicolon();
  // Skips text until a semicolon or a right brace are found. The parsing continue after the
  // semicolon or the right brace. If an embeded block is found (delimited by left and right
  // braces), the block is skipped.
  void SkipBlock();
  // Skips text until a right brace is found. The parsing continue after the right brace. If an
  // embeded block is found (delimited by left and right braces), the block is skipped.
  void SkipRightBrace();

  // Helpers to check that we currently have a specified lexical token.
  bool Is(std::string_view keyword) { return IsIdentifier() && (current_string_ == keyword); }
  bool IsEof() const { return current_lexical_token_ == LexicalToken::kEof; }
  bool IsIdentifier() const { return current_lexical_token_ == LexicalToken::kIdentifier; }
  bool IsLeftBrace() const { return current_lexical_token_ == LexicalToken::kLeftBrace; }
  bool IsRightBrace() const { return current_lexical_token_ == LexicalToken::kRightBrace; }
  bool IsColonColon() const { return current_lexical_token_ == LexicalToken::kColonColon; }
  bool IsDot() const { return current_lexical_token_ == LexicalToken::kDot; }
  bool IsEqual() const { return current_lexical_token_ == LexicalToken::kEqual; }
  bool IsSemicolon() const { return current_lexical_token_ == LexicalToken::kSemicolon; }
  bool IsSlash() const { return current_lexical_token_ == LexicalToken::kSlash; }

  // Helpers to check and consume a specified lexical token.
  bool Consume(std::string_view keyword) {
    bool result = IsIdentifier() && (current_string_ == keyword);
    if (result) {
      NextLexicalToken();
    }
    return result;
  }
  bool Consume(LexicalToken token) {
    bool result = current_lexical_token_ == token;
    if (result) {
      NextLexicalToken();
    }
    return result;
  }
  bool ConsumeLeftBrace() { return Consume(LexicalToken::kLeftBrace); }
  bool ConsumeRightBrace() { return Consume(LexicalToken::kRightBrace); }
  bool ConsumeDot() { return Consume(LexicalToken::kDot); }
  bool ConsumeEqual() { return Consume(LexicalToken::kEqual); }
  bool ConsumeSemicolon() { return Consume(LexicalToken::kSemicolon); }
  bool ConsumeSlash() { return Consume(LexicalToken::kSlash); }

  // Helpers to check and consume a specified lexical token. If the token is not found, an error is
  // generated.
  bool Parse(std::string_view keyword) {
    bool result = IsIdentifier() && (current_string_ == keyword);
    if (result) {
      NextLexicalToken();
    } else {
      AddError() << "Keyword '" << keyword << "' expected.\n";
    }
    return result;
  }
  bool Parse(LexicalToken token, std::string_view token_string) {
    bool result = current_lexical_token_ == token;
    if (result) {
      NextLexicalToken();
    } else {
      AddError() << "Symbol '" << token_string << "' expected.\n";
    }
    return result;
  }
  bool ParseLeftBrace() { return Parse(LexicalToken::kLeftBrace, "{"); }
  bool ParseRightBrace() { return Parse(LexicalToken::kRightBrace, "}"); }
  bool ParseColonColon() { return Parse(LexicalToken::kColonColon, "::"); }
  bool ParseEqual() { return Parse(LexicalToken::kEqual, "="); }
  bool ParseSemicolon() { return Parse(LexicalToken::kSemicolon, ";"); }

  // Parses a file which contains handle semantic rules.
  void ParseSemantic();
  // Parses a library block.
  void ParseLibrary();
  // Parses an assignment (that is a semantic rule).
  void ParseAssignment(MethodSemantic* method_semantic);
  // Parses an expression.
  std::unique_ptr<Expression> ParseExpression();
  // Parses a multiplicative expression (a factor).
  std::unique_ptr<Expression> ParseMultiplicativeExpression();
  // Parses a field access expression.
  std::unique_ptr<Expression> ParseAccessExpression();
  // Parses terminal expressions.
  std::unique_ptr<Expression> ParseTerminalExpression();

 private:
  // Lexical reduction of an identifier.
  void LexerIdentifier();

  // The library loader for which we are parsing the semantic rules. The field semantic from
  // protocol methods is assigned when a rule is parsed.
  LibraryLoader* const library_loader_;
  // The text buffer we are currently parsing.
  const std::string& buffer_;
  // The error handling object.
  ParserErrors* errors_;
  // Location in the buffer of the last lexical token reduced by NextLexicalToken.
  std::string::const_iterator current_location_;
  // Next location in the buffer which will be analyzed by NextLexicalToken.
  std::string::const_iterator next_;
  // Last lexical token reduced by NextLexicalToken.
  LexicalToken current_lexical_token_ = LexicalToken::kEof;
  // For LexicalToken::kIdentifier, the value of the identifier.
  std::string_view current_string_;
  // When this field is true, LexerIdentifier accepts dots within the identifiers. This is used to
  // be able to parse library names like "fuchsia.shell".
  bool allow_dots_in_identifiers_ = false;
};

}  // namespace semantic
}  // namespace fidl_codec

#endif  // SRC_LIB_FIDL_CODEC_SEMANTIC_PARSER_H_
