// Copyright 2016 The Chromium Authors. All rights reserved.
// Copyright (C) 2016-2021 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config.h"
#include "CSSPropertyParserHelpers.h"

#include "CSSCalcSymbolTable.h"
#include "CSSCalcValue.h"
#include "CSSCanvasValue.h"
#include "CSSCrossfadeValue.h"
#include "CSSFilterImageValue.h"
#include "CSSGradientValue.h"
#include "CSSImageSetValue.h"
#include "CSSImageValue.h"
#include "CSSNamedImageValue.h"
#include "CSSPaintImageValue.h"
#include "CSSParserIdioms.h"
#include "CSSValuePool.h"
#include "CalculationCategory.h"
#include "ColorConversion.h"
#include "ColorInterpolation.h"
#include "ColorLuminance.h"
#include "ColorNormalization.h"
#include "Logging.h"
#include "Pair.h"
#include "RenderStyleConstants.h"
#include "RuntimeEnabledFeatures.h"
#include "StyleColor.h"
#include "WebKitFontFamilyNames.h"
#include <wtf/SortedArrayMap.h>
#include <wtf/text/StringConcatenateNumbers.h>
#include <wtf/text/TextStream.h>

namespace WebCore {

namespace CSSPropertyParserHelpers {

bool consumeCommaIncludingWhitespace(CSSParserTokenRange& range)
{
    CSSParserToken value = range.peek();
    if (value.type() != CommaToken)
        return false;
    range.consumeIncludingWhitespace();
    return true;
}

bool consumeSlashIncludingWhitespace(CSSParserTokenRange& range)
{
    CSSParserToken value = range.peek();
    if (value.type() != DelimiterToken || value.delimiter() != '/')
        return false;
    range.consumeIncludingWhitespace();
    return true;
}

CSSParserTokenRange consumeFunction(CSSParserTokenRange& range)
{
    ASSERT(range.peek().type() == FunctionToken);
    CSSParserTokenRange contents = range.consumeBlock();
    range.consumeWhitespace();
    contents.consumeWhitespace();
    return contents;
}

inline bool shouldAcceptUnitlessValue(double value, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
{
    // FIXME: Presentational HTML attributes shouldn't use the CSS parser for lengths.

    if (value == 0 && unitlessZero == UnitlessZeroQuirk::Allow)
        return true;

    if (isUnitlessValueParsingEnabledForMode(parserMode))
        return true;
    
    return parserMode == HTMLQuirksMode && unitless == UnitlessQuirk::Allow;
}

static bool canConsumeCalcValue(CalculationCategory category, CSSParserMode parserMode)
{
    if (category == CalculationCategory::Length || category == CalculationCategory::Percent || category == CalculationCategory::PercentLength)
        return true;

    if (parserMode != SVGAttributeMode)
        return false;

    if (category == CalculationCategory::Number || category == CalculationCategory::PercentNumber)
        return true;

    return false;
}

// FIXME: consider pulling in the parsing logic from CSSCalcExpressionNodeParser.
class CalcParser {
public:
    explicit CalcParser(CSSParserTokenRange& range, CalculationCategory destinationCategory, ValueRange valueRange = ValueRange::All, const CSSCalcSymbolTable& symbolTable = { }, CSSValuePool& pool = CSSValuePool::singleton(), NegativePercentagePolicy negativePercentagePolicy = NegativePercentagePolicy::Forbid)
        : m_sourceRange(range)
        , m_range(range)
        , m_pool(pool)
    {
        const CSSParserToken& token = range.peek();
        auto functionId = token.functionId();
        if (CSSCalcValue::isCalcFunction(functionId))
            m_calcValue = CSSCalcValue::create(functionId, consumeFunction(m_range), destinationCategory, valueRange, symbolTable, negativePercentagePolicy == NegativePercentagePolicy::Allow);
    }

    const CSSCalcValue* value() const { return m_calcValue.get(); }

    RefPtr<CSSPrimitiveValue> consumeValue()
    {
        if (!m_calcValue)
            return nullptr;
        m_sourceRange = m_range;
        return m_pool.createValue(WTFMove(m_calcValue));
    }

    RefPtr<CSSPrimitiveValue> consumeValueIfCategory(CalculationCategory category)
    {
        if (!m_calcValue)
            return nullptr;

        if (m_calcValue->category() != category) {
            LOG_WITH_STREAM(Calc, stream << "CalcParser::consumeValueIfCategory - failing because calc category " << m_calcValue->category() << " does not match requested category " << category);
            return nullptr;
        }
        m_sourceRange = m_range;
        return m_pool.createValue(WTFMove(m_calcValue));
    }

private:
    CSSParserTokenRange& m_sourceRange;
    CSSParserTokenRange m_range;
    RefPtr<CSSCalcValue> m_calcValue;
    CSSValuePool& m_pool;
};

// MARK: - Primitive value consumers for callers that know the token type.

static RefPtr<CSSCalcValue> consumeCalcRawWithKnownTokenTypeFunction(CSSParserTokenRange& range, CalculationCategory category, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange)
{
    ASSERT(range.peek().type() == FunctionToken);

    const auto& token = range.peek();
    auto functionId = token.functionId();
    if (!CSSCalcValue::isCalcFunction(functionId))
        return nullptr;

    auto calcValue = CSSCalcValue::create(functionId, consumeFunction(range), category, valueRange, symbolTable);
    if (calcValue && calcValue->category() == category)
        return calcValue;

    return nullptr;
}

// MARK: Integer (Raw)

enum class IntegerRange { All, ZeroAndGreater, OneAndGreater };

static constexpr double computeMinimumValue(IntegerRange range)
{
    switch (range) {
    case IntegerRange::All:
        return -std::numeric_limits<double>::infinity();
    case IntegerRange::ZeroAndGreater:
        return 0.0;
    case IntegerRange::OneAndGreater:
        return 1.0;
    }

    RELEASE_ASSERT_NOT_REACHED_UNDER_CONSTEXPR_CONTEXT();

    return 0.0;
}
// MARK: Integer (Raw)

template<typename IntType, IntegerRange integerRange>
struct IntegerTypeRawKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static std::optional<IntType> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == FunctionToken);

        auto rangeCopy = range;
        if (auto value = consumeCalcRawWithKnownTokenTypeFunction(rangeCopy, CalculationCategory::Number, { }, ValueRange::All)) {
            range = rangeCopy;
            return clampTo<IntType>(std::round(std::max(value->doubleValue(), computeMinimumValue(integerRange))));
        }

        return std::nullopt;
    }
};

template<typename IntType, IntegerRange integerRange>
struct IntegerTypeRawKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static std::optional<IntType> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == NumberToken);
        
        if (range.peek().numericValueType() == NumberValueType || range.peek().numericValue() < computeMinimumValue(integerRange))
            return std::nullopt;
        return clampTo<IntType>(range.consumeIncludingWhitespace().numericValue());
    }
};

// MARK: Integer (CSSPrimitiveValue - maintaining calc)

template<typename IntType, IntegerRange integerRange>
struct IntegerTypeKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == FunctionToken);

        if (auto integer = IntegerTypeRawKnownTokenTypeFunctionConsumer<IntType, integerRange>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero))
            return pool.createValue(*integer, CSSUnitType::CSS_INTEGER);
        return nullptr;
    }
};

template<typename IntType, IntegerRange integerRange>
struct IntegerTypeKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == NumberToken);
        
        if (auto integer = IntegerTypeRawKnownTokenTypeNumberConsumer<IntType, integerRange>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero))
            return pool.createValue(*integer, CSSUnitType::CSS_INTEGER);
        return nullptr;
    }
};

// MARK: Number (Raw)

static std::optional<NumberRaw> validatedNumberRaw(double value, ValueRange valueRange)
{
    if (valueRange == ValueRange::NonNegative && value < 0)
        return std::nullopt;
    return {{ value }};
}

struct NumberRawKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static std::optional<NumberRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == FunctionToken);

        auto rangeCopy = range;
        if (auto value = consumeCalcRawWithKnownTokenTypeFunction(rangeCopy, CalculationCategory::Number, symbolTable, valueRange)) {
            if (auto validatedValue = validatedNumberRaw(value->doubleValue(), valueRange)) {
                range = rangeCopy;
                return validatedValue;
            }
        }

        return std::nullopt;
    }
};

struct NumberRawKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static std::optional<NumberRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == NumberToken);
        
        if (auto validatedValue = validatedNumberRaw(range.peek().numericValue(), valueRange)) {
            range.consumeIncludingWhitespace();
            return validatedValue;
        }
        return std::nullopt;
    }
};

struct NumberRawKnownTokenTypeIdentConsumer {
    static constexpr CSSParserTokenType tokenType = IdentToken;
    static std::optional<NumberRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == IdentToken);

        if (auto variable = symbolTable.get(range.peek().id())) {
            switch (variable->type) {
            case CSSUnitType::CSS_NUMBER:
                if (auto validatedValue = validatedNumberRaw(variable->value, valueRange)) {
                    range.consumeIncludingWhitespace();
                    return validatedValue;
                }
                break;

            default:
                break;
            }
        }
        return std::nullopt;
    }
};

// MARK: Number (CSSPrimitiveValue - maintaining calc)

struct NumberCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == FunctionToken);

        CalcParser parser(range, CalculationCategory::Number, valueRange, symbolTable, pool);
        return parser.consumeValueIfCategory(CalculationCategory::Number);
    }
};

struct NumberCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == NumberToken);
        
        auto token = range.peek();
        
        if (auto validatedValue = validatedNumberRaw(token.numericValue(), valueRange)) {
            auto unitType = token.unitType();
            range.consumeIncludingWhitespace();
            return pool.createValue(validatedValue->value, unitType);
        }
        return nullptr;
    }
};

// MARK: Percent (raw)

static std::optional<PercentRaw> validatedPercentRaw(double value, ValueRange valueRange)
{
    if (valueRange == ValueRange::NonNegative && value < 0)
        return std::nullopt;
    if (std::isinf(value))
        return std::nullopt;
    return {{ value }};
}

struct PercentRawKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static std::optional<PercentRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == FunctionToken);

        auto rangeCopy = range;
        if (auto value = consumeCalcRawWithKnownTokenTypeFunction(rangeCopy, CalculationCategory::Percent, symbolTable, valueRange)) {
            range = rangeCopy;

            // FIXME: Should this validate the calc value as is done for the NumberRaw variant?
            return {{ value->doubleValue() }};
        }

        return std::nullopt;
    }
};

struct PercentRawKnownTokenTypePercentConsumer {
    static constexpr CSSParserTokenType tokenType = PercentageToken;
    static std::optional<PercentRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == PercentageToken);

        if (auto validatedValue = validatedPercentRaw(range.peek().numericValue(), valueRange)) {
            range.consumeIncludingWhitespace();
            return validatedValue;
        }
        return std::nullopt;
    }
};

struct PercentRawKnownTokenTypeIdentConsumer {
    static constexpr CSSParserTokenType tokenType = IdentToken;
    static std::optional<PercentRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == IdentToken);

        if (auto variable = symbolTable.get(range.peek().id())) {
            switch (variable->type) {
            case CSSUnitType::CSS_PERCENTAGE:
                if (auto validatedValue = validatedPercentRaw(variable->value, valueRange)) {
                    range.consumeIncludingWhitespace();
                    return validatedValue;
                }
                break;

            default:
                break;
            }
        }
        return std::nullopt;
    }
};

// MARK: Percent (CSSPrimitiveValue - maintaining calc)

struct PercentCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == FunctionToken);

        CalcParser parser(range, CalculationCategory::Percent, valueRange, symbolTable, pool);
        return parser.consumeValueIfCategory(CalculationCategory::Percent);
    }
};

struct PercentCSSPrimitiveValueWithCalcWithKnownTokenTypePercentConsumer {
    static constexpr CSSParserTokenType tokenType = PercentageToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == PercentageToken);
        
        if (auto validatedValue = validatedPercentRaw(range.peek().numericValue(), valueRange)) {
            range.consumeIncludingWhitespace();
            return pool.createValue(validatedValue->value, CSSUnitType::CSS_PERCENTAGE);
        }
        return nullptr;
    }
};

// MARK: Length (raw)

static std::optional<double> validatedLengthRaw(double value, ValueRange valueRange)
{
    if (valueRange == ValueRange::NonNegative && value < 0)
        return std::nullopt;
    if (std::isinf(value))
        return std::nullopt;
    return value;
}

struct LengthRawKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static std::optional<LengthRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == FunctionToken);

        auto rangeCopy = range;
        if (auto value = consumeCalcRawWithKnownTokenTypeFunction(rangeCopy, CalculationCategory::Length, symbolTable, valueRange)) {
            range = rangeCopy;

            // FIXME: Should this validate the calc value as is done for the NumberRaw variant?
            return { { value->primitiveType(), value->doubleValue() } };
        }
        return std::nullopt;
    }
};

struct LengthRawKnownTokenTypeDimensionConsumer {
    static constexpr CSSParserTokenType tokenType = DimensionToken;
    static std::optional<LengthRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == DimensionToken);

        auto& token = range.peek();

        auto unitType = token.unitType();
        switch (unitType) {
        case CSSUnitType::CSS_QUIRKY_EMS:
            if (parserMode != UASheetMode)
                return std::nullopt;
            FALLTHROUGH;
        case CSSUnitType::CSS_EMS:
        case CSSUnitType::CSS_REMS:
        case CSSUnitType::CSS_LHS:
        case CSSUnitType::CSS_RLHS:
        case CSSUnitType::CSS_CHS:
        case CSSUnitType::CSS_IC:
        case CSSUnitType::CSS_EXS:
        case CSSUnitType::CSS_PX:
        case CSSUnitType::CSS_CM:
        case CSSUnitType::CSS_MM:
        case CSSUnitType::CSS_IN:
        case CSSUnitType::CSS_PT:
        case CSSUnitType::CSS_PC:
        case CSSUnitType::CSS_VW:
        case CSSUnitType::CSS_VH:
        case CSSUnitType::CSS_VMIN:
        case CSSUnitType::CSS_VMAX:
        case CSSUnitType::CSS_VB:
        case CSSUnitType::CSS_VI:
        case CSSUnitType::CSS_SVW:
        case CSSUnitType::CSS_SVH:
        case CSSUnitType::CSS_SVMIN:
        case CSSUnitType::CSS_SVMAX:
        case CSSUnitType::CSS_SVB:
        case CSSUnitType::CSS_SVI:
        case CSSUnitType::CSS_LVW:
        case CSSUnitType::CSS_LVH:
        case CSSUnitType::CSS_LVMIN:
        case CSSUnitType::CSS_LVMAX:
        case CSSUnitType::CSS_LVB:
        case CSSUnitType::CSS_LVI:
        case CSSUnitType::CSS_DVW:
        case CSSUnitType::CSS_DVH:
        case CSSUnitType::CSS_DVMIN:
        case CSSUnitType::CSS_DVMAX:
        case CSSUnitType::CSS_DVB:
        case CSSUnitType::CSS_DVI:
        case CSSUnitType::CSS_Q:
        case CSSUnitType::CSS_CQW:
        case CSSUnitType::CSS_CQH:
        case CSSUnitType::CSS_CQI:
        case CSSUnitType::CSS_CQB:
        case CSSUnitType::CSS_CQMIN:
        case CSSUnitType::CSS_CQMAX:
            break;
        default:
            return std::nullopt;
        }

        if (auto validatedValue = validatedLengthRaw(token.numericValue(), valueRange)) {
            range.consumeIncludingWhitespace();
            return { { unitType, *validatedValue } };
        }
        return std::nullopt;
    }
};

struct LengthRawKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static std::optional<LengthRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == NumberToken);

        auto& token = range.peek();

        if (!shouldAcceptUnitlessValue(token.numericValue(), parserMode, unitless, UnitlessZeroQuirk::Allow))
            return std::nullopt;

        if (auto validatedValue = validatedLengthRaw(token.numericValue(), valueRange)) {
            range.consumeIncludingWhitespace();
            return { { CSSUnitType::CSS_PX, *validatedValue } };
        }
        return std::nullopt;
    }
};

// MARK: Length (CSSPrimitiveValue - maintaining calc)

struct LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == FunctionToken);

        CalcParser parser(range, CalculationCategory::Length, valueRange, symbolTable, pool);
        return parser.consumeValueIfCategory(CalculationCategory::Length);
    }
};

struct LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer {
    static constexpr CSSParserTokenType tokenType = DimensionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == DimensionToken);

        if (auto lengthRaw = LengthRawKnownTokenTypeDimensionConsumer::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero))
            return pool.createValue(lengthRaw->value, lengthRaw->type);
        return nullptr;
    }
};

struct LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == NumberToken);

        if (auto lengthRaw = LengthRawKnownTokenTypeNumberConsumer::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero))
            return pool.createValue(lengthRaw->value, lengthRaw->type);
        return nullptr;
    }
};

// MARK: Angle (raw)

struct AngleRawKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static std::optional<AngleRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        auto rangeCopy = range;
        if (auto value = consumeCalcRawWithKnownTokenTypeFunction(rangeCopy, CalculationCategory::Angle, symbolTable, valueRange)) {
            range = rangeCopy;
            return { { value->primitiveType(), value->doubleValue() } };
        }
        return std::nullopt;
    }
};

struct AngleRawKnownTokenTypeDimensionConsumer {
    static constexpr CSSParserTokenType tokenType = DimensionToken;
    static std::optional<AngleRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == DimensionToken);

        auto unitType = range.peek().unitType();
        switch (unitType) {
        case CSSUnitType::CSS_DEG:
        case CSSUnitType::CSS_RAD:
        case CSSUnitType::CSS_GRAD:
        case CSSUnitType::CSS_TURN:
            return { { unitType, range.consumeIncludingWhitespace().numericValue() } };
        default:
            break;
        }

        return std::nullopt;
    }
};

struct AngleRawKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static std::optional<AngleRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
    {
        ASSERT(range.peek().type() == NumberToken);

        if (shouldAcceptUnitlessValue(range.peek().numericValue(), parserMode, unitless, unitlessZero))
            return { { CSSUnitType::CSS_DEG, range.consumeIncludingWhitespace().numericValue() } };
        return std::nullopt;
    }
};

// MARK: Angle (CSSPrimitiveValue - maintaining calc)

struct AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == FunctionToken);

        CalcParser parser(range, CalculationCategory::Angle, valueRange, symbolTable, pool);
        return parser.consumeValueIfCategory(CalculationCategory::Angle);
    }
};

struct AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer {
    static constexpr CSSParserTokenType tokenType = DimensionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == DimensionToken);

        if (auto angleRaw = AngleRawKnownTokenTypeDimensionConsumer::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero))
            return pool.createValue(angleRaw->value, angleRaw->type);
        return nullptr;
    }
};

struct AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == NumberToken);

        if (auto angleRaw = AngleRawKnownTokenTypeNumberConsumer::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero))
            return pool.createValue(angleRaw->value, angleRaw->type);
        return nullptr;
    }
};

// MARK: Time (CSSPrimitiveValue - maintaining calc)

struct TimeCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer {
    static constexpr CSSParserTokenType tokenType = FunctionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == FunctionToken);

        CalcParser parser(range, CalculationCategory::Time, valueRange, symbolTable, pool);
        return parser.consumeValueIfCategory(CalculationCategory::Time);
    }
};

struct TimeCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer {
    static constexpr CSSParserTokenType tokenType = DimensionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == DimensionToken);

        if (valueRange == ValueRange::NonNegative && range.peek().numericValue() < 0)
            return nullptr;

        if (auto unit = range.peek().unitType(); unit == CSSUnitType::CSS_MS || unit == CSSUnitType::CSS_S)
            return pool.createValue(range.consumeIncludingWhitespace().numericValue(), unit);

        return nullptr;
    }
};

struct TimeCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer {
    static constexpr CSSParserTokenType tokenType = NumberToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == NumberToken);

        if (unitless == UnitlessQuirk::Allow && shouldAcceptUnitlessValue(range.peek().numericValue(), parserMode, unitless, UnitlessZeroQuirk::Allow)) {
            if (valueRange == ValueRange::NonNegative && range.peek().numericValue() < 0)
                return nullptr;
            return pool.createValue(range.consumeIncludingWhitespace().numericValue(), CSSUnitType::CSS_MS);
        }
        return nullptr;
    }
};

