// Copyright 2022 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_SRC_ATTRIBUTE_SCHEMA_H_
#define TOOLS_FIDL_FIDLC_SRC_ATTRIBUTE_SCHEMA_H_

#include <lib/fit/function.h>
#include <zircon/assert.h>

#include "tools/fidl/fidlc/src/experimental_flags.h"
#include "tools/fidl/fidlc/src/flat_ast.h"
#include "tools/fidl/fidlc/src/reporter.h"

namespace fidlc {

class CompileStep;

// AttributeArgSchema defines a schema for a single argument in an attribute.
// This includes its type (string, uint64, etc.), whether it is optional or
// required, and (if applicable) a special-case rule for resolving its value.
class AttributeArgSchema {
 public:
  enum class Optionality : uint8_t {
    kOptional,
    kRequired,
  };

  enum class SpecialCase : uint8_t {
    // Allows a uint32 literal or the special constant `NEXT` or `HEAD`.
    kVersion,
  };

  explicit AttributeArgSchema(std::variant<ConstantValue::Kind, SpecialCase> type,
                              Optionality optionality = Optionality::kRequired)
      : type_(type), optionality_(optionality) {
    if (auto kind = std::get_if<ConstantValue::Kind>(&type_)) {
      ZX_ASSERT(*kind != ConstantValue::Kind::kDocComment);
    }
  }

  bool IsOptional() const { return optionality_ == Optionality::kOptional; }

  void ResolveArg(CompileStep* step, Attribute* attribute, AttributeArg* arg,
                  bool literal_only) const;

 private:
  const std::variant<ConstantValue::Kind, SpecialCase> type_;
  const Optionality optionality_;
};

// Use transparent comparator std::less<> to allow std::string_view lookups.
using AttributeSchemaMap = std::map<std::string, AttributeSchema, std::less<>>;

// AttributeSchema defines a schema for attributes. This includes the allowed
// placement (e.g. on a method, on a struct), names and schemas for arguments,
// and an optional constraint validator.
class AttributeSchema {
 public:
  // Note: Constraints get access to the fully compiled Element.
  // This is one reason why VerifyAttributesStep is a separate step.
  using Constraint = fit::function<bool(Reporter* reporter, ExperimentalFlagSet flags,
                                        const Attribute* attribute, const Element* element)>;

  // Constructs a new schema that allows any placement, takes no arguments, and
  // has no constraint. Use the methods below to customize it.
  AttributeSchema() = default;

  // Chainable mutators for customizing the schema.
  AttributeSchema& RestrictTo(std::set<Element::Kind> placements);
  AttributeSchema& RestrictToAnonymousLayouts();
  AttributeSchema& DisallowOnAnonymousLayouts();
  AttributeSchema& AddArg(AttributeArgSchema arg_schema);
  AttributeSchema& AddArg(std::string name, AttributeArgSchema arg_schema);
  AttributeSchema& Constrain(AttributeSchema::Constraint constraint);
  // Marks as use-early. See Kind::kUseEarly below.
  AttributeSchema& UseEarly();
  // Marks as compile-early. See Kind::kCompileEarly below.
  AttributeSchema& CompileEarly();
  // Marks as deprecated. See Kind::kDeprecated below.
  AttributeSchema& Deprecate();

  // Special schema for arbitrary user-defined attributes.
  static const AttributeSchema kUserDefined;

  // Returns true if this schema allows early compilations.
  bool IsCompileEarly() const { return kind_ == Kind::kCompileEarly; }

  // Resolves constants in the attribute's arguments. In the case of an
  // anonymous argument like @foo("abc"), infers the argument's name too.
  void ResolveArgs(CompileStep* step, Attribute* attribute) const;

  // Validates the attribute's placement and constraints. Must call
  // `ResolveArgs` first.
  void Validate(Reporter* reporter, ExperimentalFlagSet flags, const Attribute* attribute,
                const Element* element) const;

  // Returns attribute schemas for FIDL's officially recognized attributes.
  static AttributeSchemaMap OfficialAttributes();

 private:
  enum class Kind : uint8_t {
    // Most attributes are validate-only. They do not participate in compilation
    // apart from validation at the end (possibly with a custom constraint).
    kValidateOnly,
    // Some attributes influence compilation and are used early, before
    // VerifyAttributesStep. These schemas do not allow a constraint, since
    // constraint validation happens too late to be relied on.
    kUseEarly,
    // Some attributes get compiled and used early, before the main CompileStep.
    // These schemas ensure all arguments are literals to avoid kicking off
    // other compilations. Like kUseEarly, they do not allow a constraint.
    kCompileEarly,
    // Deprecated attributes produce an error if used.
    kDeprecated,
    // All unrecognized attributes are considered user-defined. They receive
    // minimal validation since we don't know what to expect. They allow any
    // placement, only support string and bool arguments (lacking a way to
    // decide between int8, uint32, etc.), and have no constraint.
    kUserDefined,
  };

  enum class Placement : uint8_t {
    // Allowed anywhere.
    kAnywhere,
    // Only allowed in certain places specified by std::set<Element::Kind>.
    kSpecific,
    // Only allowed on anonymous layouts (i.e. layouts not directly bound to a
    // type declaration as in `type Foo = struct { ... };`).
    kAnonymousLayout,
    // The opposite of kAnonymousLayout.
    kAnythingButAnonymousLayout,
  };

  explicit AttributeSchema(Kind kind) : kind_(kind) {}

  static void ResolveArgsWithoutSchema(CompileStep* compile_step, Attribute* attribute);

  Kind kind_ = Kind::kValidateOnly;
  Placement placement_ = Placement::kAnywhere;
  std::set<Element::Kind> specific_placements_;
  // Use transparent comparator std::less<> to allow std::string_view lookups.
  std::map<std::string, AttributeArgSchema, std::less<>> arg_schemas_;
  Constraint constraint_ = nullptr;
};

}  // namespace fidlc

#endif  // TOOLS_FIDL_FIDLC_SRC_ATTRIBUTE_SCHEMA_H_
