// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.android.xml;

import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.not;

import com.android.aapt.Resources.Attribute;
import com.android.aapt.Resources.Attribute.Symbol;
import com.android.aapt.Resources.Value;
import com.android.resources.ResourceType;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Ordering;
import com.google.devtools.build.android.AndroidDataWritingVisitor;
import com.google.devtools.build.android.AndroidDataWritingVisitor.StartTag;
import com.google.devtools.build.android.AndroidDataWritingVisitor.ValuesResourceDefinition;
import com.google.devtools.build.android.AndroidResourceSymbolSink;
import com.google.devtools.build.android.DataSource;
import com.google.devtools.build.android.FullyQualifiedName;
import com.google.devtools.build.android.XmlResourceValue;
import com.google.devtools.build.android.XmlResourceValues;
import com.google.devtools.build.android.proto.SerializeFormat;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

/**
 * Represents an Android Resource custom attribute.
 *
 * <p>Attribute are the most complicated Android resource, and therefore the least documented. Most
 * of the information about them is found by reading the android compatibility library source. An
 * Attribute defines a parameter that can be passed into a view class -- as such you can think of
 * attributes as creating slots for other resources to fit into. Each slot will have at least one
 * format, and can have multiples. Simple attributes (color, boolean, reference, dimension, float,
 * integer, string, and fraction) are defined as &lt;attr name="<em>name</em>" format=
 * "<em>format</em>" /&gt; while the complex ones, flag and enum, have sub parentTags: &lt;attr
 * name= "<em>name</em>" &gt&lt;flag name="<em>name</em>" value="<em>value</em>"&gt; &lt;/attr&gt;.
 *
 * <p>Attributes also have a double duty as defining validation logic for layout resources -- each
 * layout attribute *must* have a corresponding attribute which will be used to validate the
 * value/resource reference defined in it.
 *
 * <p>AttrXmlValue, due to the multiple types of attributes is actually a composite class that
 * contains multiple {@link XmlResourceValue} instances for each resource.
 */
@Immutable
public class AttrXmlResourceValue implements XmlResourceValue {

  private static final String FRACTION = "fraction";
  private static final String STRING = "string";
  private static final String INTEGER = "integer";
  private static final String FLOAT = "float";
  private static final String DIMENSION = "dimension";
  private static final String BOOLEAN = "boolean";
  private static final String COLOR = "color";
  private static final String REFERENCE = "reference";
  private static final String ENUM = "enum";
  private static final String FLAGS = "flags";
  private static final QName TAG_ENUM = QName.valueOf(ENUM);
  private static final QName TAG_FLAG = QName.valueOf("flag");
  private final ImmutableMap<String, ResourceXmlAttrValue> formats;
  private final boolean weak;

  private AttrXmlResourceValue(ImmutableMap<String, ResourceXmlAttrValue> formats, boolean weak) {
    this.formats = formats;
    this.weak = weak;
  }

  private static Map<String, String> readSubValues(XMLEventReader reader, QName subTagType)
      throws XMLStreamException {
    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
    while (reader.hasNext()
        && XmlResourceValues.isTag(XmlResourceValues.peekNextTag(reader), subTagType)) {
      StartElement element = reader.nextEvent().asStartElement();
      builder.put(
          XmlResourceValues.getElementName(element), XmlResourceValues.getElementValue(element));
      XMLEvent endTag = reader.nextEvent();
      if (!XmlResourceValues.isEndTag(endTag, subTagType)) {
        throw new XMLStreamException(
            String.format("Unexpected [%s]; Expected %s", endTag, "</enum>"), endTag.getLocation());
      }
    }
    return builder.build();
  }

  private static void endAttrElement(XMLEventReader reader) throws XMLStreamException {
    XMLEvent endTag = reader.nextTag();
    if (!endTag.isEndElement() || !QName.valueOf("attr").equals(endTag.asEndElement().getName())) {
      throw new XMLStreamException("Unexpected ParentTag:" + endTag, endTag.getLocation());
    }
  }

  private static final class BuilderEntry implements Map.Entry<String, ResourceXmlAttrValue> {
    private final String name;
    private final ResourceXmlAttrValue value;

    BuilderEntry(String name, ResourceXmlAttrValue value) {
      this.name = name;
      this.value = value;
    }

    @Override
    public String getKey() {
      return name;
    }

    @Override
    public ResourceXmlAttrValue getValue() {
      return value;
    }

    @Override
    public ResourceXmlAttrValue setValue(ResourceXmlAttrValue value) {
      throw new UnsupportedOperationException();
    }
  }