// MARK: Resolution (CSSPrimitiveValue - no calc)

struct ResolutionCSSPrimitiveValueWithKnownTokenTypeDimensionConsumer {
    static constexpr CSSParserTokenType tokenType = DimensionToken;
    static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
    {
        ASSERT(range.peek().type() == DimensionToken);

        if (auto unit = range.peek().unitType(); unit == CSSUnitType::CSS_DPPX || unit == CSSUnitType::CSS_X || unit == CSSUnitType::CSS_DPI || unit == CSSUnitType::CSS_DPCM)
            return pool.createValue(range.consumeIncludingWhitespace().numericValue(), unit);

        return nullptr;
    }
};

// MARK: None (Raw)

struct NoneRawKnownTokenTypeIdentConsumer {
    static constexpr CSSParserTokenType tokenType = IdentToken;
    static std::optional<NoneRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == IdentToken);

        if (range.peek().id() == CSSValueNone) {
            range.consumeIncludingWhitespace();
            return NoneRaw { };
        }

        return std::nullopt;
    }
};

// MARK: Specialized combination consumers.

// FIXME: It would be good to find a way to synthesize this from an angle and number specific variants.
struct AngleOrNumberRawKnownTokenTypeIdentConsumer {
    static constexpr CSSParserTokenType tokenType = IdentToken;
    static std::optional<AngleOrNumberRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == IdentToken);

        if (auto variable = symbolTable.get(range.peek().id())) {
            switch (variable->type) {
            case CSSUnitType::CSS_DEG:
            case CSSUnitType::CSS_RAD:
            case CSSUnitType::CSS_GRAD:
            case CSSUnitType::CSS_TURN:
                range.consumeIncludingWhitespace();
                return AngleRaw { variable->type, variable->value };

            case CSSUnitType::CSS_NUMBER:
                range.consumeIncludingWhitespace();
                return NumberRaw { variable->value };

            default:
                break;
            }
        }

        return std::nullopt;
    }
};

// FIXME: It would be good to find a way to synthesize this from an number and percent specific variants.
struct NumberOrPercentRawKnownTokenTypeIdentConsumer {
    static constexpr CSSParserTokenType tokenType = IdentToken;
    static std::optional<NumberOrPercentRaw> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
    {
        ASSERT(range.peek().type() == IdentToken);

        if (auto variable = symbolTable.get(range.peek().id())) {
            switch (variable->type) {
            case CSSUnitType::CSS_PERCENTAGE:
                if (auto validatedValue = validatedPercentRaw(variable->value, valueRange)) {
                    range.consumeIncludingWhitespace();
                    return {{ *validatedValue }};
                }
                break;

            case CSSUnitType::CSS_NUMBER:
                if (auto validatedValue = validatedNumberRaw(variable->value, valueRange)) {
                    range.consumeIncludingWhitespace();
                    return {{ *validatedValue }};
                }
                break;

            default:
                break;
            }
        }

        return std::nullopt;
    }
};

// MARK: - Meta Consumers

template<typename Consumer, typename = void>
struct TransformApplier {
    template<typename T> static decltype(auto) apply(T value) { return value; }
};

template<typename Consumer>
struct TransformApplier<Consumer, typename std::void_t<typename Consumer::Transformer>> {
    template<typename T> static decltype(auto) apply(T value) { return Consumer::Transformer::transform(value); }
};

template<typename Consumer, typename T>
static decltype(auto) applyTransform(T value)
{
    return TransformApplier<Consumer>::apply(value);
}

// Transformers:

template<typename ResultType>
struct IdentityTransformer {
    using Result = ResultType;
    static Result transform(Result value) { return value; }
};

template<typename ResultType>
struct RawIdentityTransformer {
    using Result = std::optional<ResultType>;

    static Result transform(Result value) { return value; }

    template<typename... Types>
    static Result transform(const std::variant<Types...>& value)
    {
        return WTF::switchOn(value, [] (auto value) -> Result { return value; });
    }

    template<typename T>
    static Result transform(std::optional<T> value)
    {
        if (value)
            return transform(*value);
        return std::nullopt;
    }
};

template<typename Parent, typename ResultType>
struct RawVariantTransformerBase {
    using Result = std::optional<ResultType>;

    template<typename... Types>
    static Result transform(const std::variant<Types...>& value)
    {
        return WTF::switchOn(value, [] (auto value) { return Parent::transform(value); });
    }

    static typename Result::value_type transform(typename Result::value_type value)
    {
        return value;
    }

    template<typename T>
    static Result transform(std::optional<T> value)
    {
        if (value)
            return Parent::transform(*value);
        return std::nullopt;
    }
};

struct NumberOrPercentDividedBy100Transformer : RawVariantTransformerBase<NumberOrPercentDividedBy100Transformer, double> {
    using RawVariantTransformerBase<NumberOrPercentDividedBy100Transformer, double>::transform;

    static double transform(NumberRaw value)
    {
        return value.value;
    }

    static double transform(PercentRaw value)
    {
        return value.value / 100.0;
    }
};

// MARK: MetaConsumerDispatcher

template<CSSParserTokenType tokenType, typename Consumer, typename = void>
struct MetaConsumerDispatcher {
    template<typename... Args>
    static typename Consumer::Result consume(Args&&...)
    {
        return { };
    }
};

template<typename Consumer>
struct MetaConsumerDispatcher<FunctionToken, Consumer, typename std::void_t<typename Consumer::FunctionToken>> {
    template<typename... Args>
    static typename Consumer::Result consume(Args&&... args)
    {
        return applyTransform<Consumer>(Consumer::FunctionToken::consume(std::forward<Args>(args)...));
    }
};

template<typename Consumer>
struct MetaConsumerDispatcher<NumberToken, Consumer, typename std::void_t<typename Consumer::NumberToken>> {
    template<typename... Args>
    static typename Consumer::Result consume(Args&&... args)
    {
        return applyTransform<Consumer>(Consumer::NumberToken::consume(std::forward<Args>(args)...));
    }
};

template<typename Consumer>
struct MetaConsumerDispatcher<PercentageToken, Consumer, typename std::void_t<typename Consumer::PercentageToken>> {
    template<typename... Args>
    static typename Consumer::Result consume(Args&&... args)
    {
        return applyTransform<Consumer>(Consumer::PercentageToken::consume(std::forward<Args>(args)...));
    }
};

template<typename Consumer>
struct MetaConsumerDispatcher<DimensionToken, Consumer, typename std::void_t<typename Consumer::DimensionToken>> {
    template<typename... Args>
    static typename Consumer::Result consume(Args&&... args)
    {
        return applyTransform<Consumer>(Consumer::DimensionToken::consume(std::forward<Args>(args)...));
    }
};

template<typename Consumer>
struct MetaConsumerDispatcher<IdentToken, Consumer, typename std::void_t<typename Consumer::IdentToken>> {
    template<typename... Args>
    static typename Consumer::Result consume(Args&&... args)
    {
        return applyTransform<Consumer>(Consumer::IdentToken::consume(std::forward<Args>(args)...));
    }
};

template<typename Consumer, typename... Args>
auto consumeMetaConsumer(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, Args&&... args) -> typename Consumer::Result
{
    switch (range.peek().type()) {
    case FunctionToken:
        return MetaConsumerDispatcher<FunctionToken, Consumer>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero, std::forward<Args>(args)...);

    case NumberToken:
        return MetaConsumerDispatcher<NumberToken, Consumer>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero, std::forward<Args>(args)...);

    case PercentageToken:
        return MetaConsumerDispatcher<PercentageToken, Consumer>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero, std::forward<Args>(args)...);

    case DimensionToken:
        return MetaConsumerDispatcher<DimensionToken, Consumer>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero, std::forward<Args>(args)...);

    case IdentToken:
        return MetaConsumerDispatcher<IdentToken, Consumer>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero, std::forward<Args>(args)...);
    
    default:
        return { };
    }
}

// MARK: SameTokenMetaConsumer

template<typename Transformer, typename ConsumersTuple, size_t I>
struct SameTokenMetaConsumerApplier {
    template<typename... Args>
    static typename Transformer::Result consume(Args&&... args)
    {
        using SelectedConsumer = std::tuple_element_t<I - 1, ConsumersTuple>;
        if (auto result = Transformer::transform(SelectedConsumer::consume(std::forward<Args>(args)...)))
            return result;
        return SameTokenMetaConsumerApplier<Transformer, ConsumersTuple, I - 1>::consume(std::forward<Args>(args)...);
    }
};

template<typename Transformer, typename ConsumersTuple>
struct SameTokenMetaConsumerApplier<Transformer, ConsumersTuple, 0> {
    template<typename... Args>
    static typename Transformer::Result consume(Args&&...)
    {
        return typename Transformer::Result { };
    }
};

template<typename Transformer, typename T, typename... Ts>
struct SameTokenMetaConsumer {
    static_assert(std::conjunction_v<std::bool_constant<Ts::tokenType == T::tokenType>...>, "All Consumers passed to SameTokenMetaConsumer must have the same tokenType");
    using ConsumersTuple = std::tuple<T, Ts...>;

    static constexpr CSSParserTokenType tokenType = T::tokenType;
    template<typename... Args>
    static typename Transformer::Result consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, Args&&... args)
    {
        ASSERT(range.peek().type() == tokenType);
        return SameTokenMetaConsumerApplier<Transformer, ConsumersTuple, std::tuple_size_v<ConsumersTuple>>::consume(range, symbolTable, valueRange, parserMode, unitless, unitlessZero, std::forward<Args>(args)...);
    }
};


// MARK: - Consumer definitions.

// MARK: Integer

template<typename IntType, IntegerRange intergerRange>
struct IntegerTypeRawConsumer {
    using Result = std::optional<IntType>;

    using FunctionToken = IntegerTypeRawKnownTokenTypeFunctionConsumer<IntType, intergerRange>;
    using NumberToken = IntegerTypeRawKnownTokenTypeNumberConsumer<IntType, intergerRange>;
};

template<typename IntType, IntegerRange intergerRange>
struct IntegerTypeConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    using FunctionToken = IntegerTypeKnownTokenTypeFunctionConsumer<IntType, intergerRange>;
    using NumberToken = IntegerTypeKnownTokenTypeNumberConsumer<IntType, intergerRange>;
};

// MARK: Number

template<typename T>
struct NumberRawConsumer {
    using Transformer = T;
    using Result = typename Transformer::Result;

    using FunctionToken = NumberRawKnownTokenTypeFunctionConsumer;
    using NumberToken = NumberRawKnownTokenTypeNumberConsumer;
};

template<typename Transformer>
struct NumberRawAllowingSymbolTableIdentConsumer : NumberRawConsumer<Transformer> {
    using IdentToken = NumberRawKnownTokenTypeIdentConsumer;
};

struct NumberConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    using FunctionToken = NumberCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer;
    using NumberToken = NumberCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer;
};

// MARK: Percent

template<typename T>
struct PercentRawConsumer {
    using Transformer = T;
    using Result = typename Transformer::Result;

    using FunctionToken = PercentRawKnownTokenTypeFunctionConsumer;
    using PercentageToken = PercentRawKnownTokenTypePercentConsumer;
};

template<typename Transformer>
struct PercentRawAllowingSymbolTableIdentConsumer : PercentRawConsumer<Transformer> {
    using IdentToken = PercentRawKnownTokenTypeIdentConsumer;
};

struct PercentConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    using FunctionToken = PercentCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer;
    using PercentageToken = PercentCSSPrimitiveValueWithCalcWithKnownTokenTypePercentConsumer;
};

// MARK: Length

template<typename T>
struct LengthRawConsumer {
    using Transformer = T;
    using Result = typename Transformer::Result;

    using FunctionToken = LengthRawKnownTokenTypeFunctionConsumer;
    using DimensionToken = LengthRawKnownTokenTypeDimensionConsumer;
    using NumberToken = LengthRawKnownTokenTypeNumberConsumer;
};

struct LengthConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    using FunctionToken = LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer;
    using NumberToken = LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer;
    using DimensionToken = LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer;
};

// MARK: Angle

template<typename T>
struct AngleRawConsumer {
    using Transformer = T;
    using Result = typename Transformer::Result;

    using FunctionToken = AngleRawKnownTokenTypeFunctionConsumer;
    using NumberToken = AngleRawKnownTokenTypeNumberConsumer;
    using DimensionToken = AngleRawKnownTokenTypeDimensionConsumer;
};

struct AngleConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    using FunctionToken = AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer;
    using NumberToken = AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer;
    using DimensionToken = AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer;
};

// MARK: Time

struct TimeConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    using FunctionToken = TimeCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer;
    using NumberToken = TimeCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer;
    using DimensionToken = TimeCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer;
};

// MARK: Resolution

struct ResolutionConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    // NOTE: Unlike the other types, calc() does not work with <resolution>.
    using DimensionToken = ResolutionCSSPrimitiveValueWithKnownTokenTypeDimensionConsumer;
};

// MARK: - Combination consumer definitions.

// MARK: Angle + Percent

struct AngleOrPercentConsumer {
    using Result = RefPtr<CSSPrimitiveValue>;

    using FunctionToken = SameTokenMetaConsumer<
        IdentityTransformer<RefPtr<CSSPrimitiveValue>>,
        AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer,
        PercentCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer
    >;
    using NumberToken = AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer;
    using PercentageToken = PercentCSSPrimitiveValueWithCalcWithKnownTokenTypePercentConsumer;
    using DimensionToken = AngleCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer;
};

// MARK: Length + Percent

template<typename T>
struct LengthOrPercentRawConsumer {
    using Transformer = T;
    using Result = typename Transformer::Result;

    using FunctionToken = SameTokenMetaConsumer<
        Transformer,
        PercentRawKnownTokenTypeFunctionConsumer,
        LengthRawKnownTokenTypeFunctionConsumer
    >;
    using NumberToken = LengthRawKnownTokenTypeNumberConsumer;
    using PercentageToken = PercentRawKnownTokenTypePercentConsumer;
    using DimensionToken = LengthRawKnownTokenTypeDimensionConsumer;
};

// MARK: Angle + Number

template<typename T>
struct AngleOrNumberRawConsumer {
    using Transformer = T;
    using Result = typename Transformer::Result;

    using FunctionToken = SameTokenMetaConsumer<
        Transformer,
        NumberRawKnownTokenTypeFunctionConsumer,
        AngleRawKnownTokenTypeFunctionConsumer
    >;
    using NumberToken = NumberRawKnownTokenTypeNumberConsumer;
    using DimensionToken = AngleRawKnownTokenTypeDimensionConsumer;
};

template<typename Transformer>
struct AngleOrNumberRawAllowingSymbolTableIdentConsumer : AngleOrNumberRawConsumer<Transformer> {
    using IdentToken = AngleOrNumberRawKnownTokenTypeIdentConsumer;
};

// MARK: Angle + Number + None

template<typename Transformer>
struct AngleOrNumberOrNoneRawConsumer : AngleOrNumberRawConsumer<Transformer> {
    using IdentToken = NoneRawKnownTokenTypeIdentConsumer;
};

template<typename Transformer>
struct AngleOrNumberOrNoneRawAllowingSymbolTableIdentConsumer : AngleOrNumberRawConsumer<Transformer> {
    using IdentToken = SameTokenMetaConsumer<
        Transformer,
        NoneRawKnownTokenTypeIdentConsumer,
        AngleOrNumberRawKnownTokenTypeIdentConsumer
    >;
};

// MARK: Number + Percent

template<typename T>
struct NumberOrPercentRawConsumer {
    using Transformer = T;
    using Result = typename Transformer::Result;

    using FunctionToken = SameTokenMetaConsumer<
        Transformer,
        PercentRawKnownTokenTypeFunctionConsumer,
        NumberRawKnownTokenTypeFunctionConsumer
    >;
    using NumberToken = NumberRawKnownTokenTypeNumberConsumer;
    using PercentageToken = PercentRawKnownTokenTypePercentConsumer;
};


template<typename Transformer>
struct NumberOrPercentRawAllowingSymbolTableIdentConsumer : NumberOrPercentRawConsumer<Transformer> {
    using IdentToken = NumberOrPercentRawKnownTokenTypeIdentConsumer;
};

// MARK: Number + None

template<typename Transformer>
struct NumberOrNoneRawConsumer : NumberRawConsumer<Transformer> {
    using IdentToken = NoneRawKnownTokenTypeIdentConsumer;
};

template<typename Transformer>
struct NumberOrNoneRawAllowingSymbolTableIdentConsumer : NumberRawConsumer<Transformer> {
    using IdentToken = SameTokenMetaConsumer<
        Transformer,
        NoneRawKnownTokenTypeIdentConsumer,
        NumberRawKnownTokenTypeIdentConsumer
    >;
};

// MARK: Percent + None

template<typename Transformer>
struct PercentOrNoneRawConsumer : PercentRawConsumer<Transformer> {
    using IdentToken = NoneRawKnownTokenTypeIdentConsumer;
};

template<typename Transformer>
struct PercentOrNoneRawAllowingSymbolTableIdentConsumer : PercentRawConsumer<Transformer> {
    using IdentToken = SameTokenMetaConsumer<
        Transformer,
        NoneRawKnownTokenTypeIdentConsumer,
        PercentRawKnownTokenTypeIdentConsumer
    >;
};

// MARK: Number + Percent + None

template<typename Transformer>
struct NumberOrPercentOrNoneRawConsumer : NumberOrPercentRawConsumer<Transformer> {
    using IdentToken = NoneRawKnownTokenTypeIdentConsumer;
};

template<typename Transformer>
struct NumberOrPercentOrNoneRawAllowingSymbolTableIdentConsumer : NumberOrPercentRawConsumer<Transformer> {
    using IdentToken = SameTokenMetaConsumer<
        Transformer,
        NoneRawKnownTokenTypeIdentConsumer,
        NumberOrPercentRawKnownTokenTypeIdentConsumer
    >;
};

// MARK: - Consumer functions - utilize consumer definitions above, giving more targetted interfaces and allowing exposure to other files.

template<typename IntType, IntegerRange intergerRange> std::optional<IntType> consumeIntegerTypeRaw(CSSParserTokenRange& range)
{
    return consumeMetaConsumer<IntegerTypeRawConsumer<IntType, intergerRange>>(range, { }, ValueRange::All, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename IntType, IntegerRange intergerRange> RefPtr<CSSPrimitiveValue> consumeIntegerType(CSSParserTokenRange& range, CSSValuePool& pool)
{
    return consumeMetaConsumer<IntegerTypeConsumer<IntType, intergerRange>>(range, { }, ValueRange::All, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid, pool);
}

std::optional<int> consumeIntegerRaw(CSSParserTokenRange& range)
{
    return consumeIntegerTypeRaw<int, IntegerRange::All>(range);
}

RefPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange& range)
{
    return consumeIntegerType<int, IntegerRange::All>(range, CSSValuePool::singleton());
}

std::optional<int> consumeIntegerZeroAndGreaterRaw(CSSParserTokenRange& range)
{
    return consumeIntegerTypeRaw<int, IntegerRange::ZeroAndGreater>(range);
}

RefPtr<CSSPrimitiveValue> consumeIntegerZeroAndGreater(CSSParserTokenRange& range)
{
    return consumeIntegerType<int, IntegerRange::ZeroAndGreater>(range, CSSValuePool::singleton());
}

std::optional<unsigned> consumePositiveIntegerRaw(CSSParserTokenRange& range)
{
    return consumeIntegerTypeRaw<unsigned, IntegerRange::OneAndGreater>(range);
}

RefPtr<CSSPrimitiveValue> consumePositiveInteger(CSSParserTokenRange& range)
{
    return consumeIntegerType<unsigned, IntegerRange::OneAndGreater>(range, CSSValuePool::singleton());
}

std::optional<NumberRaw> consumeNumberRaw(CSSParserTokenRange& range, ValueRange valueRange)
{
    return consumeMetaConsumer<NumberRawConsumer<RawIdentityTransformer<NumberRaw>>>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<NumberRaw>>
static auto consumeNumberRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<NumberRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange& range, ValueRange valueRange)
{
    return consumeMetaConsumer<NumberConsumer>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());
}

