XML deserialization for <macro>
Macro deserialization support is necessary for AarGeneratorAction to run successfully on macro resources.
PiperOrigin-RevId: 391055662
diff --git a/src/test/java/com/google/devtools/build/android/DataResourceXmlTest.java b/src/test/java/com/google/devtools/build/android/DataResourceXmlTest.java
index e44fba2..45fe210 100644
--- a/src/test/java/com/google/devtools/build/android/DataResourceXmlTest.java
+++ b/src/test/java/com/google/devtools/build/android/DataResourceXmlTest.java
@@ -15,6 +15,7 @@
import static com.google.common.truth.Truth.assertAbout;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
import com.android.resources.ResourceType;
import com.google.common.base.Function;
@@ -1033,6 +1034,19 @@
}
@Test
+ public void writeMacroXmlResource() throws Exception {
+ // TODO(b/193025750): The current version of the layoutlib prebuilt used by Bazel does not
+ // contain the macro type.
+ assumeTrue(ResourceType.getEnum("macro") != null);
+
+ String xml = "<macro name='foo'>@string/bar</macro>";
+ Path source = writeResourceXml(xml);
+ assertAbout(resourcePaths)
+ .that(parsedAndWritten(source, fqn("macro/foo")))
+ .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
+ }
+
+ @Test
public void serializeMultipleSimpleXmlResources() throws Exception {
Path serialized = fs.getPath("out/out.bin");
Path source = fs.getPath("res/values/values.xml");
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 38c3d0ed..7d56958 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
@@ -323,6 +323,12 @@
case XML:
return XmlResourceValues.parseSimple(eventReader, resourceType, start, namespacesCollector);
default:
+ // TODO(b/193025750): The current version of the layoutlib prebuilt used by Bazel does not
+ // contain the macro type. This work around allows using macro resource types internally
+ // until the layoutlib preuilt is updated or the dependency on it is removed.
+ if ("macro".equals(resourceType.getName())) {
+ return XmlResourceValues.parseMacro(eventReader, start, namespacesCollector);
+ }
throw new XMLStreamException(
String.format("Unhandled resourceType %s", resourceType), start.getLocation());
}
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 f7b97a1..9967577 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
@@ -22,6 +22,7 @@
import com.google.devtools.build.android.proto.SerializeFormat;
import com.google.devtools.build.android.xml.AttrXmlResourceValue;
import com.google.devtools.build.android.xml.IdXmlResourceValue;
+import com.google.devtools.build.android.xml.MacroXmlResourceValue;
import com.google.devtools.build.android.xml.Namespaces;
import com.google.devtools.build.android.xml.PluralXmlResourceValue;
import com.google.devtools.build.android.xml.PublicXmlResourceValue;
@@ -279,6 +280,18 @@
return attributeMap;
}
+ static XmlResourceValue parseMacro(
+ XMLEventReader eventReader, StartElement start, Namespaces.Collector namespacesCollector)
+ throws XMLStreamException {
+ if (isEndTag(eventReader.peek(), start.getName())) {
+ throw new XMLStreamException(
+ String.format("<macro> must have contents %s", start), start.getLocation());
+ }
+
+ String contents = readContentsAsString(eventReader, start.getName(), namespacesCollector);
+ return MacroXmlResourceValue.of(contents);
+ }
+
// TODO(corysmith): Replace this with real escaping system, preferably a performant high level xml
// writing library. See AndroidDataWritingVisitor TODO.
private static String escapeXmlValues(String data) {