// 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_RAW_AST_H_
#define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_RAW_AST_H_

#include <cassert>
#include <memory>
#include <optional>
#include <utility>
#include <variant>
#include <vector>

#include "source_span.h"
#include "token.h"
#include "types.h"
#include "utils.h"

// ASTs fresh out of the oven. This is a tree-shaped bunch of nodes
// pretty much exactly corresponding to the grammar of a single fidl
// file. File is the root of the tree, and consists of lists of
// Declarations, and so on down to individual SourceSpans.
// See
// https://fuchsia.dev/fuchsia-src/development/languages/fidl/reference/compiler#compiler_internals
// for additional context

// Each node owns its children via unique_ptr and vector. All tokens
// here, like everywhere in the fidl compiler, are backed by a string
// view whose contents are owned by a SourceManager.

// This class has a tight coupling with the TreeVisitor class.  Each node has a
// corresponding method in that class.  Each node type also has an Accept()
// method to help visitors visit the node.  When you add a new node, or add a
// field to an existing node, you must ensure the Accept method works.

// A raw::File is produced by parsing a token stream. All of the
// Files in a library are then flattened out into a Library.

namespace fidl {
namespace raw {

// In order to be able to associate AST nodes with their original source, each
// node is a SourceElement, which contains information about the original
// source.  The AST has a start token, whose previous_end field points to the
// end of the previous AST node, and an end token, which points to the end of
// this syntactic element.
//
// Note: The file may have a tail of whitespace / comment text not explicitly
// associated with any node.  In order to reconstruct that text, raw::File
// contains an end token; the previous_end field of that token points to the end
// of the last interesting token.
class TreeVisitor;

class SourceElement {
 public:
  explicit SourceElement(SourceElement const& element)
      : start_(element.start_), end_(element.end_) {}

  explicit SourceElement(Token start, Token end) : start_(start), end_(end) {}

  bool has_span() const {
    return start_.span().valid() && end_.span().valid() &&
           &start_.span().source_file() == &end_.span().source_file();
  }

  SourceSpan span() const {
    if (!start_.span().valid() || !end_.span().valid()) {
      return SourceSpan();
    }

    assert(has_span());
    const char* start_pos = start_.span().data().data();
    const char* end_pos = end_.span().data().data() + end_.span().data().length();
    return SourceSpan(std::string_view(start_pos, end_pos - start_pos),
                      start_.span().source_file());
  }

  std::string copy_to_str() const {
    const char* start_pos = start_.span().data().data();
    const char* end_pos = end_.span().data().data() + end_.span().data().length();
    return std::string(start_pos, end_pos);
  }

  void update_span(SourceElement const& element) {
    start_ = element.start_;
    end_ = element.end_;
  }

  virtual ~SourceElement() {}

  Token start_;
  Token end_;
};

class SourceElementMark {
 public:
  SourceElementMark(TreeVisitor* tv, const SourceElement& element);

  ~SourceElementMark();

 private:
  TreeVisitor* tv_;
  const SourceElement& element_;
};

class Identifier final : public SourceElement {
 public:
  explicit Identifier(SourceElement const& element) : SourceElement(element) {}

  void Accept(TreeVisitor* visitor) const;
};

class CompoundIdentifier final : public SourceElement {
 public:
  CompoundIdentifier(SourceElement const& element,
                     std::vector<std::unique_ptr<Identifier>> components)
      : SourceElement(element), components(std::move(components)) {}

  void Accept(TreeVisitor* visitor) const;

  std::vector<std::unique_ptr<Identifier>> components;
};

class Literal : public SourceElement {
 public:
  enum struct Kind {
    kString,
    kNumeric,
    // TODO(pascallouis): should have kBool instead.
    kTrue,
    kFalse,
  };

  explicit Literal(SourceElement const& element, Kind kind) : SourceElement(element), kind(kind) {}

  virtual ~Literal() {}

  const Kind kind;
};

class StringLiteral final : public Literal {
 public:
  explicit StringLiteral(SourceElement const& element) : Literal(element, Kind::kString) {}

  void Accept(TreeVisitor* visitor) const;
};

class NumericLiteral final : public Literal {
 public:
  NumericLiteral(SourceElement const& element) : Literal(element, Kind::kNumeric) {}

  void Accept(TreeVisitor* visitor) const;
};

class Ordinal64 final : public SourceElement {
 public:
  Ordinal64(SourceElement const& element, uint64_t value) : SourceElement(element), value(value) {}

