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