header = """/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

// See the comment in ServoBindings.h about the same.
#pragma GCC diagnostic push
#ifdef __clang__
#  pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
#endif

#ifndef mozilla_ServoStyleConsts_h
#define mozilla_ServoStyleConsts_h
"""
trailer = """
#pragma pop_macro("STRICT")
#pragma pop_macro("TRANSPARENT")

#endif // mozilla_ServoStyleConsts_h

#pragma GCC diagnostic pop
#include "mozilla/ServoStyleConstsInlines.h"
"""
autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. See RunCbindgen.py
 * To modify this file, edit servo/ports/geckolib/cbindgen.toml and build Firefox.
 */
"""
include_version = true
braces = "SameLine"
line_length = 80
tab_width = 2
language = "C++"
namespaces = ["mozilla"]
includes = ["mozilla/ServoStyleConstsForwards.h"]
after_includes = """
// Work-around silly windows.h define.
#pragma push_macro("STRICT")
#undef STRICT
#pragma push_macro("TRANSPARENT")
#undef TRANSPARENT
"""
usize_is_size_t = true

[parse]
parse_deps = true
extra_bindings = ["style"]
include = ["style", "app_units", "cssparser", "style_traits", "servo_arc"]

[struct]
associated_constants_in_body = true
derive_eq = true
derive_neq = true

[defines]
# These will actually never be defined, but is handy to avoid cbindgen
# generating Servo-only types.
"feature = servo" = "CBINDGEN_IS_SERVO"
"feature = servo-layout-2013" = "CBINDGEN_IS_SERVO"
"feature = servo-layout-2020" = "CBINDGEN_IS_SERVO"
"feature = track_alloc_size" = "CBINDGEN_IS_SERVO"
# These will always be defined.
"feature = gecko" = "CBINDGEN_IS_GECKO"
"feature = cbindgen" = "CBINDGEN_IS_GECKO"
# These depend on the build.
"target_pointer_width = 32" = "SERVO_32_BITS"
"target_pointer_width = 64" = "HAVE_64BIT_BUILD"
"unix" = "XP_UNIX"
"windows" = "XP_WIN"

[macro_expansion]
bitflags = true

[enum]
derive_helper_methods = true
derive_const_casts = true
derive_tagged_enum_destructor = true
derive_tagged_enum_copy_constructor = true
derive_tagged_enum_copy_assignment = true
private_default_tagged_enum_constructor = true
cast_assert_name = "MOZ_DIAGNOSTIC_ASSERT"

[export]
prefix = "Style"
exclude = [
  "NS_LogCtor",
  "NS_LogDtor",
  "SelectorList",
  "AuthorStyles",
  "LockedStyleRule",
  "LockedImportRule",
  "LockedFontFaceRule",
  "LockedCounterStyleRule",
  "LockedKeyframesRule",
  "LockedPageRule",
  "LockedPositionTryRule",
  "LockedNestedDeclarationsRule",
]
include = [
  "ContainerAttributeDependencyKind",
  "AlignmentBaseline",
  "AnchorName",
  "ScopedName",
  "AnimationName",
  "AnimationTimeline",
  "AnimationRangeEnd",
  "AnimationRangeStart",
  "AnimationIterationCount",
  "AnimationDirection",
  "BackgroundClip",
  "AnimationFillMode",
  "AnimationPlayState",
  "AnimationComposition",
  "AnimationDuration",
  "Appearance",
  "Au",
  "BreakBetween",
  "BreakWithin",
  "BorderSideWidth",
  "BorderStyle",
  "BorderSpacing",
  "BoolInteger",
  "OutlineStyle",
  "CaptionSide",
  "ColorGamut",
  "DominantBaseline",
  "FontSizeAdjust",
  "FontPalette",
  "FontLanguageOverride",
  "FontVariantEastAsian",
  "FontVariantLigatures",
  "FontVariantNumeric",
  "ComputedMozPrefFeatureValue",
  "ComputedFontStretchRange",
  "ComputedFontStyleRange",
  "ComputedFontWeightRange",
  "ComputedTimingFunction",
  "ComputedValueFlags",
  "CursorKind",
  "Display",
  "DisplayOutside",
  "DisplayInside",
  "DisplayMode",
  "Platform",
  "PositionAnchor",
  "PositionArea",
  "PositionAreaAxis",
  "PositionAreaTrack",
  "PositionAreaKeyword",
  "PositionTryFallbacks",
  "PositionTryOrder",
  "PositionVisibility",
  "GtkThemeFamily",
  "PrefersColorScheme",
  "PrefersContrast",
  "DynamicRange",
  "Scripting",
  "FillRule",
  "FontDisplay",
  "FontFaceSourceListComponent",
  "FontFaceSourceTechFlags",
  "FontLanguageOverride",
  "FontSynthesis",
  "FontSynthesisStyle",
  "GenericFontFamily",
  "FontFamily",
  "FontFamilyNameSyntax",
  "MozTheme",
  "OverflowWrap",
  "OffsetPath",
  "OffsetPathFunction",
  "OffsetPosition",
  "OffsetRotate",
  "RayFunction",
  "UnicodeRange",
  "UserFocus",
  "UserSelect",
  "PointerEvents",
  "Inert",
  "Float",
  "Clear",
  "OverscrollBehavior",
  "ScrollSnapAlign",
  "ScrollSnapAxis",
  "ScrollSnapStop",
  "ScrollSnapStrictness",
  "ScrollSnapType",
  "TimelineName",
  "TransitionBehavior",
  "ViewTimelineInset",
  "OverflowAnchor",
  "OverflowClipMargin",
  "Resize",
  "Overflow",
  "LengthPercentage",
  "LetterSpacing",
  "NonLocalUriDependency",
  "NonNegativeLengthPercentage",
  "LengthPercentageOrAuto",
  "LineHeight",
  "NonNegativeLengthPercentageOrAuto",
  "NonNegativeLengthPercentageOrNormal",
  "LengthOrAuto",
  "NonNegativeLengthOrAuto",
  "TextBoxEdge",
  "TextBoxTrim",
  "TextDecorationSkipInk",
  "TextDecorationLength",
  "TextDecorationInset",
  "Time",
  "Rect",
  "InitialLetter",
  "IntersectionObserverMargin",
  "Size",
  "MaxSize",
  "FlexBasis",
  "Position",
  "PositionOrAuto",
  "BackgroundSize",
  "BaselineShift",
  "BaselineSource",
  "BorderImageSlice",
  "BorderImageRepeat",
  "BorderImageRepeatKeyword",
  "BorderSpacing",
  "BorderRadius",
  "CornerShape",
  "CornerShapeRect",
  "ColorScheme",
  "ColumnCount",
  "CssRuleRef",
  "NonNegativeLengthOrNumberRect",
  "Perspective",
  "ZIndex",
  "TransformBox",
  "TransformOrigin",
  "LineBreak",
  "LineClamp",
  "WordBreak",
  "Contain",
  "ContainerType",
  "ContainerName",
  "ContentVisibility",
  "ContainIntrinsicSize",
  "Origin",
  "RestyleHint",
  "TouchAction",
  "WillChange",
  "TextDecorationLine",
  "MasonryAutoFlow",
  "MasonryPlacement",
  "MasonryItemOrder",
  "TextUnderlinePosition",
  "TextTransform",
  "TextJustify",
  "TextOverflow",
  "TextIndent",
  "MozControlCharacterVisibility",
  "RubyPosition",
  "Owned",
  "OwnedOrNull",
  "Strong",
  "ScrollbarColor",
  "CaretColor",
  "Color",
  "ColorOrAuto",
  "SystemColor",
  "SystemColorScheme",
  "SystemFont",
  "GradientItem",
  "BasicShape",
  "InsetRect",
  "ShapeRadius",
  "ShapeCommand",
  "ArcSlice",
  "ForgottenArcSlicePtr",
  "HeaderWithLength",
  "MozContextProperties",
  "Quotes",
  "BoxShadow",
  "SimpleShadow",
  "Transform",
  "Rotate",
  "Scale",
  "Translate",
  "BorderImageWidth",
  "ComputedUrl",
  "UrlOrNone",
  "Filter",
  "Gradient",
  "GridTemplateAreas",
  "GridLine",
  "TrackSize",
  "TrackBreadth",
  "ImplicitGridTracks",
  "SVGPaint",
  "SVGPaintKind",
  "GridTemplateComponent",
  "TextEmphasisStyle",
  "TextEmphasisPosition",
  "FontVariantAlternates",
  "PaintOrder",
  "SVGPaintOrder",
  "ClipRectOrAuto",
  "CounterReset",
  "CounterSet",
  "CounterIncrement",
  "WritingMode",
  "WritingModeProperty",
  "Content",
  "ContentItem",
  "ContentDistribution",
  "SelfAlignment",
  "ItemPlacement",
  "ComputedJustifyItems",
  "AlignContent",
  "JustifyContent",
  "TransformStyle",
  "Image",
  "ClipPath",
  "ShapeOutside",
  "GridAutoFlow",
  "Cursor",
  "SVGStrokeDashArray",
  "SVGLength",
  "SVGOpacity",
  "SVGWidth",
  "TextAlign",
  "TextAlignLast",
  "TextAutospace",
  "FontSizeKeyword",
  "AspectRatio",
  "DefaultFontSizes",
  "RuleChangeKind",
  "PageName",
  "PageOrientation",
  "PageSize",
  "DProperty",
  "ImageDecoding",
  "ImageRendering",
  "PrintColorAdjust",
  "ForcedColorAdjust",
  "ForcedColors",
  "ScrollbarGutter",
  "ScrollDirection",
  "HyphenateCharacter",
  "HyphenateLimitChars",
  "NumberOrAuto",
  "ComputedLinearStop",
  "PiecewiseLinearFunction",
  "BeforeFlag",
  "VectorEffect",
  "XTextScale",
  "Zoom",
  "TransitionProperty",
  "ViewTransitionClass",
  "ViewTransitionName",
  "Inset",
  "AnchorFunction",
  "AnchorSide",
  "AnchorSizeFunction",
  "Margin",
  "PositionProperty",
  "PhysicalAxis",
  "PhysicalSide",
  "QueryFontMetricsFlags",
  "AllowAnchorPosResolutionInCalcPercentage",
  "ListStyleType",
  "LinkParameters",
]
item_types = [
  "enums",
  "structs",
  "unions",
  "typedefs",
  "functions",
  "constants",
]
renaming_overrides_prefixing = true

# Prevent some renaming for Gecko types that cbindgen doesn't otherwise understand.
[export.rename]
"nscolor" = "nscolor"
"nsAtom" = "nsAtom"
"nsIURI" = "nsIURI"
"imgRequestProxy" = "imgRequestProxy"
"nsCompatibility" = "nsCompatibility"
"nsACString" = "nsACString"
"nsAString" = "nsAString"
"nsCString" = "nsCString"
"nsString" = "nsString"
"CopyableTArray" = "CopyableTArray"
"nsTArray" = "nsTArray"
"nsPresContext" = "nsPresContext"
"ComputedTiming" = "ComputedTiming"
"CountedUnknownProperty" = "CountedUnknownProperty"
"RefPtr" = "RefPtr"
"NonCustomCSSPropertyId" = "NonCustomCSSPropertyId"
"nsCSSPropertyIDSet" = "nsCSSPropertyIDSet"
"CSSPropertyId" = "CSSPropertyId"
"nsCSSValueSharedList" = "nsCSSValueSharedList"
"AnimationPropertySegment" = "AnimationPropertySegment"
"RawServoAnimationValueTable" = "RawServoAnimationValueTable"
"nsCSSUnit" = "nsCSSUnit"
"InheritTarget" = "InheritTarget"
"PseudoStyleType" = "PseudoStyleType"
"DeclarationBlockMutationClosure" = "DeclarationBlockMutationClosure"
"AtomArray" = "AtomArray"
"UpdateAnimationsTasks" = "UpdateAnimationsTasks"
"StyleRuleInclusion" = "StyleRuleInclusion"
"nsFontFaceRuleContainer" = "nsFontFaceRuleContainer"
"MediumFeaturesChangedResult" = "MediumFeaturesChangedResult"
"FontSizePrefs" = "FontSizePrefs"
"FontFaceDescriptorId" = "FontFaceDescriptorId"
"CounterStyleDescriptorId" = "CounterStyleDescriptorId"
"nsresult" = "nsresult"
"gfxFontFeature" = "gfxFontFeature"
"gfxFontFeatureValueSet" = "gfxFontFeatureValueSet"
"GeckoFontMetrics" = "GeckoFontMetrics"
"SeenPtrs" = "SeenPtrs"
"gfxFontVariation" = "gfxFontVariation"
"URLExtraData" = "URLExtraData"
"Keyframe" = "Keyframe"
"nsChangeHint" = "nsChangeHint"
"ServoElementSnapshotTable" = "ServoElementSnapshotTable"
"ComputedKeyframeValues" = "ComputedKeyframeValues"
"OriginFlags" = "OriginFlags"
"ServoTraversalFlags" = "ServoTraversalFlags"
"ServoStyleSetSizes" = "ServoStyleSetSizes"
"BeforeFlag" = "StyleEasingBeforeFlag"
"FontPaletteValueSet" = "gfx::FontPaletteValueSet"
"PaletteValues" = "gfx::FontPaletteValueSet::PaletteValues"
"ThinVec" = "CopyableTArray"
"RawPthread" = "pthread_t"
"RawHandle" = "void*"
"PseudoStyleRequest" = "PseudoStyleRequest"
"AnchorPosResolutionParams" = "AnchorPosResolutionParams"
"AnchorPosOffsetResolutionParams" = "AnchorPosOffsetResolutionParams"

[export.body]
"CSSPixelLength" = """
  static StyleCSSPixelLength FromPixels(CSSCoord aCoord) { return {aCoord}; }
  static StyleCSSPixelLength Zero() { return FromPixels(0.0f); }

  inline nscoord ToAppUnits() const;
  inline bool IsZero() const;
  CSSCoord ToCSSPixels() const { return _0; }
  inline void ScaleBy(float);
  inline StyleCSSPixelLength ScaledBy(float) const;
