Use Google3 style guide with .clang-format

Test: style change only, builds ok
Change-Id: I885180e24cb2e7b58cfb4967c3bcb40058ce4078
diff --git a/tools/aapt2/flatten/Archive.cpp b/tools/aapt2/flatten/Archive.cpp
index 3a244c0..ae08f65 100644
--- a/tools/aapt2/flatten/Archive.cpp
+++ b/tools/aapt2/flatten/Archive.cpp
@@ -18,167 +18,169 @@
 #include "util/Files.h"
 #include "util/StringPiece.h"
 
+#include <ziparchive/zip_writer.h>
 #include <cstdio>
 #include <memory>
 #include <string>
 #include <vector>
-#include <ziparchive/zip_writer.h>
 
 namespace aapt {
 
 namespace {
 
 struct DirectoryWriter : public IArchiveWriter {
-    std::string mOutDir;
-    std::unique_ptr<FILE, decltype(fclose)*> mFile = { nullptr, fclose };
+  std::string mOutDir;
+  std::unique_ptr<FILE, decltype(fclose)*> mFile = {nullptr, fclose};
 
-    bool open(IDiagnostics* diag, const StringPiece& outDir) {
-        mOutDir = outDir.toString();
-        file::FileType type = file::getFileType(mOutDir);
-        if (type == file::FileType::kNonexistant) {
-            diag->error(DiagMessage() << "directory " << mOutDir << " does not exist");
-            return false;
-        } else if (type != file::FileType::kDirectory) {
-            diag->error(DiagMessage() << mOutDir << " is not a directory");
-            return false;
-        }
-        return true;
+  bool open(IDiagnostics* diag, const StringPiece& outDir) {
+    mOutDir = outDir.toString();
+    file::FileType type = file::getFileType(mOutDir);
+    if (type == file::FileType::kNonexistant) {
+      diag->error(DiagMessage() << "directory " << mOutDir
+                                << " does not exist");
+      return false;
+    } else if (type != file::FileType::kDirectory) {
+      diag->error(DiagMessage() << mOutDir << " is not a directory");
+      return false;
+    }
+    return true;
+  }
+
+  bool startEntry(const StringPiece& path, uint32_t flags) override {
+    if (mFile) {
+      return false;
     }
 
-    bool startEntry(const StringPiece& path, uint32_t flags) override {
-        if (mFile) {
-            return false;
-        }
+    std::string fullPath = mOutDir;
+    file::appendPath(&fullPath, path);
+    file::mkdirs(file::getStem(fullPath));
 
-        std::string fullPath = mOutDir;
-        file::appendPath(&fullPath, path);
-        file::mkdirs(file::getStem(fullPath));
+    mFile = {fopen(fullPath.data(), "wb"), fclose};
+    if (!mFile) {
+      return false;
+    }
+    return true;
+  }
 
-        mFile = { fopen(fullPath.data(), "wb"), fclose };
-        if (!mFile) {
-            return false;
-        }
-        return true;
+  bool writeEntry(const BigBuffer& buffer) override {
+    if (!mFile) {
+      return false;
     }
 
-    bool writeEntry(const BigBuffer& buffer) override {
-        if (!mFile) {
-            return false;
-        }
-
-        for (const BigBuffer::Block& b : buffer) {
-            if (fwrite(b.buffer.get(), 1, b.size, mFile.get()) != b.size) {
-                mFile.reset(nullptr);
-                return false;
-            }
-        }
-        return true;
-    }
-
-    bool writeEntry(const void* data, size_t len) override {
-        if (fwrite(data, 1, len, mFile.get()) != len) {
-            mFile.reset(nullptr);
-            return false;
-        }
-        return true;
-    }
-
-    bool finishEntry() override {
-        if (!mFile) {
-            return false;
-        }
+    for (const BigBuffer::Block& b : buffer) {
+      if (fwrite(b.buffer.get(), 1, b.size, mFile.get()) != b.size) {
         mFile.reset(nullptr);
-        return true;
+        return false;
+      }
     }
+    return true;
+  }
+
+  bool writeEntry(const void* data, size_t len) override {
+    if (fwrite(data, 1, len, mFile.get()) != len) {
+      mFile.reset(nullptr);
+      return false;
+    }
+    return true;
+  }
+
+  bool finishEntry() override {
+    if (!mFile) {
+      return false;
+    }
+    mFile.reset(nullptr);
+    return true;
+  }
 };
 
 struct ZipFileWriter : public IArchiveWriter {
-    std::unique_ptr<FILE, decltype(fclose)*> mFile = { nullptr, fclose };
-    std::unique_ptr<ZipWriter> mWriter;
+  std::unique_ptr<FILE, decltype(fclose)*> mFile = {nullptr, fclose};
+  std::unique_ptr<ZipWriter> mWriter;
 
-    bool open(IDiagnostics* diag, const StringPiece& path) {
-        mFile = { fopen(path.data(), "w+b"), fclose };
-        if (!mFile) {
-            diag->error(DiagMessage() << "failed to open " << path << ": " << strerror(errno));
-            return false;
-        }
-        mWriter = util::make_unique<ZipWriter>(mFile.get());
-        return true;
+  bool open(IDiagnostics* diag, const StringPiece& path) {
+    mFile = {fopen(path.data(), "w+b"), fclose};
+    if (!mFile) {
+      diag->error(DiagMessage() << "failed to open " << path << ": "
+                                << strerror(errno));
+      return false;
+    }
+    mWriter = util::make_unique<ZipWriter>(mFile.get());
+    return true;
+  }
+
+  bool startEntry(const StringPiece& path, uint32_t flags) override {
+    if (!mWriter) {
+      return false;
     }
 
-    bool startEntry(const StringPiece& path, uint32_t flags) override {
-        if (!mWriter) {
-            return false;
-        }
-
-        size_t zipFlags = 0;
-        if (flags & ArchiveEntry::kCompress) {
-            zipFlags |= ZipWriter::kCompress;
-        }
-
-        if (flags & ArchiveEntry::kAlign) {
-            zipFlags |= ZipWriter::kAlign32;
-        }
-
-        int32_t result = mWriter->StartEntry(path.data(), zipFlags);
-        if (result != 0) {
-            return false;
-        }
-        return true;
+    size_t zipFlags = 0;
+    if (flags & ArchiveEntry::kCompress) {
+      zipFlags |= ZipWriter::kCompress;
     }
 
-    bool writeEntry(const void* data, size_t len) override {
-        int32_t result = mWriter->WriteBytes(data, len);
-        if (result != 0) {
-            return false;
-        }
-        return true;
+    if (flags & ArchiveEntry::kAlign) {
+      zipFlags |= ZipWriter::kAlign32;
     }
 
-    bool writeEntry(const BigBuffer& buffer) override {
-        for (const BigBuffer::Block& b : buffer) {
-            int32_t result = mWriter->WriteBytes(b.buffer.get(), b.size);
-            if (result != 0) {
-                return false;
-            }
-        }
-        return true;
+    int32_t result = mWriter->StartEntry(path.data(), zipFlags);
+    if (result != 0) {
+      return false;
     }
+    return true;
+  }
 
-    bool finishEntry() override {
-        int32_t result = mWriter->FinishEntry();
-        if (result != 0) {
-            return false;
-        }
-        return true;
+  bool writeEntry(const void* data, size_t len) override {
+    int32_t result = mWriter->WriteBytes(data, len);
+    if (result != 0) {
+      return false;
     }
+    return true;
+  }
 
-    virtual ~ZipFileWriter() {
-        if (mWriter) {
-            mWriter->Finish();
-        }
+  bool writeEntry(const BigBuffer& buffer) override {
+    for (const BigBuffer::Block& b : buffer) {
+      int32_t result = mWriter->WriteBytes(b.buffer.get(), b.size);
+      if (result != 0) {
+        return false;
+      }
     }
+    return true;
+  }
+
+  bool finishEntry() override {
+    int32_t result = mWriter->FinishEntry();
+    if (result != 0) {
+      return false;
+    }
+    return true;
+  }
+
+  virtual ~ZipFileWriter() {
+    if (mWriter) {
+      mWriter->Finish();
+    }
+  }
 };
 
-} // namespace
+}  // namespace
 
-std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(IDiagnostics* diag,
-                                                             const StringPiece& path) {
-
-    std::unique_ptr<DirectoryWriter> writer = util::make_unique<DirectoryWriter>();
-    if (!writer->open(diag, path)) {
-        return {};
-    }
-    return std::move(writer);
+std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(
+    IDiagnostics* diag, const StringPiece& path) {
+  std::unique_ptr<DirectoryWriter> writer =
+      util::make_unique<DirectoryWriter>();
+  if (!writer->open(diag, path)) {
+    return {};
+  }
+  return std::move(writer);
 }
 
-std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(IDiagnostics* diag,
-                                                           const StringPiece& path) {
-    std::unique_ptr<ZipFileWriter> writer = util::make_unique<ZipFileWriter>();
-    if (!writer->open(diag, path)) {
-        return {};
-    }
-    return std::move(writer);
+std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(
+    IDiagnostics* diag, const StringPiece& path) {
+  std::unique_ptr<ZipFileWriter> writer = util::make_unique<ZipFileWriter>();
+  if (!writer->open(diag, path)) {
+    return {};
+  }
+  return std::move(writer);
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/flatten/Archive.h b/tools/aapt2/flatten/Archive.h
index 96d8512..46cd0ac 100644
--- a/tools/aapt2/flatten/Archive.h
+++ b/tools/aapt2/flatten/Archive.h
@@ -31,37 +31,37 @@
 namespace aapt {
 
 struct ArchiveEntry {
-    enum : uint32_t {
-        kCompress = 0x01,
-        kAlign    = 0x02,
-    };
+  enum : uint32_t {
+    kCompress = 0x01,
+    kAlign = 0x02,
+  };
 
-    std::string path;
-    uint32_t flags;
-    size_t uncompressedSize;
+  std::string path;
+  uint32_t flags;
+  size_t uncompressedSize;
 };
 
 class IArchiveWriter : public google::protobuf::io::CopyingOutputStream {
-public:
-    virtual ~IArchiveWriter() = default;
+ public:
+  virtual ~IArchiveWriter() = default;
 
-    virtual bool startEntry(const StringPiece& path, uint32_t flags) = 0;
-    virtual bool writeEntry(const BigBuffer& buffer) = 0;
-    virtual bool writeEntry(const void* data, size_t len) = 0;
-    virtual bool finishEntry() = 0;
+  virtual bool startEntry(const StringPiece& path, uint32_t flags) = 0;
+  virtual bool writeEntry(const BigBuffer& buffer) = 0;
+  virtual bool writeEntry(const void* data, size_t len) = 0;
+  virtual bool finishEntry() = 0;
 
-    // CopyingOutputStream implementations.
-    bool Write(const void* buffer, int size) override {
-        return writeEntry(buffer, size);
-    }
+  // CopyingOutputStream implementations.
+  bool Write(const void* buffer, int size) override {
+    return writeEntry(buffer, size);
+  }
 };
 
-std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(IDiagnostics* diag,
-                                                             const StringPiece& path);
+std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(
+    IDiagnostics* diag, const StringPiece& path);
 
-std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(IDiagnostics* diag,
-                                                           const StringPiece& path);
+std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(
+    IDiagnostics* diag, const StringPiece& path);
 
-} // namespace aapt
+}  // namespace aapt
 
 #endif /* AAPT_FLATTEN_ARCHIVE_H */
diff --git a/tools/aapt2/flatten/ChunkWriter.h b/tools/aapt2/flatten/ChunkWriter.h
index de1d87a..852afd4 100644
--- a/tools/aapt2/flatten/ChunkWriter.h
+++ b/tools/aapt2/flatten/ChunkWriter.h
@@ -25,63 +25,56 @@
 namespace aapt {
 
 class ChunkWriter {
-private:
-    BigBuffer* mBuffer;
-    size_t mStartSize = 0;
-    android::ResChunk_header* mHeader = nullptr;
+ private:
+  BigBuffer* mBuffer;
+  size_t mStartSize = 0;
+  android::ResChunk_header* mHeader = nullptr;
 
-public:
-    explicit inline ChunkWriter(BigBuffer* buffer) : mBuffer(buffer) {
-    }
+ public:
+  explicit inline ChunkWriter(BigBuffer* buffer) : mBuffer(buffer) {}
 
-    ChunkWriter(const ChunkWriter&) = delete;
-    ChunkWriter& operator=(const ChunkWriter&) = delete;
-    ChunkWriter(ChunkWriter&&) = default;
-    ChunkWriter& operator=(ChunkWriter&&) = default;
+  ChunkWriter(const ChunkWriter&) = delete;
+  ChunkWriter& operator=(const ChunkWriter&) = delete;
+  ChunkWriter(ChunkWriter&&) = default;
+  ChunkWriter& operator=(ChunkWriter&&) = default;
 
-    template <typename T>
-    inline T* startChunk(uint16_t type) {
-        mStartSize = mBuffer->size();
-        T* chunk = mBuffer->nextBlock<T>();
-        mHeader = &chunk->header;
-        mHeader->type = util::hostToDevice16(type);
-        mHeader->headerSize = util::hostToDevice16(sizeof(T));
-        return chunk;
-    }
+  template <typename T>
+  inline T* startChunk(uint16_t type) {
+    mStartSize = mBuffer->size();
+    T* chunk = mBuffer->nextBlock<T>();
+    mHeader = &chunk->header;
+    mHeader->type = util::hostToDevice16(type);
+    mHeader->headerSize = util::hostToDevice16(sizeof(T));
+    return chunk;
+  }
 
-    template <typename T>
-    inline T* nextBlock(size_t count = 1) {
-        return mBuffer->nextBlock<T>(count);
-    }
+  template <typename T>
+  inline T* nextBlock(size_t count = 1) {
+    return mBuffer->nextBlock<T>(count);
+  }
 
-    inline BigBuffer* getBuffer() {
-        return mBuffer;
-    }
+  inline BigBuffer* getBuffer() { return mBuffer; }
 
-    inline android::ResChunk_header* getChunkHeader() {
-        return mHeader;
-    }
+  inline android::ResChunk_header* getChunkHeader() { return mHeader; }
 
-    inline size_t size() {
-        return mBuffer->size() - mStartSize;
-    }
+  inline size_t size() { return mBuffer->size() - mStartSize; }
 
-    inline android::ResChunk_header* finish() {
-        mBuffer->align4();
-        mHeader->size = util::hostToDevice32(mBuffer->size() - mStartSize);
-        return mHeader;
-    }
+  inline android::ResChunk_header* finish() {
+    mBuffer->align4();
+    mHeader->size = util::hostToDevice32(mBuffer->size() - mStartSize);
+    return mHeader;
+  }
 };
 
 template <>
 inline android::ResChunk_header* ChunkWriter::startChunk(uint16_t type) {
-    mStartSize = mBuffer->size();
-    mHeader = mBuffer->nextBlock<android::ResChunk_header>();
-    mHeader->type = util::hostToDevice16(type);
-    mHeader->headerSize = util::hostToDevice16(sizeof(android::ResChunk_header));
-    return mHeader;
+  mStartSize = mBuffer->size();
+  mHeader = mBuffer->nextBlock<android::ResChunk_header>();
+  mHeader->type = util::hostToDevice16(type);
+  mHeader->headerSize = util::hostToDevice16(sizeof(android::ResChunk_header));
+  return mHeader;
 }
 
-} // namespace aapt
+}  // namespace aapt
 
 #endif /* AAPT_FLATTEN_CHUNKWRITER_H */
diff --git a/tools/aapt2/flatten/ResourceTypeExtensions.h b/tools/aapt2/flatten/ResourceTypeExtensions.h
index 3e20ad6..0b19240 100644
--- a/tools/aapt2/flatten/ResourceTypeExtensions.h
+++ b/tools/aapt2/flatten/ResourceTypeExtensions.h
@@ -22,15 +22,16 @@
 namespace aapt {
 
 /**
- * An alternative struct to use instead of ResTable_map_entry. This one is a standard_layout
+ * An alternative struct to use instead of ResTable_map_entry. This one is a
+ * standard_layout
  * struct.
  */
 struct ResTable_entry_ext {
-    android::ResTable_entry entry;
-    android::ResTable_ref parent;
-    uint32_t count;
+  android::ResTable_entry entry;
+  android::ResTable_ref parent;
+  uint32_t count;
 };
 
-} // namespace aapt
+}  // namespace aapt
 
-#endif // AAPT_RESOURCE_TYPE_EXTENSIONS_H
+#endif  // AAPT_RESOURCE_TYPE_EXTENSIONS_H
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index d5067b1..d4ea6c0 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -25,9 +25,9 @@
 
 #include <android-base/macros.h>
 #include <algorithm>
+#include <numeric>
 #include <sstream>
 #include <type_traits>
-#include <numeric>
 
 using namespace android;
 
@@ -37,438 +37,454 @@
 
 template <typename T>
 static bool cmpIds(const T* a, const T* b) {
-    return a->id.value() < b->id.value();
+  return a->id.value() < b->id.value();
 }
 
 static void strcpy16_htod(uint16_t* dst, size_t len, const StringPiece16& src) {
-    if (len == 0) {
-        return;
-    }
+  if (len == 0) {
+    return;
+  }
 
-    size_t i;
-    const char16_t* srcData = src.data();
-    for (i = 0; i < len - 1 && i < src.size(); i++) {
-        dst[i] = util::hostToDevice16((uint16_t) srcData[i]);
-    }
-    dst[i] = 0;
+  size_t i;
+  const char16_t* srcData = src.data();
+  for (i = 0; i < len - 1 && i < src.size(); i++) {
+    dst[i] = util::hostToDevice16((uint16_t)srcData[i]);
+  }
+  dst[i] = 0;
 }
 
 static bool cmpStyleEntries(const Style::Entry& a, const Style::Entry& b) {
-   if (a.key.id) {
-       if (b.key.id) {
-           return a.key.id.value() < b.key.id.value();
-       }
-       return true;
-   } else if (!b.key.id) {
-       return a.key.name.value() < b.key.name.value();
-   }
-   return false;
+  if (a.key.id) {
+    if (b.key.id) {
+      return a.key.id.value() < b.key.id.value();
+    }
+    return true;
+  } else if (!b.key.id) {
+    return a.key.name.value() < b.key.name.value();
+  }
+  return false;
 }
 
 struct FlatEntry {
-    ResourceEntry* entry;
-    Value* value;
+  ResourceEntry* entry;
+  Value* value;
 
-    // The entry string pool index to the entry's name.
-    uint32_t entryKey;
+  // The entry string pool index to the entry's name.
+  uint32_t entryKey;
 };
 
 class MapFlattenVisitor : public RawValueVisitor {
-public:
-    using RawValueVisitor::visit;
+ public:
+  using RawValueVisitor::visit;
 
-    MapFlattenVisitor(ResTable_entry_ext* outEntry, BigBuffer* buffer) :
-            mOutEntry(outEntry), mBuffer(buffer) {
+  MapFlattenVisitor(ResTable_entry_ext* outEntry, BigBuffer* buffer)
+      : mOutEntry(outEntry), mBuffer(buffer) {}
+
+  void visit(Attribute* attr) override {
+    {
+      Reference key = Reference(ResourceId(ResTable_map::ATTR_TYPE));
+      BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->typeMask);
+      flattenEntry(&key, &val);
     }
 
-    void visit(Attribute* attr) override {
-        {
-            Reference key = Reference(ResourceId(ResTable_map::ATTR_TYPE));
-            BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->typeMask);
-            flattenEntry(&key, &val);
-        }
-
-        if (attr->minInt != std::numeric_limits<int32_t>::min()) {
-            Reference key = Reference(ResourceId(ResTable_map::ATTR_MIN));
-            BinaryPrimitive val(Res_value::TYPE_INT_DEC, static_cast<uint32_t>(attr->minInt));
-            flattenEntry(&key, &val);
-        }
-
-        if (attr->maxInt != std::numeric_limits<int32_t>::max()) {
-            Reference key = Reference(ResourceId(ResTable_map::ATTR_MAX));
-            BinaryPrimitive val(Res_value::TYPE_INT_DEC, static_cast<uint32_t>(attr->maxInt));
-            flattenEntry(&key, &val);
-        }
-
-        for (Attribute::Symbol& s : attr->symbols) {
-            BinaryPrimitive val(Res_value::TYPE_INT_DEC, s.value);
-            flattenEntry(&s.symbol, &val);
-        }
+    if (attr->minInt != std::numeric_limits<int32_t>::min()) {
+      Reference key = Reference(ResourceId(ResTable_map::ATTR_MIN));
+      BinaryPrimitive val(Res_value::TYPE_INT_DEC,
+                          static_cast<uint32_t>(attr->minInt));
+      flattenEntry(&key, &val);
     }
 
-    void visit(Style* style) override {
-        if (style->parent) {
-            const Reference& parentRef = style->parent.value();
-            assert(parentRef.id && "parent has no ID");
-            mOutEntry->parent.ident = util::hostToDevice32(parentRef.id.value().id);
-        }
-
-        // Sort the style.
-        std::sort(style->entries.begin(), style->entries.end(), cmpStyleEntries);
-
-        for (Style::Entry& entry : style->entries) {
-            flattenEntry(&entry.key, entry.value.get());
-        }
+    if (attr->maxInt != std::numeric_limits<int32_t>::max()) {
+      Reference key = Reference(ResourceId(ResTable_map::ATTR_MAX));
+      BinaryPrimitive val(Res_value::TYPE_INT_DEC,
+                          static_cast<uint32_t>(attr->maxInt));
+      flattenEntry(&key, &val);
     }
 
-    void visit(Styleable* styleable) override {
-        for (auto& attrRef : styleable->entries) {
-            BinaryPrimitive val(Res_value{});
-            flattenEntry(&attrRef, &val);
-        }
+    for (Attribute::Symbol& s : attr->symbols) {
+      BinaryPrimitive val(Res_value::TYPE_INT_DEC, s.value);
+      flattenEntry(&s.symbol, &val);
+    }
+  }
 
+  void visit(Style* style) override {
+    if (style->parent) {
+      const Reference& parentRef = style->parent.value();
+      assert(parentRef.id && "parent has no ID");
+      mOutEntry->parent.ident = util::hostToDevice32(parentRef.id.value().id);
     }
 
-    void visit(Array* array) override {
-        for (auto& item : array->items) {
-            ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
-            flattenValue(item.get(), outEntry);
-            outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
-            mEntryCount++;
-        }
+    // Sort the style.
+    std::sort(style->entries.begin(), style->entries.end(), cmpStyleEntries);
+
+    for (Style::Entry& entry : style->entries) {
+      flattenEntry(&entry.key, entry.value.get());
     }
+  }
 
-    void visit(Plural* plural) override {
-        const size_t count = plural->values.size();
-        for (size_t i = 0; i < count; i++) {
-            if (!plural->values[i]) {
-                continue;
-            }
-
-            ResourceId q;
-            switch (i) {
-            case Plural::Zero:
-                q.id = android::ResTable_map::ATTR_ZERO;
-                break;
-
-            case Plural::One:
-                q.id = android::ResTable_map::ATTR_ONE;
-                break;
-
-            case Plural::Two:
-                q.id = android::ResTable_map::ATTR_TWO;
-                break;
-
-            case Plural::Few:
-                q.id = android::ResTable_map::ATTR_FEW;
-                break;
-
-            case Plural::Many:
-                q.id = android::ResTable_map::ATTR_MANY;
-                break;
-
-            case Plural::Other:
-                q.id = android::ResTable_map::ATTR_OTHER;
-                break;
-
-            default:
-                assert(false);
-                break;
-            }
-
-            Reference key(q);
-            flattenEntry(&key, plural->values[i].get());
-        }
+  void visit(Styleable* styleable) override {
+    for (auto& attrRef : styleable->entries) {
+      BinaryPrimitive val(Res_value{});
+      flattenEntry(&attrRef, &val);
     }
+  }
 
-    /**
-     * Call this after visiting a Value. This will finish any work that
-     * needs to be done to prepare the entry.
-     */
-    void finish() {
-        mOutEntry->count = util::hostToDevice32(mEntryCount);
+  void visit(Array* array) override {
+    for (auto& item : array->items) {
+      ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
+      flattenValue(item.get(), outEntry);
+      outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
+      mEntryCount++;
     }
+  }
 
-private:
-    void flattenKey(Reference* key, ResTable_map* outEntry) {
-        assert(key->id && "key has no ID");
-        outEntry->name.ident = util::hostToDevice32(key->id.value().id);
+  void visit(Plural* plural) override {
+    const size_t count = plural->values.size();
+    for (size_t i = 0; i < count; i++) {
+      if (!plural->values[i]) {
+        continue;
+      }
+
+      ResourceId q;
+      switch (i) {
+        case Plural::Zero:
+          q.id = android::ResTable_map::ATTR_ZERO;
+          break;
+
+        case Plural::One:
+          q.id = android::ResTable_map::ATTR_ONE;
+          break;
+
+        case Plural::Two:
+          q.id = android::ResTable_map::ATTR_TWO;
+          break;
+
+        case Plural::Few:
+          q.id = android::ResTable_map::ATTR_FEW;
+          break;
+
+        case Plural::Many:
+          q.id = android::ResTable_map::ATTR_MANY;
+          break;
+
+        case Plural::Other:
+          q.id = android::ResTable_map::ATTR_OTHER;
+          break;
+
+        default:
+          assert(false);
+          break;
+      }
+
+      Reference key(q);
+      flattenEntry(&key, plural->values[i].get());
     }
+  }
 
-    void flattenValue(Item* value, ResTable_map* outEntry) {
-        bool result = value->flatten(&outEntry->value);
-        assert(result && "flatten failed");
-    }
+  /**
+   * Call this after visiting a Value. This will finish any work that
+   * needs to be done to prepare the entry.
+   */
+  void finish() { mOutEntry->count = util::hostToDevice32(mEntryCount); }
 
-    void flattenEntry(Reference* key, Item* value) {
-        ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
-        flattenKey(key, outEntry);
-        flattenValue(value, outEntry);
-        outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
-        mEntryCount++;
-    }
+ private:
+  void flattenKey(Reference* key, ResTable_map* outEntry) {
+    assert(key->id && "key has no ID");
+    outEntry->name.ident = util::hostToDevice32(key->id.value().id);
+  }
 
-    ResTable_entry_ext* mOutEntry;
-    BigBuffer* mBuffer;
-    size_t mEntryCount = 0;
+  void flattenValue(Item* value, ResTable_map* outEntry) {
+    bool result = value->flatten(&outEntry->value);
+    assert(result && "flatten failed");
+  }
+
+  void flattenEntry(Reference* key, Item* value) {
+    ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
+    flattenKey(key, outEntry);
+    flattenValue(value, outEntry);
+    outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
+    mEntryCount++;
+  }
+
+  ResTable_entry_ext* mOutEntry;
+  BigBuffer* mBuffer;
+  size_t mEntryCount = 0;
 };
 
 class PackageFlattener {
-public:
-    PackageFlattener(IDiagnostics* diag, ResourceTablePackage* package) :
-            mDiag(diag), mPackage(package) {
+ public:
+  PackageFlattener(IDiagnostics* diag, ResourceTablePackage* package)
+      : mDiag(diag), mPackage(package) {}
+
+  bool flattenPackage(BigBuffer* buffer) {
+    ChunkWriter pkgWriter(buffer);
+    ResTable_package* pkgHeader =
+        pkgWriter.startChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
+    pkgHeader->id = util::hostToDevice32(mPackage->id.value());
+
+    if (mPackage->name.size() >= arraysize(pkgHeader->name)) {
+      mDiag->error(DiagMessage() << "package name '" << mPackage->name
+                                 << "' is too long");
+      return false;
     }
 
-    bool flattenPackage(BigBuffer* buffer) {
-        ChunkWriter pkgWriter(buffer);
-        ResTable_package* pkgHeader = pkgWriter.startChunk<ResTable_package>(
-                RES_TABLE_PACKAGE_TYPE);
-        pkgHeader->id = util::hostToDevice32(mPackage->id.value());
+    // Copy the package name in device endianness.
+    strcpy16_htod(pkgHeader->name, arraysize(pkgHeader->name),
+                  util::utf8ToUtf16(mPackage->name));
 
-        if (mPackage->name.size() >= arraysize(pkgHeader->name)) {
-            mDiag->error(DiagMessage() <<
-                         "package name '" << mPackage->name << "' is too long");
-            return false;
-        }
+    // Serialize the types. We do this now so that our type and key strings
+    // are populated. We write those first.
+    BigBuffer typeBuffer(1024);
+    flattenTypes(&typeBuffer);
 
-        // Copy the package name in device endianness.
-        strcpy16_htod(pkgHeader->name, arraysize(pkgHeader->name),
-                      util::utf8ToUtf16(mPackage->name));
+    pkgHeader->typeStrings = util::hostToDevice32(pkgWriter.size());
+    StringPool::flattenUtf16(pkgWriter.getBuffer(), mTypePool);
 
-        // Serialize the types. We do this now so that our type and key strings
-        // are populated. We write those first.
-        BigBuffer typeBuffer(1024);
-        flattenTypes(&typeBuffer);
+    pkgHeader->keyStrings = util::hostToDevice32(pkgWriter.size());
+    StringPool::flattenUtf8(pkgWriter.getBuffer(), mKeyPool);
 
-        pkgHeader->typeStrings = util::hostToDevice32(pkgWriter.size());
-        StringPool::flattenUtf16(pkgWriter.getBuffer(), mTypePool);
+    // Append the types.
+    buffer->appendBuffer(std::move(typeBuffer));
 
-        pkgHeader->keyStrings = util::hostToDevice32(pkgWriter.size());
-        StringPool::flattenUtf8(pkgWriter.getBuffer(), mKeyPool);
+    pkgWriter.finish();
+    return true;
+  }
 
-        // Append the types.
-        buffer->appendBuffer(std::move(typeBuffer));
+ private:
+  IDiagnostics* mDiag;
+  ResourceTablePackage* mPackage;
+  StringPool mTypePool;
+  StringPool mKeyPool;
 
-        pkgWriter.finish();
-        return true;
-    }
-
-private:
-    IDiagnostics* mDiag;
-    ResourceTablePackage* mPackage;
-    StringPool mTypePool;
-    StringPool mKeyPool;
-
-    template <typename T, bool IsItem>
-    T* writeEntry(FlatEntry* entry, BigBuffer* buffer) {
-        static_assert(std::is_same<ResTable_entry, T>::value ||
+  template <typename T, bool IsItem>
+  T* writeEntry(FlatEntry* entry, BigBuffer* buffer) {
+    static_assert(std::is_same<ResTable_entry, T>::value ||
                       std::is_same<ResTable_entry_ext, T>::value,
-                      "T must be ResTable_entry or ResTable_entry_ext");
+                  "T must be ResTable_entry or ResTable_entry_ext");
 
-        T* result = buffer->nextBlock<T>();
-        ResTable_entry* outEntry = (ResTable_entry*)(result);
-        if (entry->entry->symbolStatus.state == SymbolState::kPublic) {
-            outEntry->flags |= ResTable_entry::FLAG_PUBLIC;
-        }
-
-        if (entry->value->isWeak()) {
-            outEntry->flags |= ResTable_entry::FLAG_WEAK;
-        }
-
-        if (!IsItem) {
-            outEntry->flags |= ResTable_entry::FLAG_COMPLEX;
-        }
-
-        outEntry->flags = util::hostToDevice16(outEntry->flags);
-        outEntry->key.index = util::hostToDevice32(entry->entryKey);
-        outEntry->size = util::hostToDevice16(sizeof(T));
-        return result;
+    T* result = buffer->nextBlock<T>();
+    ResTable_entry* outEntry = (ResTable_entry*)(result);
+    if (entry->entry->symbolStatus.state == SymbolState::kPublic) {
+      outEntry->flags |= ResTable_entry::FLAG_PUBLIC;
     }
 
-    bool flattenValue(FlatEntry* entry, BigBuffer* buffer) {
-        if (Item* item = valueCast<Item>(entry->value)) {
-            writeEntry<ResTable_entry, true>(entry, buffer);
-            Res_value* outValue = buffer->nextBlock<Res_value>();
-            bool result = item->flatten(outValue);
-            assert(result && "flatten failed");
-            outValue->size = util::hostToDevice16(sizeof(*outValue));
-        } else {
-            ResTable_entry_ext* outEntry = writeEntry<ResTable_entry_ext, false>(entry, buffer);
-            MapFlattenVisitor visitor(outEntry, buffer);
-            entry->value->accept(&visitor);
-            visitor.finish();
-        }
-        return true;
+    if (entry->value->isWeak()) {
+      outEntry->flags |= ResTable_entry::FLAG_WEAK;
     }
 
-    bool flattenConfig(const ResourceTableType* type, const ConfigDescription& config,
-                       std::vector<FlatEntry>* entries, BigBuffer* buffer) {
-        ChunkWriter typeWriter(buffer);
-        ResTable_type* typeHeader = typeWriter.startChunk<ResTable_type>(RES_TABLE_TYPE_TYPE);
-        typeHeader->id = type->id.value();
-        typeHeader->config = config;
-        typeHeader->config.swapHtoD();
-
-        auto maxAccum = [](uint32_t max, const std::unique_ptr<ResourceEntry>& a) -> uint32_t {
-            return std::max(max, (uint32_t) a->id.value());
-        };
-
-        // Find the largest entry ID. That is how many entries we will have.
-        const uint32_t entryCount =
-                std::accumulate(type->entries.begin(), type->entries.end(), 0, maxAccum) + 1;
-
-        typeHeader->entryCount = util::hostToDevice32(entryCount);
-        uint32_t* indices = typeWriter.nextBlock<uint32_t>(entryCount);
-
-        assert((size_t) entryCount <= std::numeric_limits<uint16_t>::max() + 1);
-        memset(indices, 0xff, entryCount * sizeof(uint32_t));
-
-        typeHeader->entriesStart = util::hostToDevice32(typeWriter.size());
-
-        const size_t entryStart = typeWriter.getBuffer()->size();
-        for (FlatEntry& flatEntry : *entries) {
-            assert(flatEntry.entry->id.value() < entryCount);
-            indices[flatEntry.entry->id.value()] = util::hostToDevice32(
-                    typeWriter.getBuffer()->size() - entryStart);
-            if (!flattenValue(&flatEntry, typeWriter.getBuffer())) {
-                mDiag->error(DiagMessage()
-                             << "failed to flatten resource '"
-                             << ResourceNameRef(mPackage->name, type->type, flatEntry.entry->name)
-                             << "' for configuration '" << config << "'");
-                return false;
-            }
-        }
-        typeWriter.finish();
-        return true;
+    if (!IsItem) {
+      outEntry->flags |= ResTable_entry::FLAG_COMPLEX;
     }
 
-    std::vector<ResourceTableType*> collectAndSortTypes() {
-        std::vector<ResourceTableType*> sortedTypes;
-        for (auto& type : mPackage->types) {
-            if (type->type == ResourceType::kStyleable) {
-                // Styleables aren't real Resource Types, they are represented in the R.java
-                // file.
-                continue;
-            }
+    outEntry->flags = util::hostToDevice16(outEntry->flags);
+    outEntry->key.index = util::hostToDevice32(entry->entryKey);
+    outEntry->size = util::hostToDevice16(sizeof(T));
+    return result;
+  }
 
-            assert(type->id && "type must have an ID set");
+  bool flattenValue(FlatEntry* entry, BigBuffer* buffer) {
+    if (Item* item = valueCast<Item>(entry->value)) {
+      writeEntry<ResTable_entry, true>(entry, buffer);
+      Res_value* outValue = buffer->nextBlock<Res_value>();
+      bool result = item->flatten(outValue);
+      assert(result && "flatten failed");
+      outValue->size = util::hostToDevice16(sizeof(*outValue));
+    } else {
+      ResTable_entry_ext* outEntry =
+          writeEntry<ResTable_entry_ext, false>(entry, buffer);
+      MapFlattenVisitor visitor(outEntry, buffer);
+      entry->value->accept(&visitor);
+      visitor.finish();
+    }
+    return true;
+  }
 
-            sortedTypes.push_back(type.get());
-        }
-        std::sort(sortedTypes.begin(), sortedTypes.end(), cmpIds<ResourceTableType>);
-        return sortedTypes;
+  bool flattenConfig(const ResourceTableType* type,
+                     const ConfigDescription& config,
+                     std::vector<FlatEntry>* entries, BigBuffer* buffer) {
+    ChunkWriter typeWriter(buffer);
+    ResTable_type* typeHeader =
+        typeWriter.startChunk<ResTable_type>(RES_TABLE_TYPE_TYPE);
+    typeHeader->id = type->id.value();
+    typeHeader->config = config;
+    typeHeader->config.swapHtoD();
+
+    auto maxAccum = [](uint32_t max,
+                       const std::unique_ptr<ResourceEntry>& a) -> uint32_t {
+      return std::max(max, (uint32_t)a->id.value());
+    };
+
+    // Find the largest entry ID. That is how many entries we will have.
+    const uint32_t entryCount =
+        std::accumulate(type->entries.begin(), type->entries.end(), 0,
+                        maxAccum) +
+        1;
+
+    typeHeader->entryCount = util::hostToDevice32(entryCount);
+    uint32_t* indices = typeWriter.nextBlock<uint32_t>(entryCount);
+
+    assert((size_t)entryCount <= std::numeric_limits<uint16_t>::max() + 1);
+    memset(indices, 0xff, entryCount * sizeof(uint32_t));
+
+    typeHeader->entriesStart = util::hostToDevice32(typeWriter.size());
+
+    const size_t entryStart = typeWriter.getBuffer()->size();
+    for (FlatEntry& flatEntry : *entries) {
+      assert(flatEntry.entry->id.value() < entryCount);
+      indices[flatEntry.entry->id.value()] =
+          util::hostToDevice32(typeWriter.getBuffer()->size() - entryStart);
+      if (!flattenValue(&flatEntry, typeWriter.getBuffer())) {
+        mDiag->error(DiagMessage()
+                     << "failed to flatten resource '"
+                     << ResourceNameRef(mPackage->name, type->type,
+                                        flatEntry.entry->name)
+                     << "' for configuration '" << config << "'");
+        return false;
+      }
+    }
+    typeWriter.finish();
+    return true;
+  }
+
+  std::vector<ResourceTableType*> collectAndSortTypes() {
+    std::vector<ResourceTableType*> sortedTypes;
+    for (auto& type : mPackage->types) {
+      if (type->type == ResourceType::kStyleable) {
+        // Styleables aren't real Resource Types, they are represented in the
+        // R.java
+        // file.
+        continue;
+      }
+
+      assert(type->id && "type must have an ID set");
+
+      sortedTypes.push_back(type.get());
+    }
+    std::sort(sortedTypes.begin(), sortedTypes.end(),
+              cmpIds<ResourceTableType>);
+    return sortedTypes;
+  }
+
+  std::vector<ResourceEntry*> collectAndSortEntries(ResourceTableType* type) {
+    // Sort the entries by entry ID.
+    std::vector<ResourceEntry*> sortedEntries;
+    for (auto& entry : type->entries) {
+      assert(entry->id && "entry must have an ID set");
+      sortedEntries.push_back(entry.get());
+    }
+    std::sort(sortedEntries.begin(), sortedEntries.end(),
+              cmpIds<ResourceEntry>);
+    return sortedEntries;
+  }
+
+  bool flattenTypeSpec(ResourceTableType* type,
+                       std::vector<ResourceEntry*>* sortedEntries,
+                       BigBuffer* buffer) {
+    ChunkWriter typeSpecWriter(buffer);
+    ResTable_typeSpec* specHeader =
+        typeSpecWriter.startChunk<ResTable_typeSpec>(RES_TABLE_TYPE_SPEC_TYPE);
+    specHeader->id = type->id.value();
+
+    if (sortedEntries->empty()) {
+      typeSpecWriter.finish();
+      return true;
     }
 
-    std::vector<ResourceEntry*> collectAndSortEntries(ResourceTableType* type) {
-        // Sort the entries by entry ID.
-        std::vector<ResourceEntry*> sortedEntries;
-        for (auto& entry : type->entries) {
-            assert(entry->id && "entry must have an ID set");
-            sortedEntries.push_back(entry.get());
+    // We can't just take the size of the vector. There may be holes in the
+    // entry ID space.
+    // Since the entries are sorted by ID, the last one will be the biggest.
+    const size_t numEntries = sortedEntries->back()->id.value() + 1;
+
+    specHeader->entryCount = util::hostToDevice32(numEntries);
+
+    // Reserve space for the masks of each resource in this type. These
+    // show for which configuration axis the resource changes.
+    uint32_t* configMasks = typeSpecWriter.nextBlock<uint32_t>(numEntries);
+
+    const size_t actualNumEntries = sortedEntries->size();
+    for (size_t entryIndex = 0; entryIndex < actualNumEntries; entryIndex++) {
+      ResourceEntry* entry = sortedEntries->at(entryIndex);
+
+      // Populate the config masks for this entry.
+
+      if (entry->symbolStatus.state == SymbolState::kPublic) {
+        configMasks[entry->id.value()] |=
+            util::hostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
+      }
+
+      const size_t configCount = entry->values.size();
+      for (size_t i = 0; i < configCount; i++) {
+        const ConfigDescription& config = entry->values[i]->config;
+        for (size_t j = i + 1; j < configCount; j++) {
+          configMasks[entry->id.value()] |=
+              util::hostToDevice32(config.diff(entry->values[j]->config));
         }
-        std::sort(sortedEntries.begin(), sortedEntries.end(), cmpIds<ResourceEntry>);
-        return sortedEntries;
+      }
     }
+    typeSpecWriter.finish();
+    return true;
+  }
 
-    bool flattenTypeSpec(ResourceTableType* type, std::vector<ResourceEntry*>* sortedEntries,
-                         BigBuffer* buffer) {
-        ChunkWriter typeSpecWriter(buffer);
-        ResTable_typeSpec* specHeader = typeSpecWriter.startChunk<ResTable_typeSpec>(
-                RES_TABLE_TYPE_SPEC_TYPE);
-        specHeader->id = type->id.value();
+  bool flattenTypes(BigBuffer* buffer) {
+    // Sort the types by their IDs. They will be inserted into the StringPool in
+    // this order.
+    std::vector<ResourceTableType*> sortedTypes = collectAndSortTypes();
 
-        if (sortedEntries->empty()) {
-            typeSpecWriter.finish();
-            return true;
+    size_t expectedTypeId = 1;
+    for (ResourceTableType* type : sortedTypes) {
+      // If there is a gap in the type IDs, fill in the StringPool
+      // with empty values until we reach the ID we expect.
+      while (type->id.value() > expectedTypeId) {
+        std::stringstream typeName;
+        typeName << "?" << expectedTypeId;
+        mTypePool.makeRef(typeName.str());
+        expectedTypeId++;
+      }
+      expectedTypeId++;
+      mTypePool.makeRef(toString(type->type));
+
+      std::vector<ResourceEntry*> sortedEntries = collectAndSortEntries(type);
+
+      if (!flattenTypeSpec(type, &sortedEntries, buffer)) {
+        return false;
+      }
+
+      // The binary resource table lists resource entries for each
+      // configuration.
+      // We store them inverted, where a resource entry lists the values for
+      // each
+      // configuration available. Here we reverse this to match the binary
+      // table.
+      std::map<ConfigDescription, std::vector<FlatEntry>> configToEntryListMap;
+      for (ResourceEntry* entry : sortedEntries) {
+        const uint32_t keyIndex =
+            (uint32_t)mKeyPool.makeRef(entry->name).getIndex();
+
+        // Group values by configuration.
+        for (auto& configValue : entry->values) {
+          configToEntryListMap[configValue->config].push_back(
+              FlatEntry{entry, configValue->value.get(), keyIndex});
         }
+      }
 
-        // We can't just take the size of the vector. There may be holes in the entry ID space.
-        // Since the entries are sorted by ID, the last one will be the biggest.
-        const size_t numEntries = sortedEntries->back()->id.value() + 1;
-
-        specHeader->entryCount = util::hostToDevice32(numEntries);
-
-        // Reserve space for the masks of each resource in this type. These
-        // show for which configuration axis the resource changes.
-        uint32_t* configMasks = typeSpecWriter.nextBlock<uint32_t>(numEntries);
-
-        const size_t actualNumEntries = sortedEntries->size();
-        for (size_t entryIndex = 0; entryIndex < actualNumEntries; entryIndex++) {
-            ResourceEntry* entry = sortedEntries->at(entryIndex);
-
-            // Populate the config masks for this entry.
-
-            if (entry->symbolStatus.state == SymbolState::kPublic) {
-                configMasks[entry->id.value()] |=
-                        util::hostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
-            }
-
-            const size_t configCount = entry->values.size();
-            for (size_t i = 0; i < configCount; i++) {
-                const ConfigDescription& config = entry->values[i]->config;
-                for (size_t j = i + 1; j < configCount; j++) {
-                    configMasks[entry->id.value()] |= util::hostToDevice32(
-                            config.diff(entry->values[j]->config));
-                }
-            }
+      // Flatten a configuration value.
+      for (auto& entry : configToEntryListMap) {
+        if (!flattenConfig(type, entry.first, &entry.second, buffer)) {
+          return false;
         }
-        typeSpecWriter.finish();
-        return true;
+      }
     }
-
-    bool flattenTypes(BigBuffer* buffer) {
-        // Sort the types by their IDs. They will be inserted into the StringPool in this order.
-        std::vector<ResourceTableType*> sortedTypes = collectAndSortTypes();
-
-        size_t expectedTypeId = 1;
-        for (ResourceTableType* type : sortedTypes) {
-            // If there is a gap in the type IDs, fill in the StringPool
-            // with empty values until we reach the ID we expect.
-            while (type->id.value() > expectedTypeId) {
-                std::stringstream typeName;
-                typeName << "?" << expectedTypeId;
-                mTypePool.makeRef(typeName.str());
-                expectedTypeId++;
-            }
-            expectedTypeId++;
-            mTypePool.makeRef(toString(type->type));
-
-            std::vector<ResourceEntry*> sortedEntries = collectAndSortEntries(type);
-
-            if (!flattenTypeSpec(type, &sortedEntries, buffer)) {
-                return false;
-            }
-
-            // The binary resource table lists resource entries for each configuration.
-            // We store them inverted, where a resource entry lists the values for each
-            // configuration available. Here we reverse this to match the binary table.
-            std::map<ConfigDescription, std::vector<FlatEntry>> configToEntryListMap;
-            for (ResourceEntry* entry : sortedEntries) {
-                const uint32_t keyIndex = (uint32_t) mKeyPool.makeRef(entry->name).getIndex();
-
-                // Group values by configuration.
-                for (auto& configValue : entry->values) {
-                    configToEntryListMap[configValue->config].push_back(FlatEntry{
-                            entry, configValue->value.get(), keyIndex });
-                }
-            }
-
-            // Flatten a configuration value.
-            for (auto& entry : configToEntryListMap) {
-                if (!flattenConfig(type, entry.first, &entry.second, buffer)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
+    return true;
+  }
 };
 
-} // namespace
+}  // namespace
 
 bool TableFlattener::consume(IAaptContext* context, ResourceTable* table) {
-    // We must do this before writing the resources, since the string pool IDs may change.
-    table->stringPool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+  // We must do this before writing the resources, since the string pool IDs may
+  // change.
+  table->stringPool.sort(
+      [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
         int diff = a.context.priority - b.context.priority;
         if (diff < 0) return true;
         if (diff > 0) return false;
@@ -476,31 +492,32 @@
         if (diff < 0) return true;
         if (diff > 0) return false;
         return a.value < b.value;
-    });
-    table->stringPool.prune();
+      });
+  table->stringPool.prune();
 
-    // Write the ResTable header.
-    ChunkWriter tableWriter(mBuffer);
-    ResTable_header* tableHeader = tableWriter.startChunk<ResTable_header>(RES_TABLE_TYPE);
-    tableHeader->packageCount = util::hostToDevice32(table->packages.size());
+  // Write the ResTable header.
+  ChunkWriter tableWriter(mBuffer);
+  ResTable_header* tableHeader =
+      tableWriter.startChunk<ResTable_header>(RES_TABLE_TYPE);
+  tableHeader->packageCount = util::hostToDevice32(table->packages.size());
 
-    // Flatten the values string pool.
-    StringPool::flattenUtf8(tableWriter.getBuffer(), table->stringPool);
+  // Flatten the values string pool.
+  StringPool::flattenUtf8(tableWriter.getBuffer(), table->stringPool);
 
-    BigBuffer packageBuffer(1024);
+  BigBuffer packageBuffer(1024);
 
-    // Flatten each package.
-    for (auto& package : table->packages) {
-        PackageFlattener flattener(context->getDiagnostics(), package.get());
-        if (!flattener.flattenPackage(&packageBuffer)) {
-            return false;
-        }
+  // Flatten each package.
+  for (auto& package : table->packages) {
+    PackageFlattener flattener(context->getDiagnostics(), package.get());
+    if (!flattener.flattenPackage(&packageBuffer)) {
+      return false;
     }
+  }
 
-    // Finally merge all the packages into the main buffer.
-    tableWriter.getBuffer()->appendBuffer(std::move(packageBuffer));
-    tableWriter.finish();
-    return true;
+  // Finally merge all the packages into the main buffer.
+  tableWriter.getBuffer()->appendBuffer(std::move(packageBuffer));
+  tableWriter.finish();
+  return true;
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/flatten/TableFlattener.h b/tools/aapt2/flatten/TableFlattener.h
index b416f20..91f9654 100644
--- a/tools/aapt2/flatten/TableFlattener.h
+++ b/tools/aapt2/flatten/TableFlattener.h
@@ -25,16 +25,15 @@
 class ResourceTable;
 
 class TableFlattener : public IResourceTableConsumer {
-public:
-    explicit TableFlattener(BigBuffer* buffer) : mBuffer(buffer) {
-    }
+ public:
+  explicit TableFlattener(BigBuffer* buffer) : mBuffer(buffer) {}
 
-    bool consume(IAaptContext* context, ResourceTable* table) override;
+  bool consume(IAaptContext* context, ResourceTable* table) override;
 
-private:
-    BigBuffer* mBuffer;
+ private:
+  BigBuffer* mBuffer;
 };
 
-} // namespace aapt
+}  // namespace aapt
 
 #endif /* AAPT_FLATTEN_TABLEFLATTENER_H */
diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp
index b25bfa7..a7706bd 100644
--- a/tools/aapt2/flatten/TableFlattener_test.cpp
+++ b/tools/aapt2/flatten/TableFlattener_test.cpp
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "ResourceUtils.h"
 #include "flatten/TableFlattener.h"
+#include "ResourceUtils.h"
 #include "test/Test.h"
 #include "unflatten/BinaryResourceParser.h"
 #include "util/Util.h"
@@ -25,195 +25,207 @@
 namespace aapt {
 
 class TableFlattenerTest : public ::testing::Test {
-public:
-    void SetUp() override {
-        mContext = test::ContextBuilder()
-                .setCompilationPackage("com.app.test")
-                .setPackageId(0x7f)
-                .build();
+ public:
+  void SetUp() override {
+    mContext = test::ContextBuilder()
+                   .setCompilationPackage("com.app.test")
+                   .setPackageId(0x7f)
+                   .build();
+  }
+
+  ::testing::AssertionResult flatten(ResourceTable* table, ResTable* outTable) {
+    BigBuffer buffer(1024);
+    TableFlattener flattener(&buffer);
+    if (!flattener.consume(mContext.get(), table)) {
+      return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
     }
 
-    ::testing::AssertionResult flatten(ResourceTable* table, ResTable* outTable) {
-        BigBuffer buffer(1024);
-        TableFlattener flattener(&buffer);
-        if (!flattener.consume(mContext.get(), table)) {
-            return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
-        }
+    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
+    if (outTable->add(data.get(), buffer.size(), -1, true) != NO_ERROR) {
+      return ::testing::AssertionFailure() << "flattened ResTable is corrupt";
+    }
+    return ::testing::AssertionSuccess();
+  }
 
-        std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-        if (outTable->add(data.get(), buffer.size(), -1, true) != NO_ERROR) {
-            return ::testing::AssertionFailure() << "flattened ResTable is corrupt";
-        }
-        return ::testing::AssertionSuccess();
+  ::testing::AssertionResult flatten(ResourceTable* table,
+                                     ResourceTable* outTable) {
+    BigBuffer buffer(1024);
+    TableFlattener flattener(&buffer);
+    if (!flattener.consume(mContext.get(), table)) {
+      return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
     }
 
-    ::testing::AssertionResult flatten(ResourceTable* table, ResourceTable* outTable) {
-        BigBuffer buffer(1024);
-        TableFlattener flattener(&buffer);
-        if (!flattener.consume(mContext.get(), table)) {
-            return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
-        }
+    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
+    BinaryResourceParser parser(mContext.get(), outTable, {}, data.get(),
+                                buffer.size());
+    if (!parser.parse()) {
+      return ::testing::AssertionFailure() << "flattened ResTable is corrupt";
+    }
+    return ::testing::AssertionSuccess();
+  }
 
-        std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-        BinaryResourceParser parser(mContext.get(), outTable, {}, data.get(), buffer.size());
-        if (!parser.parse()) {
-            return ::testing::AssertionFailure() << "flattened ResTable is corrupt";
-        }
-        return ::testing::AssertionSuccess();
+  ::testing::AssertionResult exists(ResTable* table,
+                                    const StringPiece& expectedName,
+                                    const ResourceId& expectedId,
+                                    const ConfigDescription& expectedConfig,
+                                    const uint8_t expectedDataType,
+                                    const uint32_t expectedData,
+                                    const uint32_t expectedSpecFlags) {
+    const ResourceName expectedResName = test::parseNameOrDie(expectedName);
+
+    table->setParameters(&expectedConfig);
+
+    ResTable_config config;
+    Res_value val;
+    uint32_t specFlags;
+    if (table->getResource(expectedId.id, &val, false, 0, &specFlags, &config) <
+        0) {
+      return ::testing::AssertionFailure() << "could not find resource with";
     }
 
-    ::testing::AssertionResult exists(ResTable* table,
-                                      const StringPiece& expectedName,
-                                      const ResourceId& expectedId,
-                                      const ConfigDescription& expectedConfig,
-                                      const uint8_t expectedDataType, const uint32_t expectedData,
-                                      const uint32_t expectedSpecFlags) {
-        const ResourceName expectedResName = test::parseNameOrDie(expectedName);
-
-        table->setParameters(&expectedConfig);
-
-        ResTable_config config;
-        Res_value val;
-        uint32_t specFlags;
-        if (table->getResource(expectedId.id, &val, false, 0, &specFlags, &config) < 0) {
-            return ::testing::AssertionFailure() << "could not find resource with";
-        }
-
-        if (expectedDataType != val.dataType) {
-            return ::testing::AssertionFailure()
-                    << "expected data type "
-                    << std::hex << (int) expectedDataType << " but got data type "
-                    << (int) val.dataType << std::dec << " instead";
-        }
-
-        if (expectedData != val.data) {
-            return ::testing::AssertionFailure()
-                    << "expected data "
-                    << std::hex << expectedData << " but got data "
-                    << val.data << std::dec << " instead";
-        }
-
-        if (expectedSpecFlags != specFlags) {
-            return ::testing::AssertionFailure()
-                    << "expected specFlags "
-                    << std::hex << expectedSpecFlags << " but got specFlags "
-                    << specFlags << std::dec << " instead";
-        }
-
-        ResTable::resource_name actualName;
-        if (!table->getResourceName(expectedId.id, false, &actualName)) {
-            return ::testing::AssertionFailure() << "failed to find resource name";
-        }
-
-        Maybe<ResourceName> resName = ResourceUtils::toResourceName(actualName);
-        if (!resName) {
-            return ::testing::AssertionFailure()
-                    << "expected name '" << expectedResName << "' but got '"
-                    << StringPiece16(actualName.package, actualName.packageLen)
-                    << ":"
-                    << StringPiece16(actualName.type, actualName.typeLen)
-                    << "/"
-                    << StringPiece16(actualName.name, actualName.nameLen)
-                    << "'";
-        }
-
-        if (expectedConfig != config) {
-            return ::testing::AssertionFailure()
-                    << "expected config '" << expectedConfig << "' but got '"
-                    << ConfigDescription(config) << "'";
-        }
-        return ::testing::AssertionSuccess();
+    if (expectedDataType != val.dataType) {
+      return ::testing::AssertionFailure()
+             << "expected data type " << std::hex << (int)expectedDataType
+             << " but got data type " << (int)val.dataType << std::dec
+             << " instead";
     }
 
-private:
-    std::unique_ptr<IAaptContext> mContext;
+    if (expectedData != val.data) {
+      return ::testing::AssertionFailure()
+             << "expected data " << std::hex << expectedData << " but got data "
+             << val.data << std::dec << " instead";
+    }
+
+    if (expectedSpecFlags != specFlags) {
+      return ::testing::AssertionFailure()
+             << "expected specFlags " << std::hex << expectedSpecFlags
+             << " but got specFlags " << specFlags << std::dec << " instead";
+    }
+
+    ResTable::resource_name actualName;
+    if (!table->getResourceName(expectedId.id, false, &actualName)) {
+      return ::testing::AssertionFailure() << "failed to find resource name";
+    }
+
+    Maybe<ResourceName> resName = ResourceUtils::toResourceName(actualName);
+    if (!resName) {
+      return ::testing::AssertionFailure()
+             << "expected name '" << expectedResName << "' but got '"
+             << StringPiece16(actualName.package, actualName.packageLen) << ":"
+             << StringPiece16(actualName.type, actualName.typeLen) << "/"
+             << StringPiece16(actualName.name, actualName.nameLen) << "'";
+    }
+
+    if (expectedConfig != config) {
+      return ::testing::AssertionFailure() << "expected config '"
+                                           << expectedConfig << "' but got '"
+                                           << ConfigDescription(config) << "'";
+    }
+    return ::testing::AssertionSuccess();
+  }
+
+ private:
+  std::unique_ptr<IAaptContext> mContext;
 };
 
 TEST_F(TableFlattenerTest, FlattenFullyLinkedTable) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("com.app.test", 0x7f)
-            .addSimple("com.app.test:id/one", ResourceId(0x7f020000))
-            .addSimple("com.app.test:id/two", ResourceId(0x7f020001))
-            .addValue("com.app.test:id/three", ResourceId(0x7f020002),
-                      test::buildReference("com.app.test:id/one", ResourceId(0x7f020000)))
-            .addValue("com.app.test:integer/one", ResourceId(0x7f030000),
-                      util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 1u))
-            .addValue("com.app.test:integer/one", test::parseConfigOrDie("v1"),
-                      ResourceId(0x7f030000),
-                      util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 2u))
-            .addString("com.app.test:string/test", ResourceId(0x7f040000), "foo")
-            .addString("com.app.test:layout/bar", ResourceId(0x7f050000), "res/layout/bar.xml")
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .setPackageId("com.app.test", 0x7f)
+          .addSimple("com.app.test:id/one", ResourceId(0x7f020000))
+          .addSimple("com.app.test:id/two", ResourceId(0x7f020001))
+          .addValue("com.app.test:id/three", ResourceId(0x7f020002),
+                    test::buildReference("com.app.test:id/one",
+                                         ResourceId(0x7f020000)))
+          .addValue("com.app.test:integer/one", ResourceId(0x7f030000),
+                    util::make_unique<BinaryPrimitive>(
+                        uint8_t(Res_value::TYPE_INT_DEC), 1u))
+          .addValue("com.app.test:integer/one", test::parseConfigOrDie("v1"),
+                    ResourceId(0x7f030000),
+                    util::make_unique<BinaryPrimitive>(
+                        uint8_t(Res_value::TYPE_INT_DEC), 2u))
+          .addString("com.app.test:string/test", ResourceId(0x7f040000), "foo")
+          .addString("com.app.test:layout/bar", ResourceId(0x7f050000),
+                     "res/layout/bar.xml")
+          .build();
 
-    ResTable resTable;
-    ASSERT_TRUE(flatten(table.get(), &resTable));
+  ResTable resTable;
+  ASSERT_TRUE(flatten(table.get(), &resTable));
 
-    EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020000), {},
-                       Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+  EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020000),
+                     {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
 
-    EXPECT_TRUE(exists(&resTable, "com.app.test:id/two", ResourceId(0x7f020001), {},
-                       Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+  EXPECT_TRUE(exists(&resTable, "com.app.test:id/two", ResourceId(0x7f020001),
+                     {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
 
-    EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020002), {},
-                       Res_value::TYPE_REFERENCE, 0x7f020000u, 0u));
+  EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020002),
+                     {}, Res_value::TYPE_REFERENCE, 0x7f020000u, 0u));
 
-    EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one", ResourceId(0x7f030000),
-                       {}, Res_value::TYPE_INT_DEC, 1u,
-                       ResTable_config::CONFIG_VERSION));
+  EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one",
+                     ResourceId(0x7f030000), {}, Res_value::TYPE_INT_DEC, 1u,
+                     ResTable_config::CONFIG_VERSION));
 
-    EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one", ResourceId(0x7f030000),
-                       test::parseConfigOrDie("v1"), Res_value::TYPE_INT_DEC, 2u,
-                       ResTable_config::CONFIG_VERSION));
+  EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one",
+                     ResourceId(0x7f030000), test::parseConfigOrDie("v1"),
+                     Res_value::TYPE_INT_DEC, 2u,
+                     ResTable_config::CONFIG_VERSION));
 
-    std::u16string fooStr = u"foo";
-    ssize_t idx = resTable.getTableStringBlock(0)->indexOfString(fooStr.data(), fooStr.size());
-    ASSERT_GE(idx, 0);
-    EXPECT_TRUE(exists(&resTable, "com.app.test:string/test", ResourceId(0x7f040000),
-                       {}, Res_value::TYPE_STRING, (uint32_t) idx, 0u));
+  std::u16string fooStr = u"foo";
+  ssize_t idx = resTable.getTableStringBlock(0)->indexOfString(fooStr.data(),
+                                                               fooStr.size());
+  ASSERT_GE(idx, 0);
+  EXPECT_TRUE(exists(&resTable, "com.app.test:string/test",
+                     ResourceId(0x7f040000), {}, Res_value::TYPE_STRING,
+                     (uint32_t)idx, 0u));
 
-    std::u16string barPath = u"res/layout/bar.xml";
-    idx = resTable.getTableStringBlock(0)->indexOfString(barPath.data(), barPath.size());
-    ASSERT_GE(idx, 0);
-    EXPECT_TRUE(exists(&resTable, "com.app.test:layout/bar", ResourceId(0x7f050000), {},
-                       Res_value::TYPE_STRING, (uint32_t) idx, 0u));
+  std::u16string barPath = u"res/layout/bar.xml";
+  idx = resTable.getTableStringBlock(0)->indexOfString(barPath.data(),
+                                                       barPath.size());
+  ASSERT_GE(idx, 0);
+  EXPECT_TRUE(exists(&resTable, "com.app.test:layout/bar",
+                     ResourceId(0x7f050000), {}, Res_value::TYPE_STRING,
+                     (uint32_t)idx, 0u));
 }
 
 TEST_F(TableFlattenerTest, FlattenEntriesWithGapsInIds) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("com.app.test", 0x7f)
-            .addSimple("com.app.test:id/one", ResourceId(0x7f020001))
-            .addSimple("com.app.test:id/three", ResourceId(0x7f020003))
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .setPackageId("com.app.test", 0x7f)
+          .addSimple("com.app.test:id/one", ResourceId(0x7f020001))
+          .addSimple("com.app.test:id/three", ResourceId(0x7f020003))
+          .build();
 
-    ResTable resTable;
-    ASSERT_TRUE(flatten(table.get(), &resTable));
+  ResTable resTable;
+  ASSERT_TRUE(flatten(table.get(), &resTable));
 
-    EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020001), {},
-                       Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
-    EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020003), {},
-                       Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+  EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020001),
+                     {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+  EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020003),
+                     {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
 }
 
 TEST_F(TableFlattenerTest, FlattenMinMaxAttributes) {
-    Attribute attr(false);
-    attr.typeMask = android::ResTable_map::TYPE_INTEGER;
-    attr.minInt = 10;
-    attr.maxInt = 23;
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addValue("android:attr/foo", ResourceId(0x01010000),
-                      util::make_unique<Attribute>(attr))
-            .build();
+  Attribute attr(false);
+  attr.typeMask = android::ResTable_map::TYPE_INTEGER;
+  attr.minInt = 10;
+  attr.maxInt = 23;
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .setPackageId("android", 0x01)
+          .addValue("android:attr/foo", ResourceId(0x01010000),
+                    util::make_unique<Attribute>(attr))
+          .build();
 
-    ResourceTable result;
-    ASSERT_TRUE(flatten(table.get(), &result));
+  ResourceTable result;
+  ASSERT_TRUE(flatten(table.get(), &result));
 
-    Attribute* actualAttr = test::getValue<Attribute>(&result, "android:attr/foo");
-    ASSERT_NE(nullptr, actualAttr);
-    EXPECT_EQ(attr.isWeak(), actualAttr->isWeak());
-    EXPECT_EQ(attr.typeMask, actualAttr->typeMask);
-    EXPECT_EQ(attr.minInt, actualAttr->minInt);
-    EXPECT_EQ(attr.maxInt, actualAttr->maxInt);
+  Attribute* actualAttr =
+      test::getValue<Attribute>(&result, "android:attr/foo");
+  ASSERT_NE(nullptr, actualAttr);
+  EXPECT_EQ(attr.isWeak(), actualAttr->isWeak());
+  EXPECT_EQ(attr.typeMask, actualAttr->typeMask);
+  EXPECT_EQ(attr.minInt, actualAttr->minInt);
+  EXPECT_EQ(attr.maxInt, actualAttr->maxInt);
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp
index ed5b60f..c296dde 100644
--- a/tools/aapt2/flatten/XmlFlattener.cpp
+++ b/tools/aapt2/flatten/XmlFlattener.cpp
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
+#include "flatten/XmlFlattener.h"
 #include "SdkConstants.h"
 #include "flatten/ChunkWriter.h"
 #include "flatten/ResourceTypeExtensions.h"
-#include "flatten/XmlFlattener.h"
 #include "xml/XmlDom.h"
 
 #include <androidfw/ResourceTypes.h>
+#include <utils/misc.h>
 #include <algorithm>
 #include <map>
-#include <utils/misc.h>
 #include <vector>
 
 using namespace android;
@@ -35,300 +35,316 @@
 constexpr uint32_t kLowPriority = 0xffffffffu;
 
 struct XmlFlattenerVisitor : public xml::Visitor {
-    using xml::Visitor::visit;
+  using xml::Visitor::visit;
 
-    BigBuffer* mBuffer;
-    XmlFlattenerOptions mOptions;
-    StringPool mPool;
-    std::map<uint8_t, StringPool> mPackagePools;
+  BigBuffer* mBuffer;
+  XmlFlattenerOptions mOptions;
+  StringPool mPool;
+  std::map<uint8_t, StringPool> mPackagePools;
 
-    struct StringFlattenDest {
-        StringPool::Ref ref;
-        ResStringPool_ref* dest;
-    };
-    std::vector<StringFlattenDest> mStringRefs;
+  struct StringFlattenDest {
+    StringPool::Ref ref;
+    ResStringPool_ref* dest;
+  };
+  std::vector<StringFlattenDest> mStringRefs;
 
-    // Scratch vector to filter attributes. We avoid allocations
-    // making this a member.
-    std::vector<xml::Attribute*> mFilteredAttrs;
+  // Scratch vector to filter attributes. We avoid allocations
+  // making this a member.
+  std::vector<xml::Attribute*> mFilteredAttrs;
 
+  XmlFlattenerVisitor(BigBuffer* buffer, XmlFlattenerOptions options)
+      : mBuffer(buffer), mOptions(options) {}
 
-    XmlFlattenerVisitor(BigBuffer* buffer, XmlFlattenerOptions options) :
-            mBuffer(buffer), mOptions(options) {
+  void addString(const StringPiece& str, uint32_t priority,
+                 android::ResStringPool_ref* dest,
+                 bool treatEmptyStringAsNull = false) {
+    if (str.empty() && treatEmptyStringAsNull) {
+      // Some parts of the runtime treat null differently than empty string.
+      dest->index = util::deviceToHost32(-1);
+    } else {
+      mStringRefs.push_back(StringFlattenDest{
+          mPool.makeRef(str, StringPool::Context{priority}), dest});
+    }
+  }
+
+  void addString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) {
+    mStringRefs.push_back(StringFlattenDest{ref, dest});
+  }
+
+  void writeNamespace(xml::Namespace* node, uint16_t type) {
+    ChunkWriter writer(mBuffer);
+
+    ResXMLTree_node* flatNode = writer.startChunk<ResXMLTree_node>(type);
+    flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
+    flatNode->comment.index = util::hostToDevice32(-1);
+
+    ResXMLTree_namespaceExt* flatNs =
+        writer.nextBlock<ResXMLTree_namespaceExt>();
+    addString(node->namespacePrefix, kLowPriority, &flatNs->prefix);
+    addString(node->namespaceUri, kLowPriority, &flatNs->uri);
+
+    writer.finish();
+  }
+
+  void visit(xml::Namespace* node) override {
+    if (node->namespaceUri == xml::kSchemaTools) {
+      // Skip dedicated tools namespace.
+      xml::Visitor::visit(node);
+    } else {
+      writeNamespace(node, android::RES_XML_START_NAMESPACE_TYPE);
+      xml::Visitor::visit(node);
+      writeNamespace(node, android::RES_XML_END_NAMESPACE_TYPE);
+    }
+  }
+
+  void visit(xml::Text* node) override {
+    if (util::trimWhitespace(node->text).empty()) {
+      // Skip whitespace only text nodes.
+      return;
     }
 
-    void addString(const StringPiece& str, uint32_t priority, android::ResStringPool_ref* dest,
-                   bool treatEmptyStringAsNull = false) {
-        if (str.empty() && treatEmptyStringAsNull) {
-            // Some parts of the runtime treat null differently than empty string.
-            dest->index = util::deviceToHost32(-1);
-        } else {
-            mStringRefs.push_back(StringFlattenDest{
-                    mPool.makeRef(str, StringPool::Context{ priority }),
-                    dest });
-        }
+    ChunkWriter writer(mBuffer);
+    ResXMLTree_node* flatNode =
+        writer.startChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE);
+    flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
+    flatNode->comment.index = util::hostToDevice32(-1);
+
+    ResXMLTree_cdataExt* flatText = writer.nextBlock<ResXMLTree_cdataExt>();
+    addString(node->text, kLowPriority, &flatText->data);
+
+    writer.finish();
+  }
+
+  void visit(xml::Element* node) override {
+    {
+      ChunkWriter startWriter(mBuffer);
+      ResXMLTree_node* flatNode =
+          startWriter.startChunk<ResXMLTree_node>(RES_XML_START_ELEMENT_TYPE);
+      flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
+      flatNode->comment.index = util::hostToDevice32(-1);
+
+      ResXMLTree_attrExt* flatElem =
+          startWriter.nextBlock<ResXMLTree_attrExt>();
+
+      // A missing namespace must be null, not an empty string. Otherwise the
+      // runtime
+      // complains.
+      addString(node->namespaceUri, kLowPriority, &flatElem->ns,
+                true /* treatEmptyStringAsNull */);
+      addString(node->name, kLowPriority, &flatElem->name,
+                true /* treatEmptyStringAsNull */);
+
+      flatElem->attributeStart = util::hostToDevice16(sizeof(*flatElem));
+      flatElem->attributeSize =
+          util::hostToDevice16(sizeof(ResXMLTree_attribute));
+
+      writeAttributes(node, flatElem, &startWriter);
+
+      startWriter.finish();
     }
 
-    void addString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) {
-        mStringRefs.push_back(StringFlattenDest{ ref, dest });
-    }
-
-    void writeNamespace(xml::Namespace* node, uint16_t type) {
-        ChunkWriter writer(mBuffer);
-
-        ResXMLTree_node* flatNode = writer.startChunk<ResXMLTree_node>(type);
-        flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
-        flatNode->comment.index = util::hostToDevice32(-1);
-
-        ResXMLTree_namespaceExt* flatNs = writer.nextBlock<ResXMLTree_namespaceExt>();
-        addString(node->namespacePrefix, kLowPriority, &flatNs->prefix);
-        addString(node->namespaceUri, kLowPriority, &flatNs->uri);
-
-        writer.finish();
-    }
-
-    void visit(xml::Namespace* node) override {
-        if (node->namespaceUri == xml::kSchemaTools) {
-            // Skip dedicated tools namespace.
-            xml::Visitor::visit(node);
-        } else {
-            writeNamespace(node, android::RES_XML_START_NAMESPACE_TYPE);
-            xml::Visitor::visit(node);
-            writeNamespace(node, android::RES_XML_END_NAMESPACE_TYPE);
-        }
-    }
-
-    void visit(xml::Text* node) override {
-        if (util::trimWhitespace(node->text).empty()) {
-            // Skip whitespace only text nodes.
-            return;
-        }
-
-        ChunkWriter writer(mBuffer);
-        ResXMLTree_node* flatNode = writer.startChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE);
-        flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
-        flatNode->comment.index = util::hostToDevice32(-1);
-
-        ResXMLTree_cdataExt* flatText = writer.nextBlock<ResXMLTree_cdataExt>();
-        addString(node->text, kLowPriority, &flatText->data);
-
-        writer.finish();
-    }
-
-    void visit(xml::Element* node) override {
-        {
-            ChunkWriter startWriter(mBuffer);
-            ResXMLTree_node* flatNode = startWriter.startChunk<ResXMLTree_node>(
-                    RES_XML_START_ELEMENT_TYPE);
-            flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
-            flatNode->comment.index = util::hostToDevice32(-1);
-
-            ResXMLTree_attrExt* flatElem = startWriter.nextBlock<ResXMLTree_attrExt>();
-
-            // A missing namespace must be null, not an empty string. Otherwise the runtime
-            // complains.
-            addString(node->namespaceUri, kLowPriority, &flatElem->ns,
-                      true /* treatEmptyStringAsNull */);
-            addString(node->name, kLowPriority, &flatElem->name,
-                      true /* treatEmptyStringAsNull */);
-
-            flatElem->attributeStart = util::hostToDevice16(sizeof(*flatElem));
-            flatElem->attributeSize = util::hostToDevice16(sizeof(ResXMLTree_attribute));
-
-            writeAttributes(node, flatElem, &startWriter);
-
-            startWriter.finish();
-        }
-
-        xml::Visitor::visit(node);
-
-        {
-            ChunkWriter endWriter(mBuffer);
-            ResXMLTree_node* flatEndNode = endWriter.startChunk<ResXMLTree_node>(
-                    RES_XML_END_ELEMENT_TYPE);
-            flatEndNode->lineNumber = util::hostToDevice32(node->lineNumber);
-            flatEndNode->comment.index = util::hostToDevice32(-1);
-
-            ResXMLTree_endElementExt* flatEndElem = endWriter.nextBlock<ResXMLTree_endElementExt>();
-            addString(node->namespaceUri, kLowPriority, &flatEndElem->ns,
-                      true /* treatEmptyStringAsNull */);
-            addString(node->name, kLowPriority, &flatEndElem->name);
-
-            endWriter.finish();
-        }
-    }
-
-    static bool cmpXmlAttributeById(const xml::Attribute* a, const xml::Attribute* b) {
-        if (a->compiledAttribute && a->compiledAttribute.value().id) {
-            if (b->compiledAttribute && b->compiledAttribute.value().id) {
-                return a->compiledAttribute.value().id.value() < b->compiledAttribute.value().id.value();
-            }
-            return true;
-        } else if (!b->compiledAttribute) {
-            int diff = a->namespaceUri.compare(b->namespaceUri);
-            if (diff < 0) {
-                return true;
-            } else if (diff > 0) {
-                return false;
-            }
-            return a->name < b->name;
-        }
-        return false;
-    }
-
-    void writeAttributes(xml::Element* node, ResXMLTree_attrExt* flatElem, ChunkWriter* writer) {
-        mFilteredAttrs.clear();
-        mFilteredAttrs.reserve(node->attributes.size());
-
-        // Filter the attributes.
-        for (xml::Attribute& attr : node->attributes) {
-            if (mOptions.maxSdkLevel && attr.compiledAttribute && attr.compiledAttribute.value().id) {
-                size_t sdkLevel = findAttributeSdkLevel(attr.compiledAttribute.value().id.value());
-                if (sdkLevel > mOptions.maxSdkLevel.value()) {
-                    continue;
-                }
-            }
-            if (attr.namespaceUri == xml::kSchemaTools) {
-                continue;
-            }
-            mFilteredAttrs.push_back(&attr);
-        }
-
-        if (mFilteredAttrs.empty()) {
-            return;
-        }
-
-        const ResourceId kIdAttr(0x010100d0);
-
-        std::sort(mFilteredAttrs.begin(), mFilteredAttrs.end(), cmpXmlAttributeById);
-
-        flatElem->attributeCount = util::hostToDevice16(mFilteredAttrs.size());
-
-        ResXMLTree_attribute* flatAttr = writer->nextBlock<ResXMLTree_attribute>(
-                mFilteredAttrs.size());
-        uint16_t attributeIndex = 1;
-        for (const xml::Attribute* xmlAttr : mFilteredAttrs) {
-            // Assign the indices for specific attributes.
-            if (xmlAttr->compiledAttribute && xmlAttr->compiledAttribute.value().id &&
-                    xmlAttr->compiledAttribute.value().id.value() == kIdAttr) {
-                flatElem->idIndex = util::hostToDevice16(attributeIndex);
-            } else if (xmlAttr->namespaceUri.empty()) {
-                if (xmlAttr->name == "class") {
-                    flatElem->classIndex = util::hostToDevice16(attributeIndex);
-                } else if (xmlAttr->name == "style") {
-                    flatElem->styleIndex = util::hostToDevice16(attributeIndex);
-                }
-            }
-            attributeIndex++;
-
-            // Add the namespaceUri to the list of StringRefs to encode. Use null if the namespace
-            // is empty (doesn't exist).
-            addString(xmlAttr->namespaceUri, kLowPriority, &flatAttr->ns,
-                      true /* treatEmptyStringAsNull */);
-
-            flatAttr->rawValue.index = util::hostToDevice32(-1);
-
-            if (!xmlAttr->compiledAttribute || !xmlAttr->compiledAttribute.value().id) {
-                // The attribute has no associated ResourceID, so the string order doesn't matter.
-                addString(xmlAttr->name, kLowPriority, &flatAttr->name);
-            } else {
-                // Attribute names are stored without packages, but we use
-                // their StringPool index to lookup their resource IDs.
-                // This will cause collisions, so we can't dedupe
-                // attribute names from different packages. We use separate
-                // pools that we later combine.
-                //
-                // Lookup the StringPool for this package and make the reference there.
-                const xml::AaptAttribute& aaptAttr = xmlAttr->compiledAttribute.value();
-
-                StringPool::Ref nameRef = mPackagePools[aaptAttr.id.value().packageId()].makeRef(
-                        xmlAttr->name, StringPool::Context{ aaptAttr.id.value().id });
-
-                // Add it to the list of strings to flatten.
-                addString(nameRef, &flatAttr->name);
-            }
-
-            if (mOptions.keepRawValues || !xmlAttr->compiledValue) {
-                // Keep raw values if the value is not compiled or
-                // if we're building a static library (need symbols).
-                addString(xmlAttr->value, kLowPriority, &flatAttr->rawValue);
-            }
-
-            if (xmlAttr->compiledValue) {
-                bool result = xmlAttr->compiledValue->flatten(&flatAttr->typedValue);
-                assert(result);
-            } else {
-                // Flatten as a regular string type.
-                flatAttr->typedValue.dataType = android::Res_value::TYPE_STRING;
-                addString(xmlAttr->value, kLowPriority,
-                          (ResStringPool_ref*) &flatAttr->typedValue.data);
-            }
-
-            flatAttr->typedValue.size = util::hostToDevice16(sizeof(flatAttr->typedValue));
-            flatAttr++;
-        }
-    }
-};
-
-} // namespace
-
-bool XmlFlattener::flatten(IAaptContext* context, xml::Node* node) {
-    BigBuffer nodeBuffer(1024);
-    XmlFlattenerVisitor visitor(&nodeBuffer, mOptions);
-    node->accept(&visitor);
-
-    // Merge the package pools into the main pool.
-    for (auto& packagePoolEntry : visitor.mPackagePools) {
-        visitor.mPool.merge(std::move(packagePoolEntry.second));
-    }
-
-    // Sort the string pool so that attribute resource IDs show up first.
-    visitor.mPool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
-        return a.context.priority < b.context.priority;
-    });
-
-    // Now we flatten the string pool references into the correct places.
-    for (const auto& refEntry : visitor.mStringRefs) {
-        refEntry.dest->index = util::hostToDevice32(refEntry.ref.getIndex());
-    }
-
-    // Write the XML header.
-    ChunkWriter xmlHeaderWriter(mBuffer);
-    xmlHeaderWriter.startChunk<ResXMLTree_header>(RES_XML_TYPE);
-
-    // Flatten the StringPool.
-    StringPool::flattenUtf8(mBuffer, visitor.mPool);
+    xml::Visitor::visit(node);
 
     {
-        // Write the array of resource IDs, indexed by StringPool order.
-        ChunkWriter resIdMapWriter(mBuffer);
-        resIdMapWriter.startChunk<ResChunk_header>(RES_XML_RESOURCE_MAP_TYPE);
-        for (const auto& str : visitor.mPool) {
-            ResourceId id = { str->context.priority };
-            if (id.id == kLowPriority || !id.isValid()) {
-                // When we see the first non-resource ID,
-                // we're done.
-                break;
-            }
+      ChunkWriter endWriter(mBuffer);
+      ResXMLTree_node* flatEndNode =
+          endWriter.startChunk<ResXMLTree_node>(RES_XML_END_ELEMENT_TYPE);
+      flatEndNode->lineNumber = util::hostToDevice32(node->lineNumber);
+      flatEndNode->comment.index = util::hostToDevice32(-1);
 
-            *resIdMapWriter.nextBlock<uint32_t>() = id.id;
+      ResXMLTree_endElementExt* flatEndElem =
+          endWriter.nextBlock<ResXMLTree_endElementExt>();
+      addString(node->namespaceUri, kLowPriority, &flatEndElem->ns,
+                true /* treatEmptyStringAsNull */);
+      addString(node->name, kLowPriority, &flatEndElem->name);
+
+      endWriter.finish();
+    }
+  }
+
+  static bool cmpXmlAttributeById(const xml::Attribute* a,
+                                  const xml::Attribute* b) {
+    if (a->compiledAttribute && a->compiledAttribute.value().id) {
+      if (b->compiledAttribute && b->compiledAttribute.value().id) {
+        return a->compiledAttribute.value().id.value() <
+               b->compiledAttribute.value().id.value();
+      }
+      return true;
+    } else if (!b->compiledAttribute) {
+      int diff = a->namespaceUri.compare(b->namespaceUri);
+      if (diff < 0) {
+        return true;
+      } else if (diff > 0) {
+        return false;
+      }
+      return a->name < b->name;
+    }
+    return false;
+  }
+
+  void writeAttributes(xml::Element* node, ResXMLTree_attrExt* flatElem,
+                       ChunkWriter* writer) {
+    mFilteredAttrs.clear();
+    mFilteredAttrs.reserve(node->attributes.size());
+
+    // Filter the attributes.
+    for (xml::Attribute& attr : node->attributes) {
+      if (mOptions.maxSdkLevel && attr.compiledAttribute &&
+          attr.compiledAttribute.value().id) {
+        size_t sdkLevel =
+            findAttributeSdkLevel(attr.compiledAttribute.value().id.value());
+        if (sdkLevel > mOptions.maxSdkLevel.value()) {
+          continue;
         }
-        resIdMapWriter.finish();
+      }
+      if (attr.namespaceUri == xml::kSchemaTools) {
+        continue;
+      }
+      mFilteredAttrs.push_back(&attr);
     }
 
-    // Move the nodeBuffer and append it to the out buffer.
-    mBuffer->appendBuffer(std::move(nodeBuffer));
+    if (mFilteredAttrs.empty()) {
+      return;
+    }
 
-    // Finish the xml header.
-    xmlHeaderWriter.finish();
-    return true;
+    const ResourceId kIdAttr(0x010100d0);
+
+    std::sort(mFilteredAttrs.begin(), mFilteredAttrs.end(),
+              cmpXmlAttributeById);
+
+    flatElem->attributeCount = util::hostToDevice16(mFilteredAttrs.size());
+
+    ResXMLTree_attribute* flatAttr =
+        writer->nextBlock<ResXMLTree_attribute>(mFilteredAttrs.size());
+    uint16_t attributeIndex = 1;
+    for (const xml::Attribute* xmlAttr : mFilteredAttrs) {
+      // Assign the indices for specific attributes.
+      if (xmlAttr->compiledAttribute && xmlAttr->compiledAttribute.value().id &&
+          xmlAttr->compiledAttribute.value().id.value() == kIdAttr) {
+        flatElem->idIndex = util::hostToDevice16(attributeIndex);
+      } else if (xmlAttr->namespaceUri.empty()) {
+        if (xmlAttr->name == "class") {
+          flatElem->classIndex = util::hostToDevice16(attributeIndex);
+        } else if (xmlAttr->name == "style") {
+          flatElem->styleIndex = util::hostToDevice16(attributeIndex);
+        }
+      }
+      attributeIndex++;
+
+      // Add the namespaceUri to the list of StringRefs to encode. Use null if
+      // the namespace
+      // is empty (doesn't exist).
+      addString(xmlAttr->namespaceUri, kLowPriority, &flatAttr->ns,
+                true /* treatEmptyStringAsNull */);
+
+      flatAttr->rawValue.index = util::hostToDevice32(-1);
+
+      if (!xmlAttr->compiledAttribute ||
+          !xmlAttr->compiledAttribute.value().id) {
+        // The attribute has no associated ResourceID, so the string order
+        // doesn't matter.
+        addString(xmlAttr->name, kLowPriority, &flatAttr->name);
+      } else {
+        // Attribute names are stored without packages, but we use
+        // their StringPool index to lookup their resource IDs.
+        // This will cause collisions, so we can't dedupe
+        // attribute names from different packages. We use separate
+        // pools that we later combine.
+        //
+        // Lookup the StringPool for this package and make the reference there.
+        const xml::AaptAttribute& aaptAttr = xmlAttr->compiledAttribute.value();
+
+        StringPool::Ref nameRef =
+            mPackagePools[aaptAttr.id.value().packageId()].makeRef(
+                xmlAttr->name, StringPool::Context{aaptAttr.id.value().id});
+
+        // Add it to the list of strings to flatten.
+        addString(nameRef, &flatAttr->name);
+      }
+
+      if (mOptions.keepRawValues || !xmlAttr->compiledValue) {
+        // Keep raw values if the value is not compiled or
+        // if we're building a static library (need symbols).
+        addString(xmlAttr->value, kLowPriority, &flatAttr->rawValue);
+      }
+
+      if (xmlAttr->compiledValue) {
+        bool result = xmlAttr->compiledValue->flatten(&flatAttr->typedValue);
+        assert(result);
+      } else {
+        // Flatten as a regular string type.
+        flatAttr->typedValue.dataType = android::Res_value::TYPE_STRING;
+        addString(xmlAttr->value, kLowPriority,
+                  (ResStringPool_ref*)&flatAttr->typedValue.data);
+      }
+
+      flatAttr->typedValue.size =
+          util::hostToDevice16(sizeof(flatAttr->typedValue));
+      flatAttr++;
+    }
+  }
+};
+
+}  // namespace
+
+bool XmlFlattener::flatten(IAaptContext* context, xml::Node* node) {
+  BigBuffer nodeBuffer(1024);
+  XmlFlattenerVisitor visitor(&nodeBuffer, mOptions);
+  node->accept(&visitor);
+
+  // Merge the package pools into the main pool.
+  for (auto& packagePoolEntry : visitor.mPackagePools) {
+    visitor.mPool.merge(std::move(packagePoolEntry.second));
+  }
+
+  // Sort the string pool so that attribute resource IDs show up first.
+  visitor.mPool.sort(
+      [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+        return a.context.priority < b.context.priority;
+      });
+
+  // Now we flatten the string pool references into the correct places.
+  for (const auto& refEntry : visitor.mStringRefs) {
+    refEntry.dest->index = util::hostToDevice32(refEntry.ref.getIndex());
+  }
+
+  // Write the XML header.
+  ChunkWriter xmlHeaderWriter(mBuffer);
+  xmlHeaderWriter.startChunk<ResXMLTree_header>(RES_XML_TYPE);
+
+  // Flatten the StringPool.
+  StringPool::flattenUtf8(mBuffer, visitor.mPool);
+
+  {
+    // Write the array of resource IDs, indexed by StringPool order.
+    ChunkWriter resIdMapWriter(mBuffer);
+    resIdMapWriter.startChunk<ResChunk_header>(RES_XML_RESOURCE_MAP_TYPE);
+    for (const auto& str : visitor.mPool) {
+      ResourceId id = {str->context.priority};
+      if (id.id == kLowPriority || !id.isValid()) {
+        // When we see the first non-resource ID,
+        // we're done.
+        break;
+      }
+
+      *resIdMapWriter.nextBlock<uint32_t>() = id.id;
+    }
+    resIdMapWriter.finish();
+  }
+
+  // Move the nodeBuffer and append it to the out buffer.
+  mBuffer->appendBuffer(std::move(nodeBuffer));
+
+  // Finish the xml header.
+  xmlHeaderWriter.finish();
+  return true;
 }
 
 bool XmlFlattener::consume(IAaptContext* context, xml::XmlResource* resource) {
-    if (!resource->root) {
-        return false;
-    }
-    return flatten(context, resource->root.get());
+  if (!resource->root) {
+    return false;
+  }
+  return flatten(context, resource->root.get());
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/flatten/XmlFlattener.h b/tools/aapt2/flatten/XmlFlattener.h
index a688ac9..d8d592b 100644
--- a/tools/aapt2/flatten/XmlFlattener.h
+++ b/tools/aapt2/flatten/XmlFlattener.h
@@ -24,32 +24,31 @@
 namespace aapt {
 
 struct XmlFlattenerOptions {
-    /**
-     * Keep attribute raw string values along with typed values.
-     */
-    bool keepRawValues = false;
+  /**
+   * Keep attribute raw string values along with typed values.
+   */
+  bool keepRawValues = false;
 
-    /**
-     * If set, the max SDK level of attribute to flatten. All others are ignored.
-     */
-    Maybe<size_t> maxSdkLevel;
+  /**
+   * If set, the max SDK level of attribute to flatten. All others are ignored.
+   */
+  Maybe<size_t> maxSdkLevel;
 };
 
 class XmlFlattener : public IXmlResourceConsumer {
-public:
-    XmlFlattener(BigBuffer* buffer, XmlFlattenerOptions options) :
-            mBuffer(buffer), mOptions(options) {
-    }
+ public:
+  XmlFlattener(BigBuffer* buffer, XmlFlattenerOptions options)
+      : mBuffer(buffer), mOptions(options) {}
 
-    bool consume(IAaptContext* context, xml::XmlResource* resource) override;
+  bool consume(IAaptContext* context, xml::XmlResource* resource) override;
 
-private:
-    BigBuffer* mBuffer;
-    XmlFlattenerOptions mOptions;
+ private:
+  BigBuffer* mBuffer;
+  XmlFlattenerOptions mOptions;
 
-    bool flatten(IAaptContext* context, xml::Node* node);
+  bool flatten(IAaptContext* context, xml::Node* node);
 };
 
-} // namespace aapt
+}  // namespace aapt
 
 #endif /* AAPT_FLATTEN_XMLFLATTENER_H */
diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp
index 4d1e178..e0159cb 100644
--- a/tools/aapt2/flatten/XmlFlattener_test.cpp
+++ b/tools/aapt2/flatten/XmlFlattener_test.cpp
@@ -25,230 +25,240 @@
 namespace aapt {
 
 class XmlFlattenerTest : public ::testing::Test {
-public:
-    void SetUp() override {
-        mContext = test::ContextBuilder()
-                .setCompilationPackage("com.app.test")
-                .setNameManglerPolicy(NameManglerPolicy{ "com.app.test" })
-                .addSymbolSource(test::StaticSymbolSourceBuilder()
-                        .addSymbol("android:attr/id", ResourceId(0x010100d0),
-                                   test::AttributeBuilder().build())
-                        .addSymbol("com.app.test:id/id", ResourceId(0x7f020000))
-                        .addSymbol("android:attr/paddingStart", ResourceId(0x010103b3),
-                                   test::AttributeBuilder().build())
-                        .addSymbol("android:attr/colorAccent", ResourceId(0x01010435),
-                                   test::AttributeBuilder().build())
-                        .build())
-                .build();
+ public:
+  void SetUp() override {
+    mContext =
+        test::ContextBuilder()
+            .setCompilationPackage("com.app.test")
+            .setNameManglerPolicy(NameManglerPolicy{"com.app.test"})
+            .addSymbolSource(
+                test::StaticSymbolSourceBuilder()
+                    .addSymbol("android:attr/id", ResourceId(0x010100d0),
+                               test::AttributeBuilder().build())
+                    .addSymbol("com.app.test:id/id", ResourceId(0x7f020000))
+                    .addSymbol("android:attr/paddingStart",
+                               ResourceId(0x010103b3),
+                               test::AttributeBuilder().build())
+                    .addSymbol("android:attr/colorAccent",
+                               ResourceId(0x01010435),
+                               test::AttributeBuilder().build())
+                    .build())
+            .build();
+  }
+
+  ::testing::AssertionResult flatten(xml::XmlResource* doc,
+                                     android::ResXMLTree* outTree,
+                                     const XmlFlattenerOptions& options = {}) {
+    using namespace android;  // For NO_ERROR on windows because it is a macro.
+
+    BigBuffer buffer(1024);
+    XmlFlattener flattener(&buffer, options);
+    if (!flattener.consume(mContext.get(), doc)) {
+      return ::testing::AssertionFailure() << "failed to flatten XML Tree";
     }
 
-    ::testing::AssertionResult flatten(xml::XmlResource* doc, android::ResXMLTree* outTree,
-                                       const XmlFlattenerOptions& options = {}) {
-        using namespace android; // For NO_ERROR on windows because it is a macro.
-
-        BigBuffer buffer(1024);
-        XmlFlattener flattener(&buffer, options);
-        if (!flattener.consume(mContext.get(), doc)) {
-            return ::testing::AssertionFailure() << "failed to flatten XML Tree";
-        }
-
-        std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-        if (outTree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
-            return ::testing::AssertionFailure() << "flattened XML is corrupt";
-        }
-        return ::testing::AssertionSuccess();
+    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
+    if (outTree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
+      return ::testing::AssertionFailure() << "flattened XML is corrupt";
     }
+    return ::testing::AssertionSuccess();
+  }
 
-protected:
-    std::unique_ptr<IAaptContext> mContext;
+ protected:
+  std::unique_ptr<IAaptContext> mContext;
 };
 
 TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) {
-    std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
             <View xmlns:test="http://com.test"
                   attr="hey">
               <Layout test:hello="hi" />
               <Layout>Some text</Layout>
             </View>)EOF");
 
+  android::ResXMLTree tree;
+  ASSERT_TRUE(flatten(doc.get(), &tree));
 
-    android::ResXMLTree tree;
-    ASSERT_TRUE(flatten(doc.get(), &tree));
+  ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
+  size_t len;
+  const char16_t* namespacePrefix = tree.getNamespacePrefix(&len);
+  EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test");
 
-    size_t len;
-    const char16_t* namespacePrefix = tree.getNamespacePrefix(&len);
-    EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test");
+  const char16_t* namespaceUri = tree.getNamespaceUri(&len);
+  ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test");
 
-    const char16_t* namespaceUri = tree.getNamespaceUri(&len);
-    ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test");
+  ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
+  ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
+  const char16_t* tagName = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tagName, len), u"View");
 
-    ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-    const char16_t* tagName = tree.getElementName(&len);
-    EXPECT_EQ(StringPiece16(tagName, len), u"View");
+  ASSERT_EQ(1u, tree.getAttributeCount());
+  ASSERT_EQ(tree.getAttributeNamespace(0, &len), nullptr);
+  const char16_t* attrName = tree.getAttributeName(0, &len);
+  EXPECT_EQ(StringPiece16(attrName, len), u"attr");
 
-    ASSERT_EQ(1u, tree.getAttributeCount());
-    ASSERT_EQ(tree.getAttributeNamespace(0, &len), nullptr);
-    const char16_t* attrName = tree.getAttributeName(0, &len);
-    EXPECT_EQ(StringPiece16(attrName, len), u"attr");
+  EXPECT_EQ(0, tree.indexOfAttribute(nullptr, 0, u"attr",
+                                     StringPiece16(u"attr").size()));
 
-    EXPECT_EQ(0, tree.indexOfAttribute(nullptr, 0, u"attr", StringPiece16(u"attr").size()));
+  ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
+  ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
+  tagName = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
 
-    ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-    tagName = tree.getElementName(&len);
-    EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
+  ASSERT_EQ(1u, tree.getAttributeCount());
+  const char16_t* attrNamespace = tree.getAttributeNamespace(0, &len);
+  EXPECT_EQ(StringPiece16(attrNamespace, len), u"http://com.test");
 
-    ASSERT_EQ(1u, tree.getAttributeCount());
-    const char16_t* attrNamespace = tree.getAttributeNamespace(0, &len);
-    EXPECT_EQ(StringPiece16(attrNamespace, len), u"http://com.test");
+  attrName = tree.getAttributeName(0, &len);
+  EXPECT_EQ(StringPiece16(attrName, len), u"hello");
 
-    attrName = tree.getAttributeName(0, &len);
-    EXPECT_EQ(StringPiece16(attrName, len), u"hello");
+  ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
+  ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
-    ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
+  ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
+  tagName = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
+  ASSERT_EQ(0u, tree.getAttributeCount());
 
-    ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-    tagName = tree.getElementName(&len);
-    EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
-    ASSERT_EQ(0u, tree.getAttributeCount());
+  ASSERT_EQ(tree.next(), android::ResXMLTree::TEXT);
+  const char16_t* text = tree.getText(&len);
+  EXPECT_EQ(StringPiece16(text, len), u"Some text");
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::TEXT);
-    const char16_t* text = tree.getText(&len);
-    EXPECT_EQ(StringPiece16(text, len), u"Some text");
+  ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
+  ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
+  tagName = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
-    ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-    tagName = tree.getElementName(&len);
-    EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
+  ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
+  ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
+  tagName = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tagName, len), u"View");
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
-    ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-    tagName = tree.getElementName(&len);
-    EXPECT_EQ(StringPiece16(tagName, len), u"View");
+  ASSERT_EQ(tree.next(), android::ResXMLTree::END_NAMESPACE);
+  namespacePrefix = tree.getNamespacePrefix(&len);
+  EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test");
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::END_NAMESPACE);
-    namespacePrefix = tree.getNamespacePrefix(&len);
-    EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test");
+  namespaceUri = tree.getNamespaceUri(&len);
+  ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test");
 
-    namespaceUri = tree.getNamespaceUri(&len);
-    ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test");
-
-    ASSERT_EQ(tree.next(), android::ResXMLTree::END_DOCUMENT);
+  ASSERT_EQ(tree.next(), android::ResXMLTree::END_DOCUMENT);
 }
 
 TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripSdk21) {
-    std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                 android:paddingStart="1dp"
                 android:colorAccent="#ffffff"/>)EOF");
 
-    XmlReferenceLinker linker;
-    ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
-    ASSERT_TRUE(linker.getSdkLevels().count(17) == 1);
-    ASSERT_TRUE(linker.getSdkLevels().count(21) == 1);
+  XmlReferenceLinker linker;
+  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(linker.getSdkLevels().count(17) == 1);
+  ASSERT_TRUE(linker.getSdkLevels().count(21) == 1);
 
-    android::ResXMLTree tree;
-    XmlFlattenerOptions options;
-    options.maxSdkLevel = 17;
-    ASSERT_TRUE(flatten(doc.get(), &tree, options));
+  android::ResXMLTree tree;
+  XmlFlattenerOptions options;
+  options.maxSdkLevel = 17;
+  ASSERT_TRUE(flatten(doc.get(), &tree, options));
 
-    while (tree.next() != android::ResXMLTree::START_TAG) {
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
-    }
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+  }
 
-    ASSERT_EQ(1u, tree.getAttributeCount());
-    EXPECT_EQ(uint32_t(0x010103b3), tree.getAttributeNameResID(0));
+  ASSERT_EQ(1u, tree.getAttributeCount());
+  EXPECT_EQ(uint32_t(0x010103b3), tree.getAttributeNameResID(0));
 }
 
 TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) {
-    std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
             <View xmlns:tools="http://schemas.android.com/tools"
                 xmlns:foo="http://schemas.android.com/foo"
                 foo:bar="Foo"
                 tools:ignore="MissingTranslation"/>)EOF");
 
-    android::ResXMLTree tree;
-    ASSERT_TRUE(flatten(doc.get(), &tree));
+  android::ResXMLTree tree;
+  ASSERT_TRUE(flatten(doc.get(), &tree));
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
+  ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
 
-    size_t len;
-    const char16_t* namespacePrefix = tree.getNamespacePrefix(&len);
-    EXPECT_EQ(StringPiece16(namespacePrefix, len), u"foo");
+  size_t len;
+  const char16_t* namespacePrefix = tree.getNamespacePrefix(&len);
+  EXPECT_EQ(StringPiece16(namespacePrefix, len), u"foo");
 
-    const char16_t* namespaceUri = tree.getNamespaceUri(&len);
-    ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://schemas.android.com/foo");
+  const char16_t* namespaceUri = tree.getNamespaceUri(&len);
+  ASSERT_EQ(StringPiece16(namespaceUri, len),
+            u"http://schemas.android.com/foo");
 
-    ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
+  ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
 
-    EXPECT_EQ(
-            tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"),
+  EXPECT_EQ(tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"),
             android::NAME_NOT_FOUND);
-    EXPECT_GE(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), 0);
+  EXPECT_GE(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), 0);
 }
 
 TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) {
-    std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                   android:id="@id/id"
                   class="str"
                   style="@id/id"/>)EOF");
 
