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

#include "core/css/properties/CSSParsingUtils.h"

#include "core/CSSPropertyNames.h"
#include "core/CSSValueKeywords.h"
#include "core/StylePropertyShorthand.h"
#include "core/css/CSSBasicShapeValues.h"
#include "core/css/CSSBorderImage.h"
#include "core/css/CSSContentDistributionValue.h"
#include "core/css/CSSCustomIdentValue.h"
#include "core/css/CSSFontFamilyValue.h"
#include "core/css/CSSFontFeatureValue.h"
#include "core/css/CSSFontStyleRangeValue.h"
#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSGridAutoRepeatValue.h"
#include "core/css/CSSGridLineNamesValue.h"
#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/CSSIdentifierValue.h"
#include "core/css/CSSInitialValue.h"
#include "core/css/CSSPathValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSRayValue.h"
#include "core/css/CSSShadowValue.h"
#include "core/css/CSSTimingFunctionValue.h"
#include "core/css/CSSURIValue.h"
#include "core/css/CSSValue.h"
#include "core/css/CSSValueList.h"
#include "core/css/CSSValuePair.h"
#include "core/css/parser/CSSParserContext.h"
#include "core/css/parser/CSSParserIdioms.h"
#include "core/css/parser/CSSParserLocalContext.h"
#include "core/css/parser/CSSParserToken.h"
#include "core/css/parser/CSSParserTokenRange.h"
#include "core/css/parser/CSSPropertyParserHelpers.h"
#include "core/css/properties/CSSProperty.h"
#include "core/frame/UseCounter.h"
#include "core/frame/WebFeature.h"
#include "core/svg/SVGParsingError.h"
#include "core/svg/SVGPathUtilities.h"
#include "platform/Length.h"
#include "platform/animation/TimingFunction.h"
#include "platform/runtime_enabled_features.h"
#include "platform/wtf/text/StringBuilder.h"

namespace blink {

using namespace cssvalue;

namespace CSSParsingUtils {
namespace {

bool IsLeftOrRightKeyword(CSSValueID id) {
  return CSSPropertyParserHelpers::IdentMatches<CSSValueLeft, CSSValueRight>(
      id);
}

bool IsAutoOrNormalOrStretch(CSSValueID id) {
  return CSSPropertyParserHelpers::IdentMatches<CSSValueAuto, CSSValueNormal,
                                                CSSValueStretch>(id);
}

bool IsContentDistributionKeyword(CSSValueID id) {
  return CSSPropertyParserHelpers::IdentMatches<
      CSSValueSpaceBetween, CSSValueSpaceAround, CSSValueSpaceEvenly,
      CSSValueStretch>(id);
}

bool IsOverflowKeyword(CSSValueID id) {
  return CSSPropertyParserHelpers::IdentMatches<CSSValueUnsafe, CSSValueSafe>(
      id);
}

CSSIdentifierValue* ConsumeOverflowPositionKeyword(CSSParserTokenRange& range) {
  return IsOverflowKeyword(range.Peek().Id())
             ? CSSPropertyParserHelpers::ConsumeIdent(range)
             : nullptr;
}

bool IsBaselineKeyword(CSSValueID id) {
  return CSSPropertyParserHelpers::IdentMatches<CSSValueFirst, CSSValueLast,
                                                CSSValueBaseline>(id);
}

CSSValueID GetBaselineKeyword(CSSValue& value) {
  if (!value.IsValuePair()) {
    DCHECK(ToCSSIdentifierValue(value).GetValueID() == CSSValueBaseline);
    return CSSValueBaseline;
  }

  DCHECK(ToCSSIdentifierValue(ToCSSValuePair(value).First()).GetValueID() ==
         CSSValueLast);
  DCHECK(ToCSSIdentifierValue(ToCSSValuePair(value).Second()).GetValueID() ==
         CSSValueBaseline);
  return CSSValueLastBaseline;
}

CSSValue* ConsumeBaselineKeyword(CSSParserTokenRange& range) {
  CSSIdentifierValue* preference =
      CSSPropertyParserHelpers::ConsumeIdent<CSSValueFirst, CSSValueLast>(
          range);
  CSSIdentifierValue* baseline =
      CSSPropertyParserHelpers::ConsumeIdent<CSSValueBaseline>(range);
  if (!baseline)
    return nullptr;
  if (preference && preference->GetValueID() == CSSValueLast) {
    return CSSValuePair::Create(preference, baseline,
                                CSSValuePair::kDropIdenticalValues);
  }
  return baseline;
}

CSSValue* ConsumeSteps(CSSParserTokenRange& range) {
  DCHECK_EQ(range.Peek().FunctionId(), CSSValueSteps);
  CSSParserTokenRange range_copy = range;
  CSSParserTokenRange args =
      CSSPropertyParserHelpers::ConsumeFunction(range_copy);

  CSSPrimitiveValue* steps =
      CSSPropertyParserHelpers::ConsumePositiveInteger(args);
  if (!steps)
    return nullptr;

  StepsTimingFunction::StepPosition position =
      StepsTimingFunction::StepPosition::END;
  if (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
    switch (args.ConsumeIncludingWhitespace().Id()) {
      case CSSValueMiddle:
        if (!RuntimeEnabledFeatures::WebAnimationsAPIEnabled())
          return nullptr;
        position = StepsTimingFunction::StepPosition::MIDDLE;
        break;
      case CSSValueStart:
        position = StepsTimingFunction::StepPosition::START;
        break;
      case CSSValueEnd:
        position = StepsTimingFunction::StepPosition::END;
        break;
      default:
        return nullptr;
    }
  }

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

  range = range_copy;
  return CSSStepsTimingFunctionValue::Create(steps->GetIntValue(), position);
}

CSSValue* ConsumeFrames(CSSParserTokenRange& range) {
  DCHECK_EQ(range.Peek().FunctionId(), CSSValueFrames);
  CSSParserTokenRange range_copy = range;
  CSSParserTokenRange args =
      CSSPropertyParserHelpers::ConsumeFunction(range_copy);

  CSSPrimitiveValue* frames =
      CSSPropertyParserHelpers::ConsumePositiveInteger(args);
  if (!frames)
    return nullptr;

  int frames_int = frames->GetIntValue();
  if (frames_int <= 1)
    return nullptr;

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

  range = range_copy;
  return CSSFramesTimingFunctionValue::Create(frames_int);
}

CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range) {
  DCHECK_EQ(range.Peek().FunctionId(), CSSValueCubicBezier);
  CSSParserTokenRange range_copy = range;
  CSSParserTokenRange args =
      CSSPropertyParserHelpers::ConsumeFunction(range_copy);

  double x1, y1, x2, y2;
  if (CSSPropertyParserHelpers::ConsumeNumberRaw(args, x1) && x1 >= 0 &&
      x1 <= 1 &&
      CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
      CSSPropertyParserHelpers::ConsumeNumberRaw(args, y1) &&
      CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
      CSSPropertyParserHelpers::ConsumeNumberRaw(args, x2) && x2 >= 0 &&
      x2 <= 1 &&
      CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
      CSSPropertyParserHelpers::ConsumeNumberRaw(args, y2) && args.AtEnd()) {
    range = range_copy;
    return CSSCubicBezierTimingFunctionValue::Create(x1, y1, x2, y2);
  }

  return nullptr;
}

CSSIdentifierValue* ConsumeBorderImageRepeatKeyword(
    CSSParserTokenRange& range) {
  return CSSPropertyParserHelpers::ConsumeIdent<CSSValueStretch, CSSValueRepeat,
                                                CSSValueSpace, CSSValueRound>(
      range);
}

bool ConsumeCSSValueId(CSSParserTokenRange& range, CSSValueID& value) {
  CSSIdentifierValue* keyword = CSSPropertyParserHelpers::ConsumeIdent(range);
  if (!keyword || !range.AtEnd())
    return false;
  value = keyword->GetValueID();
  return true;
}

CSSValue* ConsumeShapeRadius(CSSParserTokenRange& args,
                             CSSParserMode css_parser_mode) {
  if (CSSPropertyParserHelpers::IdentMatches<CSSValueClosestSide,
                                             CSSValueFarthestSide>(
          args.Peek().Id()))
    return CSSPropertyParserHelpers::ConsumeIdent(args);
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      args, css_parser_mode, kValueRangeNonNegative);
}

CSSBasicShapeCircleValue* ConsumeBasicShapeCircle(
    CSSParserTokenRange& args,
    const CSSParserContext& context) {
  // spec: https://drafts.csswg.org/css-shapes/#supported-basic-shapes
  // circle( [<shape-radius>]? [at <position>]? )
  CSSBasicShapeCircleValue* shape = CSSBasicShapeCircleValue::Create();
  if (CSSValue* radius = ConsumeShapeRadius(args, context.Mode()))
    shape->SetRadius(radius);
  if (CSSPropertyParserHelpers::ConsumeIdent<CSSValueAt>(args)) {
    CSSValue* center_x = nullptr;
    CSSValue* center_y = nullptr;
    if (!ConsumePosition(
            args, context, CSSPropertyParserHelpers::UnitlessQuirk::kForbid,
            WebFeature::kThreeValuedPositionBasicShape, center_x, center_y))
      return nullptr;
    shape->SetCenterX(center_x);
    shape->SetCenterY(center_y);
  }
  return shape;
}

CSSBasicShapeEllipseValue* ConsumeBasicShapeEllipse(
    CSSParserTokenRange& args,
    const CSSParserContext& context) {
  // spec: https://drafts.csswg.org/css-shapes/#supported-basic-shapes
  // ellipse( [<shape-radius>{2}]? [at <position>]? )
  CSSBasicShapeEllipseValue* shape = CSSBasicShapeEllipseValue::Create();
  WebFeature feature = WebFeature::kBasicShapeEllipseNoRadius;
  if (CSSValue* radius_x = ConsumeShapeRadius(args, context.Mode())) {
    shape->SetRadiusX(radius_x);
    feature = WebFeature::kBasicShapeEllipseOneRadius;
    if (CSSValue* radius_y = ConsumeShapeRadius(args, context.Mode())) {
      shape->SetRadiusY(radius_y);
      feature = WebFeature::kBasicShapeEllipseTwoRadius;
    }
  }
  if (CSSPropertyParserHelpers::ConsumeIdent<CSSValueAt>(args)) {
    CSSValue* center_x = nullptr;
    CSSValue* center_y = nullptr;
    if (!ConsumePosition(
            args, context, CSSPropertyParserHelpers::UnitlessQuirk::kForbid,
            WebFeature::kThreeValuedPositionBasicShape, center_x, center_y))
      return nullptr;
    shape->SetCenterX(center_x);
    shape->SetCenterY(center_y);
  }
  context.Count(feature);
  return shape;
}

CSSBasicShapePolygonValue* ConsumeBasicShapePolygon(
    CSSParserTokenRange& args,
    const CSSParserContext& context) {
  CSSBasicShapePolygonValue* shape = CSSBasicShapePolygonValue::Create();
  if (CSSPropertyParserHelpers::IdentMatches<CSSValueEvenodd, CSSValueNonzero>(
          args.Peek().Id())) {
    shape->SetWindRule(args.ConsumeIncludingWhitespace().Id() == CSSValueEvenodd
                           ? RULE_EVENODD
                           : RULE_NONZERO);
    if (!CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args))
      return nullptr;
  }

  do {
    CSSPrimitiveValue* x_length =
        CSSPropertyParserHelpers::ConsumeLengthOrPercent(args, context.Mode(),
                                                         kValueRangeAll);
    if (!x_length)
      return nullptr;
    CSSPrimitiveValue* y_length =
        CSSPropertyParserHelpers::ConsumeLengthOrPercent(args, context.Mode(),
                                                         kValueRangeAll);
    if (!y_length)
      return nullptr;
    shape->AppendPoint(x_length, y_length);
  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args));
  return shape;
}

