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 <cinttypes>
     21 #include <limits>
     22 #include <set>
     23 #include <sstream>
     24 
     25 #include "android-base/stringprintf.h"
     26 #include "androidfw/ResourceTypes.h"
     27 
     28 #include "Resource.h"
     29 #include "ResourceUtils.h"
     30 #include "ValueVisitor.h"
     31 #include "util/Util.h"
     32 
     33 using ::aapt::text::Printer;
     34 using ::android::StringPiece;
     35 using ::android::base::StringPrintf;
     36 
     37 namespace aapt {
     38 
     39 void Value::PrettyPrint(Printer* printer) const {
     40   std::ostringstream str_stream;
     41   Print(&str_stream);
     42   printer->Print(str_stream.str());
     43 }
     44 
     45 std::ostream& operator<<(std::ostream& out, const Value& value) {
     46   value.Print(&out);
     47   return out;
     48 }
     49 
     50 template <typename Derived>
     51 void BaseValue<Derived>::Accept(ValueVisitor* visitor) {
     52   visitor->Visit(static_cast<Derived*>(this));
     53 }
     54 
     55 template <typename Derived>
     56 void BaseValue<Derived>::Accept(ConstValueVisitor* visitor) const {
     57   visitor->Visit(static_cast<const Derived*>(this));
     58 }
     59 
     60 template <typename Derived>
     61 void BaseItem<Derived>::Accept(ValueVisitor* visitor) {
     62   visitor->Visit(static_cast<Derived*>(this));
     63 }
     64 
     65 template <typename Derived>
     66 void BaseItem<Derived>::Accept(ConstValueVisitor* visitor) const {
     67   visitor->Visit(static_cast<const Derived*>(this));
     68 }
     69 
     70 RawString::RawString(const StringPool::Ref& ref) : value(ref) {}
     71 
     72 bool RawString::Equals(const Value* value) const {
     73   const RawString* other = ValueCast<RawString>(value);
     74   if (!other) {
     75     return false;
     76   }
     77   return *this->value == *other->value;
     78 }
     79 
     80 RawString* RawString::Clone(StringPool* new_pool) const {
     81   RawString* rs = new RawString(new_pool->MakeRef(value));
     82   rs->comment_ = comment_;
     83   rs->source_ = source_;
     84   return rs;
     85 }
     86 
     87 bool RawString::Flatten(android::Res_value* out_value) const {
     88   out_value->dataType = android::Res_value::TYPE_STRING;
     89   out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
     90   return true;
     91 }
     92 
     93 void RawString::Print(std::ostream* out) const {
     94   *out << "(raw string) " << *value;
     95 }
     96 
     97 Reference::Reference() : reference_type(Type::kResource) {}
     98 
     99 Reference::Reference(const ResourceNameRef& n, Type t)
    100     : name(n.ToResourceName()), reference_type(t) {}
    101 
    102 Reference::Reference(const ResourceId& i, Type type)
    103     : id(i), reference_type(type) {}
    104 
    105 Reference::Reference(const ResourceNameRef& n, const ResourceId& i)
    106     : name(n.ToResourceName()), id(i), reference_type(Type::kResource) {}
    107 
    108 bool Reference::Equals(const Value* value) const {
    109   const Reference* other = ValueCast<Reference>(value);
    110   if (!other) {
    111     return false;
    112   }
    113   return reference_type == other->reference_type &&
    114          private_reference == other->private_reference && id == other->id &&
    115          name == other->name;
    116 }
    117 
    118 bool Reference::Flatten(android::Res_value* out_value) const {
    119   const ResourceId resid = id.value_or_default(ResourceId(0));
    120   const bool dynamic = resid.is_valid_dynamic() && is_dynamic;
    121 
    122   if (reference_type == Reference::Type::kResource) {
    123     if (dynamic) {
    124       out_value->dataType = android::Res_value::TYPE_DYNAMIC_REFERENCE;
    125     } else {
    126       out_value->dataType = android::Res_value::TYPE_REFERENCE;
    127     }
    128   } else {
    129     if (dynamic) {
    130       out_value->dataType = android::Res_value::TYPE_DYNAMIC_ATTRIBUTE;
    131     } else {
    132       out_value->dataType = android::Res_value::TYPE_ATTRIBUTE;
    133     }
    134   }
    135   out_value->data = util::HostToDevice32(resid.id);
    136   return true;
    137 }
    138 
    139 Reference* Reference::Clone(StringPool* /*new_pool*/) const {
    140   return new Reference(*this);
    141 }
    142 
    143 void Reference::Print(std::ostream* out) const {
    144   if (reference_type == Type::kResource) {
    145     *out << "(reference) @";
    146     if (!name && !id) {
    147       *out << "null";
    148       return;
    149     }
    150   } else {
    151     *out << "(attr-reference) ?";
    152   }
    153 
    154   if (private_reference) {
    155     *out << "*";
    156   }
    157 
    158   if (name) {
    159     *out << name.value();
    160   }
    161 
    162   if (id && id.value().is_valid_dynamic()) {
    163     if (name) {
    164       *out << " ";
    165     }
    166     *out << id.value();
    167   }
    168 }
    169 
    170 static void PrettyPrintReferenceImpl(const Reference& ref, bool print_package, Printer* printer) {
    171   switch (ref.reference_type) {
    172     case Reference::Type::kResource:
    173       printer->Print("@");
    174       break;
    175 
    176     case Reference::Type::kAttribute:
    177       printer->Print("?");
    178       break;
    179   }
    180 
    181   if (!ref.name && !ref.id) {
    182     printer->Print("null");
    183     return;
    184   }
    185 
    186   if (ref.private_reference) {
    187     printer->Print("*");
    188   }
    189 
    190   if (ref.name) {
    191     const ResourceName& name = ref.name.value();
    192     if (print_package) {
    193       printer->Print(name.to_string());
    194     } else {
    195       printer->Print(to_string(name.type));
    196       printer->Print("/");
    197       printer->Print(name.entry);
    198     }
    199   } else if (ref.id && ref.id.value().is_valid_dynamic()) {
    200     printer->Print(ref.id.value().to_string());
    201   }
    202 }
    203 
    204 void Reference::PrettyPrint(Printer* printer) const {
    205   PrettyPrintReferenceImpl(*this, true /*print_package*/, printer);
    206 }
    207 
    208 void Reference::PrettyPrint(const StringPiece& package, Printer* printer) const {
    209   const bool print_package = name ? package != name.value().package : true;
    210   PrettyPrintReferenceImpl(*this, print_package, printer);
    211 }
    212 
    213 bool Id::Equals(const Value* value) const {
    214   return ValueCast<Id>(value) != nullptr;
    215 }
    216 
    217 bool Id::Flatten(android::Res_value* out) const {
    218   out->dataType = android::Res_value::TYPE_INT_BOOLEAN;
    219   out->data = util::HostToDevice32(0);
    220   return true;
    221 }
    222 
    223 Id* Id::Clone(StringPool* /*new_pool*/) const {
    224   return new Id(*this);
    225 }
    226 
    227 void Id::Print(std::ostream* out) const {
    228   *out << "(id)";
    229 }
    230 
    231 String::String(const StringPool::Ref& ref) : value(ref) {
    232 }
    233 
    234 bool String::Equals(const Value* value) const {
    235   const String* other = ValueCast<String>(value);
    236   if (!other) {
    237     return false;
    238   }
    239 
    240   if (this->value != other->value) {
    241     return false;
    242   }
    243 
    244   if (untranslatable_sections.size() != other->untranslatable_sections.size()) {
    245     return false;
    246   }
    247 
    248   auto other_iter = other->untranslatable_sections.begin();
    249   for (const UntranslatableSection& this_section : untranslatable_sections) {
    250     if (this_section != *other_iter) {
    251       return false;
    252     }
    253     ++other_iter;
    254   }
    255   return true;
    256 }
    257 
    258 bool String::Flatten(android::Res_value* out_value) const {
    259   // Verify that our StringPool index is within encode-able limits.
    260   if (value.index() > std::numeric_limits<uint32_t>::max()) {
    261     return false;
    262   }
    263 
    264   out_value->dataType = android::Res_value::TYPE_STRING;
    265   out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
    266   return true;
    267 }
    268 
    269 String* String::Clone(StringPool* new_pool) const {
    270   String* str = new String(new_pool->MakeRef(value));
    271   str->comment_ = comment_;
    272   str->source_ = source_;
    273   str->untranslatable_sections = untranslatable_sections;
    274   return str;
    275 }
    276 
    277 void String::Print(std::ostream* out) const {
    278   *out << "(string) \"" << *value << "\"";
    279 }
    280 
    281 void String::PrettyPrint(Printer* printer) const {
    282   printer->Print("\"");
    283   printer->Print(*value);
    284   printer->Print("\"");
    285 }
    286 
    287 StyledString::StyledString(const StringPool::StyleRef& ref) : value(ref) {
    288 }
    289 
    290 bool StyledString::Equals(const Value* value) const {
    291   const StyledString* other = ValueCast<StyledString>(value);
    292   if (!other) {
    293     return false;
    294   }
    295 
    296   if (this->value != other->value) {
    297     return false;
    298   }
    299 
    300   if (untranslatable_sections.size() != other->untranslatable_sections.size()) {
    301     return false;
    302   }
    303 
    304   auto other_iter = other->untranslatable_sections.begin();
    305   for (const UntranslatableSection& this_section : untranslatable_sections) {
    306     if (this_section != *other_iter) {
    307       return false;
    308     }
    309     ++other_iter;
    310   }
    311   return true;
    312 }
    313 
    314 bool StyledString::Flatten(android::Res_value* out_value) const {
    315   if (value.index() > std::numeric_limits<uint32_t>::max()) {
    316     return false;
    317   }
    318 
    319   out_value->dataType = android::Res_value::TYPE_STRING;
    320   out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
    321   return true;
    322 }
    323 
    324 StyledString* StyledString::Clone(StringPool* new_pool) const {
    325   StyledString* str = new StyledString(new_pool->MakeRef(value));
    326   str->comment_ = comment_;
    327   str->source_ = source_;
    328   str->untranslatable_sections = untranslatable_sections;
    329   return str;
    330 }
    331 
    332 void StyledString::Print(std::ostream* out) const {
    333   *out << "(styled string) \"" << value->value << "\"";
    334   for (const StringPool::Span& span : value->spans) {
    335     *out << " " << *span.name << ":" << span.first_char << "," << span.last_char;
    336   }
    337 }
    338 
    339 FileReference::FileReference(const StringPool::Ref& _path) : path(_path) {
    340 }
    341 
    342 bool FileReference::Equals(const Value* value) const {
    343   const FileReference* other = ValueCast<FileReference>(value);
    344   if (!other) {
    345     return false;
    346   }
    347   return path == other->path;
    348 }
    349 
    350 bool FileReference::Flatten(android::Res_value* out_value) const {
    351   if (path.index() > std::numeric_limits<uint32_t>::max()) {
    352     return false;
    353   }
    354 
    355   out_value->dataType = android::Res_value::TYPE_STRING;
    356   out_value->data = util::HostToDevice32(static_cast<uint32_t>(path.index()));
    357   return true;
    358 }
    359 
    360 FileReference* FileReference::Clone(StringPool* new_pool) const {
    361   FileReference* fr = new FileReference(new_pool->MakeRef(path));
    362   fr->file = file;
    363   fr->type = type;
    364   fr->comment_ = comment_;
    365   fr->source_ = source_;
    366   return fr;
    367 }
    368 
    369 void FileReference::Print(std::ostream* out) const {
    370   *out << "(file) " << *path;
    371   switch (type) {
    372     case ResourceFile::Type::kBinaryXml:
    373       *out << " type=XML";
    374       break;
    375     case ResourceFile::Type::kProtoXml:
    376       *out << " type=protoXML";
    377       break;
    378     case ResourceFile::Type::kPng:
    379       *out << " type=PNG";
    380       break;
    381     default:
    382       break;
    383   }
    384 }
    385 
    386 BinaryPrimitive::BinaryPrimitive(const android::Res_value& val) : value(val) {
    387 }
    388 
    389 BinaryPrimitive::BinaryPrimitive(uint8_t dataType, uint32_t data) {
    390   value.dataType = dataType;
    391   value.data = data;
    392 }
    393 
    394 bool BinaryPrimitive::Equals(const Value* value) const {
    395   const BinaryPrimitive* other = ValueCast<BinaryPrimitive>(value);
    396   if (!other) {
    397     return false;
    398   }
    399   return this->value.dataType == other->value.dataType &&
    400          this->value.data == other->value.data;
    401 }
    402 
    403 bool BinaryPrimitive::Flatten(::android::Res_value* out_value) const {
    404   out_value->dataType = value.dataType;
    405   out_value->data = util::HostToDevice32(value.data);
    406   return true;
    407 }
    408 
    409 BinaryPrimitive* BinaryPrimitive::Clone(StringPool* /*new_pool*/) const {
    410   return new BinaryPrimitive(*this);
    411 }
    412 
    413 void BinaryPrimitive::Print(std::ostream* out) const {
    414   *out << StringPrintf("(primitive) type=0x%02x data=0x%08x", value.dataType, value.data);
    415 }
    416 
    417 static std::string ComplexToString(uint32_t complex_value, bool fraction) {
    418   using ::android::Res_value;
    419 
    420   constexpr std::array<int, 4> kRadixShifts = {{23, 16, 8, 0}};
    421 
    422   // Determine the radix that was used.
    423   const uint32_t radix =
    424       (complex_value >> Res_value::COMPLEX_RADIX_SHIFT) & Res_value::COMPLEX_RADIX_MASK;
    425   const uint64_t mantissa = uint64_t{(complex_value >> Res_value::COMPLEX_MANTISSA_SHIFT) &
    426                                      Res_value::COMPLEX_MANTISSA_MASK}
    427                             << kRadixShifts[radix];
    428   const float value = mantissa * (1.0f / (1 << 23));
    429 
    430   std::string str = StringPrintf("%f", value);
    431 
    432   const int unit_type =
    433       (complex_value >> Res_value::COMPLEX_UNIT_SHIFT) & Res_value::COMPLEX_UNIT_MASK;
    434   if (fraction) {
    435     switch (unit_type) {
    436       case Res_value::COMPLEX_UNIT_FRACTION:
    437         str += "%";
    438         break;
    439       case Res_value::COMPLEX_UNIT_FRACTION_PARENT:
    440         str += "%p";
    441         break;
    442       default:
    443         str += "???";
    444         break;
    445     }
    446   } else {
    447     switch (unit_type) {
    448       case Res_value::COMPLEX_UNIT_PX:
    449         str += "px";
    450         break;
    451       case Res_value::COMPLEX_UNIT_DIP:
    452         str += "dp";
    453         break;
    454       case Res_value::COMPLEX_UNIT_SP:
    455         str += "sp";
    456         break;
    457       case Res_value::COMPLEX_UNIT_PT:
    458         str += "pt";
    459         break;
    460       case Res_value::COMPLEX_UNIT_IN:
    461         str += "in";
    462         break;
    463       case Res_value::COMPLEX_UNIT_MM:
    464         str += "mm";
    465         break;
    466       default:
    467         str += "???";
    468         break;
    469     }
    470   }
    471   return str;
    472 }
    473 
    474 void BinaryPrimitive::PrettyPrint(Printer* printer) const {
    475   using ::android::Res_value;
    476   switch (value.dataType) {
    477     case Res_value::TYPE_NULL:
    478       if (value.data == Res_value::DATA_NULL_EMPTY) {
    479         printer->Print("@empty");
    480       } else {
    481         printer->Print("@null");
    482       }
    483       break;
    484 
    485     case Res_value::TYPE_INT_DEC:
    486       printer->Print(StringPrintf("%" PRIi32, static_cast<int32_t>(value.data)));
    487       break;
    488 
    489     case Res_value::TYPE_INT_HEX:
    490       printer->Print(StringPrintf("0x%08x", value.data));
    491       break;
    492 
    493     case Res_value::TYPE_INT_BOOLEAN:
    494       printer->Print(value.data != 0 ? "true" : "false");
    495       break;
    496 
    497     case Res_value::TYPE_INT_COLOR_ARGB8:
    498     case Res_value::TYPE_INT_COLOR_RGB8:
    499     case Res_value::TYPE_INT_COLOR_ARGB4:
    500     case Res_value::TYPE_INT_COLOR_RGB4:
    501       printer->Print(StringPrintf("#%08x", value.data));
    502       break;
    503 
    504     case Res_value::TYPE_FLOAT:
    505       printer->Print(StringPrintf("%g", *reinterpret_cast<const float*>(&value.data)));
    506       break;
    507 
    508     case Res_value::TYPE_DIMENSION:
    509       printer->Print(ComplexToString(value.data, false /*fraction*/));
    510       break;
    511 
    512     case Res_value::TYPE_FRACTION:
    513       printer->Print(ComplexToString(value.data, true /*fraction*/));
    514       break;
    515 
    516     default:
    517       printer->Print(StringPrintf("(unknown 0x%02x) 0x%08x", value.dataType, value.data));
    518       break;
    519   }
    520 }
    521 
    522 Attribute::Attribute(uint32_t t)
    523     : type_mask(t),
    524       min_int(std::numeric_limits<int32_t>::min()),
    525       max_int(std::numeric_limits<int32_t>::max()) {
    526 }
    527 
    528 std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) {
    529   if (s.symbol.name) {
    530     out << s.symbol.name.value().entry;
    531   } else {
    532     out << "???";
    533   }
    534   return out << "=" << s.value;
    535 }
    536 
    537 template <typename T>
    538 constexpr T* add_pointer(T& val) {
    539   return &val;
    540 }
    541 
    542 bool Attribute::Equals(const Value* value) const {
    543   const Attribute* other = ValueCast<Attribute>(value);
    544   if (!other) {
    545     return false;
    546   }
    547 
    548   if (symbols.size() != other->symbols.size()) {
    549     return false;
    550   }
    551 
    552   if (type_mask != other->type_mask || min_int != other->min_int || max_int != other->max_int) {
    553     return false;
    554   }
    555 
    556   std::vector<const Symbol*> sorted_a;
    557   std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a),
    558                  add_pointer<const Symbol>);
    559   std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool {
    560     return a->symbol.name < b->symbol.name;
    561   });
    562 
    563   std::vector<const Symbol*> sorted_b;
    564   std::transform(other->symbols.begin(), other->symbols.end(), std::back_inserter(sorted_b),
    565                  add_pointer<const Symbol>);
    566   std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool {
    567     return a->symbol.name < b->symbol.name;
    568   });
    569 
    570   return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
    571                     [](const Symbol* a, const Symbol* b) -> bool {
    572                       return a->symbol.Equals(&b->symbol) && a->value == b->value;
    573                     });
    574 }
    575 
    576 bool Attribute::IsCompatibleWith(const Attribute& attr) const {
    577   if (Equals(&attr)) {
    578     return true;
    579   }
    580 
    581   // If the high bits are set on any of these attribute type masks, then they are incompatible.
    582   // We don't check that flags and enums are identical.
    583   if ((type_mask & ~android::ResTable_map::TYPE_ANY) != 0 ||
    584       (attr.type_mask & ~android::ResTable_map::TYPE_ANY) != 0) {
    585     return false;
    586   }
    587 
    588   // Every attribute accepts a reference.
    589   uint32_t this_type_mask = type_mask | android::ResTable_map::TYPE_REFERENCE;
    590   uint32_t that_type_mask = attr.type_mask | android::ResTable_map::TYPE_REFERENCE;
    591   return this_type_mask == that_type_mask;
    592 }
    593 
    594 Attribute* Attribute::Clone(StringPool* /*new_pool*/) const {
    595   return new Attribute(*this);
    596 }
    597 
    598 std::string Attribute::MaskString() const {
    599   if (type_mask == android::ResTable_map::TYPE_ANY) {
    600     return "any";
    601   }
    602 
    603   std::ostringstream out;
    604   bool set = false;
    605   if ((type_mask & android::ResTable_map::TYPE_REFERENCE) != 0) {
    606     if (!set) {
    607       set = true;
    608     } else {
    609       out << "|";
    610     }
    611     out << "reference";
    612   }
    613 
    614   if ((type_mask & android::ResTable_map::TYPE_STRING) != 0) {
    615     if (!set) {
    616       set = true;
    617     } else {
    618       out << "|";
    619     }
    620     out << "string";
    621   }
    622 
    623   if ((type_mask & android::ResTable_map::TYPE_INTEGER) != 0) {
    624     if (!set) {
    625       set = true;
    626     } else {
    627       out << "|";
    628     }
    629     out << "integer";
    630   }
    631 
    632   if ((type_mask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
    633     if (!set) {
    634       set = true;
    635     } else {
    636       out << "|";
    637     }
    638     out << "boolean";
    639   }
    640 
    641   if ((type_mask & android::ResTable_map::TYPE_COLOR) != 0) {
    642     if (!set) {
    643       set = true;
    644     } else {
    645       out << "|";
    646     }
    647     out << "color";
    648   }
    649 
    650   if ((type_mask & android::ResTable_map::TYPE_FLOAT) != 0) {
    651     if (!set) {
    652       set = true;
    653     } else {
    654       out << "|";
    655     }
    656     out << "float";
    657   }
    658 
    659   if ((type_mask & android::ResTable_map::TYPE_DIMENSION) != 0) {
    660     if (!set) {
    661       set = true;
    662     } else {
    663       out << "|";
    664     }
    665     out << "dimension";
    666   }
    667 
    668   if ((type_mask & android::ResTable_map::TYPE_FRACTION) != 0) {
    669     if (!set) {
    670       set = true;
    671     } else {
    672       out << "|";
    673     }
    674     out << "fraction";
    675   }
    676 
    677   if ((type_mask & android::ResTable_map::TYPE_ENUM) != 0) {
    678     if (!set) {
    679       set = true;
    680     } else {
    681       out << "|";
    682     }
    683     out << "enum";
    684   }
    685 
    686   if ((type_mask & android::ResTable_map::TYPE_FLAGS) != 0) {
    687     if (!set) {
    688       set = true;
    689     } else {
    690       out << "|";
    691     }
    692     out << "flags";
    693   }
    694   return out.str();
    695 }
    696 
    697 void Attribute::Print(std::ostream* out) const {
    698   *out << "(attr) " << MaskString();
    699 
    700   if (!symbols.empty()) {
    701     *out << " [" << util::Joiner(symbols, ", ") << "]";
    702   }
    703 
    704   if (min_int != std::numeric_limits<int32_t>::min()) {
    705     *out << " min=" << min_int;
    706   }
    707 
    708   if (max_int != std::numeric_limits<int32_t>::max()) {
    709     *out << " max=" << max_int;
    710   }
    711 
    712   if (IsWeak()) {
    713     *out << " [weak]";
    714   }
    715 }
    716 
    717 static void BuildAttributeMismatchMessage(const Attribute& attr, const Item& value,
    718                                           DiagMessage* out_msg) {
    719   *out_msg << "expected";
    720   if (attr.type_mask & android::ResTable_map::TYPE_BOOLEAN) {
    721     *out_msg << " boolean";
    722   }
    723 
    724   if (attr.type_mask & android::ResTable_map::TYPE_COLOR) {
    725     *out_msg << " color";
    726   }
    727 
    728   if (attr.type_mask & android::ResTable_map::TYPE_DIMENSION) {
    729     *out_msg << " dimension";
    730   }
    731 
    732   if (attr.type_mask & android::ResTable_map::TYPE_ENUM) {
    733     *out_msg << " enum";
    734   }
    735 
    736   if (attr.type_mask & android::ResTable_map::TYPE_FLAGS) {
    737     *out_msg << " flags";
    738   }
    739 
    740   if (attr.type_mask & android::ResTable_map::TYPE_FLOAT) {
    741     *out_msg << " float";
    742   }
    743 
    744   if (attr.type_mask & android::ResTable_map::TYPE_FRACTION) {
    745     *out_msg << " fraction";
    746   }
    747 
    748   if (attr.type_mask & android::ResTable_map::TYPE_INTEGER) {
    749     *out_msg << " integer";
    750   }
    751 
    752   if (attr.type_mask & android::ResTable_map::TYPE_REFERENCE) {
    753     *out_msg << " reference";
    754   }
    755 
    756   if (attr.type_mask & android::ResTable_map::TYPE_STRING) {
    757     *out_msg << " string";
    758   }
    759 
    760   *out_msg << " but got " << value;
    761 }
    762 
    763 bool Attribute::Matches(const Item& item, DiagMessage* out_msg) const {
    764   constexpr const uint32_t TYPE_ENUM = android::ResTable_map::TYPE_ENUM;
    765   constexpr const uint32_t TYPE_FLAGS = android::ResTable_map::TYPE_FLAGS;
    766   constexpr const uint32_t TYPE_INTEGER = android::ResTable_map::TYPE_INTEGER;
    767   constexpr const uint32_t TYPE_REFERENCE = android::ResTable_map::TYPE_REFERENCE;
    768 
    769   android::Res_value val = {};
    770   item.Flatten(&val);
    771 
    772   const uint32_t flattened_data = util::DeviceToHost32(val.data);
    773 
    774   // Always allow references.
    775   const uint32_t actual_type = ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType);
    776 
    777   // Only one type must match between the actual and expected.
    778   if ((actual_type & (type_mask | TYPE_REFERENCE)) == 0) {
    779     if (out_msg) {
    780       BuildAttributeMismatchMessage(*this, item, out_msg);
    781     }
    782     return false;
    783   }
    784 
    785   // Enums and flags are encoded as integers, so check them first before doing any range checks.
    786   if ((type_mask & TYPE_ENUM) != 0 && (actual_type & TYPE_ENUM) != 0) {
    787     for (const Symbol& s : symbols) {
    788       if (flattened_data == s.value) {
    789         return true;
    790       }
    791     }
    792 
    793     // If the attribute accepts integers, we can't fail here.
    794     if ((type_mask & TYPE_INTEGER) == 0) {
    795       if (out_msg) {
    796         *out_msg << item << " is not a valid enum";
    797       }
    798       return false;
    799     }
    800   }
    801 
    802   if ((type_mask & TYPE_FLAGS) != 0 && (actual_type & TYPE_FLAGS) != 0) {
    803     uint32_t mask = 0u;
    804     for (const Symbol& s : symbols) {
    805       mask |= s.value;
    806     }
    807 
    808     // Check if the flattened data is covered by the flag bit mask.
    809     // If the attribute accepts integers, we can't fail here.
    810     if ((mask & flattened_data) == flattened_data) {
    811       return true;
    812     } else if ((type_mask & TYPE_INTEGER) == 0) {
    813       if (out_msg) {
    814         *out_msg << item << " is not a valid flag";
    815       }
    816       return false;
    817     }
    818   }
    819 
    820   // Finally check the integer range of the value.
    821   if ((type_mask & TYPE_INTEGER) != 0 && (actual_type & TYPE_INTEGER) != 0) {
    822     if (static_cast<int32_t>(flattened_data) < min_int) {
    823       if (out_msg) {
    824         *out_msg << item << " is less than minimum integer " << min_int;
    825       }
    826       return false;
    827     } else if (static_cast<int32_t>(flattened_data) > max_int) {
    828       if (out_msg) {
    829         *out_msg << item << " is greater than maximum integer " << max_int;
    830       }
    831       return false;
    832     }
    833   }
    834   return true;
    835 }
    836 
    837 std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) {
    838   if (entry.key.name) {
    839     out << entry.key.name.value();
    840   } else if (entry.key.id) {
    841     out << entry.key.id.value();
    842   } else {
    843     out << "???";
    844   }
    845   out << " = " << entry.value;
    846   return out;
    847 }
    848 
    849 template <typename T>
    850 std::vector<T*> ToPointerVec(std::vector<T>& src) {
    851   std::vector<T*> dst;
    852   dst.reserve(src.size());
    853   for (T& in : src) {
    854     dst.push_back(&in);
    855   }
    856   return dst;
    857 }
    858 
    859 template <typename T>
    860 std::vector<const T*> ToPointerVec(const std::vector<T>& src) {
    861   std::vector<const T*> dst;
    862   dst.reserve(src.size());
    863   for (const T& in : src) {
    864     dst.push_back(&in);
    865   }
    866   return dst;
    867 }
    868 
    869 static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) {
    870   return a->key.name < b->key.name;
    871 }
    872 
    873 bool Style::Equals(const Value* value) const {
    874   const Style* other = ValueCast<Style>(value);
    875   if (!other) {
    876     return false;
    877   }
    878 
    879   if (bool(parent) != bool(other->parent) ||
    880       (parent && other->parent && !parent.value().Equals(&other->parent.value()))) {
    881     return false;
    882   }
    883 
    884   if (entries.size() != other->entries.size()) {
    885     return false;
    886   }
    887 
    888   std::vector<const Entry*> sorted_a = ToPointerVec(entries);
    889   std::sort(sorted_a.begin(), sorted_a.end(), KeyNameComparator);
    890 
    891   std::vector<const Entry*> sorted_b = ToPointerVec(other->entries);
    892   std::sort(sorted_b.begin(), sorted_b.end(), KeyNameComparator);
    893 
    894   return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
    895                     [](const Entry* a, const Entry* b) -> bool {
    896                       return a->key.Equals(&b->key) && a->value->Equals(b->value.get());
    897                     });
    898 }
    899 
    900 Style* Style::Clone(StringPool* new_pool) const {
    901   Style* style = new Style();
    902   style->parent = parent;
    903   style->parent_inferred = parent_inferred;
    904   style->comment_ = comment_;
    905   style->source_ = source_;
    906   for (auto& entry : entries) {
    907     style->entries.push_back(Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
    908   }
    909   return style;
    910 }
    911 
    912 void Style::Print(std::ostream* out) const {
    913   *out << "(style) ";
    914   if (parent && parent.value().name) {
    915     const Reference& parent_ref = parent.value();
    916     if (parent_ref.private_reference) {
    917       *out << "*";
    918     }
    919     *out << parent_ref.name.value();
    920   }
    921   *out << " [" << util::Joiner(entries, ", ") << "]";
    922 }
    923 
    924 Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) {
    925   Style::Entry cloned_entry{entry.key};
    926   if (entry.value != nullptr) {
    927     cloned_entry.value.reset(entry.value->Clone(pool));
    928   }
    929   return cloned_entry;
    930 }
    931 
    932 void Style::MergeWith(Style* other, StringPool* pool) {
    933   if (other->parent) {
    934     parent = other->parent;
    935   }
    936 
    937   // We can't assume that the entries are sorted alphabetically since they're supposed to be
    938   // sorted by Resource Id. Not all Resource Ids may be set though, so we can't sort and merge
    939   // them keying off that.
    940   //
    941   // Instead, sort the entries of each Style by their name in a separate structure. Then merge
    942   // those.
    943 
    944   std::vector<Entry*> this_sorted = ToPointerVec(entries);
    945   std::sort(this_sorted.begin(), this_sorted.end(), KeyNameComparator);
    946 
    947   std::vector<Entry*> other_sorted = ToPointerVec(other->entries);
    948   std::sort(other_sorted.begin(), other_sorted.end(), KeyNameComparator);
    949 
    950   auto this_iter = this_sorted.begin();
    951   const auto this_end = this_sorted.end();
    952 
    953   auto other_iter = other_sorted.begin();
    954   const auto other_end = other_sorted.end();
    955 
    956   std::vector<Entry> merged_entries;
    957   while (this_iter != this_end) {
    958     if (other_iter != other_end) {
    959       if ((*this_iter)->key.name < (*other_iter)->key.name) {
    960         merged_entries.push_back(std::move(**this_iter));
    961         ++this_iter;
    962       } else {
    963         // The other overrides.
    964         merged_entries.push_back(CloneEntry(**other_iter, pool));
    965         if ((*this_iter)->key.name == (*other_iter)->key.name) {
    966           ++this_iter;
    967         }
    968         ++other_iter;
    969       }
    970     } else {
    971       merged_entries.push_back(std::move(**this_iter));
    972       ++this_iter;
    973     }
    974   }
    975 
    976   while (other_iter != other_end) {
    977     merged_entries.push_back(CloneEntry(**other_iter, pool));
    978     ++other_iter;
    979   }
    980 
    981   entries = std::move(merged_entries);
    982 }
    983 
    984 bool Array::Equals(const Value* value) const {
    985   const Array* other = ValueCast<Array>(value);
    986   if (!other) {
    987     return false;
    988   }
    989 
    990   if (elements.size() != other->elements.size()) {
    991     return false;
    992   }
    993 
    994   return std::equal(elements.begin(), elements.end(), other->elements.begin(),
    995                     [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
    996                       return a->Equals(b.get());
    997                     });
    998 }
    999 
   1000 Array* Array::Clone(StringPool* new_pool) const {
   1001   Array* array = new Array();
   1002   array->comment_ = comment_;
   1003   array->source_ = source_;
   1004   for (auto& item : elements) {
   1005     array->elements.emplace_back(std::unique_ptr<Item>(item->Clone(new_pool)));
   1006   }
   1007   return array;
   1008 }
   1009 
   1010 void Array::Print(std::ostream* out) const {
   1011   *out << "(array) [" << util::Joiner(elements, ", ") << "]";
   1012 }
   1013 
   1014 bool Plural::Equals(const Value* value) const {
   1015   const Plural* other = ValueCast<Plural>(value);
   1016   if (!other) {
   1017     return false;
   1018   }
   1019 
   1020   auto one_iter = values.begin();
   1021   auto one_end_iter = values.end();
   1022   auto two_iter = other->values.begin();
   1023   for (; one_iter != one_end_iter; ++one_iter, ++two_iter) {
   1024     const std::unique_ptr<Item>& a = *one_iter;
   1025     const std::unique_ptr<Item>& b = *two_iter;
   1026     if (a != nullptr && b != nullptr) {
   1027       if (!a->Equals(b.get())) {
   1028         return false;
   1029       }
   1030     } else if (a != b) {
   1031       return false;
   1032     }
   1033   }
   1034   return true;
   1035 }
   1036 
   1037 Plural* Plural::Clone(StringPool* new_pool) const {
   1038   Plural* p = new Plural();
   1039   p->comment_ = comment_;
   1040   p->source_ = source_;
   1041   const size_t count = values.size();
   1042   for (size_t i = 0; i < count; i++) {
   1043     if (values[i]) {
   1044       p->values[i] = std::unique_ptr<Item>(values[i]->Clone(new_pool));
   1045     }
   1046   }
   1047   return p;
   1048 }
   1049 
   1050 void Plural::Print(std::ostream* out) const {
   1051   *out << "(plural)";
   1052   if (values[Zero]) {
   1053     *out << " zero=" << *values[Zero];
   1054   }
   1055 
   1056   if (values[One]) {
   1057     *out << " one=" << *values[One];
   1058   }
   1059 
   1060   if (values[Two]) {
   1061     *out << " two=" << *values[Two];
   1062   }
   1063 
   1064   if (values[Few]) {
   1065     *out << " few=" << *values[Few];
   1066   }
   1067 
   1068   if (values[Many]) {
   1069     *out << " many=" << *values[Many];
   1070   }
   1071 
   1072   if (values[Other]) {
   1073     *out << " other=" << *values[Other];
   1074   }
   1075 }
   1076 
   1077 bool Styleable::Equals(const Value* value) const {
   1078   const Styleable* other = ValueCast<Styleable>(value);
   1079   if (!other) {
   1080     return false;
   1081   }
   1082 
   1083   if (entries.size() != other->entries.size()) {
   1084     return false;
   1085   }
   1086 
   1087   return std::equal(entries.begin(), entries.end(), other->entries.begin(),
   1088                     [](const Reference& a, const Reference& b) -> bool {
   1089                       return a.Equals(&b);
   1090                     });
   1091 }
   1092 
   1093 Styleable* Styleable::Clone(StringPool* /*new_pool*/) const {
   1094   return new Styleable(*this);
   1095 }
   1096 
   1097 void Styleable::Print(std::ostream* out) const {
   1098   *out << "(styleable) "
   1099        << " [" << util::Joiner(entries, ", ") << "]";
   1100 }
   1101 
   1102 bool operator<(const Reference& a, const Reference& b) {
   1103   int cmp = a.name.value_or_default({}).compare(b.name.value_or_default({}));
   1104   if (cmp != 0) return cmp < 0;
   1105   return a.id < b.id;
   1106 }
   1107 
   1108 bool operator==(const Reference& a, const Reference& b) {
   1109   return a.name == b.name && a.id == b.id;
   1110 }
   1111 
   1112 bool operator!=(const Reference& a, const Reference& b) {
   1113   return a.name != b.name || a.id != b.id;
   1114 }
   1115 
   1116 struct NameOnlyComparator {
   1117   bool operator()(const Reference& a, const Reference& b) const {
   1118     return a.name < b.name;
   1119   }
   1120 };
   1121 
   1122 void Styleable::MergeWith(Styleable* other) {
   1123   // Compare only names, because some References may already have their IDs
   1124   // assigned (framework IDs that don't change).
   1125   std::set<Reference, NameOnlyComparator> references;
   1126   references.insert(entries.begin(), entries.end());
   1127   references.insert(other->entries.begin(), other->entries.end());
   1128   entries.clear();
   1129   entries.reserve(references.size());
   1130   entries.insert(entries.end(), references.begin(), references.end());
   1131 }
   1132 
   1133 }  // namespace aapt
   1134