std::optional<PercentRaw> consumePercentRaw(CSSParserTokenRange& range, ValueRange valueRange)
{
    return consumeMetaConsumer<PercentRawConsumer<RawIdentityTransformer<PercentRaw>>>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<PercentRaw>>
static auto consumePercentRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<PercentRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

RefPtr<CSSPrimitiveValue> consumePercent(CSSParserTokenRange& range, ValueRange valueRange)
{
    return consumePercentWorkerSafe(range, valueRange, CSSValuePool::singleton());
}

RefPtr<CSSPrimitiveValue> consumePercentWorkerSafe(CSSParserTokenRange& range, ValueRange valueRange, CSSValuePool& pool)
{
    return consumeMetaConsumer<PercentConsumer>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid, pool);
}

std::optional<LengthRaw> consumeLengthRaw(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless)
{
    return consumeMetaConsumer<LengthRawConsumer<RawIdentityTransformer<LengthRaw>>>(range, { }, valueRange, parserMode, unitless, UnitlessZeroQuirk::Forbid);
}

RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless)
{
    return consumeMetaConsumer<LengthConsumer>(range, { }, valueRange, parserMode, unitless, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());
}

std::optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
{
    return consumeMetaConsumer<AngleRawConsumer<RawIdentityTransformer<AngleRaw>>>(range, { }, ValueRange::All, parserMode, unitless, unitlessZero);
}

RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
{
    return consumeAngleWorkerSafe(range, parserMode, CSSValuePool::singleton(), unitless, unitlessZero);
}

RefPtr<CSSPrimitiveValue> consumeAngleWorkerSafe(CSSParserTokenRange& range, CSSParserMode parserMode, CSSValuePool& pool, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
{
    return consumeMetaConsumer<AngleConsumer>(range, { }, ValueRange::All, parserMode, unitless, unitlessZero, pool);
}

RefPtr<CSSPrimitiveValue> consumeTime(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless)
{
    return consumeMetaConsumer<TimeConsumer>(range, { }, valueRange, parserMode, unitless, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());
}

RefPtr<CSSPrimitiveValue> consumeResolution(CSSParserTokenRange& range)
{
    return consumeMetaConsumer<ResolutionConsumer>(range, { }, ValueRange::All, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());
}

static RefPtr<CSSPrimitiveValue> consumeAngleOrPercent(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero, CSSValuePool& pool = CSSValuePool::singleton())
{
    return consumeMetaConsumer<AngleOrPercentConsumer>(range, { }, valueRange, parserMode, unitless, unitlessZero, pool);
}

std::optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless)
{
    return consumeMetaConsumer<LengthOrPercentRawConsumer<RawIdentityTransformer<LengthOrPercentRaw>>>(range, { }, valueRange, parserMode, unitless, UnitlessZeroQuirk::Forbid);
}

// FIXME: This doesn't work with the current scheme due to the NegativePercentagePolicy parameter
RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless, NegativePercentagePolicy negativePercentagePolicy)
{
    auto& token = range.peek();

    switch (token.type()) {
    case FunctionToken: {
        // FIXME: Should this be using trying to generate the calc with both Length and Percent destination category types?
        CalcParser parser(range, CalculationCategory::Length, valueRange, { }, CSSValuePool::singleton(), negativePercentagePolicy);
        if (auto calculation = parser.value(); calculation && canConsumeCalcValue(calculation->category(), parserMode))
            return parser.consumeValue();
        break;
    }

    case DimensionToken:
        return LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer::consume(range, { }, valueRange, parserMode, unitless, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());

    case NumberToken:
        return LengthCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer::consume(range, { }, valueRange, parserMode, unitless, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());

    case PercentageToken:
        return PercentCSSPrimitiveValueWithCalcWithKnownTokenTypePercentConsumer::consume(range, { }, valueRange, parserMode, unitless, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());

    default:
        break;
    }

    return nullptr;
}

template<typename Transformer = RawIdentityTransformer<AngleOrNumberRaw>>
static auto consumeAngleOrNumberRaw(CSSParserTokenRange& range, CSSParserMode parserMode) -> typename Transformer::Result
{
    return consumeMetaConsumer<AngleOrNumberRawConsumer<Transformer>>(range, { }, ValueRange::All, parserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<AngleOrNumberRaw>>
static auto consumeAngleOrNumberRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, CSSParserMode parserMode) -> typename Transformer::Result
{
    return consumeMetaConsumer<AngleOrNumberRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, ValueRange::All, parserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<AngleOrNumberOrNoneRaw>>
static auto consumeAngleOrNumberOrNoneRaw(CSSParserTokenRange& range, CSSParserMode parserMode) -> typename Transformer::Result
{
    return consumeMetaConsumer<AngleOrNumberOrNoneRawConsumer<Transformer>>(range, { }, ValueRange::All, parserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<AngleOrNumberOrNoneRaw>>
static auto consumeAngleOrNumberOrNoneRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, CSSParserMode parserMode) -> typename Transformer::Result
{
    return consumeMetaConsumer<AngleOrNumberOrNoneRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, ValueRange::All, parserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<NumberOrPercentRaw>>
static auto consumeNumberOrPercentRaw(CSSParserTokenRange& range, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<NumberOrPercentRawConsumer<Transformer>>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<NumberOrPercentRaw>>
static auto consumeNumberOrPercentRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<NumberOrPercentRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<NumberOrNoneRaw>>
static auto consumeNumberOrNoneRaw(CSSParserTokenRange& range, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<NumberOrNoneRawConsumer<Transformer>>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<NumberOrNoneRaw>>
static auto consumeNumberOrNoneRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<NumberOrNoneRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<PercentOrNoneRaw>>
static auto consumePercentOrNoneRaw(CSSParserTokenRange& range, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<PercentOrNoneRawConsumer<Transformer>>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<PercentOrNoneRaw>>
static auto consumePercentOrNoneRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<PercentOrNoneRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<NumberOrPercentOrNoneRaw>>
static auto consumeNumberOrPercentOrNoneRaw(CSSParserTokenRange& range, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<NumberOrPercentOrNoneRawConsumer<Transformer>>(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}

template<typename Transformer = RawIdentityTransformer<NumberOrPercentOrNoneRaw>>
static auto consumeNumberOrPercentOrNoneRawAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange = ValueRange::All) -> typename Transformer::Result
{
    return consumeMetaConsumer<NumberOrPercentOrNoneRawAllowingSymbolTableIdentConsumer<Transformer>>(range, symbolTable, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
}


// FIXME: This needs a more clear name to indicate its behavior of dividing percents by 100 only if an explicit percent token, not if a result of a calc().
RefPtr<CSSPrimitiveValue> consumeNumberOrPercent(CSSParserTokenRange& range, ValueRange valueRange)
{
    auto& token = range.peek();

    switch (token.type()) {
    case FunctionToken:
        if (auto value = NumberCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer::consume(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton()))
            return value;
        return PercentCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer::consume(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());

    case NumberToken:
        return NumberCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer::consume(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid, CSSValuePool::singleton());

    case PercentageToken:
        if (auto percentRaw = PercentRawKnownTokenTypePercentConsumer::consume(range, { }, valueRange, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
            return CSSValuePool::singleton().createValue(percentRaw->value / 100.0, CSSUnitType::CSS_NUMBER);
        break;

    default:
        break;
    }

    return nullptr;
}

// MARK: - Non-primitive consumers.

std::optional<double> consumeFontWeightNumberRaw(CSSParserTokenRange& range)
{
    // Values less than or equal to 0 or greater than or equal to 1000 are parse errors.

#if !ENABLE(VARIATION_FONTS)
    auto isIntegerAndDivisibleBy100 = [](double value) {
        ASSERT(value > 0 && value <= 1000);
        return static_cast<int>(value / 100) * 100 == value;
    };
#endif

    auto& token = range.peek();
    switch (token.type()) {
    case FunctionToken: {
        // "[For calc()], the used value resulting from an expression must be clamped to the range allowed in the target context."
        auto result = NumberRawKnownTokenTypeFunctionConsumer::consume(range, { }, ValueRange::All, CSSParserMode::HTMLStandardMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid);
        if (!result)
            break;
#if !ENABLE(VARIATION_FONTS)
        if (!(result->value > 0 && result->value < 1000) || !isIntegerAndDivisibleBy100(result->value))
            break;
#endif
        return std::clamp(result->value, std::nextafter(0.0, 1.0), std::nextafter(1000.0, 0.0));
    }

    case NumberToken: {
        auto result = token.numericValue();
        
        // FIXME: This allows value of 1000, unlike the comment above and the behavior of the FunctionToken parsing path.
        if (!(result >= 1 && result <= 1000))
            break;
#if !ENABLE(VARIATION_FONTS)
        if (token.numericValueType() != IntegerValueType || !isIntegerAndDivisibleBy100(result))
            break;
#endif
        range.consumeIncludingWhitespace();
        return result;
    }
    
    default:
        break;
    }

    return std::nullopt;
}

RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange& range)
{
    return consumeFontWeightNumberWorkerSafe(range, CSSValuePool::singleton());
}

RefPtr<CSSPrimitiveValue> consumeFontWeightNumberWorkerSafe(CSSParserTokenRange& range, CSSValuePool& pool)
{
    if (auto result = consumeFontWeightNumberRaw(range))
        return pool.createValue(*result, CSSUnitType::CSS_NUMBER);
    return nullptr;
}

std::optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange& range)
{
    if (range.peek().type() != IdentToken)
        return std::nullopt;
    return range.consumeIncludingWhitespace().id();
}

RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
{
    return consumeIdentWorkerSafe(range, CSSValuePool::singleton());
}

RefPtr<CSSPrimitiveValue> consumeIdentWorkerSafe(CSSParserTokenRange& range, CSSValuePool& pool)
{
    if (auto result = consumeIdentRaw(range))
        return pool.createIdentifierValue(*result);
    return nullptr;
}

std::optional<CSSValueID> consumeIdentRangeRaw(CSSParserTokenRange& range, CSSValueID lower, CSSValueID upper)
{
    if (range.peek().id() < lower || range.peek().id() > upper)
        return std::nullopt;
    return consumeIdentRaw(range);
}

RefPtr<CSSPrimitiveValue> consumeIdentRange(CSSParserTokenRange& range, CSSValueID lower, CSSValueID upper)
{
    if (range.peek().id() < lower || range.peek().id() > upper)
        return nullptr;
    return consumeIdent(range);
}

RefPtr<CSSPrimitiveValue> consumeCustomIdent(CSSParserTokenRange& range, bool shouldLowercase)
{
    if (range.peek().type() != IdentToken || !isValidCustomIdentifier(range.peek().id()))
        return nullptr;
    auto identifier = range.consumeIncludingWhitespace().value();
    return CSSValuePool::singleton().createCustomIdent(shouldLowercase ? identifier.convertToASCIILowercase() : identifier.toString());
}

RefPtr<CSSPrimitiveValue> consumeDashedIdent(CSSParserTokenRange& range, bool shouldLowercase)
{
    auto result = consumeCustomIdent(range, shouldLowercase);
    if (result && result->stringValue().startsWith("--"_s))
        return result;
    return nullptr;
}

RefPtr<CSSPrimitiveValue> consumeString(CSSParserTokenRange& range)
{
    if (range.peek().type() != StringToken)
        return nullptr;
    return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().value().toString(), CSSUnitType::CSS_STRING);
}

StringView consumeUrlAsStringView(CSSParserTokenRange& range)
{
    const CSSParserToken& token = range.peek();
    if (token.type() == UrlToken) {
        range.consumeIncludingWhitespace();
        return token.value();
    }
    if (token.functionId() == CSSValueUrl) {
        CSSParserTokenRange urlRange = range;
        CSSParserTokenRange urlArgs = urlRange.consumeBlock();
        const CSSParserToken& next = urlArgs.consumeIncludingWhitespace();
        if (next.type() == BadStringToken || !urlArgs.atEnd())
            return StringView();
        ASSERT(next.type() == StringToken);
        range = urlRange;
        range.consumeWhitespace();
        return next.value();
    }

    return { };
}

RefPtr<CSSPrimitiveValue> consumeUrl(CSSParserTokenRange& range)
{
    StringView url = consumeUrlAsStringView(range);
    if (url.isNull())
        return nullptr;
    return CSSValuePool::singleton().createValue(url.toString(), CSSUnitType::CSS_URI);
}

static Color consumeOriginColor(CSSParserTokenRange& args, const CSSParserContext& context)
{
    auto value = consumeColor(args, context);
    if (!value)
        return { };

    if (value->isRGBColor())
        return value->color();

    ASSERT(value->isValueID());
    auto keyword = value->valueID();

    // FIXME: We don't have enough context in the parser to resolving a system keyword
    // correctly. We should package up the relative color parameters and resolve the
    // whole thing at the appropriate time when the origin color is a system keyword.
    if (StyleColor::isSystemColorKeyword(keyword))
        return { };

    return StyleColor::colorFromKeyword(keyword, { });
}

static std::optional<double> consumeOptionalAlpha(CSSParserTokenRange& range)
{
    if (!consumeSlashIncludingWhitespace(range))
        return 1.0;

    if (auto alphaParameter = consumeNumberOrPercentOrNoneRaw(range)) {
        return WTF::switchOn(*alphaParameter,
            [] (NumberRaw number) { return std::clamp(number.value, 0.0, 1.0); },
            [] (PercentRaw percent) { return std::clamp(percent.value / 100.0, 0.0, 1.0); },
            [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
        );
    }

    return std::nullopt;
}

static std::optional<double> consumeOptionalAlphaAllowingSymbolTableIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable)
{
    if (!consumeSlashIncludingWhitespace(range))
        return 1.0;

    if (auto alphaParameter = consumeNumberOrPercentOrNoneRawAllowingSymbolTableIdent(range, symbolTable, ValueRange::All)) {
        return WTF::switchOn(*alphaParameter,
            [] (NumberRaw number) { return std::clamp(number.value, 0.0, 1.0); },
            [] (PercentRaw percent) { return std::clamp(percent.value / 100.0, 0.0, 1.0); },
            [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
        );
    }

    return std::nullopt;
}

static uint8_t normalizeRGBComponentToSRGBAByte(NumberRaw value)
{
    return convertPrescaledSRGBAFloatToSRGBAByte(value.value);
}

static uint8_t normalizeRGBComponentToSRGBAByte(PercentRaw value)
{
    return convertPrescaledSRGBAFloatToSRGBAByte(value.value / 100.0 * 255.0);
}

enum class RGBOrHSLSeparatorSyntax { Commas, WhitespaceSlash };

static bool consumeRGBOrHSLSeparator(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax)
{
    if (syntax == RGBOrHSLSeparatorSyntax::Commas)
        return consumeCommaIncludingWhitespace(args);
    return true;
}

static bool consumeRGBOrHSLAlphaSeparator(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax)
{
    if (syntax == RGBOrHSLSeparatorSyntax::Commas)
        return consumeCommaIncludingWhitespace(args);
    return consumeSlashIncludingWhitespace(args);
}

static std::optional<double> consumeRGBOrHSLOptionalAlpha(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax)
{
    if (!consumeRGBOrHSLAlphaSeparator(args, syntax))
        return 1.0;

    if (auto alphaParameter = consumeNumberOrPercentOrNoneRaw(args)) {
        return WTF::switchOn(*alphaParameter,
            [] (NumberRaw number) { return std::clamp(number.value, 0.0, 1.0); },
            [] (PercentRaw percent) { return std::clamp(percent.value / 100.0, 0.0, 1.0); },
            [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
        );
    }

    return std::nullopt;
}

static Color parseRelativeRGBParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueFrom);
    consumeIdentRaw(args);

    auto originColor = consumeOriginColor(args, context);
    if (!originColor.isValid())
        return { };

    auto originColorAsSRGB = originColor.toColorTypeLossy<SRGBA<float>>().resolved();

    CSSCalcSymbolTable symbolTable {
        { CSSValueR, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.red * 100.0 },
        { CSSValueG, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.green * 100.0 },
        { CSSValueB, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.blue * 100.0 },
        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.alpha * 100.0 }
    };

    auto red = consumeNumberOrPercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable);
    if (!red)
        return { };

    auto green = consumeNumberOrPercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable);
    if (!green)
        return { };

    auto blue = consumeNumberOrPercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable);
    if (!blue)
        return { };

    auto alpha = consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    if (std::holds_alternative<NoneRaw>(*red) || std::holds_alternative<NoneRaw>(*green) || std::holds_alternative<NoneRaw>(*blue) || std::isnan(*alpha)) {
        auto normalizeComponentAllowingNone = [] (auto component) {
            return WTF::switchOn(component,
                [] (PercentRaw percent) { return std::clamp(percent.value / 100.0, 0.0, 1.0); },
                [] (NumberRaw number) { return std::clamp(number.value / 255.0, 0.0, 1.0); },
                [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
            );
        };

        auto normalizedRed = normalizeComponentAllowingNone(*red);
        auto normalizedGreen = normalizeComponentAllowingNone(*green);
        auto normalizedBlue = normalizeComponentAllowingNone(*blue);

        // If any component uses "none", we store the value as a SRGBA<float> to allow for storage of the special value as NaN.
        return SRGBA<float> { static_cast<float>(normalizedRed), static_cast<float>(normalizedGreen), static_cast<float>(normalizedBlue), static_cast<float>(*alpha) };
    }

    auto normalizeComponentDisallowingNone = [] (auto component) {
        return WTF::switchOn(component,
            [] (NumberRaw number) -> uint8_t { return normalizeRGBComponentToSRGBAByte(number); },
            [] (PercentRaw percent) -> uint8_t { return normalizeRGBComponentToSRGBAByte(percent); },
            [] (NoneRaw) -> uint8_t { ASSERT_NOT_REACHED(); return 0; }
        );
    };

    auto normalizedRed = normalizeComponentDisallowingNone(*red);
    auto normalizedGreen = normalizeComponentDisallowingNone(*green);
    auto normalizedBlue = normalizeComponentDisallowingNone(*blue);
    auto normalizedAlpha = convertFloatAlphaTo<uint8_t>(*alpha);

    return SRGBA<uint8_t> { normalizedRed, normalizedGreen, normalizedBlue, normalizedAlpha };
}

static Color parseNonRelativeRGBParameters(CSSParserTokenRange& args)
{
    struct Component {
        enum class Type { Number, Percentage, Unknown };
        
        double value;
        Type type;
    };

    auto consumeComponent = [](auto& args, auto previousComponentType) -> std::optional<Component> {
        switch (previousComponentType) {
        case Component::Type::Number:
            if (auto component = consumeNumberOrNoneRaw(args)) {
                return WTF::switchOn(*component,
                    [] (NumberRaw number) -> Component { return { number.value, Component::Type::Number }; },
                    [] (NoneRaw) -> Component { return { std::numeric_limits<double>::quiet_NaN(), Component::Type::Number }; }
                );
            }
            return std::nullopt;
        case Component::Type::Percentage:
            if (auto component = consumePercentOrNoneRaw(args)) {
                return WTF::switchOn(*component,
                    [] (PercentRaw percent) -> Component  { return { percent.value, Component::Type::Percentage }; },
                    [] (NoneRaw) -> Component { return { std::numeric_limits<double>::quiet_NaN(), Component::Type::Percentage }; }
                );
            }
            return std::nullopt;
        case Component::Type::Unknown:
            if (auto component = consumeNumberOrPercentOrNoneRaw(args)) {
                return WTF::switchOn(*component,
                    [] (NumberRaw number) -> Component { return { number.value, Component::Type::Number }; },
                    [] (PercentRaw percent) -> Component  { return { percent.value, Component::Type::Percentage }; },
                    [] (NoneRaw) -> Component { return { std::numeric_limits<double>::quiet_NaN(), Component::Type::Unknown }; }
                );
            }
            return std::nullopt;
        }
        RELEASE_ASSERT_NOT_REACHED();
    };

    auto red = consumeComponent(args, Component::Type::Unknown);
    if (!red)
        return { };

    auto syntax = consumeCommaIncludingWhitespace(args) ? RGBOrHSLSeparatorSyntax::Commas : RGBOrHSLSeparatorSyntax::WhitespaceSlash;

    auto green = consumeComponent(args, red->type);
    if (!green)
        return { };

    if (!consumeRGBOrHSLSeparator(args, syntax))
        return { };

    auto blue = consumeComponent(args, green->type);
    if (!blue)
        return { };

    auto resolvedComponentType = blue->type;

    auto alpha = consumeRGBOrHSLOptionalAlpha(args, syntax);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    if (std::isnan(red->value) || std::isnan(green->value) || std::isnan(blue->value) || std::isnan(*alpha)) {
        // "none" values are only allowed with the WhitespaceSlash syntax.
        if (syntax != RGBOrHSLSeparatorSyntax::WhitespaceSlash)
            return { };

        auto normalizeNumber = [] (double number) { return std::isnan(number) ? number : std::clamp(number / 255.0, 0.0, 1.0); };
        auto normalizePercent = [] (double percent) { return std::isnan(percent) ? percent : std::clamp(percent / 100.0, 0.0, 1.0); };

        // If any component uses "none", we store the value as a SRGBA<float> to allow for storage of the special value as NaN.
        switch (resolvedComponentType) {
        case Component::Type::Number:
            return SRGBA<float> { static_cast<float>(normalizeNumber(red->value)), static_cast<float>(normalizeNumber(green->value)), static_cast<float>(normalizeNumber(blue->value)), static_cast<float>(*alpha) };
        case Component::Type::Percentage:
            return SRGBA<float> { static_cast<float>(normalizePercent(red->value)), static_cast<float>(normalizePercent(green->value)), static_cast<float>(normalizePercent(blue->value)), static_cast<float>(*alpha) };
        case Component::Type::Unknown:
            return SRGBA<float> { static_cast<float>(red->value), static_cast<float>(green->value), static_cast<float>(blue->value), static_cast<float>(*alpha) };
        }

        ASSERT_NOT_REACHED();
        return { };
    }

    switch (resolvedComponentType) {
    case Component::Type::Number:
        return SRGBA<uint8_t> { normalizeRGBComponentToSRGBAByte(NumberRaw { red->value }), normalizeRGBComponentToSRGBAByte(NumberRaw { green->value }), normalizeRGBComponentToSRGBAByte(NumberRaw { blue->value }), convertFloatAlphaTo<uint8_t>(*alpha) };
    case Component::Type::Percentage:
        return SRGBA<uint8_t> { normalizeRGBComponentToSRGBAByte(PercentRaw { red->value }), normalizeRGBComponentToSRGBAByte(PercentRaw { green->value }), normalizeRGBComponentToSRGBAByte(PercentRaw { blue->value }), convertFloatAlphaTo<uint8_t>(*alpha) };
    case Component::Type::Unknown:
        // The only way the resolvedComponentType can be Component::Type::Unknown is if all the components are "none", which is handled above.
        ASSERT_NOT_REACHED();
        return { };
    }

    ASSERT_NOT_REACHED();
    return { };
}

enum class RGBFunctionMode { RGB, RGBA };

template<RGBFunctionMode Mode> static Color parseRGBParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    ASSERT(range.peek().functionId() == (Mode == RGBFunctionMode::RGB ? CSSValueRgb : CSSValueRgba));
    auto args = consumeFunction(range);

    if constexpr (Mode == RGBFunctionMode::RGB) {
        if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
            return parseRelativeRGBParameters(args, context);
    }
    return parseNonRelativeRGBParameters(args);
}

static Color colorByNormalizingHSLComponents(AngleOrNumberOrNoneRaw hue, PercentOrNoneRaw saturation, PercentOrNoneRaw lightness, double alpha, RGBOrHSLSeparatorSyntax syntax)
{
    auto normalizedHue = WTF::switchOn(hue,
        [] (AngleRaw angle) { return normalizeHue(CSSPrimitiveValue::computeDegrees(angle.type, angle.value)); },
        [] (NumberRaw number) { return normalizeHue(number.value); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto normalizedSaturation = WTF::switchOn(saturation,
        [] (PercentRaw percent) { return std::clamp(percent.value, 0.0, 100.0); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto normalizedLightness = WTF::switchOn(lightness,
        [] (PercentRaw percent) { return std::clamp(percent.value, 0.0, 100.0); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );

    if (std::isnan(normalizedHue) || std::isnan(normalizedSaturation) || std::isnan(normalizedLightness) || std::isnan(alpha)) {
        // "none" values are only allowed with the WhitespaceSlash syntax.
        if (syntax != RGBOrHSLSeparatorSyntax::WhitespaceSlash)
            return { };

        // If any component uses "none", we store the value as a HSLA<float> to allow for storage of the special value as NaN.
        return HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(alpha) };
    }

    // NOTE: The explicit conversion to SRGBA<uint8_t> is intentional for performance (no extra allocation for
    // the extended color) and compatability, forcing serialiazation to use the rgb()/rgba() form.
    return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(alpha) });
}

static Color parseRelativeHSLParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueFrom);
    consumeIdentRaw(args);

    auto originColor = consumeOriginColor(args, context);
    if (!originColor.isValid())
        return { };

    auto originColorAsHSL = originColor.toColorTypeLossy<HSLA<float>>().resolved();

    CSSCalcSymbolTable symbolTable {
        { CSSValueH, CSSUnitType::CSS_DEG, originColorAsHSL.hue },
        { CSSValueS, CSSUnitType::CSS_PERCENTAGE, originColorAsHSL.saturation },
        { CSSValueL, CSSUnitType::CSS_PERCENTAGE, originColorAsHSL.lightness },
        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsHSL.alpha * 100.0 }
    };

    auto hue = consumeAngleOrNumberOrNoneRawAllowingSymbolTableIdent(args, symbolTable, context.mode);
    if (!hue)
        return { };

    auto saturation = consumePercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable);
    if (!saturation)
        return { };

    auto lightness = consumePercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable);
    if (!lightness)
        return { };

    auto alpha = consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    return colorByNormalizingHSLComponents(*hue, *saturation, *lightness, *alpha, RGBOrHSLSeparatorSyntax::WhitespaceSlash);
}