"""

"CalcLengthPercentage" = """
  inline CSSCoord ResolveToCSSPixels(CSSCoord aBasis) const;
  template<typename Rounder>
  inline nscoord Resolve(nscoord aBasis, Rounder) const;
"""

"GenericCalcNode" = """
  void ScaleLengthsBy(float);
"""

"LengthPercentage" = """
  using Self = StyleLengthPercentage;

  // We need to do all this manually because cbindgen can't reason about unions.
  inline StyleLengthPercentage();
  inline StyleLengthPercentage(const Self&);
  inline ~StyleLengthPercentage();
  inline Self& operator=(const Self&);

  inline bool operator==(const Self& aOther) const;
  inline bool operator!=(const Self& aOther) const;

  inline bool IsLengthOrPercentage() const;
  inline bool IsLength() const;
  inline bool IsPercentage() const;
  inline bool IsCalc() const;

  inline const StyleLength& AsLength() const;
  inline StyleLength& AsLength();

  inline const StylePercentage& AsPercentage() const;
  inline StylePercentage& AsPercentage();

  inline const StyleCalcLengthPercentage& AsCalc() const;
  inline StyleCalcLengthPercentage& AsCalc();

  static inline Self Zero();
  static inline Self FromAppUnits(nscoord);
  static inline Self FromPixels(CSSCoord);
  static inline Self FromPercentage(float);

  inline void ScaleLengthsBy(float);
  inline bool HasPercent() const;
  inline bool ConvertsToLength() const;
  inline nscoord ToLength() const;
  inline CSSCoord ToLengthInCSSPixels() const;
  inline bool ConvertsToPercentage() const;
  inline bool HasLengthAndPercentage() const;
  inline float ToPercentage() const;
  inline bool IsDefinitelyZero() const;
  inline CSSCoord ResolveToCSSPixels(CSSCoord aPercentageBasisInCSSPixels) const;
  template<typename T> inline CSSCoord ResolveToCSSPixelsWith(T aPercentageGetter) const;
  template<typename T, typename Rounder>
  inline nscoord Resolve(T aPercentageGetter, Rounder) const;
  template<typename Rounder>
  inline nscoord Resolve(nscoord aPercentageBasis, Rounder) const;
  template<typename T> inline nscoord Resolve(T aPercentageGetter) const;
  inline nscoord Resolve(nscoord aPercentageBasis) const;
