/*
 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
 * All rights reserved.
 * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
 * Copyright (C) 2013 Intel Corporation. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "core/css/CSSPropertyValueSet.h"

#include "core/StylePropertyShorthand.h"
#include "core/css/CSSCustomPropertyDeclaration.h"
#include "core/css/CSSIdentifierValue.h"
#include "core/css/StylePropertySerializer.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/parser/CSSParser.h"
#include "core/css/parser/CSSParserContext.h"
#include "core/css/properties/CSSProperty.h"
#include "core/frame/UseCounter.h"
#include "platform/wtf/text/StringBuilder.h"

#ifndef NDEBUG
#include <stdio.h>
#include "platform/wtf/text/CString.h"
#endif

namespace blink {

static size_t SizeForImmutableCSSPropertyValueSetWithPropertyCount(
    unsigned count) {
  return sizeof(ImmutableCSSPropertyValueSet) - sizeof(void*) +
         sizeof(Member<CSSValue>) * count +
         sizeof(CSSPropertyValueMetadata) * count;
}

ImmutableCSSPropertyValueSet* ImmutableCSSPropertyValueSet::Create(
    const CSSPropertyValue* properties,
    unsigned count,
    CSSParserMode css_parser_mode) {
  DCHECK_LE(count, static_cast<unsigned>(kMaxArraySize));
  void* slot = ThreadHeap::Allocate<CSSPropertyValueSet>(
      SizeForImmutableCSSPropertyValueSetWithPropertyCount(count));
  return new (slot)
      ImmutableCSSPropertyValueSet(properties, count, css_parser_mode);
}

ImmutableCSSPropertyValueSet* CSSPropertyValueSet::ImmutableCopyIfNeeded()
    const {
  if (!IsMutable()) {
    return ToImmutableCSSPropertyValueSet(
        const_cast<CSSPropertyValueSet*>(this));
  }
  const MutableCSSPropertyValueSet* mutable_this =
      ToMutableCSSPropertyValueSet(this);
  return ImmutableCSSPropertyValueSet::Create(
      mutable_this->property_vector_.data(),
      mutable_this->property_vector_.size(), CssParserMode());
}

MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
    CSSParserMode css_parser_mode)
    : CSSPropertyValueSet(css_parser_mode) {}

MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
    const CSSPropertyValue* properties,
    unsigned length)
    : CSSPropertyValueSet(kHTMLStandardMode) {
  property_vector_.ReserveInitialCapacity(length);
  for (unsigned i = 0; i < length; ++i)
    property_vector_.UncheckedAppend(properties[i]);
}

ImmutableCSSPropertyValueSet::ImmutableCSSPropertyValueSet(
    const CSSPropertyValue* properties,
    unsigned length,
    CSSParserMode css_parser_mode)
    : CSSPropertyValueSet(css_parser_mode, length) {
  CSSPropertyValueMetadata* metadata_array =
      const_cast<CSSPropertyValueMetadata*>(this->MetadataArray());
  Member<const CSSValue>* value_array =
      const_cast<Member<const CSSValue>*>(this->ValueArray());
  for (unsigned i = 0; i < array_size_; ++i) {
    metadata_array[i] = properties[i].Metadata();
    value_array[i] = properties[i].Value();
  }
}

ImmutableCSSPropertyValueSet::~ImmutableCSSPropertyValueSet() = default;

// Convert property into an uint16_t for comparison with metadata's property id
// to avoid the compiler converting it to an int multiple times in a loop.
static uint16_t GetConvertedCSSPropertyID(CSSPropertyID property_id) {
  return static_cast<uint16_t>(property_id);
}

static uint16_t GetConvertedCSSPropertyID(const AtomicString&) {
  return static_cast<uint16_t>(CSSPropertyVariable);
}

static uint16_t GetConvertedCSSPropertyID(AtRuleDescriptorID descriptor_id) {
  return static_cast<uint16_t>(
      AtRuleDescriptorIDAsCSSPropertyID(descriptor_id));
}

static bool IsPropertyMatch(const CSSPropertyValueMetadata& metadata,
                            const CSSValue&,
                            uint16_t id,
                            CSSPropertyID property_id) {
  DCHECK_EQ(id, property_id);
  bool result = metadata.Property().PropertyID() == id;
// Only enabled properties should be part of the style.
#if DCHECK_IS_ON()
  DCHECK(!result ||
         CSSProperty::Get(resolveCSSPropertyID(property_id)).IsEnabled());
#endif
  return result;
}

static bool IsPropertyMatch(const CSSPropertyValueMetadata& metadata,
                            const CSSValue& value,
                            uint16_t id,
                            const AtomicString& custom_property_name) {
  DCHECK_EQ(id, CSSPropertyVariable);
  return metadata.Property().PropertyID() == id &&
         ToCSSCustomPropertyDeclaration(value).GetName() ==
             custom_property_name;
}

static bool IsPropertyMatch(const CSSPropertyValueMetadata& metadata,
                            const CSSValue& css_value,
                            uint16_t id,
                            AtRuleDescriptorID descriptor_id) {
  return IsPropertyMatch(metadata, css_value, id,
                         AtRuleDescriptorIDAsCSSPropertyID(descriptor_id));
}

template <typename T>
int ImmutableCSSPropertyValueSet::FindPropertyIndex(T property) const {
  uint16_t id = GetConvertedCSSPropertyID(property);
  for (int n = array_size_ - 1; n >= 0; --n) {
    if (IsPropertyMatch(MetadataArray()[n], *ValueArray()[n], id, property))
      return n;
  }

  return -1;
}
template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
    CSSPropertyID) const;
template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
    AtomicString) const;
template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
    AtRuleDescriptorID) const;

void ImmutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
  const Member<const CSSValue>* values = ValueArray();
  for (unsigned i = 0; i < array_size_; i++)
    visitor->Trace(values[i]);
  CSSPropertyValueSet::TraceAfterDispatch(visitor);
}

MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
    const CSSPropertyValueSet& other)
    : CSSPropertyValueSet(other.CssParserMode()) {
  if (other.IsMutable()) {
    property_vector_ = ToMutableCSSPropertyValueSet(other).property_vector_;
  } else {
    property_vector_.ReserveInitialCapacity(other.PropertyCount());
    for (unsigned i = 0; i < other.PropertyCount(); ++i) {
      PropertyReference property = other.PropertyAt(i);
      property_vector_.UncheckedAppend(
          CSSPropertyValue(property.PropertyMetadata(), property.Value()));
    }
  }
}

static String SerializeShorthand(const CSSPropertyValueSet& property_set,
                                 CSSPropertyID property_id) {
  return StylePropertySerializer(property_set).GetPropertyValue(property_id);
}

static String SerializeShorthand(const CSSPropertyValueSet&,
                                 const AtomicString& custom_property_name) {
  // Custom properties are never shorthands.
  return "";
}

static String SerializeShorthand(const CSSPropertyValueSet& property_set,
                                 AtRuleDescriptorID atrule_id) {
  return StylePropertySerializer(property_set)
      .GetPropertyValue(AtRuleDescriptorIDAsCSSPropertyID(atrule_id));
  ;
}

template <typename T>
String CSSPropertyValueSet::GetPropertyValue(T property) const {
  const CSSValue* value = GetPropertyCSSValue(property);
  if (value)
    return value->CssText();
  return SerializeShorthand(*this, property);
}
template CORE_EXPORT String
    CSSPropertyValueSet::GetPropertyValue<CSSPropertyID>(CSSPropertyID) const;
template CORE_EXPORT String
    CSSPropertyValueSet::GetPropertyValue<AtRuleDescriptorID>(
        AtRuleDescriptorID) const;
template CORE_EXPORT String
    CSSPropertyValueSet::GetPropertyValue<AtomicString>(AtomicString) const;

template <typename T>
const CSSValue* CSSPropertyValueSet::GetPropertyCSSValue(T property) const {
  int found_property_index = FindPropertyIndex(property);
  if (found_property_index == -1)
    return nullptr;
  return &PropertyAt(found_property_index).Value();
}
template CORE_EXPORT const CSSValue* CSSPropertyValueSet::GetPropertyCSSValue<
    CSSPropertyID>(CSSPropertyID) const;
template CORE_EXPORT const CSSValue* CSSPropertyValueSet::GetPropertyCSSValue<
    AtRuleDescriptorID>(AtRuleDescriptorID) const;
template CORE_EXPORT const CSSValue*
    CSSPropertyValueSet::GetPropertyCSSValue<AtomicString>(AtomicString) const;

void CSSPropertyValueSet::Trace(blink::Visitor* visitor) {
  if (is_mutable_)
    ToMutableCSSPropertyValueSet(this)->TraceAfterDispatch(visitor);
  else
    ToImmutableCSSPropertyValueSet(this)->TraceAfterDispatch(visitor);
}

void CSSPropertyValueSet::FinalizeGarbageCollectedObject() {
  if (is_mutable_)
    ToMutableCSSPropertyValueSet(this)->~MutableCSSPropertyValueSet();
  else
    ToImmutableCSSPropertyValueSet(this)->~ImmutableCSSPropertyValueSet();
}

bool MutableCSSPropertyValueSet::RemoveShorthandProperty(
    CSSPropertyID property_id) {
  StylePropertyShorthand shorthand = shorthandForProperty(property_id);
  if (!shorthand.length())
    return false;

  return RemovePropertiesInSet(shorthand.properties(), shorthand.length());
}

bool MutableCSSPropertyValueSet::RemovePropertyAtIndex(int property_index,
                                                       String* return_text) {
  if (property_index == -1) {
    if (return_text)
      *return_text = "";
    return false;
  }

  if (return_text)
    *return_text = PropertyAt(property_index).Value().CssText();

  // A more efficient removal strategy would involve marking entries as empty
  // and sweeping them when the vector grows too big.
  property_vector_.EraseAt(property_index);

  return true;
}

template <typename T>
bool MutableCSSPropertyValueSet::RemoveProperty(T property,
                                                String* return_text) {
  if (RemoveShorthandProperty(property)) {
    // FIXME: Return an equivalent shorthand when possible.
    if (return_text)
      *return_text = "";
    return true;
  }

  int found_property_index = FindPropertyIndex(property);
  return RemovePropertyAtIndex(found_property_index, return_text);
}
template CORE_EXPORT bool MutableCSSPropertyValueSet::RemoveProperty(
    CSSPropertyID,
    String*);
template CORE_EXPORT bool MutableCSSPropertyValueSet::RemoveProperty(
    AtomicString,
    String*);

template <typename T>
bool CSSPropertyValueSet::PropertyIsImportant(T property) const {
  int found_property_index = FindPropertyIndex(property);
  if (found_property_index != -1)
    return PropertyAt(found_property_index).IsImportant();
  return ShorthandIsImportant(property);
}
template bool CSSPropertyValueSet::PropertyIsImportant<CSSPropertyID>(
    CSSPropertyID) const;
template bool CSSPropertyValueSet::PropertyIsImportant<AtomicString>(
    AtomicString) const;

bool CSSPropertyValueSet::ShorthandIsImportant(
    CSSPropertyID property_id) const {
  StylePropertyShorthand shorthand = shorthandForProperty(property_id);
  if (!shorthand.length())
    return false;

  for (unsigned i = 0; i < shorthand.length(); ++i) {
    if (!PropertyIsImportant(shorthand.properties()[i]->PropertyID()))
      return false;
  }
  return true;
}

bool CSSPropertyValueSet::ShorthandIsImportant(
    AtomicString custom_property_name) const {
  // Custom properties are never shorthands.
  return false;
}

CSSPropertyID CSSPropertyValueSet::GetPropertyShorthand(
    CSSPropertyID property_id) const {
  int found_property_index = FindPropertyIndex(property_id);
  if (found_property_index == -1)
    return CSSPropertyInvalid;
  return PropertyAt(found_property_index).ShorthandID();
}

bool CSSPropertyValueSet::IsPropertyImplicit(CSSPropertyID property_id) const {
  int found_property_index = FindPropertyIndex(property_id);
  if (found_property_index == -1)
    return false;
  return PropertyAt(found_property_index).IsImplicit();
}

MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
    CSSPropertyID unresolved_property,
    const String& value,
    bool important,
    SecureContextMode secure_context_mode,
    StyleSheetContents* context_style_sheet) {
  DCHECK_GE(unresolved_property, firstCSSProperty);

  // Setting the value to an empty string just removes the property in both IE
  // and Gecko. Setting it to null seems to produce less consistent results, but
  // we treat it just the same.
  if (value.IsEmpty()) {
    bool did_parse = true;
    bool did_change = RemoveProperty(resolveCSSPropertyID(unresolved_property));
    return SetResult{did_parse, did_change};
  }

  // When replacing an existing property value, this moves the property to the
  // end of the list. Firefox preserves the position, and MSIE moves the
  // property to the beginning.
  return CSSParser::ParseValue(this, unresolved_property, value, important,
                               secure_context_mode, context_style_sheet);
}

MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
    const AtomicString& custom_property_name,
    const PropertyRegistry* registry,
    const String& value,
    bool important,
    SecureContextMode secure_context_mode,
    StyleSheetContents* context_style_sheet,
    bool is_animation_tainted) {
  if (value.IsEmpty()) {
    bool did_parse = true;
    bool did_change = RemoveProperty(custom_property_name);
    return MutableCSSPropertyValueSet::SetResult{did_parse, did_change};
  }
  return CSSParser::ParseValueForCustomProperty(
      this, custom_property_name, registry, value, important,
      secure_context_mode, context_style_sheet, is_animation_tainted);
}

void MutableCSSPropertyValueSet::SetProperty(CSSPropertyID property_id,
                                             const CSSValue& value,
                                             bool important) {
  StylePropertyShorthand shorthand = shorthandForProperty(property_id);
  if (!shorthand.length()) {
    SetProperty(
        CSSPropertyValue(CSSProperty::Get(property_id), value, important));
    return;
  }

  RemovePropertiesInSet(shorthand.properties(), shorthand.length());

  for (unsigned i = 0; i < shorthand.length(); ++i) {
    property_vector_.push_back(
        CSSPropertyValue(*shorthand.properties()[i], value, important));
  }
}

bool MutableCSSPropertyValueSet::SetProperty(const CSSPropertyValue& property,
                                             CSSPropertyValue* slot) {
  const AtomicString& name =
      (property.Id() == CSSPropertyVariable)
          ? ToCSSCustomPropertyDeclaration(property.Value())->GetName()
          : g_null_atom;
  CSSPropertyValue* to_replace =
      slot ? slot : FindCSSPropertyWithID(property.Id(), name);
  if (to_replace && *to_replace == property)
    return false;
  if (to_replace) {
    *to_replace = property;
    return true;
  }
  property_vector_.push_back(property);
  return true;
}

bool MutableCSSPropertyValueSet::SetProperty(CSSPropertyID property_id,
                                             CSSValueID identifier,
                                             bool important) {
  SetProperty(CSSPropertyValue(CSSProperty::Get(property_id),
                               *CSSIdentifierValue::Create(identifier),
                               important));
  return true;
}

void MutableCSSPropertyValueSet::ParseDeclarationList(
    const String& style_declaration,
    SecureContextMode secure_context_mode,
    StyleSheetContents* context_style_sheet) {
  property_vector_.clear();

  CSSParserContext* context;
  if (context_style_sheet) {
    context = CSSParserContext::CreateWithStyleSheetContents(
        context_style_sheet->ParserContext(), context_style_sheet);
    context->SetMode(CssParserMode());
  } else {
    context = CSSParserContext::Create(CssParserMode(), secure_context_mode);
  }

  CSSParser::ParseDeclarationList(context, this, style_declaration);
}

bool MutableCSSPropertyValueSet::AddParsedProperties(
    const HeapVector<CSSPropertyValue, 256>& properties) {
  bool changed = false;
  property_vector_.ReserveCapacity(property_vector_.size() + properties.size());
  for (unsigned i = 0; i < properties.size(); ++i)
    changed |= SetProperty(properties[i]);
  return changed;
}

bool MutableCSSPropertyValueSet::AddRespectingCascade(
    const CSSPropertyValue& property) {
  // Only add properties that have no !important counterpart present
  if (!PropertyIsImportant(property.Id()) || property.IsImportant())
    return SetProperty(property);
  return false;
}

String CSSPropertyValueSet::AsText() const {
  return StylePropertySerializer(*this).AsText();
}

void MutableCSSPropertyValueSet::MergeAndOverrideOnConflict(
    const CSSPropertyValueSet* other) {
  unsigned size = other->PropertyCount();
  for (unsigned n = 0; n < size; ++n) {
    PropertyReference to_merge = other->PropertyAt(n);
    // TODO(leviw): This probably doesn't work correctly with Custom Properties
    CSSPropertyValue* old = FindCSSPropertyWithID(to_merge.Id());
    if (old) {
      SetProperty(
          CSSPropertyValue(to_merge.PropertyMetadata(), to_merge.Value()), old);
    } else {
      property_vector_.push_back(
          CSSPropertyValue(to_merge.PropertyMetadata(), to_merge.Value()));
    }
  }
}

bool CSSPropertyValueSet::HasFailedOrCanceledSubresources() const {
  unsigned size = PropertyCount();
  for (unsigned i = 0; i < size; ++i) {
    if (PropertyAt(i).Value().HasFailedOrCanceledSubresources())
      return true;
  }
  return false;
}

void MutableCSSPropertyValueSet::Clear() {
  property_vector_.clear();
}

inline bool ContainsId(const CSSProperty** set,
                       unsigned length,
                       CSSPropertyID id) {
  for (unsigned i = 0; i < length; ++i) {
    if (set[i]->IDEquals(id))
      return true;
  }
  return false;
}

bool MutableCSSPropertyValueSet::RemovePropertiesInSet(const CSSProperty** set,
                                                       unsigned length) {
  if (property_vector_.IsEmpty())
    return false;

  CSSPropertyValue* properties = property_vector_.data();
  unsigned old_size = property_vector_.size();
  unsigned new_index = 0;
  for (unsigned old_index = 0; old_index < old_size; ++old_index) {
    const CSSPropertyValue& property = properties[old_index];
    if (ContainsId(set, length, property.Id()))
      continue;
    // Modify property_vector_ in-place since this method is
    // performance-sensitive.
    properties[new_index++] = properties[old_index];
  }
  if (new_index != old_size) {
    property_vector_.Shrink(new_index);
    return true;
  }
  return false;
}

CSSPropertyValue* MutableCSSPropertyValueSet::FindCSSPropertyWithID(
    CSSPropertyID property_id,
    const AtomicString& custom_property_name) {
  int found_property_index = -1;
  if (property_id == CSSPropertyVariable && !custom_property_name.IsNull()) {
    // TODO(shanestephens): fix call sites so we always have a
    // customPropertyName here.
    found_property_index = FindPropertyIndex(custom_property_name);
  } else {
    DCHECK(custom_property_name.IsNull());
    found_property_index = FindPropertyIndex(property_id);
  }
  if (found_property_index == -1)
    return nullptr;
  return &property_vector_.at(found_property_index);
}

bool CSSPropertyValueSet::PropertyMatches(
    CSSPropertyID property_id,
    const CSSValue& property_value) const {
  int found_property_index = FindPropertyIndex(property_id);
  if (found_property_index == -1)
    return false;
  return PropertyAt(found_property_index).Value() == property_value;
}

void MutableCSSPropertyValueSet::RemoveEquivalentProperties(
    const CSSPropertyValueSet* style) {
  Vector<CSSPropertyID> properties_to_remove;
  unsigned size = property_vector_.size();
  for (unsigned i = 0; i < size; ++i) {
    PropertyReference property = PropertyAt(i);
    if (style->PropertyMatches(property.Id(), property.Value()))
      properties_to_remove.push_back(property.Id());
  }
  // FIXME: This should use mass removal.
  for (unsigned i = 0; i < properties_to_remove.size(); ++i)
    RemoveProperty(properties_to_remove[i]);
}

void MutableCSSPropertyValueSet::RemoveEquivalentProperties(
    const CSSStyleDeclaration* style) {
  Vector<CSSPropertyID> properties_to_remove;
  unsigned size = property_vector_.size();
  for (unsigned i = 0; i < size; ++i) {
    PropertyReference property = PropertyAt(i);
    if (style->CssPropertyMatches(property.Id(), &property.Value()))
      properties_to_remove.push_back(property.Id());
  }
  // FIXME: This should use mass removal.
  for (unsigned i = 0; i < properties_to_remove.size(); ++i)
    RemoveProperty(properties_to_remove[i]);
}

MutableCSSPropertyValueSet* CSSPropertyValueSet::MutableCopy() const {
  return new MutableCSSPropertyValueSet(*this);
}

MutableCSSPropertyValueSet* CSSPropertyValueSet::CopyPropertiesInSet(
    const Vector<const CSSProperty*>& properties) const {
  HeapVector<CSSPropertyValue, 256> list;
  list.ReserveInitialCapacity(properties.size());
  for (unsigned i = 0; i < properties.size(); ++i) {
    const CSSValue* value = GetPropertyCSSValue(properties[i]->PropertyID());
    if (value) {
      list.push_back(CSSPropertyValue(*properties[i], *value, false));
    }
  }
  return MutableCSSPropertyValueSet::Create(list.data(), list.size());
}

CSSStyleDeclaration* MutableCSSPropertyValueSet::EnsureCSSStyleDeclaration() {
  // FIXME: get rid of this weirdness of a CSSStyleDeclaration inside of a
  // style property set.
  if (cssom_wrapper_) {
    DCHECK(
        !static_cast<CSSStyleDeclaration*>(cssom_wrapper_.Get())->parentRule());
    DCHECK(!cssom_wrapper_->ParentElement());
    return cssom_wrapper_.Get();
  }
  cssom_wrapper_ = new PropertySetCSSStyleDeclaration(*this);
  return cssom_wrapper_.Get();
}

template <typename T>
int MutableCSSPropertyValueSet::FindPropertyIndex(T property) const {
  const CSSPropertyValue* begin = property_vector_.data();
  const CSSPropertyValue* end = begin + property_vector_.size();

  uint16_t id = GetConvertedCSSPropertyID(property);

  const CSSPropertyValue* it = std::find_if(
      begin, end, [property, id](const CSSPropertyValue& css_property) -> bool {
        return IsPropertyMatch(css_property.Metadata(), *css_property.Value(),
                               id, property);
      });

  return (it == end) ? -1 : it - begin;
}
template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
    CSSPropertyID) const;
template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
    AtomicString) const;

void MutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
  visitor->Trace(cssom_wrapper_);
  visitor->Trace(property_vector_);
  CSSPropertyValueSet::TraceAfterDispatch(visitor);
}

unsigned CSSPropertyValueSet::AverageSizeInBytes() {
  // Please update this if the storage scheme changes so that this longer
  // reflects the actual size.
  return SizeForImmutableCSSPropertyValueSetWithPropertyCount(4);
}

// See the function above if you need to update this.
struct SameSizeAsCSSPropertyValueSet
    : public GarbageCollectedFinalized<SameSizeAsCSSPropertyValueSet> {
  unsigned bitfield;
};
static_assert(sizeof(CSSPropertyValueSet) ==
                  sizeof(SameSizeAsCSSPropertyValueSet),
              "CSSPropertyValueSet should stay small");

#ifndef NDEBUG
void CSSPropertyValueSet::ShowStyle() {
  fprintf(stderr, "%s\n", AsText().Ascii().data());
}
#endif

MutableCSSPropertyValueSet* MutableCSSPropertyValueSet::Create(
    CSSParserMode css_parser_mode) {
  return new MutableCSSPropertyValueSet(css_parser_mode);
}

MutableCSSPropertyValueSet* MutableCSSPropertyValueSet::Create(
    const CSSPropertyValue* properties,
    unsigned count) {
  return new MutableCSSPropertyValueSet(properties, count);
}

void CSSLazyPropertyParser::Trace(blink::Visitor* visitor) {}

}  // namespace blink