CSSBasicShapeInsetValue* ConsumeBasicShapeInset(
    CSSParserTokenRange& args,
    const CSSParserContext& context) {
  CSSBasicShapeInsetValue* shape = CSSBasicShapeInsetValue::Create();
  CSSPrimitiveValue* top = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      args, context.Mode(), kValueRangeAll);
  if (!top)
    return nullptr;
  CSSPrimitiveValue* right = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      args, context.Mode(), kValueRangeAll);
  CSSPrimitiveValue* bottom = nullptr;
  CSSPrimitiveValue* left = nullptr;
  if (right) {
    bottom = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
        args, context.Mode(), kValueRangeAll);
    if (bottom) {
      left = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
          args, context.Mode(), kValueRangeAll);
    }
  }
  if (left)
    shape->UpdateShapeSize4Values(top, right, bottom, left);
  else if (bottom)
    shape->UpdateShapeSize3Values(top, right, bottom);
  else if (right)
    shape->UpdateShapeSize2Values(top, right);
  else
    shape->UpdateShapeSize1Value(top);

  if (CSSPropertyParserHelpers::ConsumeIdent<CSSValueRound>(args)) {
    CSSValue* horizontal_radii[4] = {nullptr};
    CSSValue* vertical_radii[4] = {nullptr};
    if (!ConsumeRadii(horizontal_radii, vertical_radii, args, context.Mode(),
                      false))
      return nullptr;
    shape->SetTopLeftRadius(
        CSSValuePair::Create(horizontal_radii[0], vertical_radii[0],
                             CSSValuePair::kDropIdenticalValues));
    shape->SetTopRightRadius(
        CSSValuePair::Create(horizontal_radii[1], vertical_radii[1],
                             CSSValuePair::kDropIdenticalValues));
    shape->SetBottomRightRadius(
        CSSValuePair::Create(horizontal_radii[2], vertical_radii[2],
                             CSSValuePair::kDropIdenticalValues));
    shape->SetBottomLeftRadius(
        CSSValuePair::Create(horizontal_radii[3], vertical_radii[3],
                             CSSValuePair::kDropIdenticalValues));
  }
  return shape;
}

bool ConsumeNumbers(CSSParserTokenRange& args,
                    CSSFunctionValue*& transform_value,
                    unsigned number_of_arguments) {
  do {
    CSSValue* parsed_value =
        CSSPropertyParserHelpers::ConsumeNumber(args, kValueRangeAll);
    if (!parsed_value)
      return false;
    transform_value->Append(*parsed_value);
    if (--number_of_arguments &&
        !CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
      return false;
    }
  } while (number_of_arguments);
  return true;
}

bool ConsumePerspective(CSSParserTokenRange& args,
                        const CSSParserContext& context,
                        CSSFunctionValue*& transform_value,
                        bool use_legacy_parsing) {
  CSSPrimitiveValue* parsed_value = CSSPropertyParserHelpers::ConsumeLength(
      args, context.Mode(), kValueRangeNonNegative);
  if (!parsed_value && use_legacy_parsing) {
    double perspective;
    if (!CSSPropertyParserHelpers::ConsumeNumberRaw(args, perspective) ||
        perspective < 0) {
      return false;
    }
    context.Count(WebFeature::kUnitlessPerspectiveInTransformProperty);
    parsed_value = CSSPrimitiveValue::Create(
        perspective, CSSPrimitiveValue::UnitType::kPixels);
  }
  if (!parsed_value)
    return false;
  transform_value->Append(*parsed_value);
  return true;
}

bool ConsumeTranslate3d(CSSParserTokenRange& args,
                        CSSParserMode css_parser_mode,
                        CSSFunctionValue*& transform_value) {
  unsigned number_of_arguments = 2;
  CSSValue* parsed_value = nullptr;
  do {
    parsed_value = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
        args, css_parser_mode, kValueRangeAll);
    if (!parsed_value)
      return false;
    transform_value->Append(*parsed_value);
    if (!CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args))
      return false;
  } while (--number_of_arguments);
  parsed_value = CSSPropertyParserHelpers::ConsumeLength(args, css_parser_mode,
                                                         kValueRangeAll);
  if (!parsed_value)
    return false;
  transform_value->Append(*parsed_value);
  return true;
}

CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
                                const CSSParserContext& context,
                                bool use_legacy_parsing) {
  CSSValueID function_id = range.Peek().FunctionId();
  if (function_id == CSSValueInvalid)
    return nullptr;
  CSSParserTokenRange args = CSSPropertyParserHelpers::ConsumeFunction(range);
  if (args.AtEnd())
    return nullptr;
  CSSFunctionValue* transform_value = CSSFunctionValue::Create(function_id);
  CSSValue* parsed_value = nullptr;
  switch (function_id) {
    case CSSValueRotate:
    case CSSValueRotateX:
    case CSSValueRotateY:
    case CSSValueRotateZ:
    case CSSValueSkewX:
    case CSSValueSkewY:
    case CSSValueSkew:
      parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
          args, &context, WebFeature::kUnitlessZeroAngleTransform);
      if (!parsed_value)
        return nullptr;
      if (function_id == CSSValueSkew &&
          CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
        transform_value->Append(*parsed_value);
        parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
            args, &context, WebFeature::kUnitlessZeroAngleTransform);
        if (!parsed_value)
          return nullptr;
      }
      break;
    case CSSValueScaleX:
    case CSSValueScaleY:
    case CSSValueScaleZ:
    case CSSValueScale:
      parsed_value =
          CSSPropertyParserHelpers::ConsumeNumber(args, kValueRangeAll);
      if (!parsed_value)
        return nullptr;
      if (function_id == CSSValueScale &&
          CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
        transform_value->Append(*parsed_value);
        parsed_value =
            CSSPropertyParserHelpers::ConsumeNumber(args, kValueRangeAll);
        if (!parsed_value)
          return nullptr;
      }
      break;
    case CSSValuePerspective:
      if (!ConsumePerspective(args, context, transform_value,
                              use_legacy_parsing)) {
        return nullptr;
      }
      break;
    case CSSValueTranslateX:
    case CSSValueTranslateY:
    case CSSValueTranslate:
      parsed_value = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
          args, context.Mode(), kValueRangeAll);
      if (!parsed_value)
        return nullptr;
      if (function_id == CSSValueTranslate &&
          CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
        transform_value->Append(*parsed_value);
        parsed_value = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
            args, context.Mode(), kValueRangeAll);
        if (!parsed_value)
          return nullptr;
      }
      break;
    case CSSValueTranslateZ:
      parsed_value = CSSPropertyParserHelpers::ConsumeLength(
          args, context.Mode(), kValueRangeAll);
      break;
    case CSSValueMatrix:
    case CSSValueMatrix3d:
      if (!ConsumeNumbers(args, transform_value,
                          (function_id == CSSValueMatrix3d) ? 16 : 6)) {
        return nullptr;
      }
      break;
    case CSSValueScale3d:
      if (!ConsumeNumbers(args, transform_value, 3))
        return nullptr;
      break;
    case CSSValueRotate3d:
      if (!ConsumeNumbers(args, transform_value, 3) ||
          !CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
        return nullptr;
      }
      parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
          args, &context, WebFeature::kUnitlessZeroAngleTransform);
      if (!parsed_value)
        return nullptr;
      break;
    case CSSValueTranslate3d:
      if (!ConsumeTranslate3d(args, context.Mode(), transform_value))
        return nullptr;
      break;
    default:
      return nullptr;
  }
  if (parsed_value)
    transform_value->Append(*parsed_value);
  if (!args.AtEnd())
    return nullptr;
  return transform_value;
}

}  // namespace

bool IsSelfPositionKeyword(CSSValueID id) {
  return CSSPropertyParserHelpers::IdentMatches<
      CSSValueStart, CSSValueEnd, CSSValueCenter, CSSValueSelfStart,
      CSSValueSelfEnd, CSSValueFlexStart, CSSValueFlexEnd>(id);
}

bool IsSelfPositionOrLeftOrRightKeyword(CSSValueID id) {
  return IsSelfPositionKeyword(id) || IsLeftOrRightKeyword(id);
}

bool IsContentPositionKeyword(CSSValueID id) {
  return CSSPropertyParserHelpers::IdentMatches<
      CSSValueStart, CSSValueEnd, CSSValueCenter, CSSValueFlexStart,
      CSSValueFlexEnd>(id);
}

bool IsContentPositionOrLeftOrRightKeyword(CSSValueID id) {
  return IsContentPositionKeyword(id) || IsLeftOrRightKeyword(id);
}

CSSValue* ConsumeSelfPositionOverflowPosition(
    CSSParserTokenRange& range,
    IsPositionKeyword is_position_keyword) {
  DCHECK(is_position_keyword);
  CSSValueID id = range.Peek().Id();
  if (IsAutoOrNormalOrStretch(id))
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  if (IsBaselineKeyword(id))
    return ConsumeBaselineKeyword(range);

  CSSIdentifierValue* overflow_position = ConsumeOverflowPositionKeyword(range);
  if (!is_position_keyword(range.Peek().Id()))
    return nullptr;
  CSSIdentifierValue* self_position =
      CSSPropertyParserHelpers::ConsumeIdent(range);
  if (overflow_position) {
    return CSSValuePair::Create(overflow_position, self_position,
                                CSSValuePair::kDropIdenticalValues);
  }
  return self_position;
}

CSSValue* ConsumeSimplifiedItemPosition(CSSParserTokenRange& range,
                                        IsPositionKeyword is_position_keyword) {
  DCHECK(is_position_keyword);
  CSSValueID id = range.Peek().Id();
  if (IsAutoOrNormalOrStretch(id) || is_position_keyword(id))
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  if (IsBaselineKeyword(id))
    return ConsumeBaselineKeyword(range);

  return nullptr;
}

CSSValue* ConsumeContentDistributionOverflowPosition(
    CSSParserTokenRange& range,
    IsPositionKeyword is_position_keyword) {
  DCHECK(is_position_keyword);
  CSSValueID id = range.Peek().Id();
  if (CSSPropertyParserHelpers::IdentMatches<CSSValueNormal>(id)) {
    return CSSContentDistributionValue::Create(
        CSSValueInvalid, range.ConsumeIncludingWhitespace().Id(),
        CSSValueInvalid);
  }

  if (IsBaselineKeyword(id)) {
    CSSValue* baseline = ConsumeBaselineKeyword(range);
    if (!baseline)
      return nullptr;
    return CSSContentDistributionValue::Create(
        CSSValueInvalid, GetBaselineKeyword(*baseline), CSSValueInvalid);
  }

  if (IsContentDistributionKeyword(id)) {
    return CSSContentDistributionValue::Create(
        range.ConsumeIncludingWhitespace().Id(), CSSValueInvalid,
        CSSValueInvalid);
  }

  CSSValueID overflow = IsOverflowKeyword(id)
                            ? range.ConsumeIncludingWhitespace().Id()
                            : CSSValueInvalid;
  if (is_position_keyword(range.Peek().Id())) {
    return CSSContentDistributionValue::Create(
        CSSValueInvalid, range.ConsumeIncludingWhitespace().Id(), overflow);
  }

  return nullptr;
}

CSSValue* ConsumeSimplifiedContentPosition(
    CSSParserTokenRange& range,
    IsPositionKeyword is_position_keyword) {
  DCHECK(is_position_keyword);
  CSSValueID id = range.Peek().Id();
  if (CSSPropertyParserHelpers::IdentMatches<CSSValueNormal>(id) ||
      is_position_keyword(id)) {
    return CSSContentDistributionValue::Create(
        CSSValueInvalid, range.ConsumeIncludingWhitespace().Id(),
        CSSValueInvalid);
  }

  if (IsBaselineKeyword(id)) {
    CSSValue* baseline = ConsumeBaselineKeyword(range);
    if (!baseline)
      return nullptr;
    return CSSContentDistributionValue::Create(
        CSSValueInvalid, GetBaselineKeyword(*baseline), CSSValueInvalid);
  }

  if (IsContentDistributionKeyword(id)) {
    return CSSContentDistributionValue::Create(
        range.ConsumeIncludingWhitespace().Id(), CSSValueInvalid,
        CSSValueInvalid);
  }

  return nullptr;
}