  @SafeVarargs
  @VisibleForTesting
  public static XmlResourceValue fromFormatEntries(
      Map.Entry<String, ResourceXmlAttrValue>... entries) {
    return of(ImmutableMap.copyOf(Arrays.asList(entries)));
  }

  @SafeVarargs
  @VisibleForTesting
  public static XmlResourceValue weakFromFormatEntries(
      Map.Entry<String, ResourceXmlAttrValue>... entries) {
    return of(ImmutableMap.copyOf(Arrays.asList(entries)), true);
  }

  @SuppressWarnings("deprecation")
  public static XmlResourceValue from(SerializeFormat.DataValueXml proto)
      throws InvalidProtocolBufferException {
    ImmutableMap.Builder<String, ResourceXmlAttrValue> formats =
        ImmutableMap.<String, AttrXmlResourceValue.ResourceXmlAttrValue>builder();
    for (Map.Entry<String, SerializeFormat.DataValueXml> entry :
        proto.getMappedXmlValue().entrySet()) {
      switch (entry.getKey()) {
        case FLAGS:
          formats.put(
              entry.getKey(), FlagResourceXmlAttrValue.of(entry.getValue().getMappedStringValue()));
          break;
        case ENUM:
          formats.put(
              entry.getKey(), EnumResourceXmlAttrValue.of(entry.getValue().getMappedStringValue()));
          break;
        case REFERENCE:
          formats.put(entry.getKey(), ReferenceResourceXmlAttrValue.of());
          break;
        case COLOR:
          formats.put(entry.getKey(), ColorResourceXmlAttrValue.of());
          break;
        case BOOLEAN:
          formats.put(entry.getKey(), BooleanResourceXmlAttrValue.of());
          break;
        case DIMENSION:
          formats.put(entry.getKey(), DimensionResourceXmlAttrValue.of());
          break;
        case FLOAT:
          formats.put(entry.getKey(), FloatResourceXmlAttrValue.of());
          break;
        case INTEGER:
          formats.put(entry.getKey(), IntegerResourceXmlAttrValue.of());
          break;
        case STRING:
          formats.put(entry.getKey(), StringResourceXmlAttrValue.of());
          break;
        case FRACTION:
          formats.put(entry.getKey(), FractionResourceXmlAttrValue.of());
          break;
        default:
          throw new InvalidProtocolBufferException("Unexpected format: " + entry.getKey());
      }
    }
    return of(formats.build());
  }

  public static XmlResourceValue from(Value proto) throws InvalidProtocolBufferException {
    ImmutableMap.Builder<String, ResourceXmlAttrValue> formats = ImmutableMap.builder();

    Attribute attribute = proto.getCompoundValue().getAttr();
    int formatFlags = attribute.getFormatFlags();

    if (formatFlags != 0xFFFF) {
      // These flags are defined in AOSP in ResourceTypes.h:ResTable_map
      if ((formatFlags & 1 << 0) != 0) {
        formats.put("reference", ReferenceResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 1) != 0) {
        formats.put("string", StringResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 2) != 0) {
        formats.put("integer", IntegerResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 3) != 0) {
        formats.put("boolean", BooleanResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 4) != 0) {
        formats.put("color", ColorResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 5) != 0) {
        formats.put("float", FloatResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 6) != 0) {
        formats.put("dimension", DimensionResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 7) != 0) {
        formats.put("fraction", FractionResourceXmlAttrValue.of());
      }
      if ((formatFlags & 1 << 16) != 0) {
        Map<String, String> enums = new HashMap<>();

        for (Symbol attrSymbol : attribute.getSymbolList()) {
          String name = attrSymbol.getName().getName().replaceFirst("id/", "");
          enums.put(name, Integer.toString(attrSymbol.getValue()));
        }

        formats.put("enum", EnumResourceXmlAttrValue.of(enums));
      }
      if ((formatFlags & 1 << 17) != 0) {
        Map<String, String> flags = new HashMap<>();
        for (Symbol attrSymbol : attribute.getSymbolList()) {
          String name = attrSymbol.getName().getName().replaceFirst("id/", "");
          flags.put(name, Integer.toString(attrSymbol.getValue()));
        }

        formats.put("flags", FlagResourceXmlAttrValue.of(flags));
      }
      if ((formatFlags & 0xFFFCFF00) != 0) {
        throw new InvalidProtocolBufferException("Unexpected format flags: " + formatFlags);
      }
    }
    return of(formats.build(), proto.getWeak());
  }