static Color parseNonRelativeHSLParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    auto hue = consumeAngleOrNumberOrNoneRaw(args, context.mode);
    if (!hue)
        return { };

    auto syntax = consumeCommaIncludingWhitespace(args) ? RGBOrHSLSeparatorSyntax::Commas : RGBOrHSLSeparatorSyntax::WhitespaceSlash;

    auto saturation = consumePercentOrNoneRaw(args);
    if (!saturation)
        return { };

    if (!consumeRGBOrHSLSeparator(args, syntax))
        return { };

    auto lightness = consumePercentOrNoneRaw(args);
    if (!lightness)
        return { };

    auto alpha = consumeRGBOrHSLOptionalAlpha(args, syntax);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    return colorByNormalizingHSLComponents(*hue, *saturation, *lightness, *alpha, syntax);
}

enum class HSLFunctionMode { HSL, HSLA };

template<HSLFunctionMode Mode> static Color parseHSLParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    ASSERT(range.peek().functionId() == (Mode == HSLFunctionMode::HSL ? CSSValueHsl : CSSValueHsla));
    auto args = consumeFunction(range);

    if constexpr (Mode == HSLFunctionMode::HSL) {
        if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
            return parseRelativeHSLParameters(args, context);
    }

    return parseNonRelativeHSLParameters(args, context);
}

template<typename ConsumerForHue, typename ConsumerForWhitenessAndBlackness, typename ConsumerForAlpha>
static Color parseHWBParameters(CSSParserTokenRange& args, ConsumerForHue&& hueConsumer, ConsumerForWhitenessAndBlackness&& whitenessAndBlacknessConsumer, ConsumerForAlpha&& alphaConsumer)
{
    auto hue = hueConsumer(args);
    if (!hue)
        return { };

    auto whiteness = whitenessAndBlacknessConsumer(args);
    if (!whiteness)
        return { };

    auto blackness = whitenessAndBlacknessConsumer(args);
    if (!blackness)
        return { };

    auto alpha = alphaConsumer(args);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    auto normalizedHue = WTF::switchOn(*hue,
        [] (AngleRaw angle) { return normalizeHue(CSSPrimitiveValue::computeDegrees(angle.type, angle.value)); },
        [] (NumberRaw number) { return normalizeHue(number.value); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto clampedWhiteness = WTF::switchOn(*whiteness,
        [] (PercentRaw percent) { return std::clamp(percent.value, 0.0, 100.0); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto clampedBlackness = WTF::switchOn(*blackness,
        [] (PercentRaw percent) { return std::clamp(percent.value, 0.0, 100.0); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );

    if (std::isnan(normalizedHue) || std::isnan(clampedWhiteness) || std::isnan(clampedBlackness) || std::isnan(*alpha)) {
        auto [normalizedWhitness, normalizedBlackness] = normalizeClampedWhitenessBlacknessAllowingNone(clampedWhiteness, clampedBlackness);

        // If any component uses "none", we store the value as a HSLA<float> to allow for storage of the special value as NaN.
        return HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(*alpha) };
    }

    auto [normalizedWhitness, normalizedBlackness] = normalizeClampedWhitenessBlacknessDisallowingNone(clampedWhiteness, clampedBlackness);

    // NOTE: The explicit conversion to SRGBA<uint8_t> is intentional for performance (no extra allocation for
    // the extended color) and compatability, forcing serialiazation to use the rgb()/rgba() form.
    return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(*alpha) });
}

static Color parseRelativeHWBParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueFrom);
    consumeIdentRaw(args);

    auto originColor = consumeOriginColor(args, context);
    if (!originColor.isValid())
        return { };

    auto originColorAsHWB = originColor.toColorTypeLossy<HWBA<float>>().resolved();

    CSSCalcSymbolTable symbolTable {
        { CSSValueH, CSSUnitType::CSS_DEG, originColorAsHWB.hue },
        { CSSValueW, CSSUnitType::CSS_PERCENTAGE, originColorAsHWB.whiteness },
        { CSSValueB, CSSUnitType::CSS_PERCENTAGE, originColorAsHWB.blackness },
        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsHWB.alpha * 100.0 }
    };

    auto hueConsumer = [&symbolTable, &context](auto& args) { return consumeAngleOrNumberOrNoneRawAllowingSymbolTableIdent(args, symbolTable, context.mode); };
    auto whitenessAndBlacknessConsumer = [&symbolTable](auto& args) { return consumePercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable); };
    auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };

    return parseHWBParameters(args, WTFMove(hueConsumer), WTFMove(whitenessAndBlacknessConsumer), WTFMove(alphaConsumer));
}

static Color parseNonRelativeHWBParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    auto hueConsumer = [&context](auto& args) { return consumeAngleOrNumberOrNoneRaw(args, context.mode); };
    auto whitenessAndBlacknessConsumer = [](auto& args) { return consumePercentOrNoneRaw(args); };
    auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); };

    return parseHWBParameters(args, WTFMove(hueConsumer), WTFMove(whitenessAndBlacknessConsumer), WTFMove(alphaConsumer));
}

static Color parseHWBParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    ASSERT(range.peek().functionId() == CSSValueHwb);

    if (!context.cssColor4)
        return { };

    auto args = consumeFunction(range);

    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
        return parseRelativeHWBParameters(args, context);
    return parseNonRelativeHWBParameters(args, context);
}

template<typename ColorType, typename ConsumerForLightness, typename ConsumerForAB, typename ConsumerForAlpha>
static Color parseLabParameters(CSSParserTokenRange& args, ConsumerForLightness&& lightnessConsumer, ConsumerForAB&& abConsumer, ConsumerForAlpha&& alphaConsumer)
{
    auto lightness = lightnessConsumer(args);
    if (!lightness)
        return { };

    auto aValue = abConsumer(args);
    if (!aValue)
        return { };

    auto bValue = abConsumer(args);
    if (!bValue)
        return { };

    auto alpha = alphaConsumer(args);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    auto normalizedLightness = WTF::switchOn(*lightness,
        [] (PercentRaw percent) { return std::max(0.0, percent.value); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto normalizedA = WTF::switchOn(*aValue,
        [] (NumberRaw number) { return number.value; },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto normalizedB = WTF::switchOn(*bValue,
        [] (NumberRaw number) { return number.value; },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );

    return ColorType { static_cast<float>(normalizedLightness), static_cast<float>(normalizedA), static_cast<float>(normalizedB), static_cast<float>(*alpha) };
}

template<typename ColorType>
static Color parseRelativeLabParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueFrom);
    consumeIdentRaw(args);

    auto originColor = consumeOriginColor(args, context);
    if (!originColor.isValid())
        return { };

    auto originColorAsLab = originColor.toColorTypeLossy<ColorType>().resolved();

    CSSCalcSymbolTable symbolTable {
        { CSSValueL, CSSUnitType::CSS_PERCENTAGE, originColorAsLab.lightness },
        { CSSValueA, CSSUnitType::CSS_NUMBER, originColorAsLab.a },
        { CSSValueB, CSSUnitType::CSS_NUMBER, originColorAsLab.b },
        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsLab.alpha * 100.0 }
    };

    auto lightnessConsumer = [&symbolTable](auto& args) { return consumePercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable); };
    auto abConsumer = [&symbolTable](auto& args) { return consumeNumberOrNoneRawAllowingSymbolTableIdent(args, symbolTable); };
    auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };

    return parseLabParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer));
}

template<typename ColorType>
static Color parseNonRelativeLabParameters(CSSParserTokenRange& args)
{
    auto lightnessConsumer = [](auto& args) { return consumePercentOrNoneRaw(args); };
    auto abConsumer = [](auto& args) { return consumeNumberOrNoneRaw(args); };
    auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); };

    return parseLabParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer));
}

template<typename ColorType>
static Color parseLabParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    ASSERT(range.peek().functionId() == CSSValueLab || range.peek().functionId() == CSSValueOklab);

    if (!context.cssColor4)
        return { };

    auto args = consumeFunction(range);

    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
        return parseRelativeLabParameters<ColorType>(args, context);
    return parseNonRelativeLabParameters<ColorType>(args);
}

template<typename ColorType, typename ConsumerForLightness, typename ConsumerForChroma, typename ConsumerForHue, typename ConsumerForAlpha>
static Color parseLCHParameters(CSSParserTokenRange& args, ConsumerForLightness&& lightnessConsumer, ConsumerForChroma&& chromaConsumer, ConsumerForHue&& hueConsumer, ConsumerForAlpha&& alphaConsumer)
{
    auto lightness = lightnessConsumer(args);
    if (!lightness)
        return { };

    auto chroma = chromaConsumer(args);
    if (!chroma)
        return { };

    auto hue = hueConsumer(args);
    if (!hue)
        return { };

    auto alpha = alphaConsumer(args);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    auto normalizedLightness = WTF::switchOn(*lightness,
        [] (PercentRaw percent) { return std::max(0.0, percent.value); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto normalizedChroma = WTF::switchOn(*chroma,
        [] (NumberRaw number) { return std::max(0.0, number.value); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );
    auto normalizedHue = WTF::switchOn(*hue,
        [] (AngleRaw angle) { return normalizeHue(CSSPrimitiveValue::computeDegrees(angle.type, angle.value)); },
        [] (NumberRaw number) { return normalizeHue(number.value); },
        [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
    );

    return ColorType { static_cast<float>(normalizedLightness), static_cast<float>(normalizedChroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) };
}

template<typename ColorType>
static Color parseRelativeLCHParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueFrom);
    consumeIdentRaw(args);

    auto originColor = consumeOriginColor(args, context);
    if (!originColor.isValid())
        return { };

    auto originColorAsLCH = originColor.toColorTypeLossy<ColorType>().resolved();

    CSSCalcSymbolTable symbolTable {
        { CSSValueL, CSSUnitType::CSS_PERCENTAGE, originColorAsLCH.lightness },
        { CSSValueC, CSSUnitType::CSS_NUMBER, originColorAsLCH.chroma },
        { CSSValueH, CSSUnitType::CSS_DEG, originColorAsLCH.hue },
        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsLCH.alpha * 100.0 }
    };

    auto lightnessConsumer = [&symbolTable](auto& args) { return consumePercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable); };
    auto chromaConsumer = [&symbolTable](auto& args) { return consumeNumberOrNoneRawAllowingSymbolTableIdent(args, symbolTable); };
    auto hueConsumer = [&symbolTable, &context](auto& args) { return consumeAngleOrNumberOrNoneRawAllowingSymbolTableIdent(args, symbolTable, context.mode); };
    auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };

    return parseLCHParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer));
}

template<typename ColorType>
static Color parseNonRelativeLCHParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    auto lightnessConsumer = [](auto& args) { return consumePercentOrNoneRaw(args); };
    auto chromaConsumer = [](auto& args) { return consumeNumberOrNoneRaw(args); };
    auto hueConsumer = [&context](auto& args) { return consumeAngleOrNumberOrNoneRaw(args, context.mode); };
    auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); };

    return parseLCHParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer));
}

template<typename ColorType>
static Color parseLCHParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    ASSERT(range.peek().functionId() == CSSValueLch || range.peek().functionId() == CSSValueOklch);

    if (!context.cssColor4)
        return { };

    auto args = consumeFunction(range);

    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
        return parseRelativeLCHParameters<ColorType>(args, context);
    return parseNonRelativeLCHParameters<ColorType>(args, context);
}

template<typename ColorType, typename ConsumerForRGB, typename ConsumerForAlpha>
static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args, ConsumerForRGB&& rgbConsumer, ConsumerForAlpha&& alphaConsumer)
{
    double channels[3] = { 0, 0, 0 };
    for (auto& channel : channels) {
        auto value = rgbConsumer(args);
        if (!value)
            break;

        channel = WTF::switchOn(*value,
            [] (PercentRaw percent) { return percent.value / 100.0; },
            [] (NumberRaw number) { return number.value; },
            [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
        );
    }

    auto alpha = alphaConsumer(args);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    return { ColorType { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
}

template<typename ColorType> static Color parseRelativeColorFunctionForRGBTypes(CSSParserTokenRange& args, Color originColor, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueDisplayP3 || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSRGB || args.peek().id() == CSSValueSrgbLinear);

    // Support sRGB and Display-P3 regardless of the setting as we have shipped support for them for a while.
    if (!context.cssColor4 && (args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSrgbLinear))
        return { };

    consumeIdentRaw(args);

    auto originColorAsColorType = originColor.toColorTypeLossy<ColorType>().resolved();

    CSSCalcSymbolTable symbolTable {
        { CSSValueR, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.red * 100.0 },
        { CSSValueG, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.green * 100.0 },
        { CSSValueB, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.blue * 100.0 },
        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.alpha * 100.0 }
    };

    auto consumeRGB = [&symbolTable](auto& args) { return consumeNumberOrPercentOrNoneRawAllowingSymbolTableIdent(args, symbolTable, ValueRange::All); };
    auto consumeAlpha = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };

    return parseColorFunctionForRGBTypes<ColorType>(args, WTFMove(consumeRGB), WTFMove(consumeAlpha));
}

template<typename ColorType> static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueDisplayP3 || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSRGB || args.peek().id() == CSSValueSrgbLinear);

    // Support sRGB and Display-P3 regardless of the setting as we have shipped support for them for a while.
    if (!context.cssColor4 && (args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSrgbLinear))
        return { };

    consumeIdentRaw(args);

    auto consumeRGB = [](auto& args) { return consumeNumberOrPercentOrNoneRaw(args); };
    auto consumeAlpha = [](auto& args) { return consumeOptionalAlpha(args); };

    return parseColorFunctionForRGBTypes<ColorType>(args, WTFMove(consumeRGB), WTFMove(consumeAlpha));
}

template<typename ColorType, typename ConsumerForXYZ, typename ConsumerForAlpha>
static Color parseColorFunctionForXYZTypes(CSSParserTokenRange& args, ConsumerForXYZ&& xyzConsumer, ConsumerForAlpha&& alphaConsumer)
{
    double channels[3] = { 0, 0, 0 };
    for (auto& channel : channels) {
        auto value = xyzConsumer(args);
        if (!value)
            break;

        channel = WTF::switchOn(*value,
            [] (NumberRaw number) { return number.value; },
            [] (NoneRaw) { return std::numeric_limits<double>::quiet_NaN(); }
        );
    }

    auto alpha = alphaConsumer(args);
    if (!alpha)
        return { };

    if (!args.atEnd())
        return { };

    return { ColorType { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
}

template<typename ColorType> static Color parseRelativeColorFunctionForXYZTypes(CSSParserTokenRange& args, Color originColor, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueXyz || args.peek().id() == CSSValueXyzD50 || args.peek().id() == CSSValueXyzD65);

    if (!context.cssColor4)
        return { };

    consumeIdentRaw(args);

    auto originColorAsXYZ = originColor.toColorTypeLossy<ColorType>().resolved();

    CSSCalcSymbolTable symbolTable {
        { CSSValueX, CSSUnitType::CSS_NUMBER, originColorAsXYZ.x },
        { CSSValueY, CSSUnitType::CSS_NUMBER, originColorAsXYZ.y },
        { CSSValueZ, CSSUnitType::CSS_NUMBER, originColorAsXYZ.z },
        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsXYZ.alpha * 100.0 }
    };

    auto consumeXYZ = [&symbolTable](auto& args) { return consumeNumberOrNoneRawAllowingSymbolTableIdent(args, symbolTable); };
    auto consumeAlpha = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };

    return parseColorFunctionForXYZTypes<ColorType>(args, WTFMove(consumeXYZ), WTFMove(consumeAlpha));
}