CSSValue* ConsumeAnimationIterationCount(CSSParserTokenRange& range) {
  if (range.Peek().Id() == CSSValueInfinite)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumeNumber(range, kValueRangeNonNegative);
}

CSSValue* ConsumeAnimationName(CSSParserTokenRange& range,
                               const CSSParserContext& context,
                               bool allow_quoted_name) {
  if (range.Peek().Id() == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  if (allow_quoted_name && range.Peek().GetType() == kStringToken) {
    // Legacy support for strings in prefixed animations.
    context.Count(WebFeature::kQuotedAnimationName);

    const CSSParserToken& token = range.ConsumeIncludingWhitespace();
    if (EqualIgnoringASCIICase(token.Value(), "none"))
      return CSSIdentifierValue::Create(CSSValueNone);
    return CSSCustomIdentValue::Create(token.Value().ToAtomicString());
  }

  return CSSPropertyParserHelpers::ConsumeCustomIdent(range);
}

CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range) {
  CSSValueID id = range.Peek().Id();
  if (id == CSSValueEase || id == CSSValueLinear || id == CSSValueEaseIn ||
      id == CSSValueEaseOut || id == CSSValueEaseInOut ||
      id == CSSValueStepStart || id == CSSValueStepEnd ||
      id == CSSValueStepMiddle)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  CSSValueID function = range.Peek().FunctionId();
  if (function == CSSValueSteps)
    return ConsumeSteps(range);
  if (RuntimeEnabledFeatures::FramesTimingFunctionEnabled() &&
      function == CSSValueFrames) {
    return ConsumeFrames(range);
  }
  if (function == CSSValueCubicBezier)
    return ConsumeCubicBezier(range);
  return nullptr;
}

bool ConsumeAnimationShorthand(
    const StylePropertyShorthand& shorthand,
    HeapVector<Member<CSSValueList>, kMaxNumAnimationLonghands>& longhands,
    ConsumeAnimationItemValue consumeLonghandItem,
    CSSParserTokenRange& range,
    const CSSParserContext& context,
    bool use_legacy_parsing) {
  DCHECK(consumeLonghandItem);
  const unsigned longhand_count = shorthand.length();
  DCHECK_LE(longhand_count, kMaxNumAnimationLonghands);

  for (size_t i = 0; i < longhand_count; ++i)
    longhands[i] = CSSValueList::CreateCommaSeparated();

  do {
    bool parsed_longhand[kMaxNumAnimationLonghands] = {false};
    do {
      bool found_property = false;
      for (size_t i = 0; i < longhand_count; ++i) {
        if (parsed_longhand[i])
          continue;

        CSSValue* value =
            consumeLonghandItem(shorthand.properties()[i]->PropertyID(), range,
                                context, use_legacy_parsing);
        if (value) {
          parsed_longhand[i] = true;
          found_property = true;
          longhands[i]->Append(*value);
          break;
        }
      }
      if (!found_property)
        return false;
    } while (!range.AtEnd() && range.Peek().GetType() != kCommaToken);

    // TODO(timloh): This will make invalid longhands, see crbug.com/386459
    for (size_t i = 0; i < longhand_count; ++i) {
      if (!parsed_longhand[i])
        longhands[i]->Append(*CSSInitialValue::Create());
      parsed_longhand[i] = false;
    }
  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));

  return true;
}

void AddBackgroundValue(CSSValue*& list, CSSValue* value) {
  if (list) {
    if (!list->IsBaseValueList()) {
      CSSValue* first_value = list;
      list = CSSValueList::CreateCommaSeparated();
      ToCSSValueList(list)->Append(*first_value);
    }
    ToCSSValueList(list)->Append(*value);
  } else {
    // To conserve memory we don't actually wrap a single value in a list.
    list = value;
  }
}

CSSValue* ConsumeBackgroundAttachment(CSSParserTokenRange& range) {
  return CSSPropertyParserHelpers::ConsumeIdent<CSSValueScroll, CSSValueFixed,
                                                CSSValueLocal>(range);
}

CSSValue* ConsumeBackgroundBlendMode(CSSParserTokenRange& range) {
  CSSValueID id = range.Peek().Id();
  if (id == CSSValueNormal || id == CSSValueOverlay ||
      (id >= CSSValueMultiply && id <= CSSValueLuminosity))
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return nullptr;
}

CSSValue* ConsumeBackgroundBox(CSSParserTokenRange& range) {
  return CSSPropertyParserHelpers::ConsumeIdent<
      CSSValueBorderBox, CSSValuePaddingBox, CSSValueContentBox>(range);
}

CSSValue* ConsumeBackgroundComposite(CSSParserTokenRange& range) {
  return CSSPropertyParserHelpers::ConsumeIdentRange(range, CSSValueClear,
                                                     CSSValuePlusLighter);
}

CSSValue* ConsumeMaskSourceType(CSSParserTokenRange& range) {
  DCHECK(RuntimeEnabledFeatures::CSSMaskSourceTypeEnabled());
  return CSSPropertyParserHelpers::ConsumeIdent<CSSValueAuto, CSSValueAlpha,
                                                CSSValueLuminance>(range);
}

CSSValue* ConsumeBackgroundSize(CSSParserTokenRange& range,
                                CSSParserMode css_parser_mode,
                                ParsingStyle parsing_style) {
  if (CSSPropertyParserHelpers::IdentMatches<CSSValueContain, CSSValueCover>(
          range.Peek().Id())) {
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  }

  CSSValue* horizontal =
      CSSPropertyParserHelpers::ConsumeIdent<CSSValueAuto>(range);
  if (!horizontal) {
    horizontal = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
        range, css_parser_mode, kValueRangeAll,
        CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
  }

  CSSValue* vertical = nullptr;
  if (!range.AtEnd()) {
    if (range.Peek().Id() == CSSValueAuto) {  // `auto' is the default
      range.ConsumeIncludingWhitespace();
    } else {
      vertical = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
          range, css_parser_mode, kValueRangeAll,
          CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
    }
  } else if (parsing_style == ParsingStyle::kLegacy) {
    // Legacy syntax: "-webkit-background-size: 10px" is equivalent to
    // "background-size: 10px 10px".
    vertical = horizontal;
  }
  if (!vertical)
    return horizontal;
  return CSSValuePair::Create(horizontal, vertical,
                              CSSValuePair::kKeepIdenticalValues);
}