-    android::ResXMLTree tree;
-    ASSERT_TRUE(flatten(doc.get(), &tree));
+  android::ResXMLTree tree;
+  ASSERT_TRUE(flatten(doc.get(), &tree));
 
-    while (tree.next() != android::ResXMLTree::START_TAG) {
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
-    }
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+  }
 
-    EXPECT_EQ(tree.indexOfClass(), 0);
-    EXPECT_EQ(tree.indexOfStyle(), 1);
+  EXPECT_EQ(tree.indexOfClass(), 0);
+  EXPECT_EQ(tree.indexOfStyle(), 1);
 }
 
 /*
- * The device ResXMLParser in libandroidfw differentiates between empty namespace and null
+ * The device ResXMLParser in libandroidfw differentiates between empty
+ * namespace and null
  * namespace.
  */
 TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) {
-    std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom("<View package=\"android\"/>");
+  std::unique_ptr<xml::XmlResource> doc =
+      test::buildXmlDom("<View package=\"android\"/>");
 
-    android::ResXMLTree tree;
-    ASSERT_TRUE(flatten(doc.get(), &tree));
+  android::ResXMLTree tree;
+  ASSERT_TRUE(flatten(doc.get(), &tree));
 
-    while (tree.next() != android::ResXMLTree::START_TAG) {
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
-    }
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+  }
 