  void Accept(TreeVisitor* visitor) const;

  const uint64_t value;
};

class TrueLiteral final : public Literal {
 public:
  TrueLiteral(SourceElement const& element) : Literal(element, Kind::kTrue) {}

  void Accept(TreeVisitor* visitor) const;
};

class FalseLiteral final : public Literal {
 public:
  FalseLiteral(SourceElement const& element) : Literal(element, Kind::kFalse) {}

  void Accept(TreeVisitor* visitor) const;
};

class Constant : public SourceElement {
 public:
  enum class Kind { kIdentifier, kLiteral, kBinaryOperator };

  explicit Constant(Token token, Kind kind) : SourceElement(token, token), kind(kind) {}
  explicit Constant(const SourceElement& element, Kind kind) : SourceElement(element), kind(kind) {}

  virtual ~Constant() {}

  const Kind kind;
};

class IdentifierConstant final : public Constant {
 public:
  explicit IdentifierConstant(std::unique_ptr<CompoundIdentifier> identifier)
      : Constant(SourceElement(identifier->start_, identifier->end_), Kind::kIdentifier),
        identifier(std::move(identifier)) {}

  std::unique_ptr<CompoundIdentifier> identifier;

  void Accept(TreeVisitor* visitor) const;
};

class LiteralConstant final : public Constant {
 public:
  explicit LiteralConstant(std::unique_ptr<Literal> literal)
      : Constant(literal->start_, Kind::kLiteral), literal(std::move(literal)) {}

  std::unique_ptr<Literal> literal;

  void Accept(TreeVisitor* visitor) const;
};

class BinaryOperatorConstant final : public Constant {
 public:
  enum class Operator { kOr };
  explicit BinaryOperatorConstant(std::unique_ptr<Constant> left_operand,
                                  std::unique_ptr<Constant> right_operand, Operator op)
      : Constant(SourceElement(left_operand->start_, right_operand->end_), Kind::kBinaryOperator),
        left_operand(std::move(left_operand)),
        right_operand(std::move(right_operand)),
        op(op) {}

  std::unique_ptr<Constant> left_operand;
  std::unique_ptr<Constant> right_operand;
  Operator op;

  void Accept(TreeVisitor* visitor) const;
};

class Attribute final : public SourceElement {
 public:
  Attribute(SourceElement const& element, std::string name, std::string value)
      : SourceElement(element), name(std::move(name)), value(std::move(value)) {}

  void Accept(TreeVisitor* visitor) const;

  const std::string name;
  const std::string value;
};

class AttributeList final : public SourceElement {
 public:
  AttributeList(SourceElement const& element, std::vector<Attribute> attributes)
      : SourceElement(element), attributes(std::move(attributes)) {}

  bool HasAttribute(std::string name) const {
    for (const auto& attribute : attributes) {
      if (attribute.name == name)
        return true;
    }
    return false;
  }

  void Accept(TreeVisitor* visitor) const;