"""

"GenericLengthPercentageOrAuto" = """
  inline bool ConvertsToLength() const;
  inline nscoord ToLength() const;
  inline bool ConvertsToPercentage() const;
  inline float ToPercentage() const;
  inline bool HasPercent() const;
  inline bool HasLengthAndPercentage() const;

  // Just some convenient aliases for LengthOrAuto, to avoid confusing naming.
  inline bool IsLength() const;
  inline const StyleLength& AsLength() const;

  static inline StyleGenericLengthPercentageOrAuto Zero();
"""

"GenericSize" = """
  inline bool ConvertsToLength() const;
  inline nscoord ToLength() const;
  inline bool ConvertsToPercentage() const;
  inline float ToPercentage() const;
  inline bool HasPercent() const;
  inline bool HasLengthAndPercentage() const;
  inline bool BehavesLikeStretchOnInlineAxis() const;
  inline bool BehavesLikeStretchOnBlockAxis() const;
  inline bool BehavesLikeInitialValueOnBlockAxis() const;
  inline bool BehavesLikeInitialValue(LogicalAxis) const;
  inline bool HasAnchorPositioningFunction() const;
  inline explicit StyleGenericSize(const LengthPercent &);
  static inline StyleGenericSize FromAppUnits(nscoord);
"""

"GenericFlexBasis" = """
  inline bool IsAuto() const;
