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 "Diagnostics.h"
     21 #include "Resource.h"
     22 #include "StringPool.h"
     23 #include "io/File.h"
     24 #include "util/Maybe.h"
     25 
     26 #include <array>
     27 #include <androidfw/ResourceTypes.h>
     28 #include <ostream>
     29 #include <vector>
     30 
     31 namespace aapt {
     32 
     33 struct RawValueVisitor;
     34 
     35 /**
     36  * A resource value. This is an all-encompassing representation
     37  * of Item and Map and their subclasses. The way to do
     38  * type specific operations is to check the Value's type() and
     39  * cast it to the appropriate subclass. This isn't super clean,
     40  * but it is the simplest strategy.
     41  */
     42 struct Value {
     43 	virtual ~Value() = default;
     44 
     45     /**
     46      * Whether this value is weak and can be overridden without
     47      * warning or error. Default is false.
     48      */
     49     bool isWeak() const {
     50         return mWeak;
     51     }
     52 
     53     void setWeak(bool val) {
     54         mWeak = val;
     55     }
     56 
     57     // Whether the value is marked as translateable.
     58     // This does not persist when flattened.
     59     // It is only used during compilation phase.
     60     void setTranslateable(bool val) {
     61         mTranslateable = val;
     62     }
     63 
     64     // Default true.
     65     bool isTranslateable() const {
     66         return mTranslateable;
     67     }
     68 
     69     /**
     70      * Returns the source where this value was defined.
     71      */
     72     const Source& getSource() const {
     73         return mSource;
     74     }
     75 
     76     void setSource(const Source& source) {
     77         mSource = source;
     78     }
     79 
     80     void setSource(Source&& source) {
     81         mSource = std::move(source);
     82     }
     83 
     84     /**
     85      * Returns the comment that was associated with this resource.
     86      */
     87     StringPiece16 getComment() const {
     88         return mComment;
     89     }
     90 
     91     void setComment(const StringPiece16& str) {
     92         mComment = str.toString();
     93     }
     94 
     95     void setComment(std::u16string&& str) {
     96         mComment = std::move(str);
     97     }
     98 
     99     virtual bool equals(const Value* value) const = 0;
    100 
    101     /**
    102      * Calls the appropriate overload of ValueVisitor.
    103      */
    104     virtual void accept(RawValueVisitor* visitor) = 0;
    105 
    106     /**
    107      * Clone the value.
    108      */
    109     virtual Value* clone(StringPool* newPool) const = 0;
    110 
    111     /**
    112      * Human readable printout of this value.
    113      */
    114     virtual void print(std::ostream* out) const = 0;
    115 
    116 protected:
    117     Source mSource;
    118     std::u16string mComment;
    119     bool mWeak = false;
    120     bool mTranslateable = true;
    121 };
    122 
    123 /**
    124  * Inherit from this to get visitor accepting implementations for free.
    125  */
    126 template <typename Derived>
    127 struct BaseValue : public Value {
    128     void accept(RawValueVisitor* visitor) override;
    129 };
    130 
    131 /**
    132  * A resource item with a single value. This maps to android::ResTable_entry.
    133  */
    134 struct Item : public Value {
    135     /**
    136      * Clone the Item.
    137      */
    138     virtual Item* clone(StringPool* newPool) const override = 0;
    139 
    140     /**
    141      * Fills in an android::Res_value structure with this Item's binary representation.
    142      * Returns false if an error occurred.
    143      */
    144     virtual bool flatten(android::Res_value* outValue) const = 0;
    145 };
    146 
    147 /**
    148  * Inherit from this to get visitor accepting implementations for free.
    149  */
    150 template <typename Derived>
    151 struct BaseItem : public Item {
    152     void accept(RawValueVisitor* visitor) override;
    153 };
    154 
    155 /**
    156  * A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
    157  *
    158  * A reference can be symbolic (with the name set to a valid resource name) or be
    159  * numeric (the id is set to a valid resource ID).
    160  */
    161 struct Reference : public BaseItem<Reference> {
    162     enum class Type {
    163         kResource,
    164         kAttribute,
    165     };
    166 
    167     Maybe<ResourceName> name;
    168     Maybe<ResourceId> id;
    169     Reference::Type referenceType;
    170     bool privateReference = false;
    171 
    172     Reference();
    173     explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
    174     explicit Reference(const ResourceId& i, Type type = Type::kResource);
    175 
    176     bool equals(const Value* value) const override;
    177     bool flatten(android::Res_value* outValue) const override;
    178     Reference* clone(StringPool* newPool) const override;
    179     void print(std::ostream* out) const override;
    180 };
    181 
    182 /**
    183  * An ID resource. Has no real value, just a place holder.
    184  */
    185 struct Id : public BaseItem<Id> {
    186     Id() { mWeak = true; }
    187     bool equals(const Value* value) const override;
    188     bool flatten(android::Res_value* out) const override;
    189     Id* clone(StringPool* newPool) const override;
    190     void print(std::ostream* out) const override;
    191 };
    192 
    193 /**
    194  * A raw, unprocessed string. This may contain quotations,
    195  * escape sequences, and whitespace. This shall *NOT*
    196  * end up in the final resource table.
    197  */
    198 struct RawString : public BaseItem<RawString> {
    199     StringPool::Ref value;
    200 
    201     RawString(const StringPool::Ref& ref);
    202 
    203     bool equals(const Value* value) const override;
    204     bool flatten(android::Res_value* outValue) const override;
    205     RawString* clone(StringPool* newPool) const override;
    206     void print(std::ostream* out) const override;
    207 };
    208 
    209 struct String : public BaseItem<String> {
    210     StringPool::Ref value;
    211 
    212     String(const StringPool::Ref& ref);
    213 
    214     bool equals(const Value* value) const override;
    215     bool flatten(android::Res_value* outValue) const override;
    216     String* clone(StringPool* newPool) const override;
    217     void print(std::ostream* out) const override;
    218 };
    219 
    220 struct StyledString : public BaseItem<StyledString> {
    221     StringPool::StyleRef value;
    222 
    223     StyledString(const StringPool::StyleRef& ref);
    224 
    225     bool equals(const Value* value) const override;
    226     bool flatten(android::Res_value* outValue) const override;
    227     StyledString* clone(StringPool* newPool) const override;
    228     void print(std::ostream* out) const override;
    229 };
    230 
    231 struct FileReference : public BaseItem<FileReference> {
    232     StringPool::Ref path;
    233 
    234     /**
    235      * A handle to the file object from which this file can be read.
    236      */
    237     io::IFile* file = nullptr;
    238 
    239     FileReference() = default;
    240     FileReference(const StringPool::Ref& path);
    241 
    242     bool equals(const Value* value) const override;
    243     bool flatten(android::Res_value* outValue) const override;
    244     FileReference* clone(StringPool* newPool) const override;
    245     void print(std::ostream* out) const override;
    246 };
    247 
    248 /**
    249  * Represents any other android::Res_value.
    250  */
    251 struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
    252     android::Res_value value;
    253 
    254     BinaryPrimitive() = default;
    255     BinaryPrimitive(const android::Res_value& val);
    256     BinaryPrimitive(uint8_t dataType, uint32_t data);
    257 
    258     bool equals(const Value* value) const override;
    259     bool flatten(android::Res_value* outValue) const override;
    260     BinaryPrimitive* clone(StringPool* newPool) const override;
    261     void print(std::ostream* out) const override;
    262 };
    263 
    264 struct Attribute : public BaseValue<Attribute> {
    265     struct Symbol {
    266         Reference symbol;
    267         uint32_t value;
    268     };
    269 
    270     uint32_t typeMask;
    271     int32_t minInt;
    272     int32_t maxInt;
    273     std::vector<Symbol> symbols;
    274 
    275     Attribute(bool w, uint32_t t = 0u);
    276 
    277     bool equals(const Value* value) const override;
    278     Attribute* clone(StringPool* newPool) const override;
    279     void printMask(std::ostream* out) const;
    280     void print(std::ostream* out) const override;
    281     bool matches(const Item* item, DiagMessage* outMsg) const;
    282 };
    283 
    284 struct Style : public BaseValue<Style> {
    285     struct Entry {
    286         Reference key;
    287         std::unique_ptr<Item> value;
    288     };
    289 
    290     Maybe<Reference> parent;
    291 
    292     /**
    293      * If set to true, the parent was auto inferred from the
    294      * style's name.
    295      */
    296     bool parentInferred = false;
    297 
    298     std::vector<Entry> entries;
    299 
    300     bool equals(const Value* value) const override;
    301     Style* clone(StringPool* newPool) const override;
    302     void print(std::ostream* out) const override;
    303 };
    304 
    305 struct Array : public BaseValue<Array> {
    306     std::vector<std::unique_ptr<Item>> items;
    307 
    308     bool equals(const Value* value) const override;
    309     Array* clone(StringPool* newPool) const override;
    310     void print(std::ostream* out) const override;
    311 };
    312 
    313 struct Plural : public BaseValue<Plural> {
    314     enum {
    315         Zero = 0,
    316         One,
    317         Two,
    318         Few,
    319         Many,
    320         Other,
    321         Count
    322     };
    323 
    324     std::array<std::unique_ptr<Item>, Count> values;
    325 
    326     bool equals(const Value* value) const override;
    327     Plural* clone(StringPool* newPool) const override;
    328     void print(std::ostream* out) const override;
    329 };
    330 
    331 struct Styleable : public BaseValue<Styleable> {
    332     std::vector<Reference> entries;
    333 
    334     bool equals(const Value* value) const override;
    335     Styleable* clone(StringPool* newPool) const override;
    336     void print(std::ostream* out) const override;
    337 };
    338 
    339 /**
    340  * Stream operator for printing Value objects.
    341  */
    342 inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
    343     value.print(&out);
    344     return out;
    345 }
    346 
    347 inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
    348     if (s.symbol.name) {
    349         out << s.symbol.name.value().entry;
    350     } else {
    351         out << "???";
    352     }
    353     return out << "=" << s.value;
    354 }
    355 
    356 } // namespace aapt
    357 
    358 #endif // AAPT_RESOURCE_VALUES_H
    359