  /** Creates a new {@link AttrXmlResourceValue}. Returns null if there are no formats. */
  @Nullable
  public static XmlResourceValue from(
      StartElement attr, @Nullable String format, XMLEventReader eventReader)
      throws XMLStreamException {
    Set<String> formatNames = new HashSet<>();
    if (format != null) {
      Collections.addAll(formatNames, format.split("\\|"));
    }
    XMLEvent nextTag = XmlResourceValues.peekNextTag(eventReader);
    if (nextTag != null && nextTag.isStartElement()) {
      QName tagName = nextTag.asStartElement().getName();
      if (TAG_FLAG.equals(tagName)) {
        formatNames.add(FLAGS);
      } else {
        formatNames.add(tagName.getLocalPart().toLowerCase());
      }
    }

    ImmutableMap.Builder<String, ResourceXmlAttrValue> formats = ImmutableMap.builder();
    for (String formatName : formatNames) {
      switch (formatName) {
        case FLAGS:
          Map<String, String> flags = readSubValues(eventReader, TAG_FLAG);
          endAttrElement(eventReader);
          formats.put(formatName, FlagResourceXmlAttrValue.of(flags));
          break;
        case ENUM:
          Map<String, String> enums = readSubValues(eventReader, TAG_ENUM);
          endAttrElement(eventReader);
          formats.put(formatName, EnumResourceXmlAttrValue.of(enums));
          break;
        case REFERENCE:
          formats.put(formatName, ReferenceResourceXmlAttrValue.of());
          break;
        case COLOR:
          formats.put(formatName, ColorResourceXmlAttrValue.of());
          break;
        case BOOLEAN:
          formats.put(formatName, BooleanResourceXmlAttrValue.of());
          break;
        case DIMENSION:
          formats.put(formatName, DimensionResourceXmlAttrValue.of());
          break;
        case FLOAT:
          formats.put(formatName, FloatResourceXmlAttrValue.of());
          break;
        case INTEGER:
          formats.put(formatName, IntegerResourceXmlAttrValue.of());
          break;
        case STRING:
          formats.put(formatName, StringResourceXmlAttrValue.of());
          break;
        case FRACTION:
          formats.put(formatName, FractionResourceXmlAttrValue.of());
          break;
        default:
          throw new XMLStreamException(
              String.format("Unexpected attr format: %S", formatName), attr.getLocation());
      }
    }
    return of(formats.build());
  }

  public static XmlResourceValue of(ImmutableMap<String, ResourceXmlAttrValue> formats) {
    return new AttrXmlResourceValue(formats, /* weak= */ false);
  }

  public static XmlResourceValue of(
      ImmutableMap<String, ResourceXmlAttrValue> formats, boolean weak) {
    return new AttrXmlResourceValue(formats, weak);
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    AttrXmlResourceValue other = (AttrXmlResourceValue) o;
    return Objects.equals(formats, other.formats) && weak == other.weak;
  }

  @Override
  public int hashCode() {
    return Objects.hash(formats, weak);
  }

  @Override
  public String toString() {
    return MoreObjects.toStringHelper(this).add("formats", formats).add("weak", weak).toString();
  }

  @Override
  public void write(
      FullyQualifiedName key, DataSource source, AndroidDataWritingVisitor mergedDataWriter) {

    if (formats.isEmpty()) {
      mergedDataWriter
          .define(key)
          .derivedFrom(source)
          .startTag("attr")
          .named(key)
          .closeUnaryTag()
          .save();
    } else {
      ImmutableList<String> formatKeys =
          FluentIterable.from(formats.keySet())
              .filter(not(equalTo(FLAGS)))
              .filter(not(equalTo(ENUM)))
              .toSortedList(Ordering.natural());
      StartTag startTag =
          mergedDataWriter
              .define(key)
              .derivedFrom(source)
              .startTag("attr")
              .named(key)
              .optional()
              .attribute("format")
              .setFrom(formatKeys)
              .joinedBy("|");
      ValuesResourceDefinition definition;
      if (formats.keySet().contains(FLAGS) || formats.keySet().contains(ENUM)) {
        definition = startTag.closeTag();
        for (ResourceXmlAttrValue value : formats.values()) {
          definition = value.writeTo(definition);
        }
        definition = definition.addCharactersOf("\n").endTag();
      } else {
        definition = startTag.closeUnaryTag();
      }
      definition.save();
    }
  }