-    const StringPiece16 kPackage = u"package";
-    EXPECT_GE(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), 0);
+  const StringPiece16 kPackage = u"package";
+  EXPECT_GE(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()),
+            0);
 }
 
 TEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) {
-    std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom("<View package=\"\"/>");
+  std::unique_ptr<xml::XmlResource> doc =
+      test::buildXmlDom("<View package=\"\"/>");
 
-    android::ResXMLTree tree;
-    ASSERT_TRUE(flatten(doc.get(), &tree));
+  android::ResXMLTree tree;
+  ASSERT_TRUE(flatten(doc.get(), &tree));
 
-    while (tree.next() != android::ResXMLTree::START_TAG) {
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-        ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
-    }
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
+    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+  }
 
-    const StringPiece16 kPackage = u"package";
-    ssize_t idx = tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size());
-    ASSERT_GE(idx, 0);
+  const StringPiece16 kPackage = u"package";
+  ssize_t idx =
+      tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size());
+  ASSERT_GE(idx, 0);
 
-    size_t len;
-    EXPECT_NE(nullptr, tree.getAttributeStringValue(idx, &len));
+  size_t len;
+  EXPECT_NE(nullptr, tree.getAttributeStringValue(idx, &len));
 }
 
-} // namespace aapt
+}  // namespace aapt