Home | History | Annotate | Download | only in aapt2
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "ResourceValues.h"
     18 
     19 #include <algorithm>
     20 #include <limits>
     21 #include <set>
     22 
     23 #include "androidfw/ResourceTypes.h"
     24 
     25 #include "Resource.h"
     26 #include "ResourceUtils.h"
     27 #include "ValueVisitor.h"
     28 #include "util/Util.h"
     29 
     30 namespace aapt {
     31 
     32 std::ostream& operator<<(std::ostream& out, const Value& value) {
     33   value.Print(&out);
     34   return out;
     35 }
     36 
     37 template <typename Derived>
     38 void BaseValue<Derived>::Accept(RawValueVisitor* visitor) {
     39   visitor->Visit(static_cast<Derived*>(this));
     40 }
     41 
     42 template <typename Derived>
     43 void BaseItem<Derived>::Accept(RawValueVisitor* visitor) {
     44   visitor->Visit(static_cast<Derived*>(this));
     45 }
     46 
     47 RawString::RawString(const StringPool::Ref& ref) : value(ref) {}
     48 
     49 bool RawString::Equals(const Value* value) const {
     50   const RawString* other = ValueCast<RawString>(value);
     51   if (!other) {
     52     return false;
     53   }
     54   return *this->value == *other->value;
     55 }
     56 
     57 RawString* RawString::Clone(StringPool* new_pool) const {
     58   RawString* rs = new RawString(new_pool->MakeRef(value));
     59   rs->comment_ = comment_;
     60   rs->source_ = source_;
     61   return rs;
     62 }
     63 
     64 bool RawString::Flatten(android::Res_value* out_value) const {
     65   out_value->dataType = android::Res_value::TYPE_STRING;
     66   out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
     67   return true;
     68 }
     69 
     70 void RawString::Print(std::ostream* out) const {
     71   *out << "(raw string) " << *value;
     72 }
     73 
     74 Reference::Reference() : reference_type(Type::kResource) {}
     75 
     76 Reference::Reference(const ResourceNameRef& n, Type t)
     77     : name(n.ToResourceName()), reference_type(t) {}
     78 
     79 Reference::Reference(const ResourceId& i, Type type)
     80     : id(i), reference_type(type) {}
     81 
     82 Reference::Reference(const ResourceNameRef& n, const ResourceId& i)
     83     : name(n.ToResourceName()), id(i), reference_type(Type::kResource) {}
     84 
     85 bool Reference::Equals(const Value* value) const {
     86   const Reference* other = ValueCast<Reference>(value);
     87   if (!other) {
     88     return false;
     89   }
     90   return reference_type == other->reference_type &&
     91          private_reference == other->private_reference && id == other->id &&
     92          name == other->name;
     93 }
     94 
     95 bool Reference::Flatten(android::Res_value* out_value) const {
     96   const ResourceId resid = id.value_or_default(ResourceId(0));
     97   const bool dynamic = resid.is_valid_dynamic() && resid.package_id() != kFrameworkPackageId &&
     98                        resid.package_id() != kAppPackageId;
     99 
    100   if (reference_type == Reference::Type::kResource) {
    101     if (dynamic) {
    102       out_value->dataType = android::Res_value::TYPE_DYNAMIC_REFERENCE;
    103     } else {
    104       out_value->dataType = android::Res_value::TYPE_REFERENCE;
    105     }
    106   } else {
    107     if (dynamic) {
    108       out_value->dataType = android::Res_value::TYPE_DYNAMIC_ATTRIBUTE;
    109     } else {
    110       out_value->dataType = android::Res_value::TYPE_ATTRIBUTE;
    111     }
    112   }
    113   out_value->data = util::HostToDevice32(resid.id);
    114   return true;
    115 }
    116 
    117 Reference* Reference::Clone(StringPool* /*new_pool*/) const {
    118   return new Reference(*this);
    119 }
    120 
    121 void Reference::Print(std::ostream* out) const {
    122   if (reference_type == Type::kResource) {
    123     *out << "(reference) @";
    124     if (!name && !id) {
    125       *out << "null";
    126       return;
    127     }
    128   } else {
    129     *out << "(attr-reference) ?";
    130   }
    131 
    132   if (private_reference) {
    133     *out << "*";
    134   }
    135 
    136   if (name) {
    137     *out << name.value();
    138   }
    139 
    140   if (id && id.value().is_valid_dynamic()) {
    141     if (name) {
    142       *out << " ";
    143     }
    144     *out << id.value();
    145   }
    146 }
    147 
    148 bool Id::Equals(const Value* value) const {
    149   return ValueCast<Id>(value) != nullptr;
    150 }
    151 
    152 bool Id::Flatten(android::Res_value* out) const {
    153   out->dataType = android::Res_value::TYPE_INT_BOOLEAN;
    154   out->data = util::HostToDevice32(0);
    155   return true;
    156 }
    157 
    158 Id* Id::Clone(StringPool* /*new_pool*/) const { return new Id(*this); }
    159 
    160 void Id::Print(std::ostream* out) const { *out << "(id)"; }
    161 
    162 String::String(const StringPool::Ref& ref) : value(ref) {}
    163 
    164 bool String::Equals(const Value* value) const {
    165   const String* other = ValueCast<String>(value);
    166   if (!other) {
    167     return false;
    168   }
    169 
    170   if (this->value != other->value) {
    171     return false;
    172   }
    173 
    174   if (untranslatable_sections.size() != other->untranslatable_sections.size()) {
    175     return false;
    176   }
    177 
    178   auto other_iter = other->untranslatable_sections.begin();
    179   for (const UntranslatableSection& this_section : untranslatable_sections) {
    180     if (this_section != *other_iter) {
    181       return false;
    182     }
    183     ++other_iter;
    184   }
    185   return true;
    186 }
    187 
    188 bool String::Flatten(android::Res_value* out_value) const {
    189   // Verify that our StringPool index is within encode-able limits.
    190   if (value.index() > std::numeric_limits<uint32_t>::max()) {
    191     return false;
    192   }
    193 
    194   out_value->dataType = android::Res_value::TYPE_STRING;
    195   out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
    196   return true;
    197 }
    198 
    199 String* String::Clone(StringPool* new_pool) const {
    200   String* str = new String(new_pool->MakeRef(value));
    201   str->comment_ = comment_;
    202   str->source_ = source_;
    203   str->untranslatable_sections = untranslatable_sections;
    204   return str;
    205 }
    206 
    207 void String::Print(std::ostream* out) const {
    208   *out << "(string) \"" << *value << "\"";
    209 }
    210 
    211 StyledString::StyledString(const StringPool::StyleRef& ref) : value(ref) {}
    212 
    213 bool StyledString::Equals(const Value* value) const {
    214   const StyledString* other = ValueCast<StyledString>(value);
    215   if (!other) {
    216     return false;
    217   }
    218 
    219   if (this->value != other->value) {
    220     return false;
    221   }
    222 
    223   if (untranslatable_sections.size() != other->untranslatable_sections.size()) {
    224     return false;
    225   }
    226 
    227   auto other_iter = other->untranslatable_sections.begin();
    228   for (const UntranslatableSection& this_section : untranslatable_sections) {
    229     if (this_section != *other_iter) {
    230       return false;
    231     }
    232     ++other_iter;
    233   }
    234   return true;
    235 }
    236 
    237 bool StyledString::Flatten(android::Res_value* out_value) const {
    238   if (value.index() > std::numeric_limits<uint32_t>::max()) {
    239     return false;
    240   }
    241 
    242   out_value->dataType = android::Res_value::TYPE_STRING;
    243   out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
    244   return true;
    245 }
    246 
    247 StyledString* StyledString::Clone(StringPool* new_pool) const {
    248   StyledString* str = new StyledString(new_pool->MakeRef(value));
    249   str->comment_ = comment_;
    250   str->source_ = source_;
    251   str->untranslatable_sections = untranslatable_sections;
    252   return str;
    253 }
    254 
    255 void StyledString::Print(std::ostream* out) const {
    256   *out << "(styled string) \"" << value->value << "\"";
    257   for (const StringPool::Span& span : value->spans) {
    258     *out << " " << *span.name << ":" << span.first_char << "," << span.last_char;
    259   }
    260 }
    261 
    262 FileReference::FileReference(const StringPool::Ref& _path) : path(_path) {}
    263 
    264 bool FileReference::Equals(const Value* value) const {
    265   const FileReference* other = ValueCast<FileReference>(value);
    266   if (!other) {
    267     return false;
    268   }
    269   return path == other->path;
    270 }
    271 
    272 bool FileReference::Flatten(android::Res_value* out_value) const {
    273   if (path.index() > std::numeric_limits<uint32_t>::max()) {
    274     return false;
    275   }
    276 
    277   out_value->dataType = android::Res_value::TYPE_STRING;
    278   out_value->data = util::HostToDevice32(static_cast<uint32_t>(path.index()));
    279   return true;
    280 }
    281 
    282 FileReference* FileReference::Clone(StringPool* new_pool) const {
    283   FileReference* fr = new FileReference(new_pool->MakeRef(path));
    284   fr->file = file;
    285   fr->comment_ = comment_;
    286   fr->source_ = source_;
    287   return fr;
    288 }
    289 
    290 void FileReference::Print(std::ostream* out) const {
    291   *out << "(file) " << *path;
    292 }
    293 
    294 BinaryPrimitive::BinaryPrimitive(const android::Res_value& val) : value(val) {}
    295 
    296 BinaryPrimitive::BinaryPrimitive(uint8_t dataType, uint32_t data) {
    297   value.dataType = dataType;
    298   value.data = data;
    299 }
    300 
    301 bool BinaryPrimitive::Equals(const Value* value) const {
    302   const BinaryPrimitive* other = ValueCast<BinaryPrimitive>(value);
    303   if (!other) {
    304     return false;
    305   }
    306   return this->value.dataType == other->value.dataType &&
    307          this->value.data == other->value.data;
    308 }
    309 
    310 bool BinaryPrimitive::Flatten(android::Res_value* out_value) const {
    311   out_value->dataType = value.dataType;
    312   out_value->data = util::HostToDevice32(value.data);
    313   return true;
    314 }
    315 
    316 BinaryPrimitive* BinaryPrimitive::Clone(StringPool* /*new_pool*/) const {
    317   return new BinaryPrimitive(*this);
    318 }
    319 
    320 void BinaryPrimitive::Print(std::ostream* out) const {
    321   switch (value.dataType) {
    322     case android::Res_value::TYPE_NULL:
    323       if (value.data == android::Res_value::DATA_NULL_EMPTY) {
    324         *out << "(empty)";
    325       } else {
    326         *out << "(null)";
    327       }
    328       break;
    329     case android::Res_value::TYPE_INT_DEC:
    330       *out << "(integer) " << static_cast<int32_t>(value.data);
    331       break;
    332     case android::Res_value::TYPE_INT_HEX:
    333       *out << "(integer) 0x" << std::hex << value.data << std::dec;
    334       break;
    335     case android::Res_value::TYPE_INT_BOOLEAN:
    336       *out << "(boolean) " << (value.data != 0 ? "true" : "false");
    337       break;
    338     case android::Res_value::TYPE_INT_COLOR_ARGB8:
    339     case android::Res_value::TYPE_INT_COLOR_RGB8:
    340     case android::Res_value::TYPE_INT_COLOR_ARGB4:
    341     case android::Res_value::TYPE_INT_COLOR_RGB4:
    342       *out << "(color) #" << std::hex << value.data << std::dec;
    343       break;
    344     default:
    345       *out << "(unknown 0x" << std::hex << (int)value.dataType << ") 0x"
    346            << std::hex << value.data << std::dec;
    347       break;
    348   }
    349 }
    350 
    351 Attribute::Attribute()
    352     : type_mask(0u),
    353       min_int(std::numeric_limits<int32_t>::min()),
    354       max_int(std::numeric_limits<int32_t>::max()) {
    355 }
    356 
    357 Attribute::Attribute(bool w, uint32_t t)
    358     : type_mask(t),
    359       min_int(std::numeric_limits<int32_t>::min()),
    360       max_int(std::numeric_limits<int32_t>::max()) {
    361   weak_ = w;
    362 }
    363 
    364 std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) {
    365   if (s.symbol.name) {
    366     out << s.symbol.name.value().entry;
    367   } else {
    368     out << "???";
    369   }
    370   return out << "=" << s.value;
    371 }
    372 
    373 template <typename T>
    374 constexpr T* add_pointer(T& val) {
    375   return &val;
    376 }
    377 
    378 bool Attribute::Equals(const Value* value) const {
    379   const Attribute* other = ValueCast<Attribute>(value);
    380   if (!other) {
    381     return false;
    382   }
    383 
    384   if (symbols.size() != other->symbols.size()) {
    385     return false;
    386   }
    387 
    388   if (type_mask != other->type_mask || min_int != other->min_int || max_int != other->max_int) {
    389     return false;
    390   }
    391 
    392   std::vector<const Symbol*> sorted_a;
    393   std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a),
    394                  add_pointer<const Symbol>);
    395   std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool {
    396     return a->symbol.name < b->symbol.name;
    397   });
    398 
    399   std::vector<const Symbol*> sorted_b;
    400   std::transform(other->symbols.begin(), other->symbols.end(), std::back_inserter(sorted_b),
    401                  add_pointer<const Symbol>);
    402   std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool {
    403     return a->symbol.name < b->symbol.name;
    404   });
    405 
    406   return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
    407                     [](const Symbol* a, const Symbol* b) -> bool {
    408                       return a->symbol.Equals(&b->symbol) && a->value == b->value;
    409                     });
    410 }
    411 
    412 Attribute* Attribute::Clone(StringPool* /*new_pool*/) const {
    413   return new Attribute(*this);
    414 }
    415 
    416 void Attribute::PrintMask(std::ostream* out) const {
    417   if (type_mask == android::ResTable_map::TYPE_ANY) {
    418     *out << "any";
    419     return;
    420   }
    421 
    422   bool set = false;
    423   if ((type_mask & android::ResTable_map::TYPE_REFERENCE) != 0) {
    424     if (!set) {
    425       set = true;
    426     } else {
    427       *out << "|";
    428     }
    429     *out << "reference";
    430   }
    431 
    432   if ((type_mask & android::ResTable_map::TYPE_STRING) != 0) {
    433     if (!set) {
    434       set = true;
    435     } else {
    436       *out << "|";
    437     }
    438     *out << "string";
    439   }
    440 
    441   if ((type_mask & android::ResTable_map::TYPE_INTEGER) != 0) {
    442     if (!set) {
    443       set = true;
    444     } else {
    445       *out << "|";
    446     }
    447     *out << "integer";
    448   }
    449 
    450   if ((type_mask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
    451     if (!set) {
    452       set = true;
    453     } else {
    454       *out << "|";
    455     }
    456     *out << "boolean";
    457   }
    458 
    459   if ((type_mask & android::ResTable_map::TYPE_COLOR) != 0) {
    460     if (!set) {
    461       set = true;
    462     } else {
    463       *out << "|";
    464     }
    465     *out << "color";
    466   }
    467 
    468   if ((type_mask & android::ResTable_map::TYPE_FLOAT) != 0) {
    469     if (!set) {
    470       set = true;
    471     } else {
    472       *out << "|";
    473     }
    474     *out << "float";
    475   }
    476 
    477   if ((type_mask & android::ResTable_map::TYPE_DIMENSION) != 0) {
    478     if (!set) {
    479       set = true;
    480     } else {
    481       *out << "|";
    482     }
    483     *out << "dimension";
    484   }
    485 
    486   if ((type_mask & android::ResTable_map::TYPE_FRACTION) != 0) {
    487     if (!set) {
    488       set = true;
    489     } else {
    490       *out << "|";
    491     }
    492     *out << "fraction";
    493   }
    494 
    495   if ((type_mask & android::ResTable_map::TYPE_ENUM) != 0) {
    496     if (!set) {
    497       set = true;
    498     } else {
    499       *out << "|";
    500     }
    501     *out << "enum";
    502   }
    503 
    504   if ((type_mask & android::ResTable_map::TYPE_FLAGS) != 0) {
    505     if (!set) {
    506       set = true;
    507     } else {
    508       *out << "|";
    509     }
    510     *out << "flags";
    511   }
    512 }
    513 
    514 void Attribute::Print(std::ostream* out) const {
    515   *out << "(attr) ";
    516   PrintMask(out);
    517 
    518   if (!symbols.empty()) {
    519     *out << " [" << util::Joiner(symbols, ", ") << "]";
    520   }
    521 
    522   if (min_int != std::numeric_limits<int32_t>::min()) {
    523     *out << " min=" << min_int;
    524   }
    525 
    526   if (max_int != std::numeric_limits<int32_t>::max()) {
    527     *out << " max=" << max_int;
    528   }
    529 
    530   if (IsWeak()) {
    531     *out << " [weak]";
    532   }
    533 }
    534 
    535 static void BuildAttributeMismatchMessage(const Attribute& attr, const Item& value,
    536                                           DiagMessage* out_msg) {
    537   *out_msg << "expected";
    538   if (attr.type_mask & android::ResTable_map::TYPE_BOOLEAN) {
    539     *out_msg << " boolean";
    540   }
    541 
    542   if (attr.type_mask & android::ResTable_map::TYPE_COLOR) {
    543     *out_msg << " color";
    544   }
    545 
    546   if (attr.type_mask & android::ResTable_map::TYPE_DIMENSION) {
    547     *out_msg << " dimension";
    548   }
    549 
    550   if (attr.type_mask & android::ResTable_map::TYPE_ENUM) {
    551     *out_msg << " enum";
    552   }
    553 
    554   if (attr.type_mask & android::ResTable_map::TYPE_FLAGS) {
    555     *out_msg << " flags";
    556   }
    557 
    558   if (attr.type_mask & android::ResTable_map::TYPE_FLOAT) {
    559     *out_msg << " float";
    560   }
    561 
    562   if (attr.type_mask & android::ResTable_map::TYPE_FRACTION) {
    563     *out_msg << " fraction";
    564   }
    565 
    566   if (attr.type_mask & android::ResTable_map::TYPE_INTEGER) {
    567     *out_msg << " integer";
    568   }
    569 
    570   if (attr.type_mask & android::ResTable_map::TYPE_REFERENCE) {
    571     *out_msg << " reference";
    572   }
    573 
    574   if (attr.type_mask & android::ResTable_map::TYPE_STRING) {
    575     *out_msg << " string";
    576   }
    577 
    578   *out_msg << " but got " << value;
    579 }
    580 
    581 bool Attribute::Matches(const Item& item, DiagMessage* out_msg) const {
    582   constexpr const uint32_t TYPE_ENUM = android::ResTable_map::TYPE_ENUM;
    583   constexpr const uint32_t TYPE_FLAGS = android::ResTable_map::TYPE_FLAGS;
    584   constexpr const uint32_t TYPE_INTEGER = android::ResTable_map::TYPE_INTEGER;
    585   constexpr const uint32_t TYPE_REFERENCE = android::ResTable_map::TYPE_REFERENCE;
    586 
    587   android::Res_value val = {};
    588   item.Flatten(&val);
    589 
    590   const uint32_t flattened_data = util::DeviceToHost32(val.data);
    591 
    592   // Always allow references.
    593   const uint32_t actual_type = ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType);
    594 
    595   // Only one type must match between the actual and expected.
    596   if ((actual_type & (type_mask | TYPE_REFERENCE)) == 0) {
    597     if (out_msg) {
    598       BuildAttributeMismatchMessage(*this, item, out_msg);
    599     }
    600     return false;
    601   }
    602 
    603   // Enums and flags are encoded as integers, so check them first before doing any range checks.
    604   if ((type_mask & TYPE_ENUM) != 0 && (actual_type & TYPE_ENUM) != 0) {
    605     for (const Symbol& s : symbols) {
    606       if (flattened_data == s.value) {
    607         return true;
    608       }
    609     }
    610 
    611     // If the attribute accepts integers, we can't fail here.
    612     if ((type_mask & TYPE_INTEGER) == 0) {
    613       if (out_msg) {
    614         *out_msg << item << " is not a valid enum";
    615       }
    616       return false;
    617     }
    618   }
    619 
    620   if ((type_mask & TYPE_FLAGS) != 0 && (actual_type & TYPE_FLAGS) != 0) {
    621     uint32_t mask = 0u;
    622     for (const Symbol& s : symbols) {
    623       mask |= s.value;
    624     }
    625 
    626     // Check if the flattened data is covered by the flag bit mask.
    627     // If the attribute accepts integers, we can't fail here.
    628     if ((mask & flattened_data) == flattened_data) {
    629       return true;
    630     } else if ((type_mask & TYPE_INTEGER) == 0) {
    631       if (out_msg) {
    632         *out_msg << item << " is not a valid flag";
    633       }
    634       return false;
    635     }
    636   }
    637 
    638   // Finally check the integer range of the value.
    639   if ((type_mask & TYPE_INTEGER) != 0 && (actual_type & TYPE_INTEGER) != 0) {
    640     if (static_cast<int32_t>(flattened_data) < min_int) {
    641       if (out_msg) {
    642         *out_msg << item << " is less than minimum integer " << min_int;
    643       }
    644       return false;
    645     } else if (static_cast<int32_t>(flattened_data) > max_int) {
    646       if (out_msg) {
    647         *out_msg << item << " is greater than maximum integer " << max_int;
    648       }
    649       return false;
    650     }
    651   }
    652   return true;
    653 }
    654 
    655 std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) {
    656   if (entry.key.name) {
    657     out << entry.key.name.value();
    658   } else if (entry.key.id) {
    659     out << entry.key.id.value();
    660   } else {
    661     out << "???";
    662   }
    663   out << " = " << entry.value;
    664   return out;
    665 }
    666 
    667 template <typename T>
    668 std::vector<T*> ToPointerVec(std::vector<T>& src) {
    669   std::vector<T*> dst;
    670   dst.reserve(src.size());
    671   for (T& in : src) {
    672     dst.push_back(&in);
    673   }
    674   return dst;
    675 }
    676 
    677 template <typename T>
    678 std::vector<const T*> ToPointerVec(const std::vector<T>& src) {
    679   std::vector<const T*> dst;
    680   dst.reserve(src.size());
    681   for (const T& in : src) {
    682     dst.push_back(&in);
    683   }
    684   return dst;
    685 }
    686 
    687 static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) {
    688   return a->key.name < b->key.name;
    689 }
    690 
    691 bool Style::Equals(const Value* value) const {
    692   const Style* other = ValueCast<Style>(value);
    693   if (!other) {
    694     return false;
    695   }
    696 
    697   if (bool(parent) != bool(other->parent) ||
    698       (parent && other->parent && !parent.value().Equals(&other->parent.value()))) {
    699     return false;
    700   }
    701 
    702   if (entries.size() != other->entries.size()) {
    703     return false;
    704   }
    705 
    706   std::vector<const Entry*> sorted_a = ToPointerVec(entries);
    707   std::sort(sorted_a.begin(), sorted_a.end(), KeyNameComparator);
    708 
    709   std::vector<const Entry*> sorted_b = ToPointerVec(other->entries);
    710   std::sort(sorted_b.begin(), sorted_b.end(), KeyNameComparator);
    711 
    712   return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
    713                     [](const Entry* a, const Entry* b) -> bool {
    714                       return a->key.Equals(&b->key) && a->value->Equals(b->value.get());
    715                     });
    716 }
    717 
    718 Style* Style::Clone(StringPool* new_pool) const {
    719   Style* style = new Style();
    720   style->parent = parent;
    721   style->parent_inferred = parent_inferred;
    722   style->comment_ = comment_;
    723   style->source_ = source_;
    724   for (auto& entry : entries) {
    725     style->entries.push_back(Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
    726   }
    727   return style;
    728 }
    729 
    730 void Style::Print(std::ostream* out) const {
    731   *out << "(style) ";
    732   if (parent && parent.value().name) {
    733     const Reference& parent_ref = parent.value();
    734     if (parent_ref.private_reference) {
    735       *out << "*";
    736     }
    737     *out << parent_ref.name.value();
    738   }
    739   *out << " [" << util::Joiner(entries, ", ") << "]";
    740 }
    741 
    742 Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) {
    743   Style::Entry cloned_entry{entry.key};
    744   if (entry.value != nullptr) {
    745     cloned_entry.value.reset(entry.value->Clone(pool));
    746   }
    747   return cloned_entry;
    748 }
    749 
    750 void Style::MergeWith(Style* other, StringPool* pool) {
    751   if (other->parent) {
    752     parent = other->parent;
    753   }
    754 
    755   // We can't assume that the entries are sorted alphabetically since they're supposed to be
    756   // sorted by Resource Id. Not all Resource Ids may be set though, so we can't sort and merge
    757   // them keying off that.
    758   //
    759   // Instead, sort the entries of each Style by their name in a separate structure. Then merge
    760   // those.
    761 
    762   std::vector<Entry*> this_sorted = ToPointerVec(entries);
    763   std::sort(this_sorted.begin(), this_sorted.end(), KeyNameComparator);
    764 
    765   std::vector<Entry*> other_sorted = ToPointerVec(other->entries);
    766   std::sort(other_sorted.begin(), other_sorted.end(), KeyNameComparator);
    767 
    768   auto this_iter = this_sorted.begin();
    769   const auto this_end = this_sorted.end();
    770 
    771   auto other_iter = other_sorted.begin();
    772   const auto other_end = other_sorted.end();
    773 
    774   std::vector<Entry> merged_entries;
    775   while (this_iter != this_end) {
    776     if (other_iter != other_end) {
    777       if ((*this_iter)->key.name < (*other_iter)->key.name) {
    778         merged_entries.push_back(std::move(**this_iter));
    779         ++this_iter;
    780       } else {
    781         // The other overrides.
    782         merged_entries.push_back(CloneEntry(**other_iter, pool));
    783         if ((*this_iter)->key.name == (*other_iter)->key.name) {
    784           ++this_iter;
    785         }
    786         ++other_iter;
    787       }
    788     } else {
    789       merged_entries.push_back(std::move(**this_iter));
    790       ++this_iter;
    791     }
    792   }
    793 
    794   while (other_iter != other_end) {
    795     merged_entries.push_back(CloneEntry(**other_iter, pool));
    796     ++other_iter;
    797   }
    798 
    799   entries = std::move(merged_entries);
    800 }
    801 
    802 bool Array::Equals(const Value* value) const {
    803   const Array* other = ValueCast<Array>(value);
    804   if (!other) {
    805     return false;
    806   }
    807 
    808   if (elements.size() != other->elements.size()) {
    809     return false;
    810   }
    811 
    812   return std::equal(elements.begin(), elements.end(), other->elements.begin(),
    813                     [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
    814                       return a->Equals(b.get());
    815                     });
    816 }
    817 
    818 Array* Array::Clone(StringPool* new_pool) const {
    819   Array* array = new Array();
    820   array->comment_ = comment_;
    821   array->source_ = source_;
    822   for (auto& item : elements) {
    823     array->elements.emplace_back(std::unique_ptr<Item>(item->Clone(new_pool)));
    824   }
    825   return array;
    826 }
    827 
    828 void Array::Print(std::ostream* out) const {
    829   *out << "(array) [" << util::Joiner(elements, ", ") << "]";
    830 }
    831 
    832 bool Plural::Equals(const Value* value) const {
    833   const Plural* other = ValueCast<Plural>(value);
    834   if (!other) {
    835     return false;
    836   }
    837 
    838   auto one_iter = values.begin();
    839   auto one_end_iter = values.end();
    840   auto two_iter = other->values.begin();
    841   for (; one_iter != one_end_iter; ++one_iter, ++two_iter) {
    842     const std::unique_ptr<Item>& a = *one_iter;
    843     const std::unique_ptr<Item>& b = *two_iter;
    844     if (a != nullptr && b != nullptr) {
    845       if (!a->Equals(b.get())) {
    846         return false;
    847       }
    848     } else if (a != b) {
    849       return false;
    850     }
    851   }
    852   return true;
    853 }
    854 
    855 Plural* Plural::Clone(StringPool* new_pool) const {
    856   Plural* p = new Plural();
    857   p->comment_ = comment_;
    858   p->source_ = source_;
    859   const size_t count = values.size();
    860   for (size_t i = 0; i < count; i++) {
    861     if (values[i]) {
    862       p->values[i] = std::unique_ptr<Item>(values[i]->Clone(new_pool));
    863     }
    864   }
    865   return p;
    866 }
    867 
    868 void Plural::Print(std::ostream* out) const {
    869   *out << "(plural)";
    870   if (values[Zero]) {
    871     *out << " zero=" << *values[Zero];
    872   }
    873 
    874   if (values[One]) {
    875     *out << " one=" << *values[One];
    876   }
    877 
    878   if (values[Two]) {
    879     *out << " two=" << *values[Two];
    880   }
    881 
    882   if (values[Few]) {
    883     *out << " few=" << *values[Few];
    884   }
    885 
    886   if (values[Many]) {
    887     *out << " many=" << *values[Many];
    888   }
    889 
    890   if (values[Other]) {
    891     *out << " other=" << *values[Other];
    892   }
    893 }
    894 
    895 bool Styleable::Equals(const Value* value) const {
    896   const Styleable* other = ValueCast<Styleable>(value);
    897   if (!other) {
    898     return false;
    899   }
    900 
    901   if (entries.size() != other->entries.size()) {
    902     return false;
    903   }
    904 
    905   return std::equal(entries.begin(), entries.end(), other->entries.begin(),
    906                     [](const Reference& a, const Reference& b) -> bool {
    907                       return a.Equals(&b);
    908                     });
    909 }
    910 
    911 Styleable* Styleable::Clone(StringPool* /*new_pool*/) const {
    912   return new Styleable(*this);
    913 }
    914 
    915 void Styleable::Print(std::ostream* out) const {
    916   *out << "(styleable) "
    917        << " [" << util::Joiner(entries, ", ") << "]";
    918 }
    919 
    920 bool operator<(const Reference& a, const Reference& b) {
    921   int cmp = a.name.value_or_default({}).compare(b.name.value_or_default({}));
    922   if (cmp != 0) return cmp < 0;
    923   return a.id < b.id;
    924 }
    925 
    926 bool operator==(const Reference& a, const Reference& b) {
    927   return a.name == b.name && a.id == b.id;
    928 }
    929 
    930 bool operator!=(const Reference& a, const Reference& b) {
    931   return a.name != b.name || a.id != b.id;
    932 }
    933 
    934 struct NameOnlyComparator {
    935   bool operator()(const Reference& a, const Reference& b) const {
    936     return a.name < b.name;
    937   }
    938 };
    939 
    940 void Styleable::MergeWith(Styleable* other) {
    941   // Compare only names, because some References may already have their IDs
    942   // assigned (framework IDs that don't change).
    943   std::set<Reference, NameOnlyComparator> references;
    944   references.insert(entries.begin(), entries.end());
    945   references.insert(other->entries.begin(), other->entries.end());
    946   entries.clear();
    947   entries.reserve(references.size());
    948   entries.insert(entries.end(), references.begin(), references.end());
    949 }
    950 
    951 }  // namespace aapt
    952