template<typename ColorType> static Color parseColorFunctionForXYZTypes(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueXyz || args.peek().id() == CSSValueXyzD50 || args.peek().id() == CSSValueXyzD65);

    if (!context.cssColor4)
        return { };

    consumeIdentRaw(args);

    auto consumeXYZ = [](auto& args) { return consumeNumberOrNoneRaw(args); };
    auto consumeAlpha = [](auto& args) { return consumeOptionalAlpha(args); };

    return parseColorFunctionForXYZTypes<ColorType>(args, WTFMove(consumeXYZ), WTFMove(consumeAlpha));
}

static Color parseRelativeColorFunctionParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ASSERT(args.peek().id() == CSSValueFrom);
    consumeIdentRaw(args);

    auto originColor = consumeOriginColor(args, context);
    if (!originColor.isValid())
        return { };

    switch (args.peek().id()) {
    case CSSValueA98Rgb:
        return parseRelativeColorFunctionForRGBTypes<ExtendedA98RGB<float>>(args, WTFMove(originColor), context);
    case CSSValueDisplayP3:
        return parseRelativeColorFunctionForRGBTypes<ExtendedDisplayP3<float>>(args, WTFMove(originColor), context);
    case CSSValueProphotoRgb:
        return parseRelativeColorFunctionForRGBTypes<ExtendedProPhotoRGB<float>>(args, WTFMove(originColor), context);
    case CSSValueRec2020:
        return parseRelativeColorFunctionForRGBTypes<ExtendedRec2020<float>>(args, WTFMove(originColor), context);
    case CSSValueSRGB:
        return parseRelativeColorFunctionForRGBTypes<ExtendedSRGBA<float>>(args, WTFMove(originColor), context);
    case CSSValueSrgbLinear:
        return parseRelativeColorFunctionForRGBTypes<ExtendedLinearSRGBA<float>>(args, WTFMove(originColor), context);
    case CSSValueXyzD50:
        return parseRelativeColorFunctionForXYZTypes<XYZA<float, WhitePoint::D50>>(args, WTFMove(originColor), context);
    case CSSValueXyz:
    case CSSValueXyzD65:
        return parseRelativeColorFunctionForXYZTypes<XYZA<float, WhitePoint::D65>>(args, WTFMove(originColor), context);
    default:
        return { };
    }

    ASSERT_NOT_REACHED();
    return { };
}

static Color parseNonRelativeColorFunctionParameters(CSSParserTokenRange& args, const CSSParserContext& context)
{
    switch (args.peek().id()) {
    case CSSValueA98Rgb:
        return parseColorFunctionForRGBTypes<ExtendedA98RGB<float>>(args, context);
    case CSSValueDisplayP3:
        return parseColorFunctionForRGBTypes<ExtendedDisplayP3<float>>(args, context);
    case CSSValueProphotoRgb:
        return parseColorFunctionForRGBTypes<ExtendedProPhotoRGB<float>>(args, context);
    case CSSValueRec2020:
        return parseColorFunctionForRGBTypes<ExtendedRec2020<float>>(args, context);
    case CSSValueSRGB:
        return parseColorFunctionForRGBTypes<ExtendedSRGBA<float>>(args, context);
    case CSSValueSrgbLinear:
        return parseColorFunctionForRGBTypes<ExtendedLinearSRGBA<float>>(args, context);
    case CSSValueXyzD50:
        return parseColorFunctionForXYZTypes<XYZA<float, WhitePoint::D50>>(args, context);
    case CSSValueXyz:
    case CSSValueXyzD65:
        return parseColorFunctionForXYZTypes<XYZA<float, WhitePoint::D65>>(args, context);
    default:
        return { };
    }

    ASSERT_NOT_REACHED();
    return { };
}

static Color parseColorFunctionParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    ASSERT(range.peek().functionId() == CSSValueColor);
    auto args = consumeFunction(range);

    auto color = [&] {
        if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
            return parseRelativeColorFunctionParameters(args, context);
        return parseNonRelativeColorFunctionParameters(args, context);
    }();

    ASSERT(!color.isValid() || color.usesColorFunctionSerialization());
    return color;
}

static Color selectFirstColorThatMeetsOrExceedsTargetContrast(const Color& originBackgroundColor, Vector<Color>&& colorsToCompareAgainst, double targetContrast)
{
    auto originBackgroundColorLuminance = originBackgroundColor.luminance();

    for (auto& color : colorsToCompareAgainst) {
        if (contrastRatio(originBackgroundColorLuminance, color.luminance()) >= targetContrast)
            return WTFMove(color);
    }

    // If there is a target contrast, and the end of the list is reached without meeting that target,
    // either white or black is returned, whichever has the higher contrast.
    auto contrastWithWhite = contrastRatio(originBackgroundColorLuminance, 1.0);
    auto contrastWithBlack = contrastRatio(originBackgroundColorLuminance, 0.0);
    return contrastWithWhite > contrastWithBlack ? Color::white : Color::black;
}

static Color selectFirstColorWithHighestContrast(const Color& originBackgroundColor, Vector<Color>&& colorsToCompareAgainst)
{
    auto originBackgroundColorLuminance = originBackgroundColor.luminance();

    auto* colorWithGreatestContrast = &colorsToCompareAgainst[0];
    double greatestContrastSoFar = 0;
    for (auto& color : colorsToCompareAgainst) {
        auto contrast = contrastRatio(originBackgroundColorLuminance, color.luminance());
        if (contrast > greatestContrastSoFar) {
            greatestContrastSoFar = contrast;
            colorWithGreatestContrast = &color;
        }
    }

    return WTFMove(*colorWithGreatestContrast);
}

static Color parseColorContrastFunctionParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    ASSERT(range.peek().functionId() == CSSValueColorContrast);

    if (!context.colorContrastEnabled)
        return { };

    auto args = consumeFunction(range);

    auto originBackgroundColor = consumeOriginColor(args, context);
    if (!originBackgroundColor.isValid())
        return { };

    if (!consumeIdentRaw<CSSValueVs>(args))
        return { };

    Vector<Color> colorsToCompareAgainst;
    bool consumedTo = false;
    do {
        auto colorToCompareAgainst = consumeOriginColor(args, context);
        if (!colorToCompareAgainst.isValid())
            return { };

        colorsToCompareAgainst.append(WTFMove(colorToCompareAgainst));

        if (consumeIdentRaw<CSSValueTo>(args)) {
            consumedTo = true;
            break;
        }
    } while (consumeCommaIncludingWhitespace(args));

    if (colorsToCompareAgainst.size() == 1)
        return { };

    if (consumedTo) {
        auto targetContrast = [&] () -> std::optional<NumberRaw> {
            if (args.peek().type() == IdentToken) {
                static constexpr std::pair<CSSValueID, NumberRaw> targetContrastMappings[] {
                    { CSSValueAA, NumberRaw { 4.5 } },
                    { CSSValueAALarge, NumberRaw { 3.0 } },
                    { CSSValueAAA, NumberRaw { 7.0 } },
                    { CSSValueAAALarge, NumberRaw { 4.5 } },
                };
                static constexpr SortedArrayMap targetContrastMap { targetContrastMappings };
                auto value = targetContrastMap.tryGet(args.consumeIncludingWhitespace().id());
                return value ? std::make_optional(*value) : std::nullopt;
            }
            return consumeNumberRaw(args);
        }();

        if (!targetContrast)
            return { };
        
        // When a target constast is specified, we select "the first color color to meet or exceed the target contrast."
        return selectFirstColorThatMeetsOrExceedsTargetContrast(originBackgroundColor, WTFMove(colorsToCompareAgainst), targetContrast->value);
    }

    // When a target constast is NOT specified, we select "the first color with the highest contrast to the single color."
    return selectFirstColorWithHighestContrast(originBackgroundColor, WTFMove(colorsToCompareAgainst));
}

static std::optional<HueInterpolationMethod> consumeHueInterpolationMethod(CSSParserTokenRange& args)
{
    switch (args.peek().id()) {
    case CSSValueShorter:
        args.consumeIncludingWhitespace();
        return HueInterpolationMethod::Shorter;
    case CSSValueLonger:
        args.consumeIncludingWhitespace();
        return HueInterpolationMethod::Longer;
    case CSSValueIncreasing:
        args.consumeIncludingWhitespace();
        return HueInterpolationMethod::Increasing;
    case CSSValueDecreasing:
        args.consumeIncludingWhitespace();
        return HueInterpolationMethod::Decreasing;
    case CSSValueSpecified:
        args.consumeIncludingWhitespace();
        return HueInterpolationMethod::Specified;
    default:
        return { };
    }
}

static std::optional<ColorInterpolationMethod> consumeColorInterpolationMethod(CSSParserTokenRange& args)
{
    // <rectangular-color-space> = srgb | srgb-linear | lab | oklab | xyz | xyz-d50 | xyz-d65
    // <polar-color-space> = hsl | hwb | lch | oklch
    // <hue-interpolation-method> = [ shorter | longer | increasing | decreasing | specified ] hue
    // <color-interpolation-method> = in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? ]

    ASSERT(args.peek().id() == CSSValueIn);
    consumeIdentRaw(args);

    auto consumePolarColorSpace = [](CSSParserTokenRange& args, auto colorInterpolationMethod) -> std::optional<ColorInterpolationMethod> {
        // Consume the color space identifier.
        args.consumeIncludingWhitespace();

        // <hue-interpolation-method> is optional, so if it is not provided, we just use the default value
        // specified in the passed in 'colorInterpolationMethod' parameter.
        auto hueInterpolationMethod = consumeHueInterpolationMethod(args);
        if (!hueInterpolationMethod)
            return {{ colorInterpolationMethod, AlphaPremultiplication::Premultiplied }};
        
        // If the hue-interpolation-method was provided it must be followed immediately by the 'hue' identifier.
        if (!consumeIdentRaw<CSSValueHue>(args))
            return { };

        colorInterpolationMethod.hueInterpolationMethod = *hueInterpolationMethod;

        return {{ colorInterpolationMethod, AlphaPremultiplication::Premultiplied }};
    };

    auto consumeRectangularColorSpace = [](CSSParserTokenRange& args, auto colorInterpolationMethod) -> std::optional<ColorInterpolationMethod> {
        // Consume the color space identifier.
        args.consumeIncludingWhitespace();

        return {{ colorInterpolationMethod, AlphaPremultiplication::Premultiplied }};
    };

    switch (args.peek().id()) {
    case CSSValueHsl:
        return consumePolarColorSpace(args, ColorInterpolationMethod::HSL { });
    case CSSValueHwb:
        return consumePolarColorSpace(args, ColorInterpolationMethod::HWB { });
    case CSSValueLch:
        return consumePolarColorSpace(args, ColorInterpolationMethod::LCH { });
    case CSSValueLab:
        return consumeRectangularColorSpace(args, ColorInterpolationMethod::Lab { });
    case CSSValueOklch:
        return consumePolarColorSpace(args, ColorInterpolationMethod::OKLCH { });
    case CSSValueOklab:
        return consumeRectangularColorSpace(args, ColorInterpolationMethod::OKLab { });
    case CSSValueSRGB:
        return consumeRectangularColorSpace(args, ColorInterpolationMethod::SRGB { });
    case CSSValueSrgbLinear:
        return consumeRectangularColorSpace(args, ColorInterpolationMethod::SRGBLinear { });
    case CSSValueXyzD50:
        return consumeRectangularColorSpace(args, ColorInterpolationMethod::XYZD50 { });
    case CSSValueXyz:
    case CSSValueXyzD65:
        return consumeRectangularColorSpace(args, ColorInterpolationMethod::XYZD65 { });
    default:
        return { };
    }
}

struct ColorMixComponent {
    Color color;
    std::optional<double> percentage;
};

static std::optional<ColorMixComponent> consumeColorMixComponent(CSSParserTokenRange& args, const CSSParserContext& context)
{
    ColorMixComponent result;

    if (auto percentage = consumePercentRaw(args)) {
        if (percentage->value < 0.0 || percentage->value > 100.0)
            return { };
        result.percentage = percentage->value;
    }

    result.color = consumeOriginColor(args, context);
    if (!result.color.isValid())
        return std::nullopt;

    if (!result.percentage) {
        if (auto percentage = consumePercentRaw(args)) {
            if (percentage->value < 0.0 || percentage->value > 100.0)
                return { };
            result.percentage = percentage->value;
        }
    }

    return result;
}

struct ColorMixPercentages {
    double p1;
    double p2;
    std::optional<double> alphaMultiplier = std::nullopt;
};

static std::optional<ColorMixPercentages> normalizedMixPercentages(const ColorMixComponent& mixComponents1, const ColorMixComponent& mixComponents2)
{
    // The percentages are normalized as follows:

    // 1. Let p1 be the first percentage and p2 the second one.

    // 2. If both percentages are omitted, they each default to 50% (an equal mix of the two colors).
    if (!mixComponents1.percentage && !mixComponents2.percentage)
        return {{ 50.0, 50.0 }};
    
    ColorMixPercentages result;

    if (!mixComponents2.percentage) {
        // 3. Otherwise, if p2 is omitted, it becomes 100% - p1
        result.p1 = *mixComponents1.percentage;
        result.p2 = 100.0 - result.p1;
    } else if (!mixComponents1.percentage) {
        // 4. Otherwise, if p1 is omitted, it becomes 100% - p2
        result.p2 = *mixComponents2.percentage;
        result.p1 = 100.0 - result.p2;
    } else {
        result.p1 = *mixComponents1.percentage;
        result.p2 = *mixComponents2.percentage;
    }

    auto sum = result.p1 + result.p2;

    // 5.If the percentages sum to zero, the function is invalid.
    if (sum == 0)
        return { };

    if (sum > 100.0) {
        // 6. Otherwise, if both are provided but do not add up to 100%, they are scaled accordingly so that they
        //    add up to 100%.
        result.p1 *= 100.0 / sum;
        result.p2 *= 100.0 / sum;
    } else if (sum < 100.0) {
        // 7. Otherwise, if both are provided and add up to less than 100%, the sum is saved as an alpha multiplier.
        //    They are then scaled accordingly so that they add up to 100%.
        result.p1 *= 100.0 / sum;
        result.p2 *= 100.0 / sum;
        result.alphaMultiplier = sum;
    }

    return result;
}

template<typename InterpolationMethod> static Color mixColorComponentsUsingColorInterpolationMethod(InterpolationMethod interpolationMethod, ColorMixPercentages mixPercentages, const Color& color1, const Color& color2)
{
    using ColorType = typename InterpolationMethod::ColorType;

    // 1. Both colors are converted to the specified <color-space>. If the specified color space has a smaller gamut than
    //    the one in which the color to be adjusted is specified, gamut mapping will occur.
    auto convertedColor1 = color1.template toColorTypeLossy<ColorType>();
    auto convertedColor2 = color2.template toColorTypeLossy<ColorType>();

    // 2. Colors are then interpolated in the specified color space, as described in CSS Color 4 § 13 Interpolation. [...]
    auto mixedColor = interpolateColorComponents<AlphaPremultiplication::Premultiplied>(interpolationMethod, convertedColor1, mixPercentages.p1 / 100.0, convertedColor2, mixPercentages.p2 / 100.0).unresolved();

    // 3. If an alpha multiplier was produced during percentage normalization, the alpha component of the interpolated result
    //    is multiplied by the alpha multiplier.
    if (mixPercentages.alphaMultiplier && !std::isnan(mixedColor.alpha))
        mixedColor.alpha *= (*mixPercentages.alphaMultiplier / 100.0);

    return makeCanonicalColor(mixedColor);
}

static Color mixColorComponents(ColorInterpolationMethod colorInterpolationMethod, const ColorMixComponent& mixComponents1, const ColorMixComponent& mixComponents2)
{
    auto mixPercentages = normalizedMixPercentages(mixComponents1, mixComponents2);
    if (!mixPercentages)
        return { };

    return WTF::switchOn(colorInterpolationMethod.colorSpace,
        [&] (auto colorSpace) {
            return mixColorComponentsUsingColorInterpolationMethod<decltype(colorSpace)>(colorSpace, *mixPercentages, mixComponents1.color, mixComponents2.color);
        }
    );
}

static Color parseColorMixFunctionParameters(CSSParserTokenRange& range, const CSSParserContext& context)
{
    // color-mix() = color-mix( <color-interpolation-method> , [ <color> && <percentage [0,100]>? ]#{2})

    ASSERT(range.peek().functionId() == CSSValueColorMix);

    if (!context.colorMixEnabled)
        return { };

    auto args = consumeFunction(range);
    
    if (args.peek().id() != CSSValueIn)
        return { };
    
    auto colorInterpolationMethod = consumeColorInterpolationMethod(args);
    if (!colorInterpolationMethod)
        return { };

    if (!consumeCommaIncludingWhitespace(args))
        return { };

    auto mixComponent1 = consumeColorMixComponent(args, context);
    if (!mixComponent1)
        return { };

    if (!consumeCommaIncludingWhitespace(args))
        return { };

    auto mixComponent2 = consumeColorMixComponent(args, context);
    if (!mixComponent2)
        return { };

    if (!args.atEnd())
        return { };

    return mixColorComponents(*colorInterpolationMethod, *mixComponent1, *mixComponent2);
}

static std::optional<SRGBA<uint8_t>> parseHexColor(CSSParserTokenRange& range, bool acceptQuirkyColors)
{
    String string;
    StringView view;
    auto& token = range.peek();
    if (token.type() == HashToken)
        view = token.value();
    else {
        if (!acceptQuirkyColors)
            return std::nullopt;
        if (token.type() == IdentToken) {
            view = token.value(); // e.g. FF0000
            if (view.length() != 3 && view.length() != 6)
                return std::nullopt;
        } else if (token.type() == NumberToken || token.type() == DimensionToken) {
            if (token.numericValueType() != IntegerValueType)
                return std::nullopt;
            auto numericValue = token.numericValue();
            if (!(numericValue >= 0 && numericValue < 1000000))
                return std::nullopt;
            auto integerValue = static_cast<int>(token.numericValue());
            if (token.type() == NumberToken)
                string = String::number(integerValue); // e.g. 112233
            else
                string = makeString(integerValue, token.unitString()); // e.g. 0001FF
            if (string.length() < 6)
                string = makeString(&"000000"[string.length()], string);

            if (string.length() != 3 && string.length() != 6)
                return std::nullopt;
            view = string;
        } else
            return std::nullopt;
    }
    auto result = CSSParser::parseHexColor(view);
    if (!result)
        return std::nullopt;
    range.consumeIncludingWhitespace();
    return *result;
}