bool ConsumeBackgroundPosition(CSSParserTokenRange& range,
                               const CSSParserContext& context,
                               CSSPropertyParserHelpers::UnitlessQuirk unitless,
                               CSSValue*& result_x,
                               CSSValue*& result_y) {
  do {
    CSSValue* position_x = nullptr;
    CSSValue* position_y = nullptr;
    if (!CSSPropertyParserHelpers::ConsumePosition(
            range, context, unitless,
            WebFeature::kThreeValuedPositionBackground, position_x, position_y))
      return false;
    AddBackgroundValue(result_x, position_x);
    AddBackgroundValue(result_y, position_y);
  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
  return true;
}

CSSValue* ConsumePrefixedBackgroundBox(CSSParserTokenRange& range,
                                       AllowTextValue allow_text_value) {
  // The values 'border', 'padding' and 'content' are deprecated and do not
  // apply to the version of the property that has the -webkit- prefix removed.
  if (CSSValue* value = CSSPropertyParserHelpers::ConsumeIdentRange(
          range, CSSValueBorder, CSSValuePaddingBox))
    return value;
  if (allow_text_value == AllowTextValue::kAllow &&
      range.Peek().Id() == CSSValueText)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return nullptr;
}

CSSValue* ParseBackgroundBox(CSSParserTokenRange& range,
                             const CSSParserLocalContext& local_context) {
  // This is legacy behavior that does not match spec, see crbug.com/604023
  if (local_context.UseAliasParsing()) {
    return CSSPropertyParserHelpers::ConsumeCommaSeparatedList(
        ConsumePrefixedBackgroundBox, range, AllowTextValue::kAllow);
  }
  return CSSPropertyParserHelpers::ConsumeCommaSeparatedList(
      ConsumeBackgroundBox, range);
}

CSSValue* ParseBackgroundOrMaskSize(
    CSSParserTokenRange& range,
    const CSSParserContext& context,
    const CSSParserLocalContext& local_context) {
  return CSSPropertyParserHelpers::ConsumeCommaSeparatedList(
      ConsumeBackgroundSize, range, context.Mode(),
      local_context.UseAliasParsing() ? ParsingStyle::kLegacy
                                      : ParsingStyle::kNotLegacy);
}

namespace {

CSSValue* ConsumeBackgroundComponent(CSSPropertyID resolved_property,
                                     CSSParserTokenRange& range,
                                     const CSSParserContext& context) {
  switch (resolved_property) {
    case CSSPropertyBackgroundClip:
      return ConsumeBackgroundBox(range);
    case CSSPropertyBackgroundAttachment:
      return ConsumeBackgroundAttachment(range);
    case CSSPropertyBackgroundOrigin:
      return ConsumeBackgroundBox(range);
    case CSSPropertyBackgroundImage:
    case CSSPropertyWebkitMaskImage:
      return CSSPropertyParserHelpers::ConsumeImageOrNone(range, &context);
    case CSSPropertyBackgroundPositionX:
    case CSSPropertyWebkitMaskPositionX:
      return ConsumePositionLonghand<CSSValueLeft, CSSValueRight>(
          range, context.Mode());
    case CSSPropertyBackgroundPositionY:
    case CSSPropertyWebkitMaskPositionY:
      return ConsumePositionLonghand<CSSValueTop, CSSValueBottom>(
          range, context.Mode());
    case CSSPropertyBackgroundSize:
    case CSSPropertyWebkitMaskSize:
      return ConsumeBackgroundSize(range, context.Mode(),
                                   ParsingStyle::kNotLegacy);
    case CSSPropertyBackgroundColor:
      return CSSPropertyParserHelpers::ConsumeColor(range, context.Mode());
    case CSSPropertyWebkitMaskClip:
      return ConsumePrefixedBackgroundBox(range, AllowTextValue::kAllow);
    case CSSPropertyWebkitMaskOrigin:
      return ConsumePrefixedBackgroundBox(range, AllowTextValue::kForbid);
    default:
      break;
  };
  return nullptr;
}

}  // namespace

// Note: this assumes y properties (e.g. background-position-y) follow the x
// properties in the shorthand array.
// TODO(jiameng): this is used by background and -webkit-mask, hence we
// need local_context as an input that contains shorthand id. We will consider
// remove local_context as an input after
//   (i). StylePropertyShorthand is refactored and
//   (ii). we split parsing logic of background and -webkit-mask into
//   different property classes.
bool ParseBackgroundOrMask(bool important,
                           CSSParserTokenRange& range,
                           const CSSParserContext& context,
                           const CSSParserLocalContext& local_context,
                           HeapVector<CSSPropertyValue, 256>& properties) {
  CSSPropertyID shorthand_id = local_context.CurrentShorthand();
  DCHECK(shorthand_id == CSSPropertyBackground ||
         shorthand_id == CSSPropertyWebkitMask);
  const StylePropertyShorthand& shorthand =
      shorthand_id == CSSPropertyBackground ? backgroundShorthand()
                                            : webkitMaskShorthand();

  const unsigned longhand_count = shorthand.length();
  CSSValue* longhands[10] = {nullptr};
  DCHECK_LE(longhand_count, 10u);

  bool implicit = false;
  do {
    bool parsed_longhand[10] = {false};
    CSSValue* origin_value = nullptr;
    do {
      bool found_property = false;
      for (size_t i = 0; i < longhand_count; ++i) {
        if (parsed_longhand[i])
          continue;

        CSSValue* value = nullptr;
        CSSValue* value_y = nullptr;
        const CSSProperty& property = *shorthand.properties()[i];
        if (property.IDEquals(CSSPropertyBackgroundRepeatX) ||
            property.IDEquals(CSSPropertyWebkitMaskRepeatX)) {
          ConsumeRepeatStyleComponent(range, value, value_y, implicit);
        } else if (property.IDEquals(CSSPropertyBackgroundPositionX) ||
                   property.IDEquals(CSSPropertyWebkitMaskPositionX)) {
          if (!CSSPropertyParserHelpers::ConsumePosition(
                  range, context,
                  CSSPropertyParserHelpers::UnitlessQuirk::kForbid,
                  WebFeature::kThreeValuedPositionBackground, value, value_y))
            continue;
        } else if (property.IDEquals(CSSPropertyBackgroundSize) ||
                   property.IDEquals(CSSPropertyWebkitMaskSize)) {
          if (!CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range))
            continue;
          value = ConsumeBackgroundSize(range, context.Mode(),
                                        ParsingStyle::kNotLegacy);
          if (!value ||
              !parsed_longhand[i - 1])  // Position must have been
                                        // parsed in the current layer.
          {
            return false;
          }
        } else if (property.IDEquals(CSSPropertyBackgroundPositionY) ||
                   property.IDEquals(CSSPropertyBackgroundRepeatY) ||
                   property.IDEquals(CSSPropertyWebkitMaskPositionY) ||
                   property.IDEquals(CSSPropertyWebkitMaskRepeatY)) {
          continue;
        } else {
          value =
              ConsumeBackgroundComponent(property.PropertyID(), range, context);
        }
        if (value) {
          if (property.IDEquals(CSSPropertyBackgroundOrigin) ||
              property.IDEquals(CSSPropertyWebkitMaskOrigin)) {
            origin_value = value;
          }
          parsed_longhand[i] = true;
          found_property = true;
          AddBackgroundValue(longhands[i], value);
          if (value_y) {
            parsed_longhand[i + 1] = true;
            AddBackgroundValue(longhands[i + 1], value_y);
          }
        }
      }
      if (!found_property)
        return false;
    } while (!range.AtEnd() && range.Peek().GetType() != kCommaToken);

    // TODO(timloh): This will make invalid longhands, see crbug.com/386459
    for (size_t i = 0; i < longhand_count; ++i) {
      const CSSProperty& property = *shorthand.properties()[i];
      if (property.IDEquals(CSSPropertyBackgroundColor) && !range.AtEnd()) {
        if (parsed_longhand[i])
          return false;  // Colors are only allowed in the last layer.
        continue;
      }
      if ((property.IDEquals(CSSPropertyBackgroundClip) ||
           property.IDEquals(CSSPropertyWebkitMaskClip)) &&
          !parsed_longhand[i] && origin_value) {
        AddBackgroundValue(longhands[i], origin_value);
        continue;
      }
      if (!parsed_longhand[i]) {
        AddBackgroundValue(longhands[i], CSSInitialValue::Create());
      }
    }
  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
  if (!range.AtEnd())
    return false;

  for (size_t i = 0; i < longhand_count; ++i) {
    const CSSProperty& property = *shorthand.properties()[i];
    if (property.IDEquals(CSSPropertyBackgroundSize) && longhands[i] &&
        context.UseLegacyBackgroundSizeShorthandBehavior())
      continue;
    CSSPropertyParserHelpers::AddProperty(
        property.PropertyID(), shorthand.id(), *longhands[i], important,
        implicit ? CSSPropertyParserHelpers::IsImplicitProperty::kImplicit
                 : CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit,
        properties);
  }
  return true;
}

bool ConsumeRepeatStyleComponent(CSSParserTokenRange& range,
                                 CSSValue*& value1,
                                 CSSValue*& value2,
                                 bool& implicit) {
  if (CSSPropertyParserHelpers::ConsumeIdent<CSSValueRepeatX>(range)) {
    value1 = CSSIdentifierValue::Create(CSSValueRepeat);
    value2 = CSSIdentifierValue::Create(CSSValueNoRepeat);
    implicit = true;
    return true;
  }
  if (CSSPropertyParserHelpers::ConsumeIdent<CSSValueRepeatY>(range)) {
    value1 = CSSIdentifierValue::Create(CSSValueNoRepeat);
    value2 = CSSIdentifierValue::Create(CSSValueRepeat);
    implicit = true;
    return true;
  }
  value1 = CSSPropertyParserHelpers::ConsumeIdent<
      CSSValueRepeat, CSSValueNoRepeat, CSSValueRound, CSSValueSpace>(range);
  if (!value1)
    return false;

  value2 = CSSPropertyParserHelpers::ConsumeIdent<
      CSSValueRepeat, CSSValueNoRepeat, CSSValueRound, CSSValueSpace>(range);
  if (!value2) {
    value2 = value1;
    implicit = true;
  }
  return true;
}

bool ConsumeRepeatStyle(CSSParserTokenRange& range,
                        CSSValue*& result_x,
                        CSSValue*& result_y,
                        bool& implicit) {
  do {
    CSSValue* repeat_x = nullptr;
    CSSValue* repeat_y = nullptr;
    if (!ConsumeRepeatStyleComponent(range, repeat_x, repeat_y, implicit))
      return false;
    AddBackgroundValue(result_x, repeat_x);
    AddBackgroundValue(result_y, repeat_y);
  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
  return true;
}

CSSValue* ConsumeWebkitBorderImage(CSSParserTokenRange& range,
                                   const CSSParserContext& context) {
  CSSValue* source = nullptr;
  CSSValue* slice = nullptr;
  CSSValue* width = nullptr;
  CSSValue* outset = nullptr;
  CSSValue* repeat = nullptr;
  if (ConsumeBorderImageComponents(range, context, source, slice, width, outset,
                                   repeat, DefaultFill::kFill))
    return CreateBorderImageValue(source, slice, width, outset, repeat);
  return nullptr;
}

bool ConsumeBorderImageComponents(CSSParserTokenRange& range,
                                  const CSSParserContext& context,
                                  CSSValue*& source,
                                  CSSValue*& slice,
                                  CSSValue*& width,
                                  CSSValue*& outset,
                                  CSSValue*& repeat,
                                  DefaultFill default_fill) {
  do {
    if (!source) {
      source = CSSPropertyParserHelpers::ConsumeImageOrNone(range, &context);
      if (source)
        continue;
    }
    if (!repeat) {
      repeat = ConsumeBorderImageRepeat(range);
      if (repeat)
        continue;
    }
    if (!slice) {
      slice = ConsumeBorderImageSlice(range, default_fill);
      if (slice) {
        DCHECK(!width);
        DCHECK(!outset);
        if (CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range)) {
          width = ConsumeBorderImageWidth(range);
          if (CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(
                  range)) {
            outset = ConsumeBorderImageOutset(range);
            if (!outset)
              return false;
          } else if (!width) {
            return false;
          }
        }
      } else {
        return false;
      }
    } else {
      return false;
    }
  } while (!range.AtEnd());
  return true;
}

CSSValue* ConsumeBorderImageRepeat(CSSParserTokenRange& range) {
  CSSIdentifierValue* horizontal = ConsumeBorderImageRepeatKeyword(range);
  if (!horizontal)
    return nullptr;
  CSSIdentifierValue* vertical = ConsumeBorderImageRepeatKeyword(range);
  if (!vertical)
    vertical = horizontal;
  return CSSValuePair::Create(horizontal, vertical,
                              CSSValuePair::kDropIdenticalValues);
}

CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange& range,
                                  DefaultFill default_fill) {
  bool fill = CSSPropertyParserHelpers::ConsumeIdent<CSSValueFill>(range);
  CSSValue* slices[4] = {nullptr};

  for (size_t index = 0; index < 4; ++index) {
    CSSPrimitiveValue* value =
        CSSPropertyParserHelpers::ConsumePercent(range, kValueRangeNonNegative);
    if (!value) {
      value = CSSPropertyParserHelpers::ConsumeNumber(range,
                                                      kValueRangeNonNegative);
    }
    if (!value)
      break;
    slices[index] = value;
  }
  if (!slices[0])
    return nullptr;
  if (CSSPropertyParserHelpers::ConsumeIdent<CSSValueFill>(range)) {
    if (fill)
      return nullptr;
    fill = true;
  }
  CSSPropertyParserHelpers::Complete4Sides(slices);
  if (default_fill == DefaultFill::kFill)
    fill = true;
  return CSSBorderImageSliceValue::Create(
      CSSQuadValue::Create(slices[0], slices[1], slices[2], slices[3],
                           CSSQuadValue::kSerializeAsQuad),
      fill);
}

CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange& range) {
  CSSValue* widths[4] = {nullptr};

  CSSValue* value = nullptr;
  for (size_t index = 0; index < 4; ++index) {
    value =
        CSSPropertyParserHelpers::ConsumeNumber(range, kValueRangeNonNegative);
    if (!value) {
      value = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
          range, kHTMLStandardMode, kValueRangeNonNegative,
          CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
    }
    if (!value)
      value = CSSPropertyParserHelpers::ConsumeIdent<CSSValueAuto>(range);
    if (!value)
      break;
    widths[index] = value;
  }
  if (!widths[0])
    return nullptr;
  CSSPropertyParserHelpers::Complete4Sides(widths);
  return CSSQuadValue::Create(widths[0], widths[1], widths[2], widths[3],
                              CSSQuadValue::kSerializeAsQuad);
}

CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange& range) {
  CSSValue* outsets[4] = {nullptr};

  CSSValue* value = nullptr;
  for (size_t index = 0; index < 4; ++index) {
    value =
        CSSPropertyParserHelpers::ConsumeNumber(range, kValueRangeNonNegative);
    if (!value) {
      value = CSSPropertyParserHelpers::ConsumeLength(range, kHTMLStandardMode,
                                                      kValueRangeNonNegative);
    }
    if (!value)
      break;
    outsets[index] = value;
  }
  if (!outsets[0])
    return nullptr;
  CSSPropertyParserHelpers::Complete4Sides(outsets);
  return CSSQuadValue::Create(outsets[0], outsets[1], outsets[2], outsets[3],
                              CSSQuadValue::kSerializeAsQuad);
}

CSSValue* ParseBorderRadiusCorner(CSSParserTokenRange& range,
                                  const CSSParserContext& context) {
  CSSValue* parsed_value1 = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, context.Mode(), kValueRangeNonNegative);
  if (!parsed_value1)
    return nullptr;
  CSSValue* parsed_value2 = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, context.Mode(), kValueRangeNonNegative);
  if (!parsed_value2)
    parsed_value2 = parsed_value1;
  return CSSValuePair::Create(parsed_value1, parsed_value2,
                              CSSValuePair::kDropIdenticalValues);
}

CSSValue* ParseBorderWidthSide(CSSParserTokenRange& range,
                               const CSSParserContext& context,
                               const CSSParserLocalContext& local_context) {
  CSSPropertyID shorthand = local_context.CurrentShorthand();
  bool allow_quirky_lengths =
      IsQuirksModeBehavior(context.Mode()) &&
      (shorthand == CSSPropertyInvalid || shorthand == CSSPropertyBorderWidth);
  CSSPropertyParserHelpers::UnitlessQuirk unitless =
      allow_quirky_lengths ? CSSPropertyParserHelpers::UnitlessQuirk::kAllow
                           : CSSPropertyParserHelpers::UnitlessQuirk::kForbid;
  return ConsumeBorderWidth(range, context.Mode(), unitless);
}

