chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_instances.cc.tmpl

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

{% from 'templates/macros.tmpl' import source_files_for_generated_file %}
{{source_files_for_generated_file(template_file, input_files)}}
// clang-format off

#include "third_party/blink/renderer/core/css/properties/css_property_instances.h"

#include "third_party/blink/renderer/core/css/properties/longhands.h"
#include "third_party/blink/renderer/core/css/properties/longhands/variable.h"
#include "third_party/blink/renderer/core/css/properties/shorthands.h"

namespace blink {

{% set all_properties = properties + aliases %}

// NOTE: Everything in here must be reinterpret_cast-able
// to CSSUnresolvedProperty! In particular, this means that
// multiple inheritance is forbidden. We enforce this through
// DCHECKs as much as we can; this also checks (compile-time)
// that everything inherits from CSSUnresolvedProperty.
union alignas(kCSSPropertyUnionBytes) CSSPropertyUnion {
  constexpr CSSPropertyUnion() {}  // For kInvalid.
  constexpr CSSPropertyUnion(Variable property)
    : variable_(std::move(property)) {
    DCHECK(reinterpret_cast<const CSSUnresolvedProperty *>(this) ==
        static_cast<const CSSUnresolvedProperty *>(&variable_));
  }

  {% for property in all_properties %}
  constexpr CSSPropertyUnion(::blink::{{property.namespace}}::{{property.classname}} property)
    : {{property.property_id.lower()}}_(std::move(property)) {
    DCHECK(reinterpret_cast<const CSSUnresolvedProperty *>(this) ==
        static_cast<const CSSUnresolvedProperty *>(&{{property.property_id.lower()}}_));
  }
  {% endfor %}

  Variable variable_;
  {% for property in all_properties %}
  ::blink::{{property.namespace}}::{{property.classname}} {{property.property_id.lower()}}_;
  {% endfor %}
};
static_assert(sizeof(CSSPropertyUnion) == kCSSPropertyUnionBytes);

const CSSPropertyUnion kCssProperties[] = {
  {},  // kInvalid.
  Variable(),
  {% for property in all_properties %}
  ::blink::{{property.namespace}}::{{property.classname}}(),
  {% endfor %}
};

// Mapping from a property's ID to that of its visited counterpart,
// or kInvalid if it has none.
const uint8_t kPropertyVisitedIDs[] = {
  static_cast<uint8_t>(CSSPropertyID::kInvalid),
  static_cast<uint8_t>(CSSPropertyID::kInvalid),  // kVariable.
  {% for property in all_properties %}
    {% if property.visited_property %}
      static_cast<uint8_t>(CSSPropertyID::{{property.visited_property.enum_key}}),  // {{property.enum_key}}.
    {% else %}
      static_cast<uint8_t>(CSSPropertyID::kInvalid),  // {{property.enum_key}}.
    {% endif %}
  {% endfor %}
};

// Verify that all properties (used in the array) fit into a uint8_t.
// If this stops holding, we'll either need to switch types of
// kPropertyVisitedIDs, or reorganize the ordering of the enum
// so that the kInternalVisited* ones are earlier.
static_assert(static_cast<size_t>(CSSPropertyID::kInvalid) < 256);
{% for property in all_properties %}
  {% if property.visited_property %}
    static_assert(static_cast<size_t>(CSSPropertyID::{{property.visited_property.enum_key}}) < 256);
  {% endif %}
{% endfor %}

// Similar, for unvisited IDs. Note that this array is much less
// hot than kPropertyVisitedIDs, so it's definitely fine that it's uint16_t.
const uint16_t kPropertyUnvisitedIDs[] = {
  static_cast<uint16_t>(CSSPropertyID::kInvalid),
  static_cast<uint16_t>(CSSPropertyID::kInvalid),  // kVariable.
  {% for property in all_properties %}
    {% if property.unvisited_property %}
      static_cast<uint16_t>(CSSPropertyID::{{property.unvisited_property.enum_key}}),  // {{property.enum_key}}.
    {% else %}
      static_cast<uint16_t>(CSSPropertyID::kInvalid),  // {{property.enum_key}}.
    {% endif %}
  {% endfor %}
};

// Same check as for kPropertyVisitedIDs.
static_assert(static_cast<size_t>(CSSPropertyID::kInvalid) < 65536);
{% for property in properties %}
  {% if property.unvisited_property %}
    static_assert(static_cast<size_t>(CSSPropertyID::{{property.unvisited_property.enum_key}}) < 65536);
  {% endif %}
{% endfor %}

}  // namespace blink