static Color parseColorFunction(CSSParserTokenRange& range, const CSSParserContext& context)
{
    CSSParserTokenRange colorRange = range;
    CSSValueID functionId = range.peek().functionId();
    Color color;
    switch (functionId) {
    case CSSValueRgb:
        color = parseRGBParameters<RGBFunctionMode::RGB>(colorRange, context);
        break;
    case CSSValueRgba:
        color = parseRGBParameters<RGBFunctionMode::RGBA>(colorRange, context);
        break;
    case CSSValueHsl:
        color = parseHSLParameters<HSLFunctionMode::HSL>(colorRange, context);
        break;
    case CSSValueHsla:
        color = parseHSLParameters<HSLFunctionMode::HSLA>(colorRange, context);
        break;
    case CSSValueHwb:
        color = parseHWBParameters(colorRange, context);
        break;
    case CSSValueLab:
        color = parseLabParameters<Lab<float>>(colorRange, context);
        break;
    case CSSValueLch:
        color = parseLCHParameters<LCHA<float>>(colorRange, context);
        break;
    case CSSValueOklab:
        color = parseLabParameters<OKLab<float>>(colorRange, context);
        break;
    case CSSValueOklch:
        color = parseLCHParameters<OKLCHA<float>>(colorRange, context);
        break;
    case CSSValueColor:
        color = parseColorFunctionParameters(colorRange, context);
        break;
    case CSSValueColorContrast:
        color = parseColorContrastFunctionParameters(colorRange, context);
        break;
    case CSSValueColorMix:
        color = parseColorMixFunctionParameters(colorRange, context);
        break;
    default:
        return { };
    }
    if (color.isValid())
        range = colorRange;
    return color;
}

Color consumeColorWorkerSafe(CSSParserTokenRange& range, const CSSParserContext& context)
{
    Color result;
    auto keyword = range.peek().id();
    if (StyleColor::isColorKeyword(keyword)) {
        // FIXME: Need a worker-safe way to compute the system colors.
        //        For now, we detect the system color, but then intentionally fail parsing.
        if (StyleColor::isSystemColorKeyword(keyword))
            return { };
        if (!isValueAllowedInMode(keyword, context.mode))
            return { };
        result = StyleColor::colorFromKeyword(keyword, { });
        range.consumeIncludingWhitespace();
    }

    if (auto parsedColor = parseHexColor(range, false))
        result = *parsedColor;
    else
        result = parseColorFunction(range, context);

    if (!range.atEnd())
        return { };

    return result;
}

RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange& range, const CSSParserContext& context, bool acceptQuirkyColors, OptionSet<StyleColor::CSSColorType> allowedColorTypes)
{
    auto keyword = range.peek().id();
    if (StyleColor::isColorKeyword(keyword, allowedColorTypes)) {
        if (!isValueAllowedInMode(keyword, context.mode))
            return nullptr;
        return consumeIdent(range);
    }
    Color color;
    if (auto parsedColor = parseHexColor(range, acceptQuirkyColors))
        color = *parsedColor;
    else {
        color = parseColorFunction(range, context);
        if (!color.isValid())
            return nullptr;
    }
    return CSSValuePool::singleton().createValue(color);
}

static RefPtr<CSSPrimitiveValue> consumePositionComponent(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, NegativePercentagePolicy negativePercentagePolicy = NegativePercentagePolicy::Forbid)
{
    if (range.peek().type() == IdentToken)
        return consumeIdent<CSSValueLeft, CSSValueTop, CSSValueBottom, CSSValueRight, CSSValueCenter>(range);
    return consumeLengthOrPercent(range, parserMode, ValueRange::All, unitless, negativePercentagePolicy);
}

static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value)
{
    return value.isValueID() && (value.valueID() == CSSValueLeft || value.valueID() == CSSValueRight);
}

static bool isVerticalPositionKeywordOnly(const CSSPrimitiveValue& value)
{
    return value.isValueID() && (value.valueID() == CSSValueTop || value.valueID() == CSSValueBottom);
}

static PositionCoordinates positionFromOneValue(CSSPrimitiveValue& value)
{
    bool valueAppliesToYAxisOnly = isVerticalPositionKeywordOnly(value);
    if (valueAppliesToYAxisOnly)
        return { CSSPrimitiveValue::createIdentifier(CSSValueCenter), value };
    return { value, CSSPrimitiveValue::createIdentifier(CSSValueCenter) };
}

static std::optional<PositionCoordinates> positionFromTwoValues(CSSPrimitiveValue& value1, CSSPrimitiveValue& value2)
{
    bool mustOrderAsXY = isHorizontalPositionKeywordOnly(value1) || isVerticalPositionKeywordOnly(value2) || !value1.isValueID() || !value2.isValueID();
    bool mustOrderAsYX = isVerticalPositionKeywordOnly(value1) || isHorizontalPositionKeywordOnly(value2);
    if (mustOrderAsXY && mustOrderAsYX)
        return std::nullopt;
    if (mustOrderAsYX)
        return PositionCoordinates { value2, value1 };
    return PositionCoordinates { value1, value2 };
}

namespace CSSPropertyParserHelpersInternal {
template<typename... Args>
static Ref<CSSPrimitiveValue> createPrimitiveValuePair(Args&&... args)
{
    return CSSValuePool::singleton().createValue(Pair::create(std::forward<Args>(args)...));
}
}

// https://drafts.csswg.org/css-backgrounds-3/#propdef-background-position
// background-position has special parsing rules, allowing a 3-value syntax:
// <bg-position> =  [ left | center | right | top | bottom | <length-percentage> ]
// |
//   [ left | center | right | <length-percentage> ]
//   [ top | center | bottom | <length-percentage> ]
// |
//   [ center | [ left | right ] <length-percentage>? ] &&
//   [ center | [ top | bottom ] <length-percentage>? ]
//
static std::optional<PositionCoordinates> backgroundPositionFromThreeValues(const std::array<CSSPrimitiveValue*, 5>& values)
{
    RefPtr<CSSPrimitiveValue> resultX;
    RefPtr<CSSPrimitiveValue> resultY;

    CSSPrimitiveValue* center = nullptr;
    for (int i = 0; values[i]; i++) {
        CSSPrimitiveValue* currentValue = values[i];
        if (!currentValue->isValueID())
            return std::nullopt;

        CSSValueID id = currentValue->valueID();
        if (id == CSSValueCenter) {
            if (center)
                return std::nullopt;
            center = currentValue;
            continue;
        }

        RefPtr<CSSPrimitiveValue> result;
        if (values[i + 1] && !values[i + 1]->isValueID())
            result = CSSPropertyParserHelpersInternal::createPrimitiveValuePair(currentValue, values[++i]);
        else
            result = currentValue;

        if (id == CSSValueLeft || id == CSSValueRight) {
            if (resultX)
                return std::nullopt;
            resultX = result;
        } else {
            ASSERT(id == CSSValueTop || id == CSSValueBottom);
            if (resultY)
                return std::nullopt;
            resultY = result;
        }
    }

    if (center) {
        ASSERT(resultX || resultY);
        if (resultX && resultY)
            return std::nullopt;
        if (!resultX)
            resultX = center;
        else
            resultY = center;
    }

    ASSERT(resultX && resultY);
    return PositionCoordinates { resultX.releaseNonNull(), resultY.releaseNonNull() };
}

// https://drafts.csswg.org/css-values-4/#typedef-position
// <position> = [
//   [ left | center | right ] || [ top | center | bottom ]
// |
//   [ left | center | right | <length-percentage> ]
//   [ top | center | bottom | <length-percentage> ]?
// |
//   [ [ left | right ] <length-percentage> ] &&
//   [ [ top | bottom ] <length-percentage> ]
//
static std::optional<PositionCoordinates> positionFromFourValues(const std::array<CSSPrimitiveValue*, 5>& values)
{
    RefPtr<CSSPrimitiveValue> resultX;
    RefPtr<CSSPrimitiveValue> resultY;

    for (int i = 0; values[i]; i++) {
        CSSPrimitiveValue* currentValue = values[i];
        if (!currentValue->isValueID())
            return std::nullopt;

        CSSValueID id = currentValue->valueID();
        if (id == CSSValueCenter)
            return std::nullopt;

        RefPtr<CSSPrimitiveValue> result;
        if (values[i + 1] && !values[i + 1]->isValueID())
            result = CSSPropertyParserHelpersInternal::createPrimitiveValuePair(currentValue, values[++i]);
        else
            result = currentValue;

        if (id == CSSValueLeft || id == CSSValueRight) {
            if (resultX)
                return std::nullopt;
            resultX = result;
        } else {
            ASSERT(id == CSSValueTop || id == CSSValueBottom);
            if (resultY)
                return std::nullopt;
            resultY = result;
        }
    }

    ASSERT(resultX && resultY);
    return PositionCoordinates { resultX.releaseNonNull(), resultY.releaseNonNull() };
}

// FIXME: This may consume from the range upon failure. The background
// shorthand works around it, but we should just fix it here.
std::optional<PositionCoordinates> consumePositionCoordinates(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, PositionSyntax positionSyntax, NegativePercentagePolicy negativePercentagePolicy)
{
    auto value1 = consumePositionComponent(range, parserMode, unitless, negativePercentagePolicy);
    if (!value1)
        return std::nullopt;

    auto value2 = consumePositionComponent(range, parserMode, unitless, negativePercentagePolicy);
    if (!value2)
        return positionFromOneValue(*value1);
    
    auto value3 = consumePositionComponent(range, parserMode, unitless, negativePercentagePolicy);
    if (!value3)
        return positionFromTwoValues(*value1, *value2);
    
    auto value4 = consumePositionComponent(range, parserMode, unitless, negativePercentagePolicy);
    
    std::array<CSSPrimitiveValue*, 5> values {
        value1.get(),
        value2.get(),
        value3.get(),
        value4.get(),
        nullptr
    };
    
    if (value4)
        return positionFromFourValues(values);
    
    if (positionSyntax != PositionSyntax::BackgroundPosition)
        return std::nullopt;

    return backgroundPositionFromThreeValues(values);
}

RefPtr<CSSPrimitiveValue> consumePosition(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, PositionSyntax positionSyntax)
{
    if (auto coordinates = consumePositionCoordinates(range, parserMode, unitless, positionSyntax))
        return CSSPropertyParserHelpersInternal::createPrimitiveValuePair(WTFMove(coordinates->x), WTFMove(coordinates->y));
    return nullptr;
}

std::optional<PositionCoordinates> consumeOneOrTwoValuedPositionCoordinates(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless)
{
    auto value1 = consumePositionComponent(range, parserMode, unitless);
    if (!value1)
        return std::nullopt;
    auto value2 = consumePositionComponent(range, parserMode, unitless);
    if (!value2)
        return positionFromOneValue(*value1);
    return positionFromTwoValues(*value1, *value2);
}

RefPtr<CSSPrimitiveValue> consumeSingleAxisPosition(CSSParserTokenRange& range, CSSParserMode parserMode, BoxOrient orientation)
{
    RefPtr<CSSPrimitiveValue> value1;

    if (range.peek().type() == IdentToken) {
        switch (orientation) {
        case BoxOrient::Horizontal:
            value1 = consumeIdent<CSSValueLeft, CSSValueRight, CSSValueCenter>(range);
            break;
        case BoxOrient::Vertical:
            value1 = consumeIdent<CSSValueTop, CSSValueBottom, CSSValueCenter>(range);
            break;
        }
        if (!value1)
            return nullptr;

        if (value1->valueID() == CSSValueCenter)
            return value1;
    }

    auto value2 = consumeLengthOrPercent(range, parserMode, ValueRange::All, UnitlessQuirk::Forbid);
    if (value1 && value2)
        return CSSPropertyParserHelpersInternal::createPrimitiveValuePair(WTFMove(value1), WTFMove(value2));

    return value1 ? value1 : value2;
}

// This should go away once we drop support for -webkit-gradient
static RefPtr<CSSPrimitiveValue> consumeDeprecatedGradientPoint(CSSParserTokenRange& args, bool horizontal)
{
    if (args.peek().type() == IdentToken) {
        if ((horizontal && consumeIdent<CSSValueLeft>(args)) || (!horizontal && consumeIdent<CSSValueTop>(args)))
            return CSSValuePool::singleton().createValue(0., CSSUnitType::CSS_PERCENTAGE);
        if ((horizontal && consumeIdent<CSSValueRight>(args)) || (!horizontal && consumeIdent<CSSValueBottom>(args)))
            return CSSValuePool::singleton().createValue(100., CSSUnitType::CSS_PERCENTAGE);
        if (consumeIdent<CSSValueCenter>(args))
            return CSSValuePool::singleton().createValue(50., CSSUnitType::CSS_PERCENTAGE);
        return nullptr;
    }
    RefPtr<CSSPrimitiveValue> result = consumePercent(args, ValueRange::All);
    if (!result)
        result = consumeNumber(args, ValueRange::All);
    return result;
}

// Used to parse colors for -webkit-gradient(...).
static RefPtr<CSSPrimitiveValue> consumeDeprecatedGradientStopColor(CSSParserTokenRange& args, const CSSParserContext& context)
{
    if (args.peek().id() == CSSValueCurrentcolor)
        return nullptr;
    return consumeColor(args, context);
}

static bool consumeDeprecatedGradientColorStop(CSSParserTokenRange& range, CSSGradientColorStop& stop, const CSSParserContext& context)
{
    CSSValueID id = range.peek().functionId();
    if (id != CSSValueFrom && id != CSSValueTo && id != CSSValueColorStop)
        return false;

    CSSParserTokenRange args = consumeFunction(range);
    double position;
    if (id == CSSValueFrom || id == CSSValueTo) {
        position = (id == CSSValueFrom) ? 0 : 1;
    } else {
        ASSERT(id == CSSValueColorStop);
        auto value = consumeNumberOrPercentRaw<NumberOrPercentDividedBy100Transformer>(args);
        if (!value)
            return false;
        position = *value;

        if (!consumeCommaIncludingWhitespace(args))
            return false;
    }

    stop.position = CSSValuePool::singleton().createValue(position, CSSUnitType::CSS_NUMBER);
    stop.color = consumeDeprecatedGradientStopColor(args, context);
    return stop.color && args.atEnd();
}

static AlphaPremultiplication gradientAlphaPremultiplication(const CSSParserContext& context)
{
    return context.gradientPremultipliedAlphaInterpolationEnabled ? AlphaPremultiplication::Premultiplied : AlphaPremultiplication::Unpremultiplied;
}

static RefPtr<CSSValue> consumeDeprecatedGradient(CSSParserTokenRange& args, const CSSParserContext& context)
{
    auto id = args.consumeIncludingWhitespace().id();
    if (id != CSSValueRadial && id != CSSValueLinear)
        return nullptr;
    
    if (!consumeCommaIncludingWhitespace(args))
        return nullptr;

    auto firstX = consumeDeprecatedGradientPoint(args, true);
    if (!firstX)
        return nullptr;
    auto firstY = consumeDeprecatedGradientPoint(args, false);
    if (!firstY)
        return nullptr;

    if (!consumeCommaIncludingWhitespace(args))
        return nullptr;

    // For radial gradients only, we now expect a numeric radius.
    RefPtr<CSSPrimitiveValue> firstRadius;
    if (id == CSSValueRadial) {
        firstRadius = consumeNumber(args, ValueRange::NonNegative);
        if (!firstRadius || !consumeCommaIncludingWhitespace(args))
            return nullptr;
    }

    auto secondX = consumeDeprecatedGradientPoint(args, true);
    if (!secondX)
        return nullptr;
    auto secondY = consumeDeprecatedGradientPoint(args, false);
    if (!secondY)
        return nullptr;

    // For radial gradients only, we now expect the second radius.
    RefPtr<CSSPrimitiveValue> secondRadius;
    if (id == CSSValueRadial) {
        if (!consumeCommaIncludingWhitespace(args))
            return nullptr;
        secondRadius = consumeNumber(args, ValueRange::NonNegative);
        if (!secondRadius)
            return nullptr;
    }

    CSSGradientColorStopList stops;
    while (consumeCommaIncludingWhitespace(args)) {
        CSSGradientColorStop stop;
        if (!consumeDeprecatedGradientColorStop(args, stop, context))
            return nullptr;
        stops.append(WTFMove(stop));
    }
    stops.shrinkToFit();

    auto colorInterpolationMethod = CSSGradientColorInterpolationMethod::legacyMethod(gradientAlphaPremultiplication(context));

    RefPtr<CSSGradientValue> result;
    if (id == CSSValueRadial)
        result = CSSRadialGradientValue::create(NonRepeating, CSSDeprecatedRadialGradient, colorInterpolationMethod, WTFMove(stops));
    else if (id == CSSValueLinear)
        result = CSSLinearGradientValue::create(NonRepeating, CSSDeprecatedLinearGradient, colorInterpolationMethod, WTFMove(stops));

    result->setFirstX(WTFMove(firstX));
    result->setFirstY(WTFMove(firstY));
    result->setSecondX(WTFMove(secondX));
    result->setSecondY(WTFMove(secondY));
    if (id == CSSValueRadial) {
        downcast<CSSRadialGradientValue>(*result).setFirstRadius(WTFMove(firstRadius));
        downcast<CSSRadialGradientValue>(*result).setSecondRadius(WTFMove(secondRadius));
    }

    return result;
}

static std::optional<CSSGradientColorStopList> consumeGradientColorStops(CSSParserTokenRange& range, const CSSParserContext& context, CSSGradientType gradientType)
{
    bool supportsColorHints = gradientType == CSSLinearGradient || gradientType == CSSRadialGradient || gradientType == CSSConicGradient;
    
    auto consumeStopPosition = [&] {
        return gradientType == CSSConicGradient
            ? consumeAngleOrPercent(range, context.mode, ValueRange::All, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow)
            : consumeLengthOrPercent(range, context.mode, ValueRange::All);
    };

    CSSGradientColorStopList stops;

    // The first color stop cannot be a color hint.
    bool previousStopWasColorHint = true;
    do {
        CSSGradientColorStop stop { consumeColor(range, context), consumeStopPosition(), { } };
        if (!stop.color && !stop.position)
            return std::nullopt;

        // Two color hints in a row are not allowed.
        if (!stop.color && (!supportsColorHints || previousStopWasColorHint))
            return std::nullopt;
        previousStopWasColorHint = !stop.color;

        // Stops with both a color and a position can have a second position, which shares the same color.
        if (stop.color && stop.position) {
            if (auto secondPosition = consumeStopPosition()) {
                stops.append(stop);
                stop.position = WTFMove(secondPosition);
            }
        }
        stops.append(WTFMove(stop));
    } while (consumeCommaIncludingWhitespace(range));

    // The last color stop cannot be a color hint.
    if (previousStopWasColorHint)
        return std::nullopt;

    // Must have two or more stops to be valid.
    if (stops.size() < 2)
        return std::nullopt;

    stops.shrinkToFit();

    return { WTFMove(stops) };
}

static RefPtr<CSSValue> consumePrefixedRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
    auto centerCoordinate = consumeOneOrTwoValuedPositionCoordinates(args, context.mode, UnitlessQuirk::Forbid);
    if (centerCoordinate && !consumeCommaIncludingWhitespace(args))
        return nullptr;

    auto shape = consumeIdent<CSSValueCircle, CSSValueEllipse>(args);
    auto sizeKeyword = consumeIdent<CSSValueClosestSide, CSSValueClosestCorner, CSSValueFarthestSide, CSSValueFarthestCorner, CSSValueContain, CSSValueCover>(args);
    if (!shape)
        shape = consumeIdent<CSSValueCircle, CSSValueEllipse>(args);

    // Or, two lengths or percentages
    RefPtr<CSSPrimitiveValue> horizontalSize;
    RefPtr<CSSPrimitiveValue> verticalSize;
    if (!shape && !sizeKeyword) {
        horizontalSize = consumeLengthOrPercent(args, context.mode, ValueRange::NonNegative);
        if (horizontalSize) {
            verticalSize = consumeLengthOrPercent(args, context.mode, ValueRange::NonNegative);
            if (!verticalSize)
                return nullptr;
            consumeCommaIncludingWhitespace(args);
        }
    } else
        consumeCommaIncludingWhitespace(args);

    auto stops = consumeGradientColorStops(args, context, CSSPrefixedRadialGradient);
    if (!stops)
        return nullptr;

    auto colorInterpolationMethod = CSSGradientColorInterpolationMethod::legacyMethod(gradientAlphaPremultiplication(context));
    auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient, colorInterpolationMethod, WTFMove(*stops));

    result->setEndHorizontalSize(WTFMove(horizontalSize));
    result->setEndVerticalSize(WTFMove(verticalSize));

    if (centerCoordinate) {
        result->setFirstX(centerCoordinate->x.copyRef());
        result->setFirstY(centerCoordinate->y.copyRef());
        result->setSecondX(WTFMove(centerCoordinate->x));
        result->setSecondY(WTFMove(centerCoordinate->y));
    }
    result->setShape(WTFMove(shape));
    result->setSizingBehavior(WTFMove(sizeKeyword));

    return result;
}