"""

"GenericMaxSize" = """
  inline bool ConvertsToLength() const;
  inline nscoord ToLength() const;
  inline bool ConvertsToPercentage() const;
  inline float ToPercentage() const;
  inline bool HasPercent() const;
  inline bool HasLengthAndPercentage() const;
  inline bool BehavesLikeStretchOnInlineAxis() const;
  inline bool BehavesLikeStretchOnBlockAxis() const;
  inline bool BehavesLikeInitialValueOnBlockAxis() const;
  inline bool BehavesLikeInitialValue(LogicalAxis) const;
  inline bool HasAnchorPositioningFunction() const;
  inline explicit StyleGenericMaxSize(const LengthPercent &);
"""

"GenericPosition" = """
  inline bool HasPercent() const;
  inline bool DependsOnPositioningAreaSize() const;
  static inline StyleGenericPosition FromPercentage(float);
  inline gfx::Point ToGfxPoint(const CSSSize* aBasis = nullptr) const;
  gfx::Point ToGfxPoint(const CSSSize& aBasis) const {
    return ToGfxPoint(&aBasis);
  };
"""

"GenericBackgroundSize" = """
  bool IsInitialValue() const;
"""

"Rect" = """
  template<typename Predicate> inline bool All(Predicate) const;
  template<typename Predicate> inline bool Any(Predicate) const;

  // Defined in WritingModes.h
  inline const T& Get(mozilla::Side) const;
  inline const T& Get(LogicalSide, WritingMode) const;
  inline const T& GetIStart(WritingMode) const;
  inline const T& GetBStart(WritingMode) const;
  inline const T& Start(LogicalAxis, WritingMode) const;
  inline const T& GetIEnd(WritingMode) const;
  inline const T& GetBEnd(WritingMode) const;
  inline const T& End(LogicalAxis, WritingMode) const;

  inline T& Get(mozilla::Side);
  inline T& Get(LogicalSide, WritingMode);
  inline T& GetIStart(WritingMode);
  inline T& GetBStart(WritingMode);
  inline T& GetIEnd(WritingMode);
  inline T& GetBEnd(WritingMode);

  static StyleRect WithAllSides(const T& aSide) {
    return {aSide, aSide, aSide, aSide};
  }
"""

"GenericBorderRadius" = """
  inline const StyleLengthPercentage& Get(HalfCorner) const;
"""

"RestyleHint" = """
  static inline StyleRestyleHint RestyleSubtree();
  static inline StyleRestyleHint RecascadeSubtree();
  static inline StyleRestyleHint ForAnimations();
  // Returns true if this change hint is guaranteed to at least recascade all
  // elements in the subtree of the element it is applied to.
  inline bool DefinitelyRecascadesAllSubtree() const;
"""

"TextTransform" = """
  bool IsNone() const { return *this == NONE; }
"""

"TextUnderlinePosition" = """
  inline bool IsAuto() const;
  inline bool IsFromFont() const;
  inline bool IsUnder() const;
  inline bool IsLeft() const;
  inline bool IsRight() const;
"""

"VectorEffect" = """
  bool HasNonScalingStroke() const { return bool(*this & StyleVectorEffect::NON_SCALING_STROKE); }
"""

# TODO(emilio): Add hooks to cbindgen to be able to generate [[nodiscard]]
# on the functions.
"Owned" = """
  UniquePtr<GeckoType> Consume() {
    UniquePtr<GeckoType> ret(ptr);
    ptr = nullptr;
    return ret;
  }
"""

"OwnedOrNull" = """
  UniquePtr<GeckoType> Consume() {
    UniquePtr<GeckoType> ret(ptr);
    ptr = nullptr;
    return ret;
  }
"""

"Strong" = """
  already_AddRefed<GeckoType> Consume() {
    already_AddRefed<GeckoType> ret(const_cast<GeckoType*>(ptr));
    ptr = nullptr;
    return ret;
  }
"""

"GenericColor" = """
  static inline StyleGenericColor FromColor(nscolor);

  static inline StyleGenericColor Transparent();
  static inline StyleGenericColor Black();
  static inline StyleGenericColor White();

  bool MaybeTransparent() const;

  bool DependsOnCurrentColor() const;

  /**
   * Compute the final color, taking into account the foreground color.
   **/
  StyleAbsoluteColor ResolveColor(const StyleAbsoluteColor&) const;

  /**
   * Compute the final color, taking into account the foreground color from the
   * frame's ComputedStyle.
   */
  nscolor CalcColor(const nsIFrame*) const;
  /**
   * Compute the final color, taking into account the foreground color from the
   * style.
   */
  nscolor CalcColor(const ComputedStyle&) const;
  /**
   * Compute the final color, making the argument the foreground color.
   */
  nscolor CalcColor(nscolor) const;
  nscolor CalcColor(const StyleAbsoluteColor&) const;
