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 the high bits are set on any of these attribute type masks, then they are incompatible.
    578   // We don't check that flags and enums are identical.
    579   if ((type_mask & ~android::ResTable_map::TYPE_ANY) != 0 ||
    580       (attr.type_mask & ~android::ResTable_map::TYPE_ANY) != 0) {
    581     return false;
    582   }
    583 
    584   // Every attribute accepts a reference.
    585   uint32_t this_type_mask = type_mask | android::ResTable_map::TYPE_REFERENCE;
    586   uint32_t that_type_mask = attr.type_mask | android::ResTable_map::TYPE_REFERENCE;
    587   return this_type_mask == that_type_mask;
    588 }
    589 
    590 Attribute* Attribute::Clone(StringPool* /*new_pool*/) const {
    591   return new Attribute(*this);
    592 }
    593 
    594 std::string Attribute::MaskString() const {
    595   if (type_mask == android::ResTable_map::TYPE_ANY) {
    596     return "any";
    597   }
    598 
    599   std::ostringstream out;
    600   bool set = false;
    601   if ((type_mask & android::ResTable_map::TYPE_REFERENCE) != 0) {
    602     if (!set) {
    603       set = true;
    604     } else {
    605       out << "|";
    606     }
    607     out << "reference";
    608   }
    609 
    610   if ((type_mask & android::ResTable_map::TYPE_STRING) != 0) {
    611     if (!set) {
    612       set = true;
    613     } else {
    614       out << "|";
    615     }
    616     out << "string";
    617   }
    618 
    619   if ((type_mask & android::ResTable_map::TYPE_INTEGER) != 0) {
    620     if (!set) {
    621       set = true;
    622     } else {
    623       out << "|";
    624     }
    625     out << "integer";
    626   }
    627 
    628   if ((type_mask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
    629     if (!set) {
    630       set = true;
    631     } else {
    632       out << "|";
    633     }
    634     out << "boolean";
    635   }
    636 
    637   if ((type_mask & android::ResTable_map::TYPE_COLOR) != 0) {
    638     if (!set) {
    639       set = true;
    640     } else {
    641       out << "|";
    642     }
    643     out << "color";
    644   }
    645 
    646   if ((type_mask & android::ResTable_map::TYPE_FLOAT) != 0) {
    647     if (!set) {
    648       set = true;
    649     } else {
    650       out << "|";
    651     }
    652     out << "float";
    653   }
    654 
    655   if ((type_mask & android::ResTable_map::TYPE_DIMENSION) != 0) {
    656     if (!set) {
    657       set = true;
    658     } else {
    659       out << "|";
    660     }
    661     out << "dimension";
    662   }
    663 
    664   if ((type_mask & android::ResTable_map::TYPE_FRACTION) != 0) {
    665     if (!set) {
    666       set = true;
    667     } else {
    668       out << "|";
    669     }
    670     out << "fraction";
    671   }
    672 
    673   if ((type_mask & android::ResTable_map::TYPE_ENUM) != 0) {
    674     if (!set) {
    675       set = true;
    676     } else {
    677       out << "|";
    678     }
    679     out << "enum";
    680   }
    681 
    682   if ((type_mask & android::ResTable_map::TYPE_FLAGS) != 0) {
    683     if (!set) {
    684       set = true;
    685     } else {
    686       out << "|";
    687     }
    688     out << "flags";
    689   }
    690   return out.str();
    691 }
    692 
    693 void Attribute::Print(std::ostream* out) const {
    694   *out << "(attr) " << MaskString();
    695 
    696   if (!symbols.empty()) {
    697     *out << " [" << util::Joiner(symbols, ", ") << "]";
    698   }
    699 
    700   if (min_int != std::numeric_limits<int32_t>::min()) {
    701     *out << " min=" << min_int;
    702   }
    703 
    704   if (max_int != std::numeric_limits<int32_t>::max()) {
    705     *out << " max=" << max_int;
    706   }
    707 
    708   if (IsWeak()) {
    709     *out << " [weak]";
    710   }
    711 }
    712 
    713 static void BuildAttributeMismatchMessage(const Attribute& attr, const Item& value,
    714                                           DiagMessage* out_msg) {
    715   *out_msg << "expected";
    716   if (attr.type_mask & android::ResTable_map::TYPE_BOOLEAN) {
    717     *out_msg << " boolean";
    718   }
    719 
    720   if (attr.type_mask & android::ResTable_map::TYPE_COLOR) {
    721     *out_msg << " color";
    722   }
    723 
    724   if (attr.type_mask & android::ResTable_map::TYPE_DIMENSION) {
    725     *out_msg << " dimension";
    726   }
    727 
    728   if (attr.type_mask & android::ResTable_map::TYPE_ENUM) {
    729     *out_msg << " enum";
    730   }
    731 
    732   if (attr.type_mask & android::ResTable_map::TYPE_FLAGS) {
    733     *out_msg << " flags";
    734   }
    735 
    736   if (attr.type_mask & android::ResTable_map::TYPE_FLOAT) {
    737     *out_msg << " float";
    738   }
    739 
    740   if (attr.type_mask & android::ResTable_map::TYPE_FRACTION) {
    741     *out_msg << " fraction";
    742   }
    743 
    744   if (attr.type_mask & android::ResTable_map::TYPE_INTEGER) {
    745     *out_msg << " integer";
    746   }
    747 
    748   if (attr.type_mask & android::ResTable_map::TYPE_REFERENCE) {
    749     *out_msg << " reference";
    750   }
    751 
    752   if (attr.type_mask & android::ResTable_map::TYPE_STRING) {
    753     *out_msg << " string";
    754   }
    755 
    756   *out_msg << " but got " << value;
    757 }
    758 
    759 bool Attribute::Matches(const Item& item, DiagMessage* out_msg) const {
    760   constexpr const uint32_t TYPE_ENUM = android::ResTable_map::TYPE_ENUM;
    761   constexpr const uint32_t TYPE_FLAGS = android::ResTable_map::TYPE_FLAGS;
    762   constexpr const uint32_t TYPE_INTEGER = android::ResTable_map::TYPE_INTEGER;
    763   constexpr const uint32_t TYPE_REFERENCE = android::ResTable_map::TYPE_REFERENCE;
    764 
    765   android::Res_value val = {};
    766   item.Flatten(&val);
    767 
    768   const uint32_t flattened_data = util::DeviceToHost32(val.data);
    769 
    770   // Always allow references.
    771   const uint32_t actual_type = ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType);
    772 
    773   // Only one type must match between the actual and expected.
    774   if ((actual_type & (type_mask | TYPE_REFERENCE)) == 0) {
    775     if (out_msg) {
    776       BuildAttributeMismatchMessage(*this, item, out_msg);
    777     }
    778     return false;
    779   }
    780 
    781   // Enums and flags are encoded as integers, so check them first before doing any range checks.
    782   if ((type_mask & TYPE_ENUM) != 0 && (actual_type & TYPE_ENUM) != 0) {
    783     for (const Symbol& s : symbols) {
    784       if (flattened_data == s.value) {
    785         return true;
    786       }
    787     }
    788 
    789     // If the attribute accepts integers, we can't fail here.
    790     if ((type_mask & TYPE_INTEGER) == 0) {
    791       if (out_msg) {
    792         *out_msg << item << " is not a valid enum";
    793       }
    794       return false;
    795     }
    796   }
    797 
    798   if ((type_mask & TYPE_FLAGS) != 0 && (actual_type & TYPE_FLAGS) != 0) {
    799     uint32_t mask = 0u;
    800     for (const Symbol& s : symbols) {
    801       mask |= s.value;
    802     }
    803 
    804     // Check if the flattened data is covered by the flag bit mask.
    805     // If the attribute accepts integers, we can't fail here.
    806     if ((mask & flattened_data) == flattened_data) {
    807       return true;
    808     } else if ((type_mask & TYPE_INTEGER) == 0) {
    809       if (out_msg) {
    810         *out_msg << item << " is not a valid flag";
    811       }
    812       return false;
    813     }
    814   }
    815 
    816   // Finally check the integer range of the value.
    817   if ((type_mask & TYPE_INTEGER) != 0 && (actual_type & TYPE_INTEGER) != 0) {
    818     if (static_cast<int32_t>(flattened_data) < min_int) {
    819       if (out_msg) {
    820         *out_msg << item << " is less than minimum integer " << min_int;
    821       }
    822       return false;
    823     } else if (static_cast<int32_t>(flattened_data) > max_int) {
    824       if (out_msg) {
    825         *out_msg << item << " is greater than maximum integer " << max_int;
    826       }
    827       return false;
    828     }
    829   }
    830   return true;
    831 }
    832 
    833 std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) {
    834   if (entry.key.name) {
    835     out << entry.key.name.value();
    836   } else if (entry.key.id) {
    837     out << entry.key.id.value();
    838   } else {
    839     out << "???";
    840   }
    841   out << " = " << entry.value;
    842   return out;
    843 }
    844 
    845 template <typename T>
    846 std::vector<T*> ToPointerVec(std::vector<T>& src) {
    847   std::vector<T*> dst;
    848   dst.reserve(src.size());
    849   for (T& in : src) {
    850     dst.push_back(&in);
    851   }
    852   return dst;
    853 }
    854 
    855 template <typename T>
    856 std::vector<const T*> ToPointerVec(const std::vector<T>& src) {
    857   std::vector<const T*> dst;
    858   dst.reserve(src.size());
    859   for (const T& in : src) {
    860     dst.push_back(&in);
    861   }
    862   return dst;
    863 }
    864 
    865 static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) {
    866   return a->key.name < b->key.name;
    867 }
    868 
    869 bool Style::Equals(const Value* value) const {
    870   const Style* other = ValueCast<Style>(value);
    871   if (!other) {
    872     return false;
    873   }
    874 
    875   if (bool(parent) != bool(other->parent) ||
    876       (parent && other->parent && !parent.value().Equals(&other->parent.value()))) {
    877     return false;
    878   }
    879 
    880   if (entries.size() != other->entries.size()) {
    881     return false;
    882   }
    883 
    884   std::vector<const Entry*> sorted_a = ToPointerVec(entries);
    885   std::sort(sorted_a.begin(), sorted_a.end(), KeyNameComparator);
    886 
    887   std::vector<const Entry*> sorted_b = ToPointerVec(other->entries);
    888   std::sort(sorted_b.begin(), sorted_b.end(), KeyNameComparator);
    889 
    890   return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
    891                     [](const Entry* a, const Entry* b) -> bool {
    892                       return a->key.Equals(&b->key) && a->value->Equals(b->value.get());
    893                     });
    894 }
    895 
    896 Style* Style::Clone(StringPool* new_pool) const {
    897   Style* style = new Style();
    898   style->parent = parent;
    899   style->parent_inferred = parent_inferred;
    900   style->comment_ = comment_;
    901   style->source_ = source_;
    902   for (auto& entry : entries) {
    903     style->entries.push_back(Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
    904   }
    905   return style;
    906 }
    907 
    908 void Style::Print(std::ostream* out) const {
    909   *out << "(style) ";
    910   if (parent && parent.value().name) {
    911     const Reference& parent_ref = parent.value();
    912     if (parent_ref.private_reference) {
    913       *out << "*";
    914     }
    915     *out << parent_ref.name.value();
    916   }
    917   *out << " [" << util::Joiner(entries, ", ") << "]";
    918 }
    919 
    920 Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) {
    921   Style::Entry cloned_entry{entry.key};
    922   if (entry.value != nullptr) {
    923     cloned_entry.value.reset(entry.value->Clone(pool));
    924   }
    925   return cloned_entry;
    926 }
    927 
    928 void Style::MergeWith(Style* other, StringPool* pool) {
    929   if (other->parent) {
    930     parent = other->parent;
    931   }
    932 
    933   // We can't assume that the entries are sorted alphabetically since they're supposed to be
    934   // sorted by Resource Id. Not all Resource Ids may be set though, so we can't sort and merge
    935   // them keying off that.
    936   //
    937   // Instead, sort the entries of each Style by their name in a separate structure. Then merge
    938   // those.
    939 
    940   std::vector<Entry*> this_sorted = ToPointerVec(entries);
    941   std::sort(this_sorted.begin(), this_sorted.end(), KeyNameComparator);
    942 
    943   std::vector<Entry*> other_sorted = ToPointerVec(other->entries);
    944   std::sort(other_sorted.begin(), other_sorted.end(), KeyNameComparator);
    945 
    946   auto this_iter = this_sorted.begin();
    947   const auto this_end = this_sorted.end();
    948 
    949   auto other_iter = other_sorted.begin();
    950   const auto other_end = other_sorted.end();
    951 
    952   std::vector<Entry> merged_entries;
    953   while (this_iter != this_end) {
    954     if (other_iter != other_end) {
    955       if ((*this_iter)->key.name < (*other_iter)->key.name) {
    956         merged_entries.push_back(std::move(**this_iter));
    957         ++this_iter;
    958       } else {
    959         // The other overrides.
    960         merged_entries.push_back(CloneEntry(**other_iter, pool));
    961         if ((*this_iter)->key.name == (*other_iter)->key.name) {
    962           ++this_iter;
    963         }
    964         ++other_iter;
    965       }
    966     } else {
    967       merged_entries.push_back(std::move(**this_iter));
    968       ++this_iter;
    969     }
    970   }
    971 
    972   while (other_iter != other_end) {
    973     merged_entries.push_back(CloneEntry(**other_iter, pool));
    974     ++other_iter;
    975   }
    976 
    977   entries = std::move(merged_entries);
    978 }
    979 
    980 bool Array::Equals(const Value* value) const {
    981   const Array* other = ValueCast<Array>(value);
    982   if (!other) {
    983     return false;
    984   }
    985 
    986   if (elements.size() != other->elements.size()) {
    987     return false;
    988   }
    989 
    990   return std::equal(elements.begin(), elements.end(), other->elements.begin(),
    991                     [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
    992                       return a->Equals(b.get());
    993                     });
    994 }
    995 
    996 Array* Array::Clone(StringPool* new_pool) const {
    997   Array* array = new Array();
    998   array->comment_ = comment_;
    999   array->source_ = source_;
   1000   for (auto& item : elements) {
   1001     array->elements.emplace_back(std::unique_ptr<Item>(item->Clone(new_pool)));
   1002   }
   1003   return array;
   1004 }
   1005 
   1006 void Array::Print(std::ostream* out) const {
   1007   *out << "(array) [" << util::Joiner(elements, ", ") << "]";
   1008 }
   1009 
   1010 bool Plural::Equals(const Value* value) const {
   1011   const Plural* other = ValueCast<Plural>(value);
   1012   if (!other) {
   1013     return false;
   1014   }
   1015 
   1016   auto one_iter = values.begin();
   1017   auto one_end_iter = values.end();
   1018   auto two_iter = other->values.begin();
   1019   for (; one_iter != one_end_iter; ++one_iter, ++two_iter) {
   1020     const std::unique_ptr<Item>& a = *one_iter;
   1021     const std::unique_ptr<Item>& b = *two_iter;
   1022     if (a != nullptr && b != nullptr) {
   1023       if (!a->Equals(b.get())) {
   1024         return false;
   1025       }
   1026     } else if (a != b) {
   1027       return false;
   1028     }
   1029   }
   1030   return true;
   1031 }
   1032 
   1033 Plural* Plural::Clone(StringPool* new_pool) const {
   1034   Plural* p = new Plural();
   1035   p->comment_ = comment_;
   1036   p->source_ = source_;
   1037   const size_t count = values.size();
   1038   for (size_t i = 0; i < count; i++) {
   1039     if (values[i]) {
   1040       p->values[i] = std::unique_ptr<Item>(values[i]->Clone(new_pool));
   1041     }
   1042   }
   1043   return p;
   1044 }
   1045 
   1046 void Plural::Print(std::ostream* out) const {
   1047   *out << "(plural)";
   1048   if (values[Zero]) {
   1049     *out << " zero=" << *values[Zero];
   1050   }
   1051 
   1052   if (values[One]) {
   1053     *out << " one=" << *values[One];
   1054   }
   1055 
   1056   if (values[Two]) {
   1057     *out << " two=" << *values[Two];
   1058   }
   1059 
   1060   if (values[Few]) {
   1061     *out << " few=" << *values[Few];
   1062   }
   1063 
   1064   if (values[Many]) {
   1065     *out << " many=" << *values[Many];
   1066   }
   1067 
   1068   if (values[Other]) {
   1069     *out << " other=" << *values[Other];
   1070   }
   1071 }
   1072 
   1073 bool Styleable::Equals(const Value* value) const {
   1074   const Styleable* other = ValueCast<Styleable>(value);
   1075   if (!other) {
   1076     return false;
   1077   }
   1078 
   1079   if (entries.size() != other->entries.size()) {
   1080     return false;
   1081   }
   1082 
   1083   return std::equal(entries.begin(), entries.end(), other->entries.begin(),
   1084                     [](const Reference& a, const Reference& b) -> bool {
   1085                       return a.Equals(&b);
   1086                     });
   1087 }
   1088 
   1089 Styleable* Styleable::Clone(StringPool* /*new_pool*/) const {
   1090   return new Styleable(*this);
   1091 }
   1092 
   1093 void Styleable::Print(std::ostream* out) const {
   1094   *out << "(styleable) "
   1095        << " [" << util::Joiner(entries, ", ") << "]";
   1096 }
   1097 
   1098 bool operator<(const Reference& a, const Reference& b) {
   1099   int cmp = a.name.value_or_default({}).compare(b.name.value_or_default({}));
   1100   if (cmp != 0) return cmp < 0;
   1101   return a.id < b.id;
   1102 }
   1103 
   1104 bool operator==(const Reference& a, const Reference& b) {
   1105   return a.name == b.name && 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 struct NameOnlyComparator {
   1113   bool operator()(const Reference& a, const Reference& b) const {
   1114     return a.name < b.name;
   1115   }
   1116 };
   1117 
   1118 void Styleable::MergeWith(Styleable* other) {
   1119   // Compare only names, because some References may already have their IDs
   1120   // assigned (framework IDs that don't change).
   1121   std::set<Reference, NameOnlyComparator> references;
   1122   references.insert(entries.begin(), entries.end());
   1123   references.insert(other->entries.begin(), other->entries.end());
   1124   entries.clear();
   1125   entries.reserve(references.size());
   1126   entries.insert(entries.end(), references.begin(), references.end());
   1127 }
   1128 
   1129 }  // namespace aapt
   1130