  std::vector<Attribute> attributes;
};

// TODO(fxbug.dev/70247): Remove the two type constructor versions and remove
// the New suffix.
class TypeConstructorOld;
class TypeConstructorNew;
using TypeConstructor =
    std::variant<std::unique_ptr<TypeConstructorNew>, std::unique_ptr<TypeConstructorOld>>;

bool IsTypeConstructorDefined(const raw::TypeConstructor& maybe_type_ctor);

class TypeConstructorOld final : public SourceElement {
 public:
  TypeConstructorOld(SourceElement const& element, std::unique_ptr<CompoundIdentifier> identifier,
                     std::unique_ptr<TypeConstructorOld> maybe_arg_type_ctor,
                     std::unique_ptr<Identifier> handle_subtype_identifier,
                     std::unique_ptr<Constant> handle_rights, std::unique_ptr<Constant> maybe_size,
                     types::Nullability nullability)
      : SourceElement(element),
        identifier(std::move(identifier)),
        maybe_arg_type_ctor(std::move(maybe_arg_type_ctor)),
        handle_subtype_identifier(std::move(handle_subtype_identifier)),
        handle_rights(std::move(handle_rights)),
        maybe_size(std::move(maybe_size)),
        nullability(nullability) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<CompoundIdentifier> identifier;
  std::unique_ptr<TypeConstructorOld> maybe_arg_type_ctor;
  std::unique_ptr<Identifier> handle_subtype_identifier;
  std::unique_ptr<Constant> handle_rights;
  std::unique_ptr<Constant> maybe_size;
  types::Nullability nullability;
};

class LayoutReference;
class LayoutParameterList;
class TypeConstraints;

class TypeConstructorNew final : public SourceElement {
 public:
  TypeConstructorNew(SourceElement const& element, std::unique_ptr<LayoutReference> layout_ref,
                     std::unique_ptr<LayoutParameterList> parameters,
                     std::unique_ptr<TypeConstraints> constraints)
      : SourceElement(element),
        layout_ref(std::move(layout_ref)),
        parameters(std::move(parameters)),
        constraints(std::move(constraints)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<LayoutReference> layout_ref;
  std::unique_ptr<LayoutParameterList> parameters;
  std::unique_ptr<TypeConstraints> constraints;
};

class BitsMember final : public SourceElement {
 public:
  BitsMember(SourceElement const& element, std::unique_ptr<Identifier> identifier,
             std::unique_ptr<Constant> value, std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        identifier(std::move(identifier)),
        value(std::move(value)),
        attributes(std::move(attributes)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<Constant> value;
  std::unique_ptr<AttributeList> attributes;
};

class BitsDeclaration final : public SourceElement {
 public:
  BitsDeclaration(SourceElement const& element, std::unique_ptr<Token> decl_start_token,
                  std::unique_ptr<AttributeList> attributes, std::unique_ptr<Identifier> identifier,
                  std::unique_ptr<TypeConstructorOld> maybe_type_ctor,
                  std::vector<std::unique_ptr<BitsMember>> members, types::Strictness strictness)
      : SourceElement(element),
        decl_start_token(std::move(decl_start_token)),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        maybe_type_ctor(std::move(maybe_type_ctor)),
        members(std::move(members)),
        strictness(strictness) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Token> decl_start_token;
  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<TypeConstructorOld> maybe_type_ctor;
  std::vector<std::unique_ptr<BitsMember>> members;
  const types::Strictness strictness;
};

class AliasDeclaration final : public SourceElement {
 public:
  AliasDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                   std::unique_ptr<Identifier> alias, TypeConstructor type_ctor)
      : SourceElement(element),
        attributes(std::move(attributes)),
        alias(std::move(alias)),
        type_ctor(std::move(type_ctor)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> alias;
  TypeConstructor type_ctor;
};

class Using final : public SourceElement {
 public:
  Using(SourceElement const& element, std::unique_ptr<Token> decl_start_token,
        std::unique_ptr<AttributeList> attributes, std::unique_ptr<CompoundIdentifier> using_path,
        std::unique_ptr<Identifier> maybe_alias,
        std::unique_ptr<TypeConstructorOld> maybe_type_ctor)
      : SourceElement(element),
        decl_start_token(std::move(decl_start_token)),
        attributes(std::move(attributes)),
        using_path(std::move(using_path)),
        maybe_alias(std::move(maybe_alias)),
        maybe_type_ctor(std::move(maybe_type_ctor)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Token> decl_start_token;
  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<CompoundIdentifier> using_path;
  std::unique_ptr<Identifier> maybe_alias;
  // TODO(fxbug.dev/7807): Use a special purpose AST element, as is the case in the
  // flat AST.
  std::unique_ptr<TypeConstructorOld> maybe_type_ctor;
};

class ConstDeclaration final : public SourceElement {
 public:
  ConstDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                   TypeConstructor type_ctor, std::unique_ptr<Identifier> identifier,
                   std::unique_ptr<Constant> constant)
      : SourceElement(element),
        attributes(std::move(attributes)),
        type_ctor(std::move(type_ctor)),
        identifier(std::move(identifier)),
        constant(std::move(constant)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<AttributeList> attributes;
  TypeConstructor type_ctor;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<Constant> constant;
};

class EnumMember final : public SourceElement {
 public:
  EnumMember(SourceElement const& element, std::unique_ptr<Identifier> identifier,
             std::unique_ptr<Constant> value, std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        identifier(std::move(identifier)),
        value(std::move(value)),
        attributes(std::move(attributes)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<Constant> value;
  std::unique_ptr<AttributeList> attributes;
};

class EnumDeclaration final : public SourceElement {
 public:
  EnumDeclaration(SourceElement const& element, std::unique_ptr<Token> decl_start_token,
                  std::unique_ptr<AttributeList> attributes, std::unique_ptr<Identifier> identifier,
                  std::unique_ptr<TypeConstructorOld> maybe_type_ctor,
                  std::vector<std::unique_ptr<EnumMember>> members, types::Strictness strictness)
      : SourceElement(element),
        decl_start_token(std::move(decl_start_token)),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        maybe_type_ctor(std::move(maybe_type_ctor)),
        members(std::move(members)),
        strictness(strictness) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Token> decl_start_token;
  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<TypeConstructorOld> maybe_type_ctor;
  std::vector<std::unique_ptr<EnumMember>> members;
  const types::Strictness strictness;
};

class Parameter final : public SourceElement {
 public:
  Parameter(SourceElement const& element, TypeConstructor type_ctor,
            std::unique_ptr<Identifier> identifier, std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        type_ctor(std::move(type_ctor)),
        identifier(std::move(identifier)),
        attributes(std::move(attributes)) {}

  void Accept(TreeVisitor* visitor) const;

  TypeConstructor type_ctor;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<AttributeList> attributes;
};

class ParameterList final : public SourceElement {
 public:
  ParameterList(SourceElement const& element,
                std::vector<std::unique_ptr<Parameter>> parameter_list)
      : SourceElement(element), parameter_list(std::move(parameter_list)) {}

  void Accept(TreeVisitor* visitor) const;

  std::vector<std::unique_ptr<Parameter>> parameter_list;
};

class ProtocolMethod : public SourceElement {
 public:
  ProtocolMethod(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                 std::unique_ptr<Identifier> identifier,
                 std::unique_ptr<ParameterList> maybe_request,
                 std::unique_ptr<ParameterList> maybe_response,
                 std::unique_ptr<TypeConstructorOld> maybe_error_ctor)
      : SourceElement(element),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        maybe_request(std::move(maybe_request)),
        maybe_response(std::move(maybe_response)),
        maybe_error_ctor(std::move(maybe_error_ctor)) {
    // `maybe_response` must exist if `maybe_error_ctor` is exists.
    if (maybe_error_ctor) {
      assert(maybe_response);
    }
  }

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<ParameterList> maybe_request;
  std::unique_ptr<ParameterList> maybe_response;
  std::unique_ptr<TypeConstructorOld> maybe_error_ctor;
};

class ComposeProtocol final : public SourceElement {
 public:
  ComposeProtocol(SourceElement const& element, std::unique_ptr<CompoundIdentifier> protocol_name)
      : SourceElement(element), protocol_name(std::move(protocol_name)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<CompoundIdentifier> protocol_name;
};

class ProtocolDeclaration final : public SourceElement {
 public:
  ProtocolDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                      std::unique_ptr<Identifier> identifier,
                      std::vector<std::unique_ptr<ComposeProtocol>> composed_protocols,
                      std::vector<std::unique_ptr<ProtocolMethod>> methods)
      : SourceElement(element),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        composed_protocols(std::move(composed_protocols)),
        methods(std::move(methods)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::vector<std::unique_ptr<ComposeProtocol>> composed_protocols;
  std::vector<std::unique_ptr<ProtocolMethod>> methods;
};

class ResourceProperty final : public SourceElement {
 public:
  ResourceProperty(SourceElement const& element, TypeConstructor type_ctor,
                   std::unique_ptr<Identifier> identifier,
                   std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        type_ctor(std::move(type_ctor)),
        identifier(std::move(identifier)),
        attributes(std::move(attributes)) {}

  void Accept(TreeVisitor* visitor) const;

  TypeConstructor type_ctor;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<AttributeList> attributes;
};

class ResourceDeclaration final : public SourceElement {
 public:
  ResourceDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                      std::unique_ptr<Identifier> identifier, TypeConstructor maybe_type_ctor,
                      std::vector<std::unique_ptr<ResourceProperty>> properties)
      : SourceElement(element),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        maybe_type_ctor(std::move(maybe_type_ctor)),
        properties(std::move(properties)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  TypeConstructor maybe_type_ctor;
  std::vector<std::unique_ptr<ResourceProperty>> properties;
};

class ServiceMember final : public SourceElement {
 public:
  ServiceMember(SourceElement const& element, TypeConstructor type_ctor,
                std::unique_ptr<Identifier> identifier, std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        type_ctor(std::move(type_ctor)),
        identifier(std::move(identifier)),
        attributes(std::move(attributes)) {}

  void Accept(TreeVisitor* visitor) const;

  TypeConstructor type_ctor;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<AttributeList> attributes;
};

class ServiceDeclaration final : public SourceElement {
 public:
  ServiceDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                     std::unique_ptr<Identifier> identifier,
                     std::vector<std::unique_ptr<ServiceMember>> members)
      : SourceElement(element),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        members(std::move(members)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::vector<std::unique_ptr<ServiceMember>> members;
};

class StructMember final : public SourceElement {
 public:
  StructMember(SourceElement const& element, std::unique_ptr<TypeConstructorOld> type_ctor,
               std::unique_ptr<Identifier> identifier,
               std::unique_ptr<Constant> maybe_default_value,
               std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        type_ctor(std::move(type_ctor)),
        identifier(std::move(identifier)),
        maybe_default_value(std::move(maybe_default_value)),
        attributes(std::move(attributes)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<TypeConstructorOld> type_ctor;
  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<Constant> maybe_default_value;
  std::unique_ptr<AttributeList> attributes;
};

class StructDeclaration final : public SourceElement {
 public:
  // Note: A nullptr passed to attributes means an empty attribute list.
  StructDeclaration(SourceElement const& element, std::unique_ptr<Token> decl_start_token,
                    std::unique_ptr<AttributeList> attributes,
                    std::unique_ptr<Identifier> identifier,
                    std::vector<std::unique_ptr<StructMember>> members,
                    types::Resourceness resourceness)
      : SourceElement(element),
        decl_start_token(std::move(decl_start_token)),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        members(std::move(members)),
        resourceness(resourceness) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Token> decl_start_token;
  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::vector<std::unique_ptr<StructMember>> members;
  const types::Resourceness resourceness;
};

struct TableMember final : public SourceElement {
  TableMember(SourceElement const& element, std::unique_ptr<Ordinal64> ordinal,
              std::unique_ptr<TypeConstructorOld> type_ctor, std::unique_ptr<Identifier> identifier,
              std::unique_ptr<Constant> maybe_default_value,
              std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        ordinal(std::move(ordinal)),
        maybe_used(std::make_unique<Used>(std::move(type_ctor), std::move(identifier),
                                          std::move(maybe_default_value), std::move(attributes))) {}

  TableMember(SourceElement const& element, std::unique_ptr<Ordinal64> ordinal)
      : SourceElement(element), ordinal(std::move(ordinal)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Ordinal64> ordinal;
  // A used member is not 'reserved'
  struct Used {
    Used(std::unique_ptr<TypeConstructorOld> type_ctor, std::unique_ptr<Identifier> identifier,
         std::unique_ptr<Constant> maybe_default_value, std::unique_ptr<AttributeList> attributes)
        : type_ctor(std::move(type_ctor)),
          identifier(std::move(identifier)),
          maybe_default_value(std::move(maybe_default_value)),
          attributes(std::move(attributes)) {}
    std::unique_ptr<TypeConstructorOld> type_ctor;
    std::unique_ptr<Identifier> identifier;
    // We parse default values on union members so that we can give precise
    // errors later in the compiler, but defaults are not supported
    std::unique_ptr<Constant> maybe_default_value;
    std::unique_ptr<AttributeList> attributes;
  };
  std::unique_ptr<Used> maybe_used;
};

struct TableDeclaration final : public SourceElement {
  TableDeclaration(SourceElement const& element, std::unique_ptr<Token> decl_start_token,
                   std::unique_ptr<AttributeList> attributes,
                   std::unique_ptr<Identifier> identifier,
                   std::vector<std::unique_ptr<TableMember>> members, types::Strictness strictness,
                   types::Resourceness resourceness)
      : SourceElement(element),
        decl_start_token(std::move(decl_start_token)),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        members(std::move(members)),
        strictness(strictness),
        resourceness(resourceness) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Token> decl_start_token;
  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::vector<std::unique_ptr<TableMember>> members;
  const types::Strictness strictness;
  const types::Resourceness resourceness;
};

class UnionMember final : public SourceElement {
 public:
  UnionMember(SourceElement const& element, std::unique_ptr<Ordinal64> ordinal,
              std::unique_ptr<TypeConstructorOld> type_ctor, std::unique_ptr<Identifier> identifier,
              std::unique_ptr<Constant> maybe_default_value,
              std::unique_ptr<AttributeList> attributes)
      : SourceElement(element),
        ordinal(std::move(ordinal)),
        maybe_used(std::make_unique<Used>(std::move(type_ctor), std::move(identifier),
                                          std::move(maybe_default_value), std::move(attributes))) {}

  UnionMember(SourceElement const& element, std::unique_ptr<Ordinal64> ordinal)
      : SourceElement(element), ordinal(std::move(ordinal)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Ordinal64> ordinal;

  // A used member is not 'reserved'
  struct Used {
    Used(std::unique_ptr<TypeConstructorOld> type_ctor, std::unique_ptr<Identifier> identifier,
         std::unique_ptr<Constant> maybe_default_value, std::unique_ptr<AttributeList> attributes)
        : type_ctor(std::move(type_ctor)),
          identifier(std::move(identifier)),
          maybe_default_value(std::move(maybe_default_value)),
          attributes(std::move(attributes)) {}
    std::unique_ptr<TypeConstructorOld> type_ctor;
    std::unique_ptr<Identifier> identifier;
    // We parse default values on union members so that we can give precise
    // errors later in the compiler, but defaults are not supported
    std::unique_ptr<Constant> maybe_default_value;
    std::unique_ptr<AttributeList> attributes;
  };
  std::unique_ptr<Used> maybe_used;
};

class UnionDeclaration final : public SourceElement {
 public:
  UnionDeclaration(SourceElement const& element, std::unique_ptr<Token> decl_start_token,
                   std::unique_ptr<AttributeList> attributes,
                   std::unique_ptr<Identifier> identifier,
                   std::vector<std::unique_ptr<UnionMember>> members, types::Strictness strictness,
                   bool strictness_specified, types::Resourceness resourceness)
      : SourceElement(element),
        decl_start_token(std::move(decl_start_token)),
        attributes(std::move(attributes)),
        identifier(std::move(identifier)),
        members(std::move(members)),
        strictness(strictness),
        strictness_specified(strictness_specified),
        resourceness(resourceness) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Token> decl_start_token;
  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<Identifier> identifier;
  std::vector<std::unique_ptr<UnionMember>> members;
  const types::Strictness strictness;
  const bool strictness_specified;
  const types::Resourceness resourceness;
};

class LayoutMember : public SourceElement {
 public:
  enum Kind {
    kOrdinaled,
    kStruct,
    kValue,
  };

  explicit LayoutMember(SourceElement const& element, Kind kind,
                        std::unique_ptr<Identifier> identifier)
      : SourceElement(element), kind(kind), identifier(std::move(identifier)) {}

  void Accept(TreeVisitor* visitor) const;

  const Kind kind;
  std::unique_ptr<Identifier> identifier;
};

class OrdinaledLayoutMember final : public LayoutMember {
 public:
  explicit OrdinaledLayoutMember(SourceElement const& element, std::unique_ptr<Ordinal64> ordinal,
                                 std::unique_ptr<Identifier> identifier,
                                 std::unique_ptr<TypeConstructorNew> type_ctor)
      : LayoutMember(element, Kind::kOrdinaled, std::move(identifier)),
        ordinal(std::move(ordinal)),
        type_ctor(std::move(type_ctor)) {}
  explicit OrdinaledLayoutMember(SourceElement const& element, std::unique_ptr<Ordinal64> ordinal)
      : LayoutMember(element, Kind::kOrdinaled, nullptr),
        ordinal(std::move(ordinal)),
        type_ctor(nullptr),
        reserved(true) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Ordinal64> ordinal;
  std::unique_ptr<TypeConstructorNew> type_ctor;
  const bool reserved = false;
};

class ValueLayoutMember final : public LayoutMember {
 public:
  explicit ValueLayoutMember(SourceElement const& element, std::unique_ptr<Identifier> identifier,
                             std::unique_ptr<Constant> value)
      : LayoutMember(element, Kind::kValue, std::move(identifier)), value(std::move(value)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Constant> value;
};

class StructLayoutMember final : public LayoutMember {
 public:
  explicit StructLayoutMember(SourceElement const& element, std::unique_ptr<Identifier> identifier,
                              std::unique_ptr<TypeConstructorNew> type_ctor,
                              std::unique_ptr<Constant> default_value)
      : LayoutMember(element, Kind::kStruct, std::move(identifier)),
        type_ctor(std::move(type_ctor)),
        default_value(std::move(default_value)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<TypeConstructorNew> type_ctor;
  std::unique_ptr<Constant> default_value;
};

class Layout final : public SourceElement {
 public:
  enum Kind {
    kBits,
    kEnum,
    kStruct,
    kTable,
    kUnion,
  };

  Layout(SourceElement const& element,
         // TODO(fxbug.dev/65978): Support layout attributes.
         Kind kind, std::vector<std::unique_ptr<LayoutMember>> members,
         std::optional<types::Strictness> strictness, types::Resourceness resourceness,
         std::unique_ptr<TypeConstructorNew> subtype_ctor)
      : SourceElement(element),
        kind(kind),
        members(std::move(members)),
        strictness(strictness),
        resourceness(resourceness),
        subtype_ctor(std::move(subtype_ctor)) {}

  Kind kind;
  std::vector<std::unique_ptr<raw::LayoutMember>> members;
  std::optional<types::Strictness> strictness;
  types::Resourceness resourceness;
  // TODO(fxbug.dev/65978): Eventually we'll make [Struct/Ordinaled/Value]Layout
  //  classes to inherit from the now-abstract Layout class, similar to what can
  //  currently be seen on LayoutMember and its children.  When that happens
  //  this field will only exist on ValueLayout.
  std::unique_ptr<TypeConstructorNew> subtype_ctor;
};

class LayoutReference : public SourceElement {
 public:
  enum Kind {
    kInline,
    kNamed,
  };

  LayoutReference(SourceElement const& element, Kind kind) : SourceElement(element), kind(kind) {}

  void Accept(TreeVisitor* visitor) const;

  const Kind kind;
};

class InlineLayoutReference final : public LayoutReference {
 public:
  explicit InlineLayoutReference(SourceElement const& element, std::unique_ptr<Layout> layout)
      : LayoutReference(element, Kind::kInline), layout(std::move(layout)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Layout> layout;
};

class NamedLayoutReference final : public LayoutReference {
 public:
  explicit NamedLayoutReference(SourceElement const& element,
                                std::unique_ptr<CompoundIdentifier> identifier)
      : LayoutReference(element, Kind::kNamed), identifier(std::move(identifier)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<CompoundIdentifier> identifier;
};

class LayoutParameter : public SourceElement {
 public:
  enum Kind {
    kAmbiguous,
    kLiteral,
    kType,
  };

  LayoutParameter(SourceElement const& element, Kind kind) : SourceElement(element), kind(kind) {}

  void Accept(TreeVisitor* visitor) const;

  const Kind kind;
};

class LiteralLayoutParameter final : public LayoutParameter {
 public:
  explicit LiteralLayoutParameter(SourceElement const& element,
                                  std::unique_ptr<LiteralConstant> literal)
      : LayoutParameter(element, Kind::kLiteral), literal(std::move(literal)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<LiteralConstant> literal;
};

class TypeLayoutParameter final : public LayoutParameter {
 public:
  explicit TypeLayoutParameter(SourceElement const& element,
                               std::unique_ptr<TypeConstructorNew> type_ctor)
      : LayoutParameter(element, Kind::kType), type_ctor(std::move(type_ctor)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<TypeConstructorNew> type_ctor;
};

class AmbiguousLayoutParameter final : public LayoutParameter {
 public:
  explicit AmbiguousLayoutParameter(SourceElement const& element,
                                    std::unique_ptr<CompoundIdentifier> identifier)
      : LayoutParameter(element, Kind::kAmbiguous), identifier(std::move(identifier)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<CompoundIdentifier> identifier;
};

class LayoutParameterList final : public SourceElement {
 public:
  LayoutParameterList(SourceElement const& element,
                      std::vector<std::unique_ptr<raw::LayoutParameter>> items)
      : SourceElement(element), items(std::move(items)) {}

  void Accept(TreeVisitor* visitor) const;

  std::vector<std::unique_ptr<raw::LayoutParameter>> items;
};

class TypeConstraints final : public SourceElement {
 public:
  TypeConstraints(SourceElement const& element, std::vector<std::unique_ptr<raw::Constant>> items)
      : SourceElement(element), items(std::move(items)) {}

  void Accept(TreeVisitor* visitor) const;

  std::vector<std::unique_ptr<raw::Constant>> items;
};

class TypeDecl final : public SourceElement {
 public:
  TypeDecl(SourceElement const& element,
           // TODO(fxbug.dev/65978): Support type decl attributes.
           std::unique_ptr<Identifier> identifier,
           // TODO(fxbug.dev/65978): We should also allow type decl over type
           // constructors, i.e. FTP-052 type declaration.
           std::unique_ptr<TypeConstructorNew> type_ctor)
      : SourceElement(element),
        identifier(std::move(identifier)),
        type_ctor(std::move(type_ctor)) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<Identifier> identifier;
  std::unique_ptr<TypeConstructorNew> type_ctor;
};

class File final : public SourceElement {
 public:
  File(SourceElement const& element, Token end, std::unique_ptr<AttributeList> attributes,
       std::unique_ptr<CompoundIdentifier> library_name,
       std::vector<std::unique_ptr<AliasDeclaration>> alias_list,
       std::vector<std::unique_ptr<Using>> using_list,
       std::vector<std::unique_ptr<BitsDeclaration>> bits_declaration_list,
       std::vector<std::unique_ptr<ConstDeclaration>> const_declaration_list,
       std::vector<std::unique_ptr<EnumDeclaration>> enum_declaration_list,
       std::vector<std::unique_ptr<ProtocolDeclaration>> protocol_declaration_list,
       std::vector<std::unique_ptr<ResourceDeclaration>> resource_declaration_list,
       std::vector<std::unique_ptr<ServiceDeclaration>> service_declaration_list,
       std::vector<std::unique_ptr<StructDeclaration>> struct_declaration_list,
       std::vector<std::unique_ptr<TableDeclaration>> table_declaration_list,
       std::vector<std::unique_ptr<UnionDeclaration>> union_declaration_list,
       std::vector<std::unique_ptr<TypeDecl>> type_decls,
       std::vector<std::unique_ptr<Token>> comment_tokens_list, fidl::utils::Syntax syntax)
      : SourceElement(element),
        attributes(std::move(attributes)),
        library_name(std::move(library_name)),
        alias_list(std::move(alias_list)),
        using_list(std::move(using_list)),
        bits_declaration_list(std::move(bits_declaration_list)),
        const_declaration_list(std::move(const_declaration_list)),
        enum_declaration_list(std::move(enum_declaration_list)),
        protocol_declaration_list(std::move(protocol_declaration_list)),
        resource_declaration_list(std::move(resource_declaration_list)),
        service_declaration_list(std::move(service_declaration_list)),
        struct_declaration_list(std::move(struct_declaration_list)),
        table_declaration_list(std::move(table_declaration_list)),
        union_declaration_list(std::move(union_declaration_list)),
        type_decls(std::move(type_decls)),
        comment_tokens_list(std::move(comment_tokens_list)),
        end_(end),
        syntax(syntax) {}

  void Accept(TreeVisitor* visitor) const;

  std::unique_ptr<AttributeList> attributes;
  std::unique_ptr<CompoundIdentifier> library_name;
  std::vector<std::unique_ptr<AliasDeclaration>> alias_list;
  std::vector<std::unique_ptr<Using>> using_list;
  std::vector<std::unique_ptr<BitsDeclaration>> bits_declaration_list;
  std::vector<std::unique_ptr<ConstDeclaration>> const_declaration_list;
  std::vector<std::unique_ptr<EnumDeclaration>> enum_declaration_list;
  std::vector<std::unique_ptr<ProtocolDeclaration>> protocol_declaration_list;
  std::vector<std::unique_ptr<ResourceDeclaration>> resource_declaration_list;
  std::vector<std::unique_ptr<ServiceDeclaration>> service_declaration_list;
  std::vector<std::unique_ptr<StructDeclaration>> struct_declaration_list;
  std::vector<std::unique_ptr<TableDeclaration>> table_declaration_list;
  std::vector<std::unique_ptr<UnionDeclaration>> union_declaration_list;
  std::vector<std::unique_ptr<TypeDecl>> type_decls;

  // TODO(fxbug.dev/70247): this member has been created solely for the benefit
  //   of fidlconv.  Once the conversion using that tool has been completed and
  //   tool has been removed, this member should be removed as well.
  std::vector<std::unique_ptr<Token>> comment_tokens_list;
  Token end_;
  fidl::utils::Syntax syntax;
};

}  // namespace raw
}  // namespace fidl

#endif  // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_RAW_AST_H_