"""

"AbsoluteColor" = """
  /**
   * Create a new AbsoluteColor in the sRGB color space in legacy color syntax.
   */
  static inline StyleAbsoluteColor SrgbLegacy(float red, float green, float blue, float alpha);

  static inline StyleAbsoluteColor FromColor(nscolor);

  /**
   * Convert this color into the given color space.
   */
  StyleAbsoluteColor ToColorSpace(StyleColorSpace aColorSpace) const;

  /**
   * Convert this color to an nscolor. The color will be converted to sRGB first
   * if required.
   */
  nscolor ToColor() const;
"""

"ColorFunction" = """
  bool DependsOnCurrentColor() const;
"""

"GenericColorMix" = """
  bool DependsOnCurrentColor() const;
"""

"OwnedArray" = """
  static_assert(N > 0);

  StyleOwnedArray() = delete;

  inline StyleOwnedArray& operator=(const StyleOwnedArray&);
  inline StyleOwnedArray& operator=(StyleOwnedArray&&) = delete;

  inline StyleOwnedArray(const StyleOwnedArray&);
  inline StyleOwnedArray(StyleOwnedArray&&) = delete;
  template <typename... Args>
    requires (sizeof...(Args) == N)
  inline explicit StyleOwnedArray(Args&&... aArgs);

  inline ~StyleOwnedArray();

  Span<const T> AsSpan() const {
    return {ptr, N};
  }

  static constexpr size_t Length() {
    return N;
  }

  bool operator==(const StyleOwnedArray& other) const {
    return AsSpan() == other.AsSpan();
  }

  bool operator!=(const StyleOwnedArray& other) const {
    return !(*this == other);
  }
"""

"OwnedSlice" = """
  constexpr StyleOwnedSlice() :
    ptr((T*)alignof(T)),
    len(0) {}

  inline void Clear();
  inline void CopyFrom(const StyleOwnedSlice&);
  inline void SwapElements(StyleOwnedSlice&);

  StyleOwnedSlice& operator=(const StyleOwnedSlice&);
  StyleOwnedSlice& operator=(StyleOwnedSlice&&);

  inline StyleOwnedSlice(const StyleOwnedSlice&);
  inline StyleOwnedSlice(StyleOwnedSlice&&);
  inline explicit StyleOwnedSlice(Vector<T>&&);

  inline ~StyleOwnedSlice();

  Span<const T> AsSpan() const {
    return {ptr, len};
  }

  size_t Length() const {
    return len;
  }

  bool IsEmpty() const { return Length() == 0; }

  bool operator==(const StyleOwnedSlice& other) const {
    return AsSpan() == other.AsSpan();
  }

  bool operator!=(const StyleOwnedSlice& other) const {
    return !(*this == other);
  }
"""

"ArcInner" = """
  // Increase the reference count.
  inline void IncrementRef();
  // Release the reference count, and return whether the result must be freed or not.
  [[nodiscard]] inline bool DecrementRef();
"""

"HeaderSlice" = """
  StyleHeaderSlice() = delete;
  StyleHeaderSlice(const StyleHeaderSlice&) = delete;

  inline ~StyleHeaderSlice();
  inline bool operator==(const StyleHeaderSlice& other) const;
  inline bool operator!=(const StyleHeaderSlice& other) const;

  inline Span<const T> AsSpan() const;
  inline size_t Length() const { return len; }
  inline bool IsEmpty() const { return len == 0; }
"""

"ArcSlice" = """
  inline StyleArcSlice();
  inline explicit StyleArcSlice(const StyleForgottenArcSlicePtr<T>& aPtr);
  inline Span<const T> AsSpan() const;
  inline size_t Length() const;
  inline bool IsEmpty() const;
"""

"Arc" = """
  StyleArc() = delete;
  inline StyleArc(const StyleArc& Other);
 private:
  inline void Release();
 public:
  explicit StyleArc(decltype(p) aP) : p(aP) {
    MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
  }
  inline ~StyleArc();

  inline StyleArc& operator=(const StyleArc&);
  inline StyleArc& operator=(StyleArc&&);

  const T* operator->() const {
    MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
    return &p->data;
  }
  const T& operator*() const {
    MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
    return p->data;
  }
  bool operator==(const StyleArc& other) const {
    return p == other.p || *(*this) == *other;
  }
  bool operator!=(const StyleArc& other) const {
    return !(*this == other);
  }
"""

"CustomIdent" = """
  inline nsAtom* AsAtom() const;
"""

"GenericHyphenateLimitChars" = """
  static StyleGenericHyphenateLimitChars Auto() {
    return StyleGenericHyphenateLimitChars{
      StyleNumberOrAuto<Integer>::Auto(),
      StyleNumberOrAuto<Integer>::Auto(),
      StyleNumberOrAuto<Integer>::Auto(),
    };
  };
"""

"Atom" = """
  StyleAtom(size_t) = delete;
  StyleAtom() = delete;

  inline bool IsStatic() const;
  inline nsAtom* AsAtom() const;

 private:
  inline void AddRef();
  inline void Release();

 public:
  inline explicit StyleAtom(already_AddRefed<nsAtom>);
  inline explicit StyleAtom(nsStaticAtom*);
  inline StyleAtom(const StyleAtom& aOther);
  inline StyleAtom& operator=(const StyleAtom&);
  inline ~StyleAtom();
"""

"OwnedStr" = """
  inline nsDependentCSubstring AsString() const;
"""

"GenericTransformOrigin" = """
  inline bool HasPercent() const;
"""

"GenericTransform" = """
  inline Span<const T> Operations() const;
  inline bool IsNone() const;
  bool HasPercent() const;
