// 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