static CSSGradientColorInterpolationMethod computeGradientColorInterpolationMethod(const CSSParserContext& context, std::optional<ColorInterpolationMethod> parsedColorInterpolationMethod, const CSSGradientColorStopList& stops)
{
    if (!context.gradientInterpolationColorSpacesEnabled)
        return CSSGradientColorInterpolationMethod::legacyMethod(gradientAlphaPremultiplication(context));

    // We detect whether stops use legacy vs. non-legacy CSS color syntax using the following rules:
    //  - A CSSValueID is always considered legacy since all keyword based colors are considered legacy by the spec.
    //  - An actual Color value is considered legacy if it is stored as 8-bit sRGB.
    //
    // While this is accurate now, we should consider a more robust mechanism to detect this at parse
    // time, perhaps keeping this information in the CSSPrimitiveValue itself.

    auto defaultColorInterpolationMethod = CSSGradientColorInterpolationMethod::Default::SRGB;
    for (auto& stop : stops) {
        if (!stop.color)
            continue;
        if (stop.color->isValueID())
            continue;
        if (stop.color->isRGBColor() && stop.color->color().tryGetAsSRGBABytes())
            continue;

        defaultColorInterpolationMethod = CSSGradientColorInterpolationMethod::Default::OKLab;
        break;
    }

    if (parsedColorInterpolationMethod)
        return { *parsedColorInterpolationMethod, defaultColorInterpolationMethod };

    switch (defaultColorInterpolationMethod) {
    case CSSGradientColorInterpolationMethod::Default::SRGB:
        return { { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) }, defaultColorInterpolationMethod };

    case CSSGradientColorInterpolationMethod::Default::OKLab:
        return { { ColorInterpolationMethod::OKLab { }, AlphaPremultiplication::Premultiplied }, defaultColorInterpolationMethod };
    }

    ASSERT_NOT_REACHED();
    return { { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) }, defaultColorInterpolationMethod };
}

static RefPtr<CSSValue> consumeRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
    // radial-gradient() = radial-gradient(
    //   [[ <ending-shape> || <size> ]? [ at <position> ]? ] || <color-interpolation-method>,
    //   <color-stop-list>
    // )

    std::optional<ColorInterpolationMethod> colorInterpolationMethod;

    if (context.gradientInterpolationColorSpacesEnabled) {
        if (args.peek().id() == CSSValueIn) {
            colorInterpolationMethod = consumeColorInterpolationMethod(args);
            if (!colorInterpolationMethod)
                return nullptr;
        }
    }

    RefPtr<CSSPrimitiveValue> shape;
    RefPtr<CSSPrimitiveValue> sizeKeyword;
    RefPtr<CSSPrimitiveValue> horizontalSize;
    RefPtr<CSSPrimitiveValue> verticalSize;

    // First part of grammar, the size/shape clause:
    // [ circle || <length> ] |
    // [ ellipse || [ <length> | <percentage> ]{2} ] |
    // [ [ circle | ellipse] || <size-keyword> ]
    for (int i = 0; i < 3; ++i) {
        if (args.peek().type() == IdentToken) {
            CSSValueID id = args.peek().id();
            if (id == CSSValueCircle || id == CSSValueEllipse) {
                if (shape)
                    return nullptr;
                shape = consumeIdent(args);
            } else if (id == CSSValueClosestSide || id == CSSValueClosestCorner || id == CSSValueFarthestSide || id == CSSValueFarthestCorner) {
                if (sizeKeyword)
                    return nullptr;
                sizeKeyword = consumeIdent(args);
            } else {
                break;
            }
        } else {
            auto center = consumeLengthOrPercent(args, context.mode, ValueRange::NonNegative);
            if (!center)
                break;
            if (horizontalSize)
                return nullptr;
            horizontalSize = center;
            center = consumeLengthOrPercent(args, context.mode, ValueRange::NonNegative);
            if (center) {
                verticalSize = center;
                ++i;
            }
        }
    }

    // You can specify size as a keyword or a length/percentage, not both.
    if (sizeKeyword && horizontalSize)
        return nullptr;
    // Circles must have 0 or 1 lengths.
    if (shape && shape->valueID() == CSSValueCircle && verticalSize)
        return nullptr;
    // Ellipses must have 0 or 2 length/percentages.
    if (shape && shape->valueID() == CSSValueEllipse && horizontalSize && !verticalSize)
        return nullptr;
    // If there's only one size, it must be a length.
    if (!verticalSize && horizontalSize && horizontalSize->isPercentage())
        return nullptr;

    std::optional<PositionCoordinates> position;
    if (consumeIdent<CSSValueAt>(args)) {
        position = consumePositionCoordinates(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position);
        if (!position)
            return nullptr;
    }

    if (context.gradientInterpolationColorSpacesEnabled) {
        if ((shape || sizeKeyword || horizontalSize || position) && !colorInterpolationMethod && args.peek().id() == CSSValueIn) {
            colorInterpolationMethod = consumeColorInterpolationMethod(args);
            if (!colorInterpolationMethod)
                return nullptr;
        }
    }

    if ((shape || sizeKeyword || horizontalSize || position || colorInterpolationMethod) && !consumeCommaIncludingWhitespace(args))
        return nullptr;

    auto stops = consumeGradientColorStops(args, context, CSSRadialGradient);
    if (!stops)
        return nullptr;

    auto computedColorInterpolationMethod = computeGradientColorInterpolationMethod(context, colorInterpolationMethod, *stops);
    auto result = CSSRadialGradientValue::create(repeating, CSSRadialGradient, computedColorInterpolationMethod, WTFMove(*stops));

    result->setShape(WTFMove(shape));
    result->setSizingBehavior(WTFMove(sizeKeyword));
    result->setEndHorizontalSize(WTFMove(horizontalSize));
    result->setEndVerticalSize(WTFMove(verticalSize));

    if (position) {
        result->setFirstX(position->x.copyRef());
        result->setFirstY(position->y.copyRef());
        
        // Right now, CSS radial gradients have the same start and end centers.
        result->setSecondX(WTFMove(position->x));
        result->setSecondY(WTFMove(position->y));
    }

    return result;
}

struct AngleOrToSideOrCorner {
    struct Angle {
        Ref<CSSPrimitiveValue> angle;
    };
    struct ToSideOrCorner {
        RefPtr<CSSPrimitiveValue> leftOrRight;
        RefPtr<CSSPrimitiveValue> topOrBottom;
    };
};

static RefPtr<CSSValue> consumePrefixedLinearGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
    auto consumeToSideOrCorner = [](CSSParserTokenRange& args) -> std::optional<AngleOrToSideOrCorner::ToSideOrCorner> {
        auto leftOrRight = consumeIdent<CSSValueLeft, CSSValueRight>(args);
        auto topOrBottom = consumeIdent<CSSValueTop, CSSValueBottom>(args);
        if (!leftOrRight && !topOrBottom)
            return { };

        if (!leftOrRight)
            leftOrRight = consumeIdent<CSSValueLeft, CSSValueRight>(args);

        return {{ WTFMove(leftOrRight), WTFMove(topOrBottom) }};
    };

    std::optional<std::variant<AngleOrToSideOrCorner::Angle, AngleOrToSideOrCorner::ToSideOrCorner>> angleOrToSideOrCorner;

    if (auto angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow))
        angleOrToSideOrCorner = AngleOrToSideOrCorner::Angle { angle.releaseNonNull() };
    else if (auto sideOrCorner = consumeToSideOrCorner(args))
        angleOrToSideOrCorner = WTFMove(*sideOrCorner);

    if (angleOrToSideOrCorner && !consumeCommaIncludingWhitespace(args))
        return nullptr;

    auto stops = consumeGradientColorStops(args, context, CSSPrefixedLinearGradient);
    if (!stops)
        return nullptr;

    auto colorInterpolationMethod = CSSGradientColorInterpolationMethod::legacyMethod(gradientAlphaPremultiplication(context));
    auto result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient, colorInterpolationMethod, WTFMove(*stops));

    if (angleOrToSideOrCorner) {
        WTF::switchOn(*angleOrToSideOrCorner,
            [&] (AngleOrToSideOrCorner::Angle& angle) {
                result->setAngle(WTFMove(angle.angle));
            },
            [&] (AngleOrToSideOrCorner::ToSideOrCorner& toSideOrCorner) {
                result->setFirstX(WTFMove(toSideOrCorner.leftOrRight));
                result->setFirstY(WTFMove(toSideOrCorner.topOrBottom));
            }
        );
    } else
        result->setFirstY(CSSValuePool::singleton().createIdentifierValue(CSSValueTop));

    return result;
}

static RefPtr<CSSValue> consumeLinearGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
    // <side-or-corner> = [left | right] || [top | bottom]
    // linear-gradient() = linear-gradient(
    //   [ <angle> | to <side-or-corner> ]? || <color-interpolation-method>,
    //   <color-stop-list>
    // )

    auto consumeToSideOrCorner = [](CSSParserTokenRange& args) -> std::optional<AngleOrToSideOrCorner::ToSideOrCorner> {
        ASSERT(args.peek().id() == CSSValueTo);
        consumeIdentRaw(args);

        auto leftOrRight = consumeIdent<CSSValueLeft, CSSValueRight>(args);
        auto topOrBottom = consumeIdent<CSSValueTop, CSSValueBottom>(args);
        if (!leftOrRight && !topOrBottom)
            return { };

        if (!leftOrRight)
            leftOrRight = consumeIdent<CSSValueLeft, CSSValueRight>(args);

        return {{ WTFMove(leftOrRight), WTFMove(topOrBottom) }};
    };


    std::optional<ColorInterpolationMethod> colorInterpolationMethod;

    if (context.gradientInterpolationColorSpacesEnabled) {
        if (args.peek().id() == CSSValueIn) {
            colorInterpolationMethod = consumeColorInterpolationMethod(args);
            if (!colorInterpolationMethod)
                return nullptr;
        }
    }

    std::optional<std::variant<AngleOrToSideOrCorner::Angle, AngleOrToSideOrCorner::ToSideOrCorner>> angleOrToSideOrCorner;

    if (auto angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow))
        angleOrToSideOrCorner = AngleOrToSideOrCorner::Angle { angle.releaseNonNull() };
    else if (args.peek().id() == CSSValueTo) {
        auto toSideOrCorner = consumeToSideOrCorner(args);
        if (!toSideOrCorner)
            return nullptr;
        angleOrToSideOrCorner = WTFMove(*toSideOrCorner);
    }

    if (context.gradientInterpolationColorSpacesEnabled) {
        if (angleOrToSideOrCorner && !colorInterpolationMethod && args.peek().id() == CSSValueIn) {
            colorInterpolationMethod = consumeColorInterpolationMethod(args);
            if (!colorInterpolationMethod)
                return nullptr;
        }
    }

    if (angleOrToSideOrCorner || colorInterpolationMethod) {
        if (!consumeCommaIncludingWhitespace(args))
            return nullptr;
    }

    auto stops = consumeGradientColorStops(args, context, CSSLinearGradient);
    if (!stops)
        return nullptr;

    auto computedColorInterpolationMethod = computeGradientColorInterpolationMethod(context, colorInterpolationMethod, *stops);
    auto result = CSSLinearGradientValue::create(repeating, CSSLinearGradient, computedColorInterpolationMethod, WTFMove(*stops));
    
    if (angleOrToSideOrCorner) {
        WTF::switchOn(*angleOrToSideOrCorner,
            [&] (AngleOrToSideOrCorner::Angle& angle) {
                result->setAngle(WTFMove(angle.angle));
            },
            [&] (AngleOrToSideOrCorner::ToSideOrCorner& toSideOrCorner) {
                result->setFirstX(WTFMove(toSideOrCorner.leftOrRight));
                result->setFirstY(WTFMove(toSideOrCorner.topOrBottom));
            }
        );
    }

    return result;
}

static RefPtr<CSSValue> consumeConicGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
#if ENABLE(CSS_CONIC_GRADIENTS)
    // conic-gradient() = conic-gradient(
    //   [ [ from <angle> ]? [ at <position> ]? ] || <color-interpolation-method>,
    //   <angular-color-stop-list>
    // )

    std::optional<ColorInterpolationMethod> colorInterpolationMethod;

    if (context.gradientInterpolationColorSpacesEnabled) {
        if (args.peek().id() == CSSValueIn) {
            colorInterpolationMethod = consumeColorInterpolationMethod(args);
            if (!colorInterpolationMethod)
                return nullptr;
        }
    }

    RefPtr<CSSPrimitiveValue> angle;
    if (consumeIdent<CSSValueFrom>(args)) {
        // FIXME: Unlike linear-gradient, conic-gradients are not specified to allow unitless 0 angles - https://www.w3.org/TR/css-images-4/#valdef-conic-gradient-angle.
        angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
        if (!angle)
            return nullptr;
    }
    
    std::optional<PositionCoordinates> position;
    if (consumeIdent<CSSValueAt>(args)) {
        position = consumePositionCoordinates(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position);
        if (!position)
            return nullptr;
    }

    if (context.gradientInterpolationColorSpacesEnabled) {
        if ((angle || position) && !colorInterpolationMethod && args.peek().id() == CSSValueIn) {
            colorInterpolationMethod = consumeColorInterpolationMethod(args);
            if (!colorInterpolationMethod)
                return nullptr;
        }
    }

    if (angle || position || colorInterpolationMethod) {
        if (!consumeCommaIncludingWhitespace(args))
            return nullptr;
    }

    auto stops = consumeGradientColorStops(args, context, CSSConicGradient);
    if (!stops)
        return nullptr;

    auto computedColorInterpolationMethod = computeGradientColorInterpolationMethod(context, colorInterpolationMethod, *stops);
    auto result = CSSConicGradientValue::create(repeating, computedColorInterpolationMethod, WTFMove(*stops));

    if (angle)
        result->setAngle(WTFMove(angle));
    if (position) {
        result->setFirstX(position->x.copyRef());
        result->setFirstY(position->y.copyRef());

        // Right now, conic gradients have the same start and end centers.
        result->setSecondX(WTFMove(position->x));
        result->setSecondY(WTFMove(position->y));
    }

    return result;
#else
    UNUSED_PARAM(args);
    UNUSED_PARAM(context);
    UNUSED_PARAM(repeating);
    return nullptr;
#endif
}

RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange& range, const CSSParserContext& context)
{
    if (range.peek().id() == CSSValueNone)
        return consumeIdent(range);
    return consumeImage(range, context);
}

static RefPtr<CSSValue> consumeCrossFade(CSSParserTokenRange& args, const CSSParserContext& context, bool prefixed)
{
    auto fromImageValue = consumeImageOrNone(args, context);
    if (!fromImageValue || !consumeCommaIncludingWhitespace(args))
        return nullptr;
    auto toImageValue = consumeImageOrNone(args, context);
    if (!toImageValue || !consumeCommaIncludingWhitespace(args))
        return nullptr;

    auto percentage = consumeNumberOrPercentRaw<NumberOrPercentDividedBy100Transformer>(args);
    if (!percentage)
        return nullptr;
    auto percentageValue = CSSValuePool::singleton().createValue(clampTo<double>(*percentage, 0, 1), CSSUnitType::CSS_NUMBER);
    return CSSCrossfadeValue::create(fromImageValue.releaseNonNull(), toImageValue.releaseNonNull(), WTFMove(percentageValue), prefixed);
}

static RefPtr<CSSValue> consumeWebkitCanvas(CSSParserTokenRange& args)
{
    if (args.peek().type() != IdentToken)
        return nullptr;
    auto canvasName = args.consumeIncludingWhitespace().value().toString();
    if (!args.atEnd())
        return nullptr;
    return CSSCanvasValue::create(canvasName);
}

static RefPtr<CSSValue> consumeWebkitNamedImage(CSSParserTokenRange& args)
{
    if (args.peek().type() != IdentToken)
        return nullptr;
    auto imageName = args.consumeIncludingWhitespace().value().toString();
    if (!args.atEnd())
        return nullptr;
    return CSSNamedImageValue::create(imageName);
}

static RefPtr<CSSValue> consumeFilterImage(CSSParserTokenRange& args, const CSSParserContext& context)
{
    auto imageValue = consumeImageOrNone(args, context);
    if (!imageValue || !consumeCommaIncludingWhitespace(args))
        return nullptr;

    auto filterValue = consumeFilter(args, context, AllowedFilterFunctions::PixelFilters);

    if (!filterValue)
        return nullptr;

    if (!args.atEnd())
        return nullptr;

    return CSSFilterImageValue::create(imageValue.releaseNonNull(), filterValue.releaseNonNull());
}

#if ENABLE(CSS_PAINTING_API)
static RefPtr<CSSValue> consumeCustomPaint(CSSParserTokenRange& args)
{
    if (!RuntimeEnabledFeatures::sharedFeatures().cssPaintingAPIEnabled())
        return nullptr;
    if (args.peek().type() != IdentToken)
        return nullptr;
    auto name = args.consumeIncludingWhitespace().value().toString();

    if (!args.atEnd() && args.peek() != CommaToken)
        return nullptr;
    if (!args.atEnd())
        args.consume();

    auto argumentList = CSSVariableData::create(args);

    while (!args.atEnd())
        args.consume();

    return CSSPaintImageValue::create(name, WTFMove(argumentList));
}
#endif

static RefPtr<CSSValue> consumeGeneratedImage(CSSParserTokenRange& range, const CSSParserContext& context)
{
    CSSValueID id = range.peek().functionId();
    CSSParserTokenRange rangeCopy = range;
    CSSParserTokenRange args = consumeFunction(rangeCopy);
    RefPtr<CSSValue> result;
    if (id == CSSValueRadialGradient)
        result = consumeRadialGradient(args, context, NonRepeating);
    else if (id == CSSValueRepeatingRadialGradient)
        result = consumeRadialGradient(args, context, Repeating);
    else if (id == CSSValueWebkitLinearGradient)
        result = consumePrefixedLinearGradient(args, context, NonRepeating);
    else if (id == CSSValueWebkitRepeatingLinearGradient)
        result = consumePrefixedLinearGradient(args, context, Repeating);
    else if (id == CSSValueRepeatingLinearGradient)
        result = consumeLinearGradient(args, context, Repeating);
    else if (id == CSSValueLinearGradient)
        result = consumeLinearGradient(args, context, NonRepeating);
    else if (id == CSSValueWebkitGradient)
        result = consumeDeprecatedGradient(args, context);
    else if (id == CSSValueWebkitRadialGradient)
        result = consumePrefixedRadialGradient(args, context, NonRepeating);
    else if (id == CSSValueWebkitRepeatingRadialGradient)
        result = consumePrefixedRadialGradient(args, context, Repeating);
    else if (id == CSSValueConicGradient)
        result = consumeConicGradient(args, context, NonRepeating);
    else if (id == CSSValueRepeatingConicGradient)
        result = consumeConicGradient(args, context, Repeating);
    else if (id == CSSValueWebkitCrossFade || id == CSSValueCrossFade)
        result = consumeCrossFade(args, context, id == CSSValueWebkitCrossFade);
    else if (id == CSSValueWebkitCanvas)
        result = consumeWebkitCanvas(args);
    else if (id == CSSValueWebkitNamedImage)
        result = consumeWebkitNamedImage(args);
    else if (id == CSSValueWebkitFilter || id == CSSValueFilter)
        result = consumeFilterImage(args, context);
#if ENABLE(CSS_PAINTING_API)
    else if (id == CSSValuePaint)
        result = consumeCustomPaint(args);
#endif
    if (!result || !args.atEnd())
        return nullptr;
    range = rangeCopy;
    return result;
}

static RefPtr<CSSValue> consumeImageSet(CSSParserTokenRange& range, const CSSParserContext& context, OptionSet<AllowedImageType> allowedImageTypes)
{
    CSSParserTokenRange rangeCopy = range;
    CSSParserTokenRange args = consumeFunction(rangeCopy);
    RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create();
    do {
        auto image = consumeImage(args, context, allowedImageTypes);
        if (!image)
            return nullptr;

        imageSet->append(image.releaseNonNull());

        auto resolution = consumeResolution(args);
        if (!resolution || resolution->floatValue() <= 0)
            return nullptr;

        imageSet->append(resolution.releaseNonNull());
    } while (consumeCommaIncludingWhitespace(args));
    if (!args.atEnd())
        return nullptr;
    range = rangeCopy;
    return imageSet;
}