"""

"Angle" = """
  inline static StyleAngle Zero();
  inline float ToDegrees() const;
  inline double ToRadians() const;
  StyleAngle operator+(const StyleAngle& aAngle) const {
    return StyleAngle{_0 + aAngle._0};
  }
  StyleAngle operator-(const StyleAngle& aAngle) const {
    return StyleAngle{_0 - aAngle._0};
  }
"""

"CoordinatePair" = """
  inline gfx::Point ToGfxPoint(const CSSSize* aBasis = nullptr) const;
  gfx::Point ToGfxPoint(const CSSSize& aBasis) const {
    return ToGfxPoint(&aBasis);
  };
"""

"CommandEndPoint" = """
  inline gfx::Point ToGfxPoint(const CSSSize* aBasis = nullptr) const;
  gfx::Point ToGfxPoint(const CSSSize& aBasis) const {
    return ToGfxPoint(&aBasis);
  };
"""

"AxisEndPoint" = """
  inline gfx::Coord ToGfxCoord(const float* aBasis = nullptr) const;
  gfx::Coord ToGfxCoord(const float& aBasis) const {
    return ToGfxCoord(&aBasis);
  };
"""

"ControlPoint" = """
  inline gfx::Point ToGfxPoint(
    const gfx::Point aStatePos, const gfx::Point aEndPoint,
    const CSSSize* aBasis = nullptr) const;
  gfx::Point ToGfxPoint(
    const gfx::Point aStatePos, const gfx::Point aEndPoint,
    const CSSSize& aBasis) const {
    return ToGfxPoint(aStatePos, aEndPoint, &aBasis);
  }
"""

"ArcRadii" = """
  inline gfx::Point ToGfxPoint(const CSSSize* aBasis = nullptr) const;
  gfx::Point ToGfxPoint(const CSSSize& aBasis) const {
    return ToGfxPoint(&aBasis);
  };
"""

"TextOverflow" = """
  StyleTextOverflow()
    : first(StyleTextOverflowSide::Clip()),
      second(StyleTextOverflowSide::Clip()),
      sides_are_logical(true) {}
"""

"GenericTextIndent" = """
  StyleGenericTextIndent()
    : length(StyleLengthPercentage::Zero()),
      hanging(false),
      each_line(false) {}
"""

"UrlExtraData" = """
  StyleUrlExtraData() = delete;

  // Could be implemented if wanted.
  StyleUrlExtraData(const StyleUrlExtraData&) = delete;
  StyleUrlExtraData& operator=(const StyleUrlExtraData&) = delete;

  inline bool IsShared() const;

  inline ~StyleUrlExtraData();
  inline const URLExtraData& get() const;
"""

"CssUrlData" = """
  // Implemented in nsStyleStruct.cpp
  bool operator==(const StyleCssUrlData& other) const;
  bool operator!=(const StyleCssUrlData& other) const {
    return !(*this == other);
  }
"""

"LoadData" = """
  ~StyleLoadData();
"""

"CssUrl" = """
  inline nsDependentCSubstring SpecifiedSerialization() const;
  inline const URLExtraData& ExtraData() const;
  inline const StyleLoadData& LoadData() const;
  inline StyleLoadData& MutLoadData() const;
  inline nsIURI* GetURI() const;
"""

"ComputedUrl" = """
  // Forwarded from CssUrl.
  inline nsDependentCSubstring SpecifiedSerialization() const;
  inline const URLExtraData& ExtraData() const;
  inline nsIURI* GetURI() const;
  inline const StyleLoadData& LoadData() const;
  inline StyleLoadData& MutLoadData() const;

  inline bool IsLocalRef() const;
  inline bool HasRef() const;
  inline StyleCorsMode CorsMode() const;

  // Only relevant for images.
  inline bool IsImageResolved() const;
  inline imgRequestProxy* GetImage() const;
  void ResolveImage(dom::Document&, const StyleComputedUrl* aOldImage);
"""

"GenericGradient" = """
  inline bool Repeating() const;
  bool IsOpaque() const;

  // Return the color interpolation method of the gradient.
  inline const StyleColorInterpolationMethod& ColorInterpolationMethod() const;
"""

"GenericGridLine" = """
  // Returns the `auto` value.
  inline StyleGenericGridLine();
  inline bool IsAuto() const;
  // The line name, or nsGkAtoms::_empty if not present.
  inline nsAtom* LineName() const;
"""

"GenericTrackBreadth" = """
  inline bool HasPercent() const;
"""

"GenericTrackSize" = """
  // Implemented in nsGridContainerFrame.cpp
  inline const StyleGenericTrackBreadth<L>& GetMin() const;
  inline const StyleGenericTrackBreadth<L>& GetMax() const;
"""

"GenericGridTemplateComponent" = """
  inline Maybe<size_t> RepeatAutoIndex() const;
  inline const StyleGenericTrackRepeat<L, I>* GetRepeatAutoValue() const;
  inline bool HasRepeatAuto() const;
  inline Span<const StyleOwnedSlice<StyleCustomIdent>> LineNameLists(bool aIsSubgrid) const;
  inline Span<const StyleGenericTrackListValue<L, I>> TrackListValues() const;
"""

"GenericClipRect" = """
  // Get the layout rect, replacing auto right / bottom values for aAutoSize.
  inline nsRect ToLayoutRect(nscoord aAutoSize = NS_MAXSIZE) const;
"""

"TimingFunction" = """
 public:
  bool IsLinearKeyword() const { return IsKeyword() && AsKeyword() == StyleTimingKeyword::Linear; }
  static StyleTimingFunction LinearKeyword() { return Keyword(StyleTimingKeyword::Linear); }

  inline double At(double, bool aBeforeFlag) const;
  inline void AppendToString(nsACString&) const;

  inline static double GetPortion(const Maybe<StyleTimingFunction>&, double, bool aBeforeFlag);