CSSValue* ConsumeShadow(CSSParserTokenRange& range,
                        CSSParserMode css_parser_mode,
                        AllowInsetAndSpread inset_and_spread) {
  if (range.Peek().Id() == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumeCommaSeparatedList(
      ParseSingleShadow, range, css_parser_mode, inset_and_spread);
}

CSSShadowValue* ParseSingleShadow(CSSParserTokenRange& range,
                                  CSSParserMode css_parser_mode,
                                  AllowInsetAndSpread inset_and_spread) {
  CSSIdentifierValue* style = nullptr;
  CSSValue* color = nullptr;

  if (range.AtEnd())
    return nullptr;
  if (range.Peek().Id() == CSSValueInset) {
    if (inset_and_spread != AllowInsetAndSpread::kAllow)
      return nullptr;
    style = CSSPropertyParserHelpers::ConsumeIdent(range);
  }
  color = CSSPropertyParserHelpers::ConsumeColor(range, css_parser_mode);

  CSSPrimitiveValue* horizontal_offset =
      CSSPropertyParserHelpers::ConsumeLength(range, css_parser_mode,
                                              kValueRangeAll);
  if (!horizontal_offset)
    return nullptr;

  CSSPrimitiveValue* vertical_offset = CSSPropertyParserHelpers::ConsumeLength(
      range, css_parser_mode, kValueRangeAll);
  if (!vertical_offset)
    return nullptr;

  CSSPrimitiveValue* blur_radius = CSSPropertyParserHelpers::ConsumeLength(
      range, css_parser_mode, kValueRangeAll);
  CSSPrimitiveValue* spread_distance = nullptr;
  if (blur_radius) {
    // Blur radius must be non-negative.
    if (blur_radius->GetDoubleValue() < 0)
      return nullptr;
    if (inset_and_spread == AllowInsetAndSpread::kAllow) {
      spread_distance = CSSPropertyParserHelpers::ConsumeLength(
          range, css_parser_mode, kValueRangeAll);
    }
  }

  if (!range.AtEnd()) {
    if (!color)
      color = CSSPropertyParserHelpers::ConsumeColor(range, css_parser_mode);
    if (range.Peek().Id() == CSSValueInset) {
      if (inset_and_spread != AllowInsetAndSpread::kAllow || style)
        return nullptr;
      style = CSSPropertyParserHelpers::ConsumeIdent(range);
    }
  }
  return CSSShadowValue::Create(horizontal_offset, vertical_offset, blur_radius,
                                spread_distance, style, color);
}

CSSValue* ConsumeColumnCount(CSSParserTokenRange& range) {
  if (range.Peek().Id() == CSSValueAuto)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumePositiveInteger(range);
}

CSSValue* ConsumeColumnWidth(CSSParserTokenRange& range) {
  if (range.Peek().Id() == CSSValueAuto)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  // Always parse lengths in strict mode here, since it would be ambiguous
  // otherwise when used in the 'columns' shorthand property.
  CSSPrimitiveValue* column_width = CSSPropertyParserHelpers::ConsumeLength(
      range, kHTMLStandardMode, kValueRangeNonNegative);
  if (!column_width ||
      (!column_width->IsCalculated() && column_width->GetDoubleValue() == 0))
    return nullptr;
  return column_width;
}

bool ConsumeColumnWidthOrCount(CSSParserTokenRange& range,
                               CSSValue*& column_width,
                               CSSValue*& column_count) {
  if (range.Peek().Id() == CSSValueAuto) {
    CSSPropertyParserHelpers::ConsumeIdent(range);
    return true;
  }
  if (!column_width) {
    column_width = ConsumeColumnWidth(range);
    if (column_width)
      return true;
  }
  if (!column_count)
    column_count = ConsumeColumnCount(range);
  return column_count;
}

CSSValue* ConsumeGapLength(CSSParserTokenRange& range,
                           const CSSParserContext& context) {
  if (range.Peek().Id() == CSSValueNormal)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, context.Mode(), kValueRangeNonNegative);
}

CSSValue* ConsumeCounter(CSSParserTokenRange& range, int default_value) {
  if (range.Peek().Id() == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
  do {
    CSSCustomIdentValue* counter_name =
        CSSPropertyParserHelpers::ConsumeCustomIdent(range);
    if (!counter_name)
      return nullptr;
    int value = default_value;
    if (CSSPrimitiveValue* counter_value =
            CSSPropertyParserHelpers::ConsumeInteger(range))
      value = clampTo<int>(counter_value->GetDoubleValue());
    list->Append(*CSSValuePair::Create(
        counter_name,
        CSSPrimitiveValue::Create(value, CSSPrimitiveValue::UnitType::kInteger),
        CSSValuePair::kDropIdenticalValues));
  } while (!range.AtEnd());
  return list;
}

CSSValue* ConsumeFontSize(CSSParserTokenRange& range,
                          CSSParserMode css_parser_mode,
                          CSSPropertyParserHelpers::UnitlessQuirk unitless) {
  if (range.Peek().Id() >= CSSValueXxSmall &&
      range.Peek().Id() <= CSSValueLarger)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, css_parser_mode, kValueRangeNonNegative, unitless);
}

CSSValue* ConsumeLineHeight(CSSParserTokenRange& range,
                            CSSParserMode css_parser_mode) {
  if (range.Peek().Id() == CSSValueNormal)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  CSSPrimitiveValue* line_height =
      CSSPropertyParserHelpers::ConsumeNumber(range, kValueRangeNonNegative);
  if (line_height)
    return line_height;
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, css_parser_mode, kValueRangeNonNegative);
}

CSSValueList* ConsumeFontFamily(CSSParserTokenRange& range) {
  CSSValueList* list = CSSValueList::CreateCommaSeparated();
  do {
    CSSValue* parsed_value = ConsumeGenericFamily(range);
    if (parsed_value) {
      list->Append(*parsed_value);
    } else {
      parsed_value = ConsumeFamilyName(range);
      if (parsed_value) {
        list->Append(*parsed_value);
      } else {
        return nullptr;
      }
    }
  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
  return list;
}

CSSValue* ConsumeGenericFamily(CSSParserTokenRange& range) {
  return CSSPropertyParserHelpers::ConsumeIdentRange(range, CSSValueSerif,
                                                     CSSValueWebkitBody);
}

CSSValue* ConsumeFamilyName(CSSParserTokenRange& range) {
  if (range.Peek().GetType() == kStringToken) {
    return CSSFontFamilyValue::Create(
        range.ConsumeIncludingWhitespace().Value().ToString());
  }
  if (range.Peek().GetType() != kIdentToken)
    return nullptr;
  String family_name = ConcatenateFamilyName(range);
  if (family_name.IsNull())
    return nullptr;
  return CSSFontFamilyValue::Create(family_name);
}

String ConcatenateFamilyName(CSSParserTokenRange& range) {
  StringBuilder builder;
  bool added_space = false;
  const CSSParserToken& first_token = range.Peek();
  while (range.Peek().GetType() == kIdentToken) {
    if (!builder.IsEmpty()) {
      builder.Append(' ');
      added_space = true;
    }
    builder.Append(range.ConsumeIncludingWhitespace().Value());
  }
  if (!added_space &&
      (CSSPropertyParserHelpers::IsCSSWideKeyword(first_token.Value()) ||
       EqualIgnoringASCIICase(first_token.Value(), "default"))) {
    return String();
  }
  return builder.ToString();
}

CSSValueList* CombineToRangeListOrNull(const CSSPrimitiveValue* range_start,
                                       const CSSPrimitiveValue* range_end) {
  DCHECK(range_start);
  DCHECK(range_end);
  if (range_end->GetFloatValue() < range_start->GetFloatValue())
    return nullptr;
  CSSValueList* value_list = CSSValueList::CreateSpaceSeparated();
  value_list->Append(*range_start);
  value_list->Append(*range_end);
  return value_list;
}

bool IsAngleWithinLimits(CSSPrimitiveValue* angle) {
  constexpr float kMaxAngle = 90.0f;
  return angle->GetFloatValue() >= -kMaxAngle &&
         angle->GetFloatValue() <= kMaxAngle;
}

CSSValue* ConsumeFontStyle(CSSParserTokenRange& range,
                           const CSSParserMode& parser_mode) {
  if (range.Peek().Id() == CSSValueNormal ||
      range.Peek().Id() == CSSValueItalic)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  if (range.Peek().Id() != CSSValueOblique)
    return nullptr;

  CSSIdentifierValue* oblique_identifier =
      CSSPropertyParserHelpers::ConsumeIdent<CSSValueOblique>(range);

  CSSPrimitiveValue* start_angle =
      CSSPropertyParserHelpers::ConsumeAngle(range, nullptr, WTF::nullopt);
  if (!start_angle)
    return oblique_identifier;
  if (!IsAngleWithinLimits(start_angle))
    return nullptr;

  if (parser_mode != kCSSFontFaceRuleMode || range.AtEnd()) {
    CSSValueList* value_list = CSSValueList::CreateSpaceSeparated();
    value_list->Append(*start_angle);
    return CSSFontStyleRangeValue::Create(*oblique_identifier, *value_list);
  }

  CSSPrimitiveValue* end_angle =
      CSSPropertyParserHelpers::ConsumeAngle(range, nullptr, WTF::nullopt);
  if (!end_angle || !IsAngleWithinLimits(end_angle))
    return nullptr;

  CSSValueList* range_list = CombineToRangeListOrNull(start_angle, end_angle);
  if (!range_list)
    return nullptr;
  return CSSFontStyleRangeValue::Create(*oblique_identifier, *range_list);
}

CSSIdentifierValue* ConsumeFontStretchKeywordOnly(CSSParserTokenRange& range) {
  const CSSParserToken& token = range.Peek();
  if (token.Id() == CSSValueNormal || (token.Id() >= CSSValueUltraCondensed &&
                                       token.Id() <= CSSValueUltraExpanded))
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return nullptr;
}

CSSValue* ConsumeFontStretch(CSSParserTokenRange& range,
                             const CSSParserMode& parser_mode) {
  CSSIdentifierValue* parsed_keyword = ConsumeFontStretchKeywordOnly(range);
  if (parsed_keyword)
    return parsed_keyword;

  CSSPrimitiveValue* start_percent =
      CSSPropertyParserHelpers::ConsumePercent(range, kValueRangeNonNegative);
  if (!start_percent || start_percent->GetFloatValue() <= 0)
    return nullptr;

  // In a non-font-face context, more than one percentage is not allowed.
  if (parser_mode != kCSSFontFaceRuleMode || range.AtEnd())
    return start_percent;

  CSSPrimitiveValue* end_percent =
      CSSPropertyParserHelpers::ConsumePercent(range, kValueRangeNonNegative);
  if (!end_percent || end_percent->GetFloatValue() <= 0)
    return nullptr;

  return CombineToRangeListOrNull(start_percent, end_percent);
}

CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
                            const CSSParserMode& parser_mode) {
  const CSSParserToken& token = range.Peek();
  if (token.Id() >= CSSValueNormal && token.Id() <= CSSValueLighter)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  // Avoid consuming the first zero of font: 0/0; e.g. in the Acid3 test.  In
  // font:0/0; the first zero is the font size, the second is the line height.
  // In font: 100 0/0; we should parse the first 100 as font-weight, the 0
  // before the slash as font size. We need to peek and check the token in order
  // to avoid parsing a 0 font size as a font-weight. If we call ConsumeNumber
  // straight away without Peek, then the parsing cursor advances too far and we
  // parsed font-size as font-weight incorrectly.
  if (token.GetType() == kNumberToken &&
      (token.NumericValue() < 1 || token.NumericValue() > 1000))
    return nullptr;

  CSSPrimitiveValue* start_weight =
      CSSPropertyParserHelpers::ConsumeNumber(range, kValueRangeNonNegative);
  if (!start_weight || start_weight->GetFloatValue() < 1 ||
      start_weight->GetFloatValue() > 1000)
    return nullptr;

  // In a non-font-face context, more than one number is not allowed. Return
  // what we have. If there is trailing garbage, the AtEnd() check in
  // CSSPropertyParser::ParseValueStart will catch that.
  if (parser_mode != kCSSFontFaceRuleMode || range.AtEnd())
    return start_weight;

  CSSPrimitiveValue* end_weight =
      CSSPropertyParserHelpers::ConsumeNumber(range, kValueRangeNonNegative);
  if (!end_weight || end_weight->GetFloatValue() < 1 ||
      end_weight->GetFloatValue() > 1000)
    return nullptr;

  return CombineToRangeListOrNull(start_weight, end_weight);
}

CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange& range) {
  if (range.Peek().Id() == CSSValueNormal)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  CSSValueList* settings = CSSValueList::CreateCommaSeparated();
  do {
    CSSFontFeatureValue* font_feature_value = ConsumeFontFeatureTag(range);
    if (!font_feature_value)
      return nullptr;
    settings->Append(*font_feature_value);
  } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
  return settings;
}

