{% from 'templates/macros.tmpl' import license %}
{{license()}}

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_NAMES_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_NAMES_H_

#include <stddef.h>
#include "third_party/blink/public/mojom/use_counter/css_property_id.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"

namespace WTF {
class AtomicString;
class String;
}  // namespace WTF

namespace blink {

class ExecutionContext;

enum class CSSPropertyID {
    kInvalid = 0,
    kVariable = 1,
{{property_enums}}
};

const CSSPropertyID kCSSPropertyAliasList[] = {
{{property_aliases}}
};

// The lowest CSSPropertyID excluding kInvalid and kVariable.
const int kIntFirstCSSProperty = {{first_property_id}};
const CSSPropertyID kFirstCSSProperty =
    static_cast<CSSPropertyID>(kIntFirstCSSProperty);

// The number of unresolved CSS properties excluding kInvalid and kVariable.
const int kNumCSSProperties = {{properties_count}};

// The highest resolved CSSPropertyID.
const int kIntLastCSSProperty = {{last_property_id}};
const CSSPropertyID kLastCSSProperty =
    static_cast<CSSPropertyID>(kIntLastCSSProperty);

// The highest unresolved CSSPropertyID.
const CSSPropertyID kLastUnresolvedCSSProperty =
    static_cast<CSSPropertyID>({{last_unresolved_property_id}});

const CSSPropertyID kFirstHighPriorityCSSProperty = kFirstCSSProperty;
const CSSPropertyID kLastHighPriorityCSSProperty = CSSPropertyID::{{last_high_priority_property_id}};

// 1 + <The highest unresolved CSSPropertyID>.
const int kNumCSSPropertyIDs = static_cast<int>(kLastUnresolvedCSSProperty) + 1;

const size_t kMaxCSSPropertyNameLength = {{max_name_length}};
constexpr size_t kCSSPropertyIDBitLength = {{property_id_bit_length}};

static_assert((static_cast<size_t>(1) << kCSSPropertyIDBitLength) >
                  static_cast<size_t>(kLastUnresolvedCSSProperty),
              "kCSSPropertyIDBitLength has enough bits");

static_assert(CSSPropertyID::kColor == kFirstHighPriorityCSSProperty,
              "CSSPropertyID::kColor is the first high-priority property");
static_assert(CSSPropertyID::kZoom == kLastHighPriorityCSSProperty,
              "CSSPropertyID::kZoom is the last high-priority property");
static_assert((static_cast<int>(kLastHighPriorityCSSProperty) -
               static_cast<int>(kFirstHighPriorityCSSProperty)) == 25,
              "There should a low number of high-priority properties");

inline int GetCSSPropertyIDIndex(CSSPropertyID id) {
    DCHECK_GE(id, kFirstCSSProperty);
    DCHECK_LE(id, kLastCSSProperty);
    return static_cast<int>(id) - kIntFirstCSSProperty;
}

constexpr bool IsHighPriority(CSSPropertyID id) {
  return id >= kFirstHighPriorityCSSProperty &&
      id <= kLastHighPriorityCSSProperty;
}

inline bool IsCSSPropertyIDWithName(CSSPropertyID id)
{
    return id >= kFirstCSSProperty && id <= kLastUnresolvedCSSProperty;
}

inline bool IsValidCSSPropertyID(CSSPropertyID id)
{
    return id != CSSPropertyID::kInvalid;
}

inline CSSPropertyID ConvertToCSSPropertyID(int value)
{
    DCHECK_GE(value, static_cast<int>(CSSPropertyID::kInvalid));
    DCHECK_LE(value, kIntLastCSSProperty);
    return static_cast<CSSPropertyID>(value);
}

inline CSSPropertyID ResolveCSSPropertyID(CSSPropertyID id)
{
    return ConvertToCSSPropertyID(static_cast<int>(id) & ~{{alias_mask}});
}

inline bool IsPropertyAlias(CSSPropertyID id) {
  return static_cast<int>(id) & {{alias_mask}};
}

CSSPropertyID CORE_EXPORT UnresolvedCSSPropertyID(const ExecutionContext*,
                                                  const WTF::String&);

CSSPropertyID CORE_EXPORT CssPropertyID(const ExecutionContext*,
                                        const WTF::String&);

class CSSPropertyIDList {
  STACK_ALLOCATED();

 public:
  class Iterator {
    STACK_ALLOCATED();
   public:
    Iterator(int id) : id_(id) {}
    CSSPropertyID operator*() const { return ConvertToCSSPropertyID(id_); }
    Iterator& operator++() {
      id_++;
      return *this;
    }
    bool operator!=(const Iterator& i) const { return id_ != i.id_; }

   private:
    int id_;
  };
  Iterator begin() const { return Iterator(kIntFirstCSSProperty); }
  Iterator end() const { return Iterator(kIntLastCSSProperty + 1); }
};

mojom::blink::CSSSampleId CORE_EXPORT GetCSSSampleId(CSSPropertyID id);

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_NAMES_H_