"""

"GenericImage" = """
 public:
  // Returns the intrinsic resolution of the image.
  //
  // The resolution is in dppx, and should be used to impact the intrinsic
  // size of the image.
  //
  // @param aStyleForZoom a style, if CSS zoom should be considered as well.
  ImageResolution GetResolution(const ComputedStyle* aStyleForZoom) const;

  // If this is an image-set(), the final image we've selected, otherwise it
  // returns *this.
  const StyleGenericImage& FinalImage() const;

  // Whether this image may have an image request associated with it.
  bool IsImageRequestType() const;

  // Gets the image request URL.
  const StyleComputedUrl* GetImageRequestURLValue() const;

  // Gets the image data of this image if it has any image request.
  imgRequestProxy* GetImageRequest() const;

  // Returns true if this image is fully loaded, and its size is calculated.
  // Always returns true if there's no image request involved and this image
  // is not `none`.
  bool IsComplete() const;

  // Returns true if this image has an available size and hasn't errored.
  // Always returns true if there's no image request involved and this image
  // is not `none`.
  bool IsSizeAvailable() const;

  // Returns true if the item is definitely opaque --- i.e., paints every
  // pixel within its bounds opaquely, and the bounds contains at least a pixel.
  bool IsOpaque() const;

  // Resolves the underlying image request if any.
  void ResolveImage(dom::Document&, const StyleGenericImage* aOld);

  // Returns whether this image has been resolved.
  bool IsResolved() const;
"""

"Ratio" = """
  inline AspectRatio ToLayoutRatio(UseBoxSizing aUseBoxSizing) const;
"""

"GenericAspectRatio" = """
  bool HasRatio() const { return ratio.IsRatio(); }
  bool HasFiniteRatio() const { return static_cast<bool>(ToLayoutRatio()); }
  inline AspectRatio ToLayoutRatio() const;

  static StyleGenericAspectRatio Auto() {
    return {true, StylePreferredRatio<N>::None()};
  }
"""

"FontFamilyList" = """
  static StyleFontFamilyList WithOneUnquotedFamily(const nsACString&);
  // Constructs a font family list with a list of names.
  static StyleFontFamilyList WithNames(nsTArray<StyleSingleFontFamily>&&);
"""

"SingleFontFamily" = """
  static StyleSingleFontFamily Parse(const nsACString& aName);
  void AppendToString(nsACString& aFamily, bool aIncludeQuotes = true) const;
  bool IsNamedFamily(const nsAString&) const;
"""

"FontWeight" = """
 SERVO_FIXED_POINT_HELPERS(StyleFontWeight, uint16_t, StyleFONT_WEIGHT_FRACTION_BITS);
 bool IsNormal() const { return *this == NORMAL; }

 inline bool IsBold() const;
 inline bool PreferBold() const;
"""

"FontStyle" = """
 SERVO_FIXED_POINT_HELPERS(StyleFontStyle, int16_t, StyleFONT_STYLE_FRACTION_BITS);
 bool IsNormal() const { return *this == NORMAL; }
 inline bool IsItalic() const;
 inline float ObliqueAngle() const;  // Not for use when IsItalic() is true
 inline float SlantAngle() const;  // Returns angle for any font-style, including
                                   // normal/italic as well as explicit oblique
"""

"FontStretch" = """
 SERVO_FIXED_POINT_HELPERS(StyleFontStretch, uint16_t, StyleFONT_STRETCH_FRACTION_BITS);
 bool IsNormal() const { return *this == NORMAL; }
"""

"Zoom" = """
 float ToFloat() const { return _0; }
 inline float Zoom(float) const;
 inline float Unzoom(float) const;
 inline nscoord ZoomCoord(nscoord) const;
 inline nscoord UnzoomCoord(nscoord) const;
 inline nsSize Zoom(const nsSize&) const;
 inline nsSize Unzoom(const nsSize&) const;
 inline nsPoint Zoom(const nsPoint&) const;
 inline nsPoint Unzoom(const nsPoint&) const;
 inline nsRect Zoom(const nsRect&) const;
 inline nsRect Unzoom(const nsRect&) const;
"""

"AnimationName" = """
 public:
  StyleAnimationName();
"""

"TimelineIdent" = """
 public:
  StyleTimelineIdent();
  nsAtom* AsAtom() const { return _0.AsAtom(); }
"""

"GenericViewTimelineInset" = """
 public:
  inline StyleGenericViewTimelineInset();
"""

"GenericAnimationRangeValue" = """
 public:
  static StyleGenericAnimationRangeValue<LengthPercent> DefaultStart();
  static StyleGenericAnimationRangeValue<LengthPercent> DefaultEnd();
"""

"Time" = """
 float ToSeconds() const { return seconds; }
 float ToMilliseconds() const { return seconds * 1000.0f; }
"""

"FontFaceSourceTechFlags" = """
  inline static StyleFontFaceSourceTechFlags Empty() {
    return StyleFontFaceSourceTechFlags{0};
  }
"""

"FontPalette" = """
  inline static StyleFontPalette Normal();
