* Standardize attribute storage in the proto
* Add attributes to PluralXmlResourceValue

--
MOS_MIGRATED_REVID=127147486
diff --git a/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java b/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java
index 242a74b..a72d063 100644
--- a/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java
+++ b/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java
@@ -171,7 +171,7 @@
       case ARRAY:
         return ArrayXmlResourceValue.parseArray(eventReader, start);
       case PLURALS:
-        return XmlResourceValues.parsePlurals(eventReader);
+        return XmlResourceValues.parsePlurals(eventReader, start);
       case ATTR:
         return XmlResourceValues.parseAttr(eventReader, start);
       case LAYOUT:
diff --git a/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java b/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java
index c154a19..411be94 100644
--- a/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java
+++ b/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java
@@ -96,7 +96,8 @@
     return inputFactoryInstance;
   }
 
-  static XmlResourceValue parsePlurals(XMLEventReader eventReader) throws XMLStreamException {
+  static XmlResourceValue parsePlurals(XMLEventReader eventReader, StartElement start)
+      throws XMLStreamException {
     ImmutableMap.Builder<String, String> values = ImmutableMap.builder();
     for (XMLEvent element = nextTag(eventReader);
         !isEndTag(element, TAG_PLURALS);
@@ -112,7 +113,8 @@
             contents == null ? "" : contents);
       }
     }
-    return PluralXmlResourceValue.of(values.build());
+    return PluralXmlResourceValue.createWithAttributesAndValues(
+        ImmutableMap.copyOf(parseTagAttributes(start)), values.build());
   }
 
   static XmlResourceValue parseStyle(XMLEventReader eventReader, StartElement start)
diff --git a/src/tools/android/java/com/google/devtools/build/android/proto/serialize_format.proto b/src/tools/android/java/com/google/devtools/build/android/proto/serialize_format.proto
index e546aa0..66f418e 100644
--- a/src/tools/android/java/com/google/devtools/build/android/proto/serialize_format.proto
+++ b/src/tools/android/java/com/google/devtools/build/android/proto/serialize_format.proto
@@ -75,4 +75,5 @@
   optional string value = 5;
   optional string value_type = 6;
   repeated DataKey references = 7;
+  map<string, string> attribute = 8;
 }
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java
index 3819d86..5c9d64b 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java
@@ -115,7 +115,7 @@
     return of(
         ArrayType.valueOf(proto.getValueType()),
         proto.getListValueList(),
-        ImmutableMap.copyOf(proto.getMappedStringValue()));
+        ImmutableMap.copyOf(proto.getAttribute()));
   }
 
   @Override
@@ -147,7 +147,7 @@
                 SerializeFormat.DataValueXml.newBuilder()
                     .addAllListValue(values)
                     .setType(SerializeFormat.DataValueXml.XmlType.ARRAY)
-                    .putAllMappedStringValue(attributes)
+                    .putAllAttribute(attributes)
                     .setValueType(arrayType.toString())));
   }
 
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java
index 64cc8e8c..29b2a26 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java
@@ -54,19 +54,36 @@
 
   private final ImmutableMap<String, String> values;
 
-  private PluralXmlResourceValue(ImmutableMap<String, String> values) {
+  private final ImmutableMap<String, String> attributes;
+
+  private PluralXmlResourceValue(
+      ImmutableMap<String, String> attributes, ImmutableMap<String, String> values) {
+    this.attributes = attributes;
     this.values = values;
   }
 
-  public static XmlResourceValue of(ImmutableMap<String, String> values) {
-    return new PluralXmlResourceValue(values);
+  public static XmlResourceValue createWithoutAttributes(ImmutableMap<String, String> values) {
+    return createWithAttributesAndValues(ImmutableMap.<String, String>of(), values);
+  }
+
+  public static XmlResourceValue createWithAttributesAndValues(
+      ImmutableMap<String, String> attributes, ImmutableMap<String, String> values) {
+    return new PluralXmlResourceValue(attributes, values);
   }
 
   @Override
   public void write(
       FullyQualifiedName key, Path source, AndroidDataWritingVisitor mergedDataWriter) {
+
     ValuesResourceDefinition definition =
-        mergedDataWriter.define(key).derivedFrom(source).startTag(PLURALS).named(key).closeTag();
+        mergedDataWriter
+            .define(key)
+            .derivedFrom(source)
+            .startTag(PLURALS)
+            .named(key)
+            .addAttributesFrom(attributes.entrySet())
+            .closeTag();
+
     for (Entry<String, String> plural : values.entrySet()) {
       definition =
           definition
@@ -83,7 +100,7 @@
 
   @Override
   public int hashCode() {
-    return values.hashCode();
+    return Objects.hash(attributes, values);
   }
 
   @Override
@@ -92,17 +109,22 @@
       return false;
     }
     PluralXmlResourceValue other = (PluralXmlResourceValue) obj;
-    return Objects.equals(values, other.values);
+    return Objects.equals(values, other.values) && Objects.equals(attributes, other.attributes);
   }
 
   @Override
   public String toString() {
-    return MoreObjects.toStringHelper(getClass()).add("values", values).toString();
+    return MoreObjects.toStringHelper(getClass())
+        .add("values", values)
+        .add("attributes", attributes)
+        .toString();
   }
 
   @SuppressWarnings("deprecation")
   public static XmlResourceValue from(SerializeFormat.DataValueXml proto) {
-    return of(ImmutableMap.copyOf(proto.getMappedStringValue()));
+    return createWithAttributesAndValues(
+        ImmutableMap.copyOf(proto.getAttribute()),
+        ImmutableMap.copyOf(proto.getMappedStringValue()));
   }
 
   @Override
@@ -115,6 +137,7 @@
                 builder
                     .getXmlValueBuilder()
                     .setType(XmlType.PLURAL)
+                    .putAllAttribute(attributes)
                     .putAllMappedStringValue(values))
             .build();
     value.writeDelimitedTo(output);
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java
index 7feb695..3e308a1 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java
@@ -209,7 +209,7 @@
   public static XmlResourceValue from(SerializeFormat.DataValueXml proto) {
     return of(
         Type.valueOf(proto.getValueType()),
-        ImmutableMap.copyOf(proto.getMappedStringValue()),
+        ImmutableMap.copyOf(proto.getAttribute()),
         proto.hasValue() ? proto.getValue() : null);
   }
 
@@ -223,7 +223,7 @@
             .setType(SerializeFormat.DataValueXml.XmlType.SIMPLE)
             // TODO(corysmith): Find a way to avoid writing strings to the serialized format
             // it's inefficient use of space and costs more when deserializing.
-            .putAllMappedStringValue(attributes);
+            .putAllAttribute(attributes);
     if (value != null) {
       xmlValueBuilder.setValue(value);
     }