AAPT2: Ensure style strings are always first in StringPool

Move the styled strings to a separate section of the StringPool so
that sorting can never mess up the order of Styles.

Bug: 63570514
Test: make aapt2_tests
Change-Id: Id2ce1355b92be1bb31ce0daa7e54ae9b5b6c2ffe
diff --git a/tools/aapt2/proto/ProtoHelpers.cpp b/tools/aapt2/proto/ProtoHelpers.cpp
index 38bf4e3..6b21364 100644
--- a/tools/aapt2/proto/ProtoHelpers.cpp
+++ b/tools/aapt2/proto/ProtoHelpers.cpp
@@ -18,8 +18,7 @@
 
 namespace aapt {
 
-void SerializeStringPoolToPb(const StringPool& pool,
-                             pb::StringPool* out_pb_pool) {
+void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool) {
   BigBuffer buffer(1024);
   StringPool::FlattenUtf8(&buffer, pool);
 
@@ -28,14 +27,12 @@
 
   size_t offset = 0;
   for (const BigBuffer::Block& block : buffer) {
-    data->insert(data->begin() + offset, block.buffer.get(),
-                 block.buffer.get() + block.size);
+    data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size);
     offset += block.size;
   }
 }
 
-void SerializeSourceToPb(const Source& source, StringPool* src_pool,
-                         pb::Source* out_pb_source) {
+void SerializeSourceToPb(const Source& source, StringPool* src_pool, pb::Source* out_pb_source) {
   StringPool::Ref ref = src_pool->MakeRef(source.path);
   out_pb_source->set_path_idx(static_cast<uint32_t>(ref.index()));
   if (source.line) {
@@ -43,8 +40,7 @@
   }
 }
 
-void DeserializeSourceFromPb(const pb::Source& pb_source,
-                             const android::ResStringPool& src_pool,
+void DeserializeSourceFromPb(const pb::Source& pb_source, const android::ResStringPool& src_pool,
                              Source* out_source) {
   if (pb_source.has_path_idx()) {
     out_source->path = util::GetString(src_pool, pb_source.path_idx());
@@ -80,8 +76,7 @@
   return SymbolState::kUndefined;
 }
 
-void SerializeConfig(const ConfigDescription& config,
-                     pb::ConfigDescription* out_pb_config) {
+void SerializeConfig(const ConfigDescription& config, pb::ConfigDescription* out_pb_config) {
   android::ResTable_config flat_config = config;
   flat_config.size = sizeof(flat_config);
   flat_config.swapHtoD();
@@ -99,8 +94,7 @@
     return false;
   }
 
-  config = reinterpret_cast<const android::ResTable_config*>(
-      pb_config.data().data());
+  config = reinterpret_cast<const android::ResTable_config*>(pb_config.data().data());
   out_config->copyFromDtoH(*config);
   return true;
 }
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
index 4b56192..37d5ed0 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -195,8 +195,7 @@
           spans++;
         }
         return util::make_unique<StyledString>(pool->MakeRef(
-            style_str,
-            StringPool::Context(StringPool::Context::kStylePriority, config)));
+            style_str, StringPool::Context(StringPool::Context::kNormalPriority, config)));
       }
       return util::make_unique<String>(
           pool->MakeRef(str, StringPool::Context(config)));
diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp
index d87d64e..730442c 100644
--- a/tools/aapt2/proto/TableProtoSerializer.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer.cpp
@@ -87,7 +87,9 @@
     pb_prim->set_data(val.data);
   }
 
-  void VisitItem(Item* item) override { LOG(FATAL) << "unimplemented item"; }
+  void VisitItem(Item* item) override {
+    LOG(FATAL) << "unimplemented item";
+  }
 
   void Visit(Attribute* attr) override {
     pb::Attribute* pb_attr = pb_compound_value()->mutable_attr();
@@ -207,19 +209,15 @@
 }  // namespace
 
 std::unique_ptr<pb::ResourceTable> SerializeTableToPb(ResourceTable* table) {
-  // We must do this before writing the resources, since the string pool IDs may
-  // change.
-  table->string_pool.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;
-        diff = a.context.config.compare(b.context.config);
-        if (diff < 0) return true;
-        if (diff > 0) return false;
-        return a.value < b.value;
-      });
+  // We must do this before writing the resources, since the string pool IDs may change.
   table->string_pool.Prune();
+  table->string_pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int {
+    int diff = util::compare(a.priority, b.priority);
+    if (diff == 0) {
+      diff = a.config.compare(b.config);
+    }
+    return diff;
+  });
 
   auto pb_table = util::make_unique<pb::ResourceTable>();
   SerializeStringPoolToPb(table->string_pool, pb_table->mutable_string_pool());