"""

"GenericOffsetPath" = """
  // Return true if the <offset-path> is ray().
  bool IsRay() const {
    return IsOffsetPath() && AsOffsetPath().path->IsRay();
  }

  const StyleRayFunction& AsRay() const {
    return AsOffsetPath().path->AsRay();
  }

  // Return true if the <offset-path> is url().
  bool IsUrl() const {
    return IsOffsetPath() && AsOffsetPath().path->IsUrl();
  }

  const StyleComputedUrl& AsUrl() const {
    return AsOffsetPath().path->AsUrl();
  }

  // Return true if the <basic-shape> is path().
  bool IsPath() const {
    if (!IsOffsetPath()) {
      return false;
    }
    const auto& path = AsOffsetPath().path;
    if (!path->IsShape()) {
      return false;
    }
    const auto& shape = path->AsShape();
    return shape.IsPathOrShape() && shape.AsPathOrShape().IsPath();
  }

  const StyleSVGPathData& AsSVGPathData() const {
    return AsOffsetPath().path->AsShape().AsPathOrShape().AsPath().path;
  }

  // Return true if this is "<basic-shape> || <coord-box>".
  bool IsBasicShapeOrCoordBox() const {
    return IsCoordBox() || (IsOffsetPath() && AsOffsetPath().path->IsShape());
  }
"""

"GenericShapeCommand" = """
  bool IsCubicType() const { return IsCubicCurve() || IsSmoothCubic(); }
  bool IsQuadraticType() const { return IsQuadCurve() || IsSmoothQuad(); }
"""

"GenericContainIntrinsicSize" = """
  bool HasAuto() const { return IsAutoLength() || IsAutoNone(); }
"""

"Display" = """
  inline StyleDisplayOutside Outside() const;
  inline StyleDisplayInside Inside() const;
  inline bool IsListItem() const;
  inline bool IsInlineFlow() const;
  inline bool IsInlineInside() const;
  inline bool IsInlineOutside() const;
  inline bool IsBlockOutside() const;
  inline bool IsRuby() const;
  inline bool IsInternalRuby() const;
  inline bool IsInternalTable() const;
  inline bool IsInternalTableExceptCell() const;
"""

"TransitionProperty" = """
  bool IsAll() const {
    return IsNonCustom() &&
           NonCustomCSSPropertyId(AsNonCustom()._0) == eCSSProperty_all;
  }
"""

"GenericInset" = """
  inline bool HasPercent() const;
  inline bool ConvertsToLength() const;
  inline bool HasLengthAndPercentage() const;
  inline bool HasAnchorPositioningFunction() const;
  inline nscoord ToLength() const;
  inline bool ConvertsToPercentage() const;
  inline float ToPercentage() const;
  inline explicit StyleGenericInset(const LP &);
"""

"GenericMargin" = """
  inline bool HasPercent() const;
  inline bool ConvertsToLength() const;
  inline bool HasLengthAndPercentage() const;
  inline nscoord ToLength() const;
  inline bool ConvertsToPercentage() const;
  inline float ToPercentage() const;
  inline bool HasAnchorPositioningFunction() const;
  inline explicit StyleGenericMargin(const LP &);
"""

"PositionArea" = """
  inline bool IsNone() const;
  constexpr StylePositionArea()
    : first(StylePositionAreaKeyword::None),
      second(StylePositionAreaKeyword::None)
  {}
"""

"CascadeLevel" = """
  inline static StyleCascadeLevel Default() {
    return SAME_TREE_AUTHOR_NORMAL;
  }
  inline int8_t ShadowCascadeOrder() const {
    bool neg(*this & CASCADE_ORDER_SIGN);
    uint8_t abs = (*this & CASCADE_ORDER_BITS)._0 >> CASCADE_ORDER_SHIFT;
    return int8_t(neg ? -abs : abs);
  }
"""

"TreeScoped" = """
  inline StyleTreeScoped()
    : value(T()),
      scope(StyleCascadeLevel::Default())
  {}
  inline explicit StyleTreeScoped(T&& aValue)
    : value(std::move(aValue)),
      scope(StyleCascadeLevel::Default())
  {}
  inline bool IsEmpty() const;
  inline Span<const mozilla::StyleAtom> AsSpan() const;
"""

"Optional" = """
  explicit operator bool() const { return IsSome(); }

  const T& operator*() const { return AsSome(); }
"""

"NumericType" = """
  static_assert(static_cast<size_t>(StyleNumericBaseType::Percent) + 1 ==
                StyleNUMERIC_BASE_TYPE_COUNT);

  inline StyleNumericType();

 private:
  inline static StyleNumericType Empty();

  // Keep in sync with NumericType::with_base_type() in Stylo.
  // This is a manual C++ duplicate to avoid FFI calls.
  inline static StyleNumericType WithBaseType(StyleNumericBaseType aBaseType);

 public:
  inline static StyleNumericType Number();
  inline static StyleNumericType Percent();
  inline static StyleNumericType Length();
  inline static StyleNumericType Angle();
  inline static StyleNumericType Time();
  inline static StyleNumericType Frequency();
  inline static StyleNumericType Resolution();
  inline static StyleNumericType Flex();

  inline int32_t Exponent(StyleNumericBaseType aBaseType) const;

  inline bool operator==(const StyleNumericType& aOther) const;
"""

"PropertyTypedValueList" = """
  StylePropertyTypedValueList(StylePropertyTypedValueList&& other)
      : tag(other.tag) {
    switch (tag) {
      case Tag::None:
        break;
      case Tag::Unsupported:
        ::new (&unsupported)
            StyleUnsupported_Body(std::move(other.unsupported));
        break;
      case Tag::Typed:
        ::new (&typed) StyleTyped_Body(std::move(other.typed));
        break;
    }
  }

  StylePropertyTypedValueList& operator=(StylePropertyTypedValueList&& other) {
    if (this != &other) {
      this->~StylePropertyTypedValueList();
      new (this) StylePropertyTypedValueList(std::move(other));
    }
    return *this;
  }

  StyleUnsupportedValue ExtractUnsupported() && {
    MOZ_DIAGNOSTIC_ASSERT(IsUnsupported());
    return std::move(unsupported._0);
  }
"""
