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