CSSFontFeatureValue* ConsumeFontFeatureTag(CSSParserTokenRange& range) {
  // Feature tag name consists of 4-letter characters.
  const unsigned kTagNameLength = 4;

  const CSSParserToken& token = range.ConsumeIncludingWhitespace();
  // Feature tag name comes first
  if (token.GetType() != kStringToken)
    return nullptr;
  if (token.Value().length() != kTagNameLength)
    return nullptr;
  AtomicString tag = token.Value().ToAtomicString();
  for (unsigned i = 0; i < kTagNameLength; ++i) {
    // Limits the range of characters to 0x20-0x7E, following the tag name rules
    // defined in the OpenType specification.
    UChar character = tag[i];
    if (character < 0x20 || character > 0x7E)
      return nullptr;
  }

  int tag_value = 1;
  // Feature tag values could follow: <integer> | on | off
  if (CSSPrimitiveValue* value =
          CSSPropertyParserHelpers::ConsumeInteger(range, 0)) {
    tag_value = clampTo<int>(value->GetDoubleValue());
  } else if (range.Peek().Id() == CSSValueOn ||
             range.Peek().Id() == CSSValueOff) {
    tag_value = range.ConsumeIncludingWhitespace().Id() == CSSValueOn;
  }
  return CSSFontFeatureValue::Create(tag, tag_value);
}

CSSIdentifierValue* ConsumeFontVariantCSS21(CSSParserTokenRange& range) {
  return CSSPropertyParserHelpers::ConsumeIdent<CSSValueNormal,
                                                CSSValueSmallCaps>(range);
}

Vector<String> ParseGridTemplateAreasColumnNames(const String& grid_row_names) {
  DCHECK(!grid_row_names.IsEmpty());
  Vector<String> column_names;
  // Using StringImpl to avoid checks and indirection in every call to
  // String::operator[].
  StringImpl& text = *grid_row_names.Impl();

  StringBuilder area_name;
  for (unsigned i = 0; i < text.length(); ++i) {
    if (IsCSSSpace(text[i])) {
      if (!area_name.IsEmpty()) {
        column_names.push_back(area_name.ToString());
        area_name.Clear();
      }
      continue;
    }
    if (text[i] == '.') {
      if (area_name == ".")
        continue;
      if (!area_name.IsEmpty()) {
        column_names.push_back(area_name.ToString());
        area_name.Clear();
      }
    } else {
      if (!IsNameCodePoint(text[i]))
        return Vector<String>();
      if (area_name == ".") {
        column_names.push_back(area_name.ToString());
        area_name.Clear();
      }
    }

    area_name.Append(text[i]);
  }

  if (!area_name.IsEmpty())
    column_names.push_back(area_name.ToString());

  return column_names;
}

CSSValue* ConsumeGridBreadth(CSSParserTokenRange& range,
                             CSSParserMode css_parser_mode) {
  const CSSParserToken& token = range.Peek();
  if (CSSPropertyParserHelpers::IdentMatches<CSSValueMinContent,
                                             CSSValueMaxContent, CSSValueAuto>(
          token.Id()))
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  if (token.GetType() == kDimensionToken &&
      token.GetUnitType() == CSSPrimitiveValue::UnitType::kFraction) {
    if (range.Peek().NumericValue() < 0)
      return nullptr;
    return CSSPrimitiveValue::Create(
        range.ConsumeIncludingWhitespace().NumericValue(),
        CSSPrimitiveValue::UnitType::kFraction);
  }
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, css_parser_mode, kValueRangeNonNegative,
      CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
}

CSSValue* ConsumeFitContent(CSSParserTokenRange& range,
                            CSSParserMode css_parser_mode) {
  CSSParserTokenRange range_copy = range;
  CSSParserTokenRange args =
      CSSPropertyParserHelpers::ConsumeFunction(range_copy);
  CSSPrimitiveValue* length = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      args, css_parser_mode, kValueRangeNonNegative,
      CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
  if (!length || !args.AtEnd())
    return nullptr;
  range = range_copy;
  CSSFunctionValue* result = CSSFunctionValue::Create(CSSValueFitContent);
  result->Append(*length);
  return result;
}

bool IsGridBreadthFixedSized(const CSSValue& value) {
  if (value.IsIdentifierValue()) {
    CSSValueID value_id = ToCSSIdentifierValue(value).GetValueID();
    return !(value_id == CSSValueMinContent || value_id == CSSValueMaxContent ||
             value_id == CSSValueAuto);
  }

  if (value.IsPrimitiveValue()) {
    return !ToCSSPrimitiveValue(value).IsFlex();
  }

  NOTREACHED();
  return true;
}

bool IsGridTrackFixedSized(const CSSValue& value) {
  if (value.IsPrimitiveValue() || value.IsIdentifierValue())
    return IsGridBreadthFixedSized(value);

  DCHECK(value.IsFunctionValue());
  auto& function = ToCSSFunctionValue(value);
  if (function.FunctionType() == CSSValueFitContent)
    return false;

  const CSSValue& min_value = function.Item(0);
  const CSSValue& max_value = function.Item(1);
  return IsGridBreadthFixedSized(min_value) ||
         IsGridBreadthFixedSized(max_value);
}

CSSValue* ConsumeGridTrackSize(CSSParserTokenRange& range,
                               CSSParserMode css_parser_mode) {
  const CSSParserToken& token = range.Peek();
  if (CSSPropertyParserHelpers::IdentMatches<CSSValueAuto>(token.Id()))
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  if (token.FunctionId() == CSSValueMinmax) {
    CSSParserTokenRange range_copy = range;
    CSSParserTokenRange args =
        CSSPropertyParserHelpers::ConsumeFunction(range_copy);
    CSSValue* min_track_breadth = ConsumeGridBreadth(args, css_parser_mode);
    if (!min_track_breadth ||
        (min_track_breadth->IsPrimitiveValue() &&
         ToCSSPrimitiveValue(min_track_breadth)->IsFlex()) ||
        !CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args))
      return nullptr;
    CSSValue* max_track_breadth = ConsumeGridBreadth(args, css_parser_mode);
    if (!max_track_breadth || !args.AtEnd())
      return nullptr;
    range = range_copy;
    CSSFunctionValue* result = CSSFunctionValue::Create(CSSValueMinmax);
    result->Append(*min_track_breadth);
    result->Append(*max_track_breadth);
    return result;
  }

  if (token.FunctionId() == CSSValueFitContent)
    return ConsumeFitContent(range, css_parser_mode);

  return ConsumeGridBreadth(range, css_parser_mode);
}

CSSCustomIdentValue* ConsumeCustomIdentForGridLine(CSSParserTokenRange& range) {
  if (range.Peek().Id() == CSSValueAuto || range.Peek().Id() == CSSValueSpan ||
      range.Peek().Id() == CSSValueDefault)
    return nullptr;
  return CSSPropertyParserHelpers::ConsumeCustomIdent(range);
}

// Appends to the passed in CSSGridLineNamesValue if any, otherwise creates a
// new one.
CSSGridLineNamesValue* ConsumeGridLineNames(
    CSSParserTokenRange& range,
    CSSGridLineNamesValue* line_names = nullptr) {
  CSSParserTokenRange range_copy = range;
  if (range_copy.ConsumeIncludingWhitespace().GetType() != kLeftBracketToken)
    return nullptr;
  if (!line_names)
    line_names = CSSGridLineNamesValue::Create();
  while (CSSCustomIdentValue* line_name =
             ConsumeCustomIdentForGridLine(range_copy))
    line_names->Append(*line_name);
  if (range_copy.ConsumeIncludingWhitespace().GetType() != kRightBracketToken)
    return nullptr;
  range = range_copy;
  return line_names;
}

bool ConsumeGridTrackRepeatFunction(CSSParserTokenRange& range,
                                    CSSParserMode css_parser_mode,
                                    CSSValueList& list,
                                    bool& is_auto_repeat,
                                    bool& all_tracks_are_fixed_sized) {
  CSSParserTokenRange args = CSSPropertyParserHelpers::ConsumeFunction(range);
  // The number of repetitions for <auto-repeat> is not important at parsing
  // level because it will be computed later, let's set it to 1.
  size_t repetitions = 1;
  is_auto_repeat =
      CSSPropertyParserHelpers::IdentMatches<CSSValueAutoFill, CSSValueAutoFit>(
          args.Peek().Id());
  CSSValueList* repeated_values;
  if (is_auto_repeat) {
    repeated_values =
        CSSGridAutoRepeatValue::Create(args.ConsumeIncludingWhitespace().Id());
  } else {
    // TODO(rob.buis): a consumeIntegerRaw would be more efficient here.
    CSSPrimitiveValue* repetition =
        CSSPropertyParserHelpers::ConsumePositiveInteger(args);
    if (!repetition)
      return false;
    repetitions =
        clampTo<size_t>(repetition->GetDoubleValue(), 0, kGridMaxTracks);
    repeated_values = CSSValueList::CreateSpaceSeparated();
  }
  if (!CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args))
    return false;
  CSSGridLineNamesValue* line_names = ConsumeGridLineNames(args);
  if (line_names)
    repeated_values->Append(*line_names);

  size_t number_of_tracks = 0;
  while (!args.AtEnd()) {
    CSSValue* track_size = ConsumeGridTrackSize(args, css_parser_mode);
    if (!track_size)
      return false;
    if (all_tracks_are_fixed_sized)
      all_tracks_are_fixed_sized = IsGridTrackFixedSized(*track_size);
    repeated_values->Append(*track_size);
    ++number_of_tracks;
    line_names = ConsumeGridLineNames(args);
    if (line_names)
      repeated_values->Append(*line_names);
  }
  // We should have found at least one <track-size> or else it is not a valid
  // <track-list>.
  if (!number_of_tracks)
    return false;

  if (is_auto_repeat) {
    list.Append(*repeated_values);
  } else {
    // We clamp the repetitions to a multiple of the repeat() track list's size,
    // while staying below the max grid size.
    repetitions = std::min(repetitions, kGridMaxTracks / number_of_tracks);
    for (size_t i = 0; i < repetitions; ++i) {
      for (size_t j = 0; j < repeated_values->length(); ++j)
        list.Append(repeated_values->Item(j));
    }
  }
  return true;
}

bool ConsumeGridTemplateRowsAndAreasAndColumns(bool important,
                                               CSSParserTokenRange& range,
                                               const CSSParserContext& context,
                                               CSSValue*& template_rows,
                                               CSSValue*& template_columns,
                                               CSSValue*& template_areas) {
  DCHECK(!template_rows);
  DCHECK(!template_columns);
  DCHECK(!template_areas);

  NamedGridAreaMap grid_area_map;
  size_t row_count = 0;
  size_t column_count = 0;
  CSSValueList* template_rows_value_list = CSSValueList::CreateSpaceSeparated();

  // Persists between loop iterations so we can use the same value for
  // consecutive <line-names> values
  CSSGridLineNamesValue* line_names = nullptr;

  do {
    // Handle leading <custom-ident>*.
    bool has_previous_line_names = line_names;
    line_names = ConsumeGridLineNames(range, line_names);
    if (line_names && !has_previous_line_names)
      template_rows_value_list->Append(*line_names);

    // Handle a template-area's row.
    if (range.Peek().GetType() != kStringToken ||
        !ParseGridTemplateAreasRow(
            range.ConsumeIncludingWhitespace().Value().ToString(),
            grid_area_map, row_count, column_count))
      return false;
    ++row_count;

    // Handle template-rows's track-size.
    CSSValue* value = ConsumeGridTrackSize(range, context.Mode());
    if (!value)
      value = CSSIdentifierValue::Create(CSSValueAuto);
    template_rows_value_list->Append(*value);

    // This will handle the trailing/leading <custom-ident>* in the grammar.
    line_names = ConsumeGridLineNames(range);
    if (line_names)
      template_rows_value_list->Append(*line_names);
  } while (!range.AtEnd() && !(range.Peek().GetType() == kDelimiterToken &&
                               range.Peek().Delimiter() == '/'));

  if (!range.AtEnd()) {
    if (!CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range))
      return false;
    template_columns = ConsumeGridTrackList(
        range, context.Mode(), TrackListType::kGridTemplateNoRepeat);
    if (!template_columns || !range.AtEnd())
      return false;
  } else {
    template_columns = CSSIdentifierValue::Create(CSSValueNone);
  }

  template_rows = template_rows_value_list;
  template_areas =
      CSSGridTemplateAreasValue::Create(grid_area_map, row_count, column_count);
  return true;
}