static bool isGeneratedImage(CSSValueID id)
{
    return id == CSSValueLinearGradient
        || id == CSSValueRadialGradient
        || id == CSSValueConicGradient
        || id == CSSValueRepeatingLinearGradient
        || id == CSSValueRepeatingRadialGradient
        || id == CSSValueRepeatingConicGradient
        || id == CSSValueWebkitLinearGradient
        || id == CSSValueWebkitRadialGradient
        || id == CSSValueWebkitRepeatingLinearGradient
        || id == CSSValueWebkitRepeatingRadialGradient
        || id == CSSValueWebkitGradient
        || id == CSSValueWebkitCrossFade
        || id == CSSValueWebkitCanvas
        || id == CSSValueCrossFade
        || id == CSSValueWebkitNamedImage
        || id == CSSValueWebkitFilter
#if ENABLE(CSS_PAINTING_API)
        || id == CSSValuePaint
#endif
        || id == CSSValueFilter;
}
    
static bool isPixelFilterFunction(CSSValueID filterFunction)
{
    switch (filterFunction) {
    case CSSValueBlur:
    case CSSValueBrightness:
    case CSSValueContrast:
    case CSSValueDropShadow:
    case CSSValueGrayscale:
    case CSSValueHueRotate:
    case CSSValueInvert:
    case CSSValueOpacity:
    case CSSValueSaturate:
    case CSSValueSepia:
        return true;
    default:
        return false;
    }
}

static bool isColorFilterFunction(CSSValueID filterFunction)
{
    switch (filterFunction) {
    case CSSValueBrightness:
    case CSSValueContrast:
    case CSSValueGrayscale:
    case CSSValueHueRotate:
    case CSSValueInvert:
    case CSSValueOpacity:
    case CSSValueSaturate:
    case CSSValueSepia:
    case CSSValueAppleInvertLightness:
        return true;
    default:
        return false;
    }
}

static bool allowsValuesGreaterThanOne(CSSValueID filterFunction)
{
    switch (filterFunction) {
    case CSSValueBrightness:
    case CSSValueContrast:
    case CSSValueSaturate:
        return true;
    default:
        return false;
    }
}

static RefPtr<CSSFunctionValue> consumeFilterFunction(CSSParserTokenRange& range, const CSSParserContext& context, AllowedFilterFunctions allowedFunctions)
{
    CSSValueID filterType = range.peek().functionId();
    switch (allowedFunctions) {
    case AllowedFilterFunctions::PixelFilters:
        if (!isPixelFilterFunction(filterType))
            return nullptr;
        break;
    case AllowedFilterFunctions::ColorFilters:
        if (!isColorFilterFunction(filterType))
            return nullptr;
        break;
    }

    CSSParserTokenRange args = consumeFunction(range);
    RefPtr<CSSFunctionValue> filterValue = CSSFunctionValue::create(filterType);

    if (filterType == CSSValueAppleInvertLightness) {
        if (!args.atEnd())
            return nullptr;
        return filterValue;
    }

    RefPtr<CSSValue> parsedValue;

    if (filterType == CSSValueDropShadow)
        parsedValue = consumeSingleShadow(args, context, false, false);
    else {
        if (args.atEnd())
            return filterValue;

        if (filterType == CSSValueHueRotate)
            parsedValue = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
        else if (filterType == CSSValueBlur)
            parsedValue = consumeLength(args, HTMLStandardMode, ValueRange::NonNegative);
        else {
            parsedValue = consumePercent(args, ValueRange::NonNegative);
            if (!parsedValue)
                parsedValue = consumeNumber(args, ValueRange::NonNegative);
            if (parsedValue && !allowsValuesGreaterThanOne(filterType)) {
                bool isPercentage = downcast<CSSPrimitiveValue>(*parsedValue).isPercentage();
                double maxAllowed = isPercentage ? 100.0 : 1.0;
                if (downcast<CSSPrimitiveValue>(*parsedValue).doubleValue() > maxAllowed)
                    parsedValue = CSSPrimitiveValue::create(maxAllowed, isPercentage ? CSSUnitType::CSS_PERCENTAGE : CSSUnitType::CSS_NUMBER);
            }
        }
    }
    if (!parsedValue || !args.atEnd())
        return nullptr;
    filterValue->append(parsedValue.releaseNonNull());
    return filterValue;
}

RefPtr<CSSValue> consumeFilter(CSSParserTokenRange& range, const CSSParserContext& context, AllowedFilterFunctions allowedFunctions)
{
    if (range.peek().id() == CSSValueNone)
        return consumeIdent(range);

    bool referenceFiltersAllowed = allowedFunctions == AllowedFilterFunctions::PixelFilters;
    auto list = CSSValueList::createSpaceSeparated();
    do {
        RefPtr<CSSValue> filterValue = referenceFiltersAllowed ? consumeUrl(range) : nullptr;
        if (!filterValue) {
            filterValue = consumeFilterFunction(range, context, allowedFunctions);
            if (!filterValue)
                return nullptr;
        }
        list->append(filterValue.releaseNonNull());
    } while (!range.atEnd());

    return list.ptr();
}

RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange& range, const CSSParserContext& context, bool allowInset, bool allowSpread)
{
    RefPtr<CSSPrimitiveValue> style;
    RefPtr<CSSPrimitiveValue> color;
    RefPtr<CSSPrimitiveValue> horizontalOffset;
    RefPtr<CSSPrimitiveValue> verticalOffset;
    RefPtr<CSSPrimitiveValue> blurRadius;
    RefPtr<CSSPrimitiveValue> spreadDistance;
    
    for (size_t i = 0; i < 3; i++) {
        if (range.atEnd())
            break;
        
        const CSSParserToken& nextToken = range.peek();
        // If we have come to a comma (e.g. if this range represents a comma-separated list of <shadow>s), we are done parsing this <shadow>.
        if (nextToken.type() == CommaToken)
            break;
        
        if (nextToken.id() == CSSValueInset) {
            if (!allowInset || style)
                return nullptr;
            style = consumeIdent(range);
            continue;
        }
        
        auto maybeColor = consumeColor(range, context);
        if (maybeColor) {
            // If we just parsed a color but already had one, the given token range is not a valid <shadow>.
            if (color)
                return nullptr;
            color = maybeColor;
            continue;
        }
        
        // If the current token is neither a color nor the `inset` keyword, it must be the lengths component of this value.
        if (horizontalOffset || verticalOffset || blurRadius || spreadDistance) {
            // If we've already parsed these lengths, the given value is invalid as there cannot be two lengths components in a single <shadow> value.
            return nullptr;
        }
        horizontalOffset = consumeLength(range, context.mode, ValueRange::All);
        if (!horizontalOffset)
            return nullptr;
        verticalOffset = consumeLength(range, context.mode, ValueRange::All);
        if (!verticalOffset)
            return nullptr;

        const CSSParserToken& token = range.peek();
        // The explicit check for calc() is unfortunate. This is ensuring that we only fail parsing if there is a length, but it fails the range check.
        if (token.type() == DimensionToken || token.type() == NumberToken || (token.type() == FunctionToken && CSSCalcValue::isCalcFunction(token.functionId()))) {
            blurRadius = consumeLength(range, context.mode, ValueRange::NonNegative);
            if (!blurRadius)
                return nullptr;
        }

        if (blurRadius && allowSpread)
            spreadDistance = consumeLength(range, context.mode, ValueRange::All);
    }
    
    // In order for this to be a valid <shadow>, at least these lengths must be present.
    if (!horizontalOffset || !verticalOffset)
        return nullptr;
    return CSSShadowValue::create(WTFMove(horizontalOffset), WTFMove(verticalOffset), WTFMove(blurRadius), WTFMove(spreadDistance), WTFMove(style), WTFMove(color));
}

RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, const CSSParserContext& context, OptionSet<AllowedImageType> allowedImageTypes)
{
    if (range.peek().type() == StringToken && allowedImageTypes.contains(AllowedImageType::RawStringAsURL)) {
        return CSSImageValue::create(context.completeURL(range.consumeIncludingWhitespace().value().toAtomString().string()),
            context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
    }

    if (range.peek().type() == FunctionToken) {
        CSSValueID functionId = range.peek().functionId();
        if ((allowedImageTypes.contains(AllowedImageType::GeneratedImage)) && isGeneratedImage(functionId))
            return consumeGeneratedImage(range, context);

        if (allowedImageTypes.contains(AllowedImageType::ImageSet)) {
            if (functionId == CSSValueImageSet)
                return consumeImageSet(range, context, (allowedImageTypes | AllowedImageType::RawStringAsURL) - AllowedImageType::ImageSet);
            if (functionId == CSSValueWebkitImageSet)
                return consumeImageSet(range, context, AllowedImageType::URLFunction);
        }
    }

    if (allowedImageTypes.contains(AllowedImageType::URLFunction)) {
        if (auto string = consumeUrlAsStringView(range); !string.isNull()) {
            return CSSImageValue::create(context.completeURL(string.toAtomString().string()),
                context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
        }
    }

    return nullptr;
}

// https://www.w3.org/TR/css-counter-styles-3/#predefined-counters
bool isPredefinedCounterStyle(CSSValueID valueID)
{
    return valueID >= CSSValueDisc && valueID <= CSSValueEthiopicNumeric;
}

// https://www.w3.org/TR/css-counter-styles-3/#typedef-counter-style-name
RefPtr<CSSPrimitiveValue> consumeCounterStyleName(CSSParserTokenRange& range)
{
    // <counter-style-name> is a <custom-ident> that is not an ASCII case-insensitive match for "none".
    auto valueID = range.peek().id();
    if (valueID == CSSValueNone)
        return nullptr;
    // If the value is an ASCII case-insensitive match for any of the predefined counter styles, lowercase it.
    if (auto name = consumeCustomIdent(range, isPredefinedCounterStyle(valueID)))
        return name;
    return nullptr;
}

// https://www.w3.org/TR/css-counter-styles-3/#typedef-counter-style-name
AtomString consumeCounterStyleNameInPrelude(CSSParserTokenRange& prelude)
{
    auto nameToken = prelude.consumeIncludingWhitespace();
    if (!prelude.atEnd())
        return AtomString();
    // Ensure this token is a valid <custom-ident>.
    if (nameToken.type() != IdentToken || !isValidCustomIdentifier(nameToken.id()))
        return AtomString();
    // In the context of the prelude of an @counter-style rule, a <counter-style-name> must not be an ASCII
    // case-insensitive match for "decimal" or "disc". No <counter-style-name>, prelude or not, may be an ASCII
    // case-insensitive match for "none".
    if (identMatches<CSSValueDecimal, CSSValueDisc, CSSValueNone>(nameToken.id()))
        return AtomString();
    auto name = nameToken.value();
    return isPredefinedCounterStyle(nameToken.id()) ? name.convertToASCIILowercaseAtom() : name.toAtomString();
}

RefPtr<CSSPrimitiveValue> consumeSingleContainerName(CSSParserTokenRange& range)
{
    if (range.peek().id() == CSSValueNone)
        return nullptr;
    if (auto ident = consumeCustomIdent(range))
        return ident;
    return nullptr;
}

std::optional<CSSValueID> consumeFontVariantCSS21Raw(CSSParserTokenRange& range)
{
    return consumeIdentRaw<CSSValueNormal, CSSValueSmallCaps>(range);
}

std::optional<CSSValueID> consumeFontWeightKeywordValueRaw(CSSParserTokenRange& range)
{
    return consumeIdentRaw<CSSValueNormal, CSSValueBold, CSSValueBolder, CSSValueLighter>(range);
}

std::optional<FontWeightRaw> consumeFontWeightRaw(CSSParserTokenRange& range)
{
    if (auto result = consumeFontWeightKeywordValueRaw(range))
        return { *result };
    if (auto result = consumeFontWeightNumberRaw(range))
        return { *result };
    return std::nullopt;
}

std::optional<CSSValueID> consumeFontStretchKeywordValueRaw(CSSParserTokenRange& range)
{
    return consumeIdentRaw<CSSValueUltraCondensed, CSSValueExtraCondensed, CSSValueCondensed, CSSValueSemiCondensed, CSSValueNormal, CSSValueSemiExpanded, CSSValueExpanded, CSSValueExtraExpanded, CSSValueUltraExpanded>(range);
}

std::optional<CSSValueID> consumeFontStyleKeywordValueRaw(CSSParserTokenRange& range)
{
    return consumeIdentRaw<CSSValueNormal, CSSValueItalic, CSSValueOblique>(range);
}

std::optional<FontStyleRaw> consumeFontStyleRaw(CSSParserTokenRange& range, CSSParserMode parserMode)
{
    auto result = consumeFontStyleKeywordValueRaw(range);
    if (!result)
        return std::nullopt;

    auto ident = *result;
    if (ident == CSSValueNormal || ident == CSSValueItalic)
        return { { ident, std::nullopt } };
    ASSERT(ident == CSSValueOblique);
#if ENABLE(VARIATION_FONTS)
    if (!range.atEnd()) {
        // FIXME: This angle does specify that unitless 0 is allowed - see https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle
        if (auto angle = consumeAngleRaw(range, parserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow)) {
            if (isFontStyleAngleInRange(CSSPrimitiveValue::computeDegrees(angle->type, angle->value)))
                return { { CSSValueOblique, WTFMove(angle) } };
            return std::nullopt;
        }
    }
#else
    UNUSED_PARAM(parserMode);
#endif
    return { { CSSValueOblique, std::nullopt } };
}

AtomString concatenateFamilyName(CSSParserTokenRange& range)
{
    StringBuilder builder;
    bool addedSpace = false;
    const CSSParserToken& firstToken = range.peek();
    while (range.peek().type() == IdentToken) {
        if (!builder.isEmpty()) {
            builder.append(' ');
            addedSpace = true;
        }
        builder.append(range.consumeIncludingWhitespace().value());
    }
    if (!addedSpace && !isValidCustomIdentifier(firstToken.id()))
        return nullAtom();
    return builder.toAtomString();
}

AtomString consumeFamilyNameRaw(CSSParserTokenRange& range)
{
    if (range.peek().type() == StringToken)
        return range.consumeIncludingWhitespace().value().toAtomString();
    if (range.peek().type() != IdentToken)
        return nullAtom();
    return concatenateFamilyName(range);
}

std::optional<CSSValueID> consumeGenericFamilyRaw(CSSParserTokenRange& range)
{
    return consumeIdentRangeRaw(range, CSSValueSerif, CSSValueWebkitBody);
}

std::optional<Vector<FontFamilyRaw>> consumeFontFamilyRaw(CSSParserTokenRange& range)
{
    Vector<FontFamilyRaw> list;
    do {
        if (auto ident = consumeGenericFamilyRaw(range))
            list.append({ *ident });
        else {
            auto familyName = consumeFamilyNameRaw(range);
            if (familyName.isNull())
                return std::nullopt;
            list.append({ familyName });
        }
    } while (consumeCommaIncludingWhitespace(range));
    return list;
}

std::optional<FontSizeRaw> consumeFontSizeRaw(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless)
{
    if (range.peek().id() >= CSSValueXxSmall && range.peek().id() <= CSSValueLarger) {
        if (auto ident = consumeIdentRaw(range))
            return { *ident };
        return std::nullopt;
    }

    if (auto result = consumeLengthOrPercentRaw(range, parserMode, ValueRange::NonNegative, unitless))
        return { *result };

    return std::nullopt;
}

std::optional<LineHeightRaw> consumeLineHeightRaw(CSSParserTokenRange& range, CSSParserMode parserMode)
{
    if (range.peek().id() == CSSValueNormal) {
        if (auto ident = consumeIdentRaw(range))
            return { *ident };
        return std::nullopt;
    }

    if (auto number = consumeNumberRaw(range, ValueRange::NonNegative))
        return { number->value };

    if (auto lengthOrPercent = consumeLengthOrPercentRaw(range, parserMode, ValueRange::NonNegative))
        return { *lengthOrPercent };

    return std::nullopt;
}

std::optional<FontRaw> consumeFontRaw(CSSParserTokenRange& range, CSSParserMode parserMode)
{
    // Let's check if there is an inherit or initial somewhere in the shorthand.
    CSSParserTokenRange rangeCopy = range;
    while (!rangeCopy.atEnd()) {
        CSSValueID id = rangeCopy.consumeIncludingWhitespace().id();
        if (id == CSSValueInherit || id == CSSValueInitial)
            return std::nullopt;
    }

    FontRaw result;

    while (!range.atEnd()) {
        CSSValueID id = range.peek().id();
        if (!result.style) {
            if ((result.style = consumeFontStyleRaw(range, parserMode)))
                continue;
        }
        if (!result.variantCaps && (id == CSSValueNormal || id == CSSValueSmallCaps)) {
            // Font variant in the shorthand is particular, it only accepts normal or small-caps.
            // See https://drafts.csswg.org/css-fonts/#propdef-font
            if ((result.variantCaps = consumeFontVariantCSS21Raw(range)))
                continue;
        }
        if (!result.weight) {
            if ((result.weight = consumeFontWeightRaw(range)))
                continue;
        }
        if (!result.stretch) {
            if ((result.stretch = consumeFontStretchKeywordValueRaw(range)))
                continue;
        }
        break;
    }

    if (range.atEnd())
        return std::nullopt;

    // Now a font size _must_ come.
    if (auto size = consumeFontSizeRaw(range, parserMode))
        result.size = *size;
    else
        return std::nullopt;

    if (range.atEnd())
        return std::nullopt;

    if (consumeSlashIncludingWhitespace(range)) {
        if (!(result.lineHeight = consumeLineHeightRaw(range, parserMode)))
            return std::nullopt;
    }

    // Font family must come now.
    if (auto family = consumeFontFamilyRaw(range))
        result.family = *family;
    else
        return std::nullopt;

    if (!range.atEnd())
        return std::nullopt;

    return result;
}

const AtomString& genericFontFamily(CSSValueID ident)
{
    switch (ident) {
    case CSSValueSerif:
        return serifFamily.get();
    case CSSValueSansSerif:
        return sansSerifFamily.get();
    case CSSValueCursive:
        return cursiveFamily.get();
    case CSSValueFantasy:
        return fantasyFamily.get();
    case CSSValueMonospace:
        return monospaceFamily.get();
    case CSSValueWebkitPictograph:
        return pictographFamily.get();
    case CSSValueSystemUi:
        return systemUiFamily.get();
    default:
        return emptyAtom();
    }
}

WebKitFontFamilyNames::FamilyNamesIndex genericFontFamilyIndex(CSSValueID ident)
{
    switch (ident) {
    case CSSValueSerif:
        return WebKitFontFamilyNames::FamilyNamesIndex::SerifFamily;
    case CSSValueSansSerif:
        return WebKitFontFamilyNames::FamilyNamesIndex::SansSerifFamily;
    case CSSValueCursive:
        return WebKitFontFamilyNames::FamilyNamesIndex::CursiveFamily;
    case CSSValueFantasy:
        return WebKitFontFamilyNames::FamilyNamesIndex::FantasyFamily;
    case CSSValueMonospace:
        return WebKitFontFamilyNames::FamilyNamesIndex::MonospaceFamily;
    case CSSValueWebkitPictograph:
        return WebKitFontFamilyNames::FamilyNamesIndex::PictographFamily;
    case CSSValueSystemUi:
        return WebKitFontFamilyNames::FamilyNamesIndex::SystemUiFamily;
    default:
        ASSERT_NOT_REACHED();
        return WebKitFontFamilyNames::FamilyNamesIndex::StandardFamily;
    }
}

RefPtr<CSSValueList> consumeAspectRatioValue(CSSParserTokenRange& range)
{
    auto leftValue = consumeNumber(range, ValueRange::NonNegative);
    if (!leftValue)
        return nullptr;

    bool slashSeen = consumeSlashIncludingWhitespace(range);
    auto rightValue = slashSeen
        ? consumeNumber(range, ValueRange::NonNegative)
        : CSSValuePool::singleton().createValue(1, CSSUnitType::CSS_NUMBER);

    if (!rightValue)
        return nullptr;

    auto ratioList = CSSValueList::createSlashSeparated();
    ratioList->append(leftValue.releaseNonNull());
    ratioList->append(rightValue.releaseNonNull());

    return ratioList;
}

} // namespace CSSPropertyParserHelpers

} // namespace WebCore