  @Override
  public void writeResourceToClass(FullyQualifiedName key, AndroidResourceSymbolSink sink) {
    sink.acceptSimpleResource(key.type(), key.name());
    // Flags and enums generate ID fields.
    if (formats.keySet().contains(FLAGS) || formats.keySet().contains(ENUM)) {
      for (ResourceXmlAttrValue value : formats.values()) {
        value.writeToClass(sink);
      }
    }
  }

  @SuppressWarnings("deprecation")
  @Override
  public int serializeTo(int sourceId, Namespaces namespaces, OutputStream output)
      throws IOException {
    SerializeFormat.DataValue.Builder builder =
        XmlResourceValues.newSerializableDataValueBuilder(sourceId);
    SerializeFormat.DataValueXml.Builder xmlValueBuilder =
        SerializeFormat.DataValueXml.newBuilder();
    xmlValueBuilder
        .setType(SerializeFormat.DataValueXml.XmlType.ATTR)
        .putAllNamespace(namespaces.asMap());
    for (Map.Entry<String, ResourceXmlAttrValue> entry : formats.entrySet()) {
      xmlValueBuilder.putMappedXmlValue(
          entry.getKey(), entry.getValue().appendTo(builder.getXmlValueBuilder()));
    }
    builder.setXmlValue(xmlValueBuilder);
    return XmlResourceValues.serializeProtoDataValue(output, builder);
  }

  @Override
  public XmlResourceValue combineWith(XmlResourceValue value) {
    throw new IllegalArgumentException(this + " is not a combinable resource.");
  }

  @Override
  public int compareMergePriorityTo(XmlResourceValue value) {
    Preconditions.checkNotNull(value);
    if (!(value instanceof AttrXmlResourceValue)) {
      // NOTE(bcsf): I don't think this can happen. The resource type makes up part of the DataKey,
      // so there would never be a collision between resources of different types.
      throw new IllegalArgumentException(
          String.format(
              "Can only compare priority with another %s, but was given a %s",
              AttrXmlResourceValue.class.getSimpleName(), value.getClass().getSimpleName()));
    }
    AttrXmlResourceValue that = (AttrXmlResourceValue) value;
    if (!weak && that.weak && (that.formats.isEmpty() || formats.equals(that.formats))) {
      return 1;
    } else if (!that.weak && weak && (formats.isEmpty() || formats.equals(that.formats))) {
      return -1;
    } else if (weak && that.weak) {
      if (!formats.isEmpty() && that.formats.isEmpty()) {
        return 1;
      } else if (formats.isEmpty() && !that.formats.isEmpty()) {
        return -1;
      }
    }
    return 0;
  }

  /** Represents the xml value for an attr definition. */
  @CheckReturnValue
  public interface ResourceXmlAttrValue {

    ValuesResourceDefinition writeTo(ValuesResourceDefinition writer);

    SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder);