CSSValue* ConsumeGridLine(CSSParserTokenRange& range) {
  if (range.Peek().Id() == CSSValueAuto)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  CSSIdentifierValue* span_value = nullptr;
  CSSCustomIdentValue* grid_line_name = nullptr;
  CSSPrimitiveValue* numeric_value =
      CSSPropertyParserHelpers::ConsumeInteger(range);
  if (numeric_value) {
    grid_line_name = ConsumeCustomIdentForGridLine(range);
    span_value = CSSPropertyParserHelpers::ConsumeIdent<CSSValueSpan>(range);
  } else {
    span_value = CSSPropertyParserHelpers::ConsumeIdent<CSSValueSpan>(range);
    if (span_value) {
      numeric_value = CSSPropertyParserHelpers::ConsumeInteger(range);
      grid_line_name = ConsumeCustomIdentForGridLine(range);
      if (!numeric_value)
        numeric_value = CSSPropertyParserHelpers::ConsumeInteger(range);
    } else {
      grid_line_name = ConsumeCustomIdentForGridLine(range);
      if (grid_line_name) {
        numeric_value = CSSPropertyParserHelpers::ConsumeInteger(range);
        span_value =
            CSSPropertyParserHelpers::ConsumeIdent<CSSValueSpan>(range);
        if (!span_value && !numeric_value)
          return grid_line_name;
      } else {
        return nullptr;
      }
    }
  }

  if (span_value && !numeric_value && !grid_line_name)
    return nullptr;  // "span" keyword alone is invalid.
  if (span_value && numeric_value && numeric_value->GetIntValue() < 0)
    return nullptr;  // Negative numbers are not allowed for span.
  if (numeric_value && numeric_value->GetIntValue() == 0)
    return nullptr;  // An <integer> value of zero makes the declaration
                     // invalid.

  if (numeric_value) {
    numeric_value = CSSPrimitiveValue::Create(
        clampTo(numeric_value->GetIntValue(), -kGridMaxTracks, kGridMaxTracks),
        CSSPrimitiveValue::UnitType::kInteger);
  }

  CSSValueList* values = CSSValueList::CreateSpaceSeparated();
  if (span_value)
    values->Append(*span_value);
  if (numeric_value)
    values->Append(*numeric_value);
  if (grid_line_name)
    values->Append(*grid_line_name);
  DCHECK(values->length());
  return values;
}

CSSValue* ConsumeGridTrackList(CSSParserTokenRange& range,
                               CSSParserMode css_parser_mode,
                               TrackListType track_list_type) {
  bool allow_grid_line_names = track_list_type != TrackListType::kGridAuto;
  CSSValueList* values = CSSValueList::CreateSpaceSeparated();
  CSSGridLineNamesValue* line_names = ConsumeGridLineNames(range);
  if (line_names) {
    if (!allow_grid_line_names)
      return nullptr;
    values->Append(*line_names);
  }

  bool allow_repeat = track_list_type == TrackListType::kGridTemplate;
  bool seen_auto_repeat = false;
  bool all_tracks_are_fixed_sized = true;
  do {
    bool is_auto_repeat;
    if (range.Peek().FunctionId() == CSSValueRepeat) {
      if (!allow_repeat)
        return nullptr;
      if (!ConsumeGridTrackRepeatFunction(range, css_parser_mode, *values,
                                          is_auto_repeat,
                                          all_tracks_are_fixed_sized))
        return nullptr;
      if (is_auto_repeat && seen_auto_repeat)
        return nullptr;
      seen_auto_repeat = seen_auto_repeat || is_auto_repeat;
    } else if (CSSValue* value = ConsumeGridTrackSize(range, css_parser_mode)) {
      if (all_tracks_are_fixed_sized)
        all_tracks_are_fixed_sized = IsGridTrackFixedSized(*value);
      values->Append(*value);
    } else {
      return nullptr;
    }
    if (seen_auto_repeat && !all_tracks_are_fixed_sized)
      return nullptr;
    line_names = ConsumeGridLineNames(range);
    if (line_names) {
      if (!allow_grid_line_names)
        return nullptr;
      values->Append(*line_names);
    }
  } while (!range.AtEnd() && range.Peek().GetType() != kDelimiterToken);
  return values;
}

bool ParseGridTemplateAreasRow(const String& grid_row_names,
                               NamedGridAreaMap& grid_area_map,
                               const size_t row_count,
                               size_t& column_count) {
  if (grid_row_names.IsEmpty() || grid_row_names.ContainsOnlyWhitespace())
    return false;

  Vector<String> column_names =
      ParseGridTemplateAreasColumnNames(grid_row_names);
  if (row_count == 0) {
    column_count = column_names.size();
    if (column_count == 0)
      return false;
  } else if (column_count != column_names.size()) {
    // The declaration is invalid if all the rows don't have the number of
    // columns.
    return false;
  }

  for (size_t current_column = 0; current_column < column_count;
       ++current_column) {
    const String& grid_area_name = column_names[current_column];

    // Unamed areas are always valid (we consider them to be 1x1).
    if (grid_area_name == ".")
      continue;

    size_t look_ahead_column = current_column + 1;
    while (look_ahead_column < column_count &&
           column_names[look_ahead_column] == grid_area_name)
      look_ahead_column++;

    NamedGridAreaMap::iterator grid_area_it =
        grid_area_map.find(grid_area_name);
    if (grid_area_it == grid_area_map.end()) {
      grid_area_map.insert(grid_area_name,
                           GridArea(GridSpan::TranslatedDefiniteGridSpan(
                                        row_count, row_count + 1),
                                    GridSpan::TranslatedDefiniteGridSpan(
                                        current_column, look_ahead_column)));
    } else {
      GridArea& grid_area = grid_area_it->value;

      // The following checks test that the grid area is a single filled-in
      // rectangle.
      // 1. The new row is adjacent to the previously parsed row.
      if (row_count != grid_area.rows.EndLine())
        return false;

      // 2. The new area starts at the same position as the previously parsed
      // area.
      if (current_column != grid_area.columns.StartLine())
        return false;

      // 3. The new area ends at the same position as the previously parsed
      // area.
      if (look_ahead_column != grid_area.columns.EndLine())
        return false;

      grid_area.rows = GridSpan::TranslatedDefiniteGridSpan(
          grid_area.rows.StartLine(), grid_area.rows.EndLine() + 1);
    }
    current_column = look_ahead_column - 1;
  }

  return true;
}

CSSValue* ConsumeGridTemplatesRowsOrColumns(CSSParserTokenRange& range,
                                            CSSParserMode css_parser_mode) {
  if (range.Peek().Id() == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return ConsumeGridTrackList(range, css_parser_mode,
                              TrackListType::kGridTemplate);
}

bool ConsumeGridItemPositionShorthand(bool important,
                                      CSSParserTokenRange& range,
                                      CSSValue*& start_value,
                                      CSSValue*& end_value) {
  // Input should be nullptrs.
  DCHECK(!start_value);
  DCHECK(!end_value);

  start_value = ConsumeGridLine(range);
  if (!start_value)
    return false;

  if (CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range)) {
    end_value = ConsumeGridLine(range);
    if (!end_value)
      return false;
  } else {
    end_value = start_value->IsCustomIdentValue()
                    ? start_value
                    : CSSIdentifierValue::Create(CSSValueAuto);
  }

  return range.AtEnd();
}

bool ConsumeGridTemplateShorthand(bool important,
                                  CSSParserTokenRange& range,
                                  const CSSParserContext& context,
                                  CSSValue*& template_rows,
                                  CSSValue*& template_columns,
                                  CSSValue*& template_areas) {
  DCHECK(!template_rows);
  DCHECK(!template_columns);
  DCHECK(!template_areas);

  DCHECK_EQ(gridTemplateShorthand().length(), 3u);

  CSSParserTokenRange range_copy = range;
  template_rows = CSSPropertyParserHelpers::ConsumeIdent<CSSValueNone>(range);

  // 1- 'none' case.
  if (template_rows && range.AtEnd()) {
    template_rows = CSSIdentifierValue::Create(CSSValueNone);
    template_columns = CSSIdentifierValue::Create(CSSValueNone);
    template_areas = CSSIdentifierValue::Create(CSSValueNone);
    return true;
  }

  // 2- <grid-template-rows> / <grid-template-columns>
  if (!template_rows) {
    template_rows = ConsumeGridTrackList(range, context.Mode(),
                                         TrackListType::kGridTemplate);
  }

  if (template_rows) {
    if (!CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range))
      return false;
    template_columns = ConsumeGridTemplatesRowsOrColumns(range, context.Mode());
    if (!template_columns || !range.AtEnd())
      return false;

    template_areas = CSSIdentifierValue::Create(CSSValueNone);
    return true;
  }

  // 3- [ <line-names>? <string> <track-size>? <line-names>? ]+
  // [ / <track-list> ]?
  range = range_copy;
  return ConsumeGridTemplateRowsAndAreasAndColumns(
      important, range, context, template_rows, template_columns,
      template_areas);
}

bool ConsumeFromPageBreakBetween(CSSParserTokenRange& range,
                                 CSSValueID& value) {
  if (!ConsumeCSSValueId(range, value)) {
    return false;
  }

  if (value == CSSValueAlways) {
    value = CSSValuePage;
    return true;
  }
  return value == CSSValueAuto || value == CSSValueAvoid ||
         value == CSSValueLeft || value == CSSValueRight;
}

bool ConsumeFromColumnBreakBetween(CSSParserTokenRange& range,
                                   CSSValueID& value) {
  if (!ConsumeCSSValueId(range, value)) {
    return false;
  }

  if (value == CSSValueAlways) {
    value = CSSValueColumn;
    return true;
  }
  return value == CSSValueAuto || value == CSSValueAvoid;
}

bool ConsumeFromColumnOrPageBreakInside(CSSParserTokenRange& range,
                                        CSSValueID& value) {
  if (!ConsumeCSSValueId(range, value)) {
    return false;
  }
  return value == CSSValueAuto || value == CSSValueAvoid;
}

bool ValidWidthOrHeightKeyword(CSSValueID id, const CSSParserContext& context) {
  if (id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent ||
      id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent ||
      id == CSSValueMinContent || id == CSSValueMaxContent ||
      id == CSSValueFitContent) {
    switch (id) {
      case CSSValueWebkitMinContent:
        context.Count(WebFeature::kCSSValuePrefixedMinContent);
        break;
      case CSSValueWebkitMaxContent:
        context.Count(WebFeature::kCSSValuePrefixedMaxContent);
        break;
      case CSSValueWebkitFillAvailable:
        context.Count(WebFeature::kCSSValuePrefixedFillAvailable);
        break;
      case CSSValueWebkitFitContent:
        context.Count(WebFeature::kCSSValuePrefixedFitContent);
        break;
      default:
        break;
    }
    return true;
  }
  return false;
}

CSSValue* ConsumePath(CSSParserTokenRange& range) {
  // FIXME: Add support for <url>, <basic-shape>, <geometry-box>.
  if (range.Peek().FunctionId() != CSSValuePath)
    return nullptr;

  CSSParserTokenRange function_range = range;
  CSSParserTokenRange function_args =
      CSSPropertyParserHelpers::ConsumeFunction(function_range);

  if (function_args.Peek().GetType() != kStringToken)
    return nullptr;
  String path_string =
      function_args.ConsumeIncludingWhitespace().Value().ToString();

  std::unique_ptr<SVGPathByteStream> byte_stream = SVGPathByteStream::Create();
  if (BuildByteStreamFromString(path_string, *byte_stream) !=
          SVGParseStatus::kNoError ||
      !function_args.AtEnd()) {
    return nullptr;
  }

  range = function_range;
  if (byte_stream->IsEmpty())
    return CSSIdentifierValue::Create(CSSValueNone);
  return CSSPathValue::Create(std::move(byte_stream));
}

