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 #ifndef AAPT_RESOURCE_VALUES_H
     18 #define AAPT_RESOURCE_VALUES_H
     19 
     20 #include <array>
     21 #include <limits>
     22 #include <ostream>
     23 #include <vector>
     24 
     25 #include "androidfw/ResourceTypes.h"
     26 #include "androidfw/StringPiece.h"
     27 
     28 #include "Diagnostics.h"
     29 #include "Resource.h"
     30 #include "StringPool.h"
     31 #include "io/File.h"
     32 #include "text/Printer.h"
     33 #include "util/Maybe.h"
     34 
     35 namespace aapt {
     36 
     37 class ValueVisitor;
     38 class ConstValueVisitor;
     39 
     40 // A resource value. This is an all-encompassing representation
     41 // of Item and Map and their subclasses. The way to do
     42 // type specific operations is to check the Value's type() and
     43 // cast it to the appropriate subclass. This isn't super clean,
     44 // but it is the simplest strategy.
     45 class Value {
     46  public:
     47   virtual ~Value() = default;
     48 
     49   // Whether this value is weak and can be overridden without warning or error. Default is false.
     50   bool IsWeak() const {
     51     return weak_;
     52   }
     53 
     54   void SetWeak(bool val) {
     55     weak_ = val;
     56   }
     57 
     58   // Whether the value is marked as translatable. This does not persist when flattened to binary.
     59   // It is only used during compilation phase.
     60   void SetTranslatable(bool val) {
     61     translatable_ = val;
     62   }
     63 
     64   // Default true.
     65   bool IsTranslatable() const {
     66     return translatable_;
     67   }
     68 
     69   // Returns the source where this value was defined.
     70   const Source& GetSource() const {
     71     return source_;
     72   }
     73 
     74   void SetSource(const Source& source) {
     75     source_ = source;
     76   }
     77 
     78   void SetSource(Source&& source) {
     79     source_ = std::move(source);
     80   }
     81 
     82   // Returns the comment that was associated with this resource.
     83   const std::string& GetComment() const {
     84     return comment_;
     85   }
     86 
     87   void SetComment(const android::StringPiece& str) {
     88     comment_ = str.to_string();
     89   }
     90 
     91   void SetComment(std::string&& str) {
     92     comment_ = std::move(str);
     93   }
     94 
     95   virtual bool Equals(const Value* value) const = 0;
     96 
     97   // Calls the appropriate overload of ValueVisitor.
     98   virtual void Accept(ValueVisitor* visitor) = 0;
     99 
    100   // Calls the appropriate overload of ConstValueVisitor.
    101   virtual void Accept(ConstValueVisitor* visitor) const = 0;
    102 
    103   // Clone the value. `new_pool` is the new StringPool that
    104   // any resources with strings should use when copying their string.
    105   virtual Value* Clone(StringPool* new_pool) const = 0;
    106 
    107   // Human readable printout of this value.
    108   virtual void Print(std::ostream* out) const = 0;
    109 
    110   // Human readable printout of this value that may omit some information for the sake
    111   // of brevity and readability. Default implementation just calls Print().
    112   virtual void PrettyPrint(text::Printer* printer) const;
    113 
    114   friend std::ostream& operator<<(std::ostream& out, const Value& value);
    115 
    116  protected:
    117   Source source_;
    118   std::string comment_;
    119   bool weak_ = false;
    120   bool translatable_ = true;
    121 };
    122 
    123 // Inherit from this to get visitor accepting implementations for free.
    124 template <typename Derived>
    125 struct BaseValue : public Value {
    126   void Accept(ValueVisitor* visitor) override;
    127   void Accept(ConstValueVisitor* visitor) const override;
    128 };
    129 
    130 // A resource item with a single value. This maps to android::ResTable_entry.
    131 struct Item : public Value {
    132   // Clone the Item.
    133   virtual Item* Clone(StringPool* new_pool) const override = 0;
    134 
    135   // Fills in an android::Res_value structure with this Item's binary representation.
    136   // Returns false if an error occurred.
    137   virtual bool Flatten(android::Res_value* out_value) const = 0;
    138 };
    139 
    140 // Inherit from this to get visitor accepting implementations for free.
    141 template <typename Derived>
    142 struct BaseItem : public Item {
    143   void Accept(ValueVisitor* visitor) override;
    144   void Accept(ConstValueVisitor* visitor) const override;
    145 };
    146 
    147 // A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
    148 // A reference can be symbolic (with the name set to a valid resource name) or be
    149 // numeric (the id is set to a valid resource ID).
    150 struct Reference : public BaseItem<Reference> {
    151   enum class Type {
    152     kResource,
    153     kAttribute,
    154   };
    155 
    156   Maybe<ResourceName> name;
    157   Maybe<ResourceId> id;
    158   Reference::Type reference_type;
    159   bool private_reference = false;
    160   bool is_dynamic = false;
    161 
    162   Reference();
    163   explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
    164   explicit Reference(const ResourceId& i, Type type = Type::kResource);
    165   Reference(const ResourceNameRef& n, const ResourceId& i);
    166 
    167   bool Equals(const Value* value) const override;
    168   bool Flatten(android::Res_value* out_value) const override;
    169   Reference* Clone(StringPool* new_pool) const override;
    170   void Print(std::ostream* out) const override;
    171   void PrettyPrint(text::Printer* printer) const override;
    172 
    173   // Prints the reference without a package name if the package name matches the one given.
    174   void PrettyPrint(const android::StringPiece& package, text::Printer* printer) const;
    175 };
    176 
    177 bool operator<(const Reference&, const Reference&);
    178 bool operator==(const Reference&, const Reference&);
    179 
    180 // An ID resource. Has no real value, just a place holder.
    181 struct Id : public BaseItem<Id> {
    182   Id() {
    183     weak_ = true;
    184   }
    185 
    186   bool Equals(const Value* value) const override;
    187   bool Flatten(android::Res_value* out) const override;
    188   Id* Clone(StringPool* new_pool) const override;
    189   void Print(std::ostream* out) const override;
    190 };
    191 
    192 // A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace.
    193 // This shall *NOT* end up in the final resource table.
    194 struct RawString : public BaseItem<RawString> {
    195   StringPool::Ref value;
    196 
    197   explicit RawString(const StringPool::Ref& ref);
    198 
    199   bool Equals(const Value* value) const override;
    200   bool Flatten(android::Res_value* out_value) const override;
    201   RawString* Clone(StringPool* new_pool) const override;
    202   void Print(std::ostream* out) const override;
    203 };
    204 
    205 // Identifies a range of characters in a string that are untranslatable.
    206 // These should not be pseudolocalized. The start and end indices are measured in bytes.
    207 struct UntranslatableSection {
    208   // Start offset inclusive.
    209   size_t start;
    210 
    211   // End offset exclusive.
    212   size_t end;
    213 };
    214 
    215 inline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) {
    216   return a.start == b.start && a.end == b.end;
    217 }
    218 
    219 inline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) {
    220   return a.start != b.start || a.end != b.end;
    221 }
    222 
    223 struct String : public BaseItem<String> {
    224   StringPool::Ref value;
    225 
    226   // Sections of the string to NOT translate. Mainly used
    227   // for pseudolocalization. This data is NOT persisted
    228   // in any format.
    229   std::vector<UntranslatableSection> untranslatable_sections;
    230 
    231   explicit String(const StringPool::Ref& ref);
    232 
    233   bool Equals(const Value* value) const override;
    234   bool Flatten(android::Res_value* out_value) const override;
    235   String* Clone(StringPool* new_pool) const override;
    236   void Print(std::ostream* out) const override;
    237   void PrettyPrint(text::Printer* printer) const override;
    238 };
    239 
    240 struct StyledString : public BaseItem<StyledString> {
    241   StringPool::StyleRef value;
    242 
    243   // Sections of the string to NOT translate. Mainly used
    244   // for pseudolocalization. This data is NOT persisted
    245   // in any format.
    246   std::vector<UntranslatableSection> untranslatable_sections;
    247 
    248   explicit StyledString(const StringPool::StyleRef& ref);
    249 
    250   bool Equals(const Value* value) const override;
    251   bool Flatten(android::Res_value* out_value) const override;
    252   StyledString* Clone(StringPool* new_pool) const override;
    253   void Print(std::ostream* out) const override;
    254 };
    255 
    256 struct FileReference : public BaseItem<FileReference> {
    257   StringPool::Ref path;
    258 
    259   // A handle to the file object from which this file can be read.
    260   // This field is NOT persisted in any format. It is transient.
    261   io::IFile* file = nullptr;
    262 
    263   // FileType of the file pointed to by `file`. This is used to know how to inflate the file,
    264   // or if to inflate at all (just copy).
    265   ResourceFile::Type type = ResourceFile::Type::kUnknown;
    266 
    267   FileReference() = default;
    268   explicit FileReference(const StringPool::Ref& path);
    269 
    270   bool Equals(const Value* value) const override;
    271   bool Flatten(android::Res_value* out_value) const override;
    272   FileReference* Clone(StringPool* new_pool) const override;
    273   void Print(std::ostream* out) const override;
    274 };
    275 
    276 // Represents any other android::Res_value.
    277 struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
    278   android::Res_value value;
    279 
    280   BinaryPrimitive() = default;
    281   explicit BinaryPrimitive(const android::Res_value& val);
    282   BinaryPrimitive(uint8_t dataType, uint32_t data);
    283 
    284   bool Equals(const Value* value) const override;
    285   bool Flatten(android::Res_value* out_value) const override;
    286   BinaryPrimitive* Clone(StringPool* new_pool) const override;
    287   void Print(std::ostream* out) const override;
    288   void PrettyPrint(text::Printer* printer) const override;
    289 };
    290 
    291 struct Attribute : public BaseValue<Attribute> {
    292   struct Symbol {
    293     Reference symbol;
    294     uint32_t value;
    295 
    296     friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol);
    297   };
    298 
    299   uint32_t type_mask;
    300   int32_t min_int;
    301   int32_t max_int;
    302   std::vector<Symbol> symbols;
    303 
    304   explicit Attribute(uint32_t t = 0u);
    305 
    306   bool Equals(const Value* value) const override;
    307 
    308   // Returns true if this Attribute's format is compatible with the given Attribute. The basic
    309   // rule is that TYPE_REFERENCE can be ignored for both of the Attributes, and TYPE_FLAGS and
    310   // TYPE_ENUMS are never compatible.
    311   bool IsCompatibleWith(const Attribute& attr) const;
    312 
    313   Attribute* Clone(StringPool* new_pool) const override;
    314   std::string MaskString() const;
    315   void Print(std::ostream* out) const override;
    316   bool Matches(const Item& item, DiagMessage* out_msg = nullptr) const;
    317 };
    318 
    319 struct Style : public BaseValue<Style> {
    320   struct Entry {
    321     Reference key;
    322     std::unique_ptr<Item> value;
    323 
    324     friend std::ostream& operator<<(std::ostream& out, const Entry& entry);
    325   };
    326 
    327   Maybe<Reference> parent;
    328 
    329   // If set to true, the parent was auto inferred from the style's name.
    330   bool parent_inferred = false;
    331 
    332   std::vector<Entry> entries;
    333 
    334   bool Equals(const Value* value) const override;
    335   Style* Clone(StringPool* new_pool) const override;
    336   void Print(std::ostream* out) const override;
    337 
    338   // Merges `style` into this Style. All identical attributes of `style` take precedence, including
    339   // the parent, if there is one.
    340   void MergeWith(Style* style, StringPool* pool);
    341 };
    342 
    343 struct Array : public BaseValue<Array> {
    344   std::vector<std::unique_ptr<Item>> elements;
    345 
    346   bool Equals(const Value* value) const override;
    347   Array* Clone(StringPool* new_pool) const override;
    348   void Print(std::ostream* out) const override;
    349 };
    350 
    351 struct Plural : public BaseValue<Plural> {
    352   enum { Zero = 0, One, Two, Few, Many, Other, Count };
    353 
    354   std::array<std::unique_ptr<Item>, Count> values;
    355 
    356   bool Equals(const Value* value) const override;
    357   Plural* Clone(StringPool* new_pool) const override;
    358   void Print(std::ostream* out) const override;
    359 };
    360 
    361 struct Styleable : public BaseValue<Styleable> {
    362   std::vector<Reference> entries;
    363 
    364   bool Equals(const Value* value) const override;
    365   Styleable* Clone(StringPool* newPool) const override;
    366   void Print(std::ostream* out) const override;
    367   void MergeWith(Styleable* styleable);
    368 };
    369 
    370 template <typename T>
    371 typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<(
    372     std::ostream& out, const std::unique_ptr<T>& value) {
    373   if (value == nullptr) {
    374     out << "NULL";
    375   } else {
    376     value->Print(&out);
    377   }
    378   return out;
    379 }
    380 
    381 }  // namespace aapt
    382 
    383 #endif  // AAPT_RESOURCE_VALUES_H
    384