// Copyright 2017 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 TOOLS_FIDL_FIDLC_INCLUDE_FIDL_TOKEN_H_
#define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_TOKEN_H_

#include <stdint.h>

#include <string_view>

#include "source_span.h"

namespace fidl {

// A Token represents a typed view into a source buffer. That is, it
// has a TokenKind, and it has a buffer representing the data
// corresponding to the token. No processing is done on the data:
// string or numeric literals aren't further parsed, identifiers
// uniqued, and so on.
class Token {
 public:
  enum Kind : uint8_t {
#define TOKEN(Name) k##Name,
#include "fidl/token_definitions.inc"
#undef TOKEN
  };

  // Each identifier token is assigned a subkind, which are defined below, or a sentinel value if
  // the token does not match one of the subkinds, to make it simple for the parser to either
  // consume a generic identifier or one that matches a specific subkind. This design makes it so
  // that there are no "reserved keywords" and any identifier can be defined by the user.
  enum Subkind : uint8_t {
    kNone = 0,
#define TOKEN_SUBKIND(Name, Spelling) k##Name,
#include "fidl/token_definitions.inc"
#undef TOKEN_SUBKIND
  };

  class KindAndSubkind {
   public:
    constexpr KindAndSubkind(Kind kind, Subkind subkind) : kind_(kind), subkind_(subkind) {}

    constexpr Kind kind() const { return kind_; }
    constexpr Subkind subkind() const { return subkind_; }
    constexpr uint16_t combined() const { return uint16_t(kind_) | uint16_t(subkind_ << 8); }

   private:
    Kind kind_;
    Subkind subkind_;
  };

  Token(SourceSpan previous_end, SourceSpan span, Kind kind, Subkind subkind)
      : previous_end_(previous_end),
        span_(span),
        kind_and_subkind_(KindAndSubkind(kind, subkind)) {}

  Token() : Token(SourceSpan(), SourceSpan(), Token::Kind::kNotAToken, Token::Subkind::kNone) {}

  static const char* Name(KindAndSubkind kind_and_subkind) {
    switch (kind_and_subkind.combined()) {
#define TOKEN(Name)          \
  case Token::Kind::k##Name: \
    return #Name;
#include "fidl/token_definitions.inc"
#undef TOKEN
#define TOKEN_SUBKIND(Name, Spelling)                                                       \
  case Token::KindAndSubkind(Token::Kind::kIdentifier, Token::Subkind::k##Name).combined(): \
    return #Spelling;
#include "fidl/token_definitions.inc"
#undef TOKEN_SUBKIND
      default:
        return "<unknown token>";
    }
  }

  std::string_view data() const { return span_.data(); }
  const SourceSpan& span() const { return span_; }
  void set_previous_end(SourceSpan span) { previous_end_ = span; }
  SourceSpan previous_end() const { return previous_end_; }
  Kind kind() const { return kind_and_subkind_.kind(); }
  Subkind subkind() const { return kind_and_subkind_.subkind(); }
  KindAndSubkind kind_and_subkind() const { return kind_and_subkind_; }

 private:
  // The end of the previous token.  Everything between this and span_ is
  // somehow uninteresting to the parser (whitespace, comments, discarded
  // braces, etc).
  SourceSpan previous_end_;
  SourceSpan span_;
  KindAndSubkind kind_and_subkind_;
};

}  // namespace fidl

#endif  // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_TOKEN_H_