    void writeToClass(AndroidResourceSymbolSink writer);
  }

  // TODO(corysmith): The ResourceXmlAttrValue implementors, other than enum and flag, share a
  // lot of boilerplate. Determine how to reduce it.
  /** Represents an Android Enum Attribute resource. */
  @VisibleForTesting
  public static class EnumResourceXmlAttrValue implements ResourceXmlAttrValue {

    private Map<String, String> values;

    private EnumResourceXmlAttrValue(Map<String, String> values) {
      this.values = values;
    }

    @VisibleForTesting
    public static Map.Entry<String, ResourceXmlAttrValue> asEntryOf(String... keyThenValue) {
      Preconditions.checkArgument(keyThenValue.length > 0);
      Preconditions.checkArgument(keyThenValue.length % 2 == 0);
      ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
      for (int i = 0; i < keyThenValue.length; i += 2) {
        builder.put(keyThenValue[i], keyThenValue[i + 1]);
      }
      return new BuilderEntry(ENUM, of(builder.build()));
    }

    public static ResourceXmlAttrValue of(Map<String, String> values) {
      return new EnumResourceXmlAttrValue(values);
    }

    @Override
    public int hashCode() {
      return values.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof EnumResourceXmlAttrValue)) {
        return false;
      }
      EnumResourceXmlAttrValue other = (EnumResourceXmlAttrValue) obj;
      return Objects.equals(values, other.values);
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(getClass()).add("values", values).toString();
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.putAllMappedStringValue(values).build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      for (Map.Entry<String, String> entry : values.entrySet()) {
        writer =
            writer
                .startTag("enum")
                .attribute("name")
                .setTo(entry.getKey())
                .attribute("value")
                .setTo(entry.getValue())
                .closeUnaryTag()
                .addCharactersOf("\n");
      }
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {
      for (Map.Entry<String, String> entry : values.entrySet()) {
        writer.acceptSimpleResource(ResourceType.ID, entry.getKey());
      }
    }
  }

  /** Represents an Android Flag Attribute resource. */
  @VisibleForTesting
  public static class FlagResourceXmlAttrValue implements ResourceXmlAttrValue {

    private Map<String, String> values;

    private FlagResourceXmlAttrValue(Map<String, String> values) {
      this.values = values;
    }

    public static ResourceXmlAttrValue of(Map<String, String> values) {
      // ImmutableMap guarantees a stable order.
      return new FlagResourceXmlAttrValue(ImmutableMap.copyOf(values));
    }

    @VisibleForTesting
    public static Map.Entry<String, ResourceXmlAttrValue> asEntryOf(String... keyThenValue) {
      ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
      Preconditions.checkArgument(keyThenValue.length > 0);
      Preconditions.checkArgument(keyThenValue.length % 2 == 0);
      for (int i = 0; i < keyThenValue.length; i += 2) {
        builder.put(keyThenValue[i], keyThenValue[i + 1]);
      }
      return new BuilderEntry(FLAGS, of(builder.build()));
    }

    @Override
    public int hashCode() {
      return values.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof FlagResourceXmlAttrValue)) {
        return false;
      }
      FlagResourceXmlAttrValue other = (FlagResourceXmlAttrValue) obj;
      return Objects.equals(values, other.values);
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(getClass()).add("values", values).toString();
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.putAllMappedStringValue(values).build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      for (Map.Entry<String, String> entry : values.entrySet()) {
        writer =
            writer
                .startTag("flag")
                .attribute("name")
                .setTo(entry.getKey())
                .attribute("value")
                .setTo(entry.getValue())
                .closeUnaryTag();
      }
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {
      for (Map.Entry<String, String> entry : values.entrySet()) {
        writer.acceptSimpleResource(ResourceType.ID, entry.getKey());
      }
    }
  }

  /** Represents an Android Reference Attribute resource. */
  @VisibleForTesting
  public static class ReferenceResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final ReferenceResourceXmlAttrValue INSTANCE =
        new ReferenceResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(REFERENCE, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  /** Represents an Android Color Attribute resource. */
  @VisibleForTesting
  public static class ColorResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final ColorResourceXmlAttrValue INSTANCE = new ColorResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(COLOR, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  /** Represents an Android Boolean Attribute resource. */
  @VisibleForTesting
  public static class BooleanResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final BooleanResourceXmlAttrValue INSTANCE = new BooleanResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(BOOLEAN, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  /** Represents an Android Float Attribute resource. */
  @VisibleForTesting
  public static class FloatResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final FloatResourceXmlAttrValue INSTANCE = new FloatResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(FLOAT, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  /** Represents an Android Dimension Attribute resource. */
  @VisibleForTesting
  public static class DimensionResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final DimensionResourceXmlAttrValue INSTANCE =
        new DimensionResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(DIMENSION, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  /** Represents an Android Integer Attribute resource. */
  @VisibleForTesting
  public static class IntegerResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final IntegerResourceXmlAttrValue INSTANCE = new IntegerResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(INTEGER, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  /** Represents an Android String Attribute resource. */
  @VisibleForTesting
  public static class StringResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final StringResourceXmlAttrValue INSTANCE = new StringResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(STRING, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  /** Represents an Android Fraction Attribute resource. */
  @VisibleForTesting
  public static class FractionResourceXmlAttrValue implements ResourceXmlAttrValue {
    private static final FractionResourceXmlAttrValue INSTANCE = new FractionResourceXmlAttrValue();

    public static ResourceXmlAttrValue of() {
      return INSTANCE;
    }

    @VisibleForTesting
    public static BuilderEntry asEntry() {
      return new BuilderEntry(FRACTION, of());
    }

    @Override
    public SerializeFormat.DataValueXml appendTo(SerializeFormat.DataValueXml.Builder builder) {
      return builder.build();
    }

    @Override
    public ValuesResourceDefinition writeTo(ValuesResourceDefinition writer) {
      return writer;
    }

    @Override
    public void writeToClass(AndroidResourceSymbolSink writer) {}
  }

  @Override
  public String asConflictStringWith(DataSource source) {
    return String.format(
        "%s [format(s): %s], [weak: %s]",
        source.asConflictString(), String.join("|", this.formats.keySet()), weak);
  }
}