CSSValue* ConsumeRay(CSSParserTokenRange& range,
                     const CSSParserContext& context) {
  DCHECK_EQ(range.Peek().FunctionId(), CSSValueRay);
  CSSParserTokenRange function_range = range;
  CSSParserTokenRange function_args =
      CSSPropertyParserHelpers::ConsumeFunction(function_range);

  CSSPrimitiveValue* angle = nullptr;
  CSSIdentifierValue* size = nullptr;
  CSSIdentifierValue* contain = nullptr;
  while (!function_args.AtEnd()) {
    if (!angle) {
      angle = CSSPropertyParserHelpers::ConsumeAngle(
          function_args, &context, WTF::Optional<WebFeature>());
      if (angle)
        continue;
    }
    if (!size) {
      size = CSSPropertyParserHelpers::ConsumeIdent<
          CSSValueClosestSide, CSSValueClosestCorner, CSSValueFarthestSide,
          CSSValueFarthestCorner, CSSValueSides>(function_args);
      if (size)
        continue;
    }
    if (RuntimeEnabledFeatures::CSSOffsetPathRayContainEnabled() && !contain) {
      contain = CSSPropertyParserHelpers::ConsumeIdent<CSSValueContain>(
          function_args);
      if (contain)
        continue;
    }
    return nullptr;
  }
  if (!angle || !size)
    return nullptr;
  range = function_range;
  return CSSRayValue::Create(*angle, *size, contain);
}

CSSValue* ConsumeMaxWidthOrHeight(
    CSSParserTokenRange& range,
    const CSSParserContext& context,
    CSSPropertyParserHelpers::UnitlessQuirk unitless) {
  if (range.Peek().Id() == CSSValueNone ||
      ValidWidthOrHeightKeyword(range.Peek().Id(), context))
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, context.Mode(), kValueRangeNonNegative, unitless);
}

CSSValue* ConsumeWidthOrHeight(
    CSSParserTokenRange& range,
    const CSSParserContext& context,
    CSSPropertyParserHelpers::UnitlessQuirk unitless) {
  if (range.Peek().Id() == CSSValueAuto ||
      ValidWidthOrHeightKeyword(range.Peek().Id(), context))
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, context.Mode(), kValueRangeNonNegative, unitless);
}

CSSValue* ConsumeMarginOrOffset(
    CSSParserTokenRange& range,
    CSSParserMode css_parser_mode,
    CSSPropertyParserHelpers::UnitlessQuirk unitless) {
  if (range.Peek().Id() == CSSValueAuto)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
      range, css_parser_mode, kValueRangeAll, unitless);
}

CSSValue* ConsumeOffsetPath(CSSParserTokenRange& range,
                            const CSSParserContext& context) {
  CSSValue* value = nullptr;
  if (RuntimeEnabledFeatures::CSSOffsetPathRayEnabled() &&
      range.Peek().FunctionId() == CSSValueRay)
    value = ConsumeRay(range, context);
  else
    value = ConsumePathOrNone(range);

  // Count when we receive a valid path other than 'none'.
  if (value && !value->IsIdentifierValue())
    context.Count(WebFeature::kCSSOffsetInEffect);
  return value;
}

CSSValue* ConsumePathOrNone(CSSParserTokenRange& range) {
  CSSValueID id = range.Peek().Id();
  if (id == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  return ConsumePath(range);
}

CSSValue* ConsumeOffsetRotate(CSSParserTokenRange& range,
                              const CSSParserContext& context) {
  CSSValue* angle = CSSPropertyParserHelpers::ConsumeAngle(
      range, &context, Optional<WebFeature>());
  CSSValue* keyword =
      CSSPropertyParserHelpers::ConsumeIdent<CSSValueAuto, CSSValueReverse>(
          range);
  if (!angle && !keyword)
    return nullptr;

  if (!angle) {
    angle = CSSPropertyParserHelpers::ConsumeAngle(range, &context,
                                                   Optional<WebFeature>());
  }

  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
  if (keyword)
    list->Append(*keyword);
  if (angle)
    list->Append(*angle);
  return list;
}

bool ConsumePlaceAlignment(CSSParserTokenRange& range,
                           ConsumePlaceAlignmentValue consume_alignment_value,
                           CSSValue*& align_value,
                           CSSValue*& justify_value) {
  DCHECK(consume_alignment_value);
  DCHECK(!align_value);
  DCHECK(!justify_value);

  bool is_baseline = IsBaselineKeyword(range.Peek().Id());
  align_value = consume_alignment_value(range, IsSelfPositionKeyword);
  if (!align_value)
    return false;

  // justify-content property does not allow the <baseline-position> values.
  if (consume_alignment_value == ConsumeSimplifiedContentPosition) {
    if (range.AtEnd() && is_baseline)
      return false;
    if (IsBaselineKeyword(range.Peek().Id()))
      return false;
  }

  justify_value =
      range.AtEnd()
          ? align_value
          : consume_alignment_value(range, IsSelfPositionOrLeftOrRightKeyword);

  return justify_value && range.AtEnd();
}

bool ConsumeRadii(CSSValue* horizontal_radii[4],
                  CSSValue* vertical_radii[4],
                  CSSParserTokenRange& range,
                  CSSParserMode css_parser_mode,
                  bool use_legacy_parsing) {
  unsigned i = 0;
  for (; i < 4 && !range.AtEnd() && range.Peek().GetType() != kDelimiterToken;
       ++i) {
    horizontal_radii[i] = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
        range, css_parser_mode, kValueRangeNonNegative);
    if (!horizontal_radii[i])
      return false;
  }
  if (!horizontal_radii[0])
    return false;
  if (range.AtEnd()) {
    // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to
    // border-radius: l1 / l2;
    if (use_legacy_parsing && i == 2) {
      vertical_radii[0] = horizontal_radii[1];
      horizontal_radii[1] = nullptr;
    } else {
      CSSPropertyParserHelpers::Complete4Sides(horizontal_radii);
      for (unsigned i = 0; i < 4; ++i)
        vertical_radii[i] = horizontal_radii[i];
      return true;
    }
  } else {
    if (!CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range))
      return false;
    for (i = 0; i < 4 && !range.AtEnd(); ++i) {
      vertical_radii[i] = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
          range, css_parser_mode, kValueRangeNonNegative);
      if (!vertical_radii[i])
        return false;
    }
    if (!vertical_radii[0] || !range.AtEnd())
      return false;
  }
  CSSPropertyParserHelpers::Complete4Sides(horizontal_radii);
  CSSPropertyParserHelpers::Complete4Sides(vertical_radii);
  return true;
}

CSSValue* ConsumeBasicShape(CSSParserTokenRange& range,
                            const CSSParserContext& context) {
  CSSValue* shape = nullptr;
  if (range.Peek().GetType() != kFunctionToken)
    return nullptr;
  CSSValueID id = range.Peek().FunctionId();
  CSSParserTokenRange range_copy = range;
  CSSParserTokenRange args =
      CSSPropertyParserHelpers::ConsumeFunction(range_copy);
  if (id == CSSValueCircle)
    shape = ConsumeBasicShapeCircle(args, context);
  else if (id == CSSValueEllipse)
    shape = ConsumeBasicShapeEllipse(args, context);
  else if (id == CSSValuePolygon)
    shape = ConsumeBasicShapePolygon(args, context);
  else if (id == CSSValueInset)
    shape = ConsumeBasicShapeInset(args, context);
  if (!shape || !args.AtEnd())
    return nullptr;

  context.Count(WebFeature::kCSSBasicShape);
  range = range_copy;
  return shape;
}

CSSValue* ConsumeTextDecorationLine(CSSParserTokenRange& range) {
  CSSValueID id = range.Peek().Id();
  if (id == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
  while (true) {
    CSSIdentifierValue* ident =
        CSSPropertyParserHelpers::ConsumeIdent<CSSValueBlink, CSSValueUnderline,
                                               CSSValueOverline,
                                               CSSValueLineThrough>(range);
    if (!ident)
      break;
    if (list->HasValue(*ident))
      return nullptr;
    list->Append(*ident);
  }

  if (!list->length())
    return nullptr;
  return list;
}

CSSValue* ConsumeTransformList(CSSParserTokenRange& range,
                               const CSSParserContext& context,
                               const CSSParserLocalContext& local_context) {
  if (range.Peek().Id() == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);

  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
  do {
    CSSValue* parsed_transform_value =
        ConsumeTransformValue(range, context, local_context.UseAliasParsing());
    if (!parsed_transform_value)
      return nullptr;
    list->Append(*parsed_transform_value);
  } while (!range.AtEnd());

  return list;
}

CSSValue* ConsumeTransitionProperty(CSSParserTokenRange& range) {
  const CSSParserToken& token = range.Peek();
  if (token.GetType() != kIdentToken)
    return nullptr;
  if (token.Id() == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  CSSPropertyID unresolved_property = token.ParseAsUnresolvedCSSPropertyID();
  if (unresolved_property != CSSPropertyInvalid &&
      unresolved_property != CSSPropertyVariable) {
#if DCHECK_IS_ON()
    DCHECK(CSSProperty::Get(resolveCSSPropertyID(unresolved_property))
               .IsEnabled());
#endif
    range.ConsumeIncludingWhitespace();
    return CSSCustomIdentValue::Create(unresolved_property);
  }
  return CSSPropertyParserHelpers::ConsumeCustomIdent(range);
}

bool IsValidPropertyList(const CSSValueList& value_list) {
  if (value_list.length() < 2)
    return true;
  for (auto& value : value_list) {
    if (value->IsIdentifierValue() &&
        ToCSSIdentifierValue(*value).GetValueID() == CSSValueNone)
      return false;
  }
  return true;
}

CSSValue* ConsumeBorderColorSide(CSSParserTokenRange& range,
                                 const CSSParserContext& context,
                                 const CSSParserLocalContext& local_context) {
  CSSPropertyID shorthand = local_context.CurrentShorthand();
  bool allow_quirky_colors =
      IsQuirksModeBehavior(context.Mode()) &&
      (shorthand == CSSPropertyInvalid || shorthand == CSSPropertyBorderColor);
  return CSSPropertyParserHelpers::ConsumeColor(range, context.Mode(),
                                                allow_quirky_colors);
}

CSSValue* ConsumeBorderWidth(CSSParserTokenRange& range,
                             CSSParserMode css_parser_mode,
                             CSSPropertyParserHelpers::UnitlessQuirk unitless) {
  return CSSPropertyParserHelpers::ConsumeLineWidth(range, css_parser_mode,
                                                    unitless);
}

CSSValue* ParseSpacing(CSSParserTokenRange& range,
                       const CSSParserContext& context) {
  if (range.Peek().Id() == CSSValueNormal)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  // TODO(timloh): allow <percentage>s in word-spacing.
  return CSSPropertyParserHelpers::ConsumeLength(
      range, context.Mode(), kValueRangeAll,
      CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
}

CSSValue* ParsePaintStroke(CSSParserTokenRange& range,
                           const CSSParserContext& context) {
  if (range.Peek().Id() == CSSValueNone)
    return CSSPropertyParserHelpers::ConsumeIdent(range);
  CSSURIValue* url = CSSPropertyParserHelpers::ConsumeUrl(range, &context);
  if (url) {
    CSSValue* parsed_value = nullptr;
    if (range.Peek().Id() == CSSValueNone) {
      parsed_value = CSSPropertyParserHelpers::ConsumeIdent(range);
    } else {
      parsed_value =
          CSSPropertyParserHelpers::ConsumeColor(range, context.Mode());
    }
    if (parsed_value) {
      CSSValueList* values = CSSValueList::CreateSpaceSeparated();
      values->Append(*url);
      values->Append(*parsed_value);
      return values;
    }
    return url;
  }
  return CSSPropertyParserHelpers::ConsumeColor(range, context.Mode());
}

}  // namespace CSSParsingUtils
}  // namespace blink
