blob: 8e317dbcd1b15f51c4a3639ee7c3ed0f10e5d4e2 [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
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
Adam Lesinskia5870652015-11-20 15:32:30 -080020#include "Diagnostics.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080021#include "Resource.h"
22#include "StringPool.h"
Adam Lesinskia5870652015-11-20 15:32:30 -080023#include "util/Maybe.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080024
25#include <array>
26#include <androidfw/ResourceTypes.h>
27#include <ostream>
28#include <vector>
29
30namespace aapt {
31
Adam Lesinski1ab598f2015-08-14 14:26:04 -070032struct RawValueVisitor;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080033
34/**
35 * A resource value. This is an all-encompassing representation
36 * of Item and Map and their subclasses. The way to do
37 * type specific operations is to check the Value's type() and
38 * cast it to the appropriate subclass. This isn't super clean,
39 * but it is the simplest strategy.
40 */
41struct Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -070042 virtual ~Value() = default;
43
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080044 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -070045 * Whether this value is weak and can be overridden without
Adam Lesinski393b5f02015-12-17 13:03:11 -080046 * warning or error. Default is false.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080047 */
Adam Lesinski393b5f02015-12-17 13:03:11 -080048 bool isWeak() const {
49 return mWeak;
50 }
51
52 void setWeak(bool val) {
53 mWeak = val;
54 }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080055
56 /**
Adam Lesinskie78fd612015-10-22 12:48:43 -070057 * Returns the source where this value was defined.
58 */
59 const Source& getSource() const {
60 return mSource;
61 }
62
63 void setSource(const Source& source) {
64 mSource = source;
65 }
66
67 void setSource(Source&& source) {
68 mSource = std::move(source);
69 }
70
71 /**
72 * Returns the comment that was associated with this resource.
73 */
74 StringPiece16 getComment() const {
75 return mComment;
76 }
77
78 void setComment(const StringPiece16& str) {
79 mComment = str.toString();
80 }
81
82 void setComment(std::u16string&& str) {
83 mComment = std::move(str);
84 }
85
86 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080087 * Calls the appropriate overload of ValueVisitor.
88 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070089 virtual void accept(RawValueVisitor* visitor) = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080090
91 /**
92 * Clone the value.
93 */
Adam Lesinski769de982015-04-10 19:43:55 -070094 virtual Value* clone(StringPool* newPool) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080095
96 /**
97 * Human readable printout of this value.
98 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070099 virtual void print(std::ostream* out) const = 0;
Adam Lesinskie78fd612015-10-22 12:48:43 -0700100
Adam Lesinskib274e352015-11-06 15:14:35 -0800101protected:
Adam Lesinskie78fd612015-10-22 12:48:43 -0700102 Source mSource;
103 std::u16string mComment;
Adam Lesinski393b5f02015-12-17 13:03:11 -0800104 bool mWeak = false;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800105};
106
107/**
108 * Inherit from this to get visitor accepting implementations for free.
109 */
110template <typename Derived>
111struct BaseValue : public Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700112 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800113};
114
115/**
116 * A resource item with a single value. This maps to android::ResTable_entry.
117 */
118struct Item : public Value {
119 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800120 * Clone the Item.
121 */
Adam Lesinski769de982015-04-10 19:43:55 -0700122 virtual Item* clone(StringPool* newPool) const override = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800123
124 /**
125 * Fills in an android::Res_value structure with this Item's binary representation.
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700126 * Returns false if an error occurred.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800127 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700128 virtual bool flatten(android::Res_value* outValue) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800129};
130
131/**
132 * Inherit from this to get visitor accepting implementations for free.
133 */
134template <typename Derived>
135struct BaseItem : public Item {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700136 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800137};
138
139/**
140 * A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
141 *
142 * A reference can be symbolic (with the name set to a valid resource name) or be
143 * numeric (the id is set to a valid resource ID).
144 */
145struct Reference : public BaseItem<Reference> {
146 enum class Type {
147 kResource,
148 kAttribute,
149 };
150
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700151 Maybe<ResourceName> name;
152 Maybe<ResourceId> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800153 Reference::Type referenceType;
154 bool privateReference = false;
155
156 Reference();
157 Reference(const ResourceNameRef& n, Type type = Type::kResource);
158 Reference(const ResourceId& i, Type type = Type::kResource);
159
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700160 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700161 Reference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700162 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800163};
164
165/**
166 * An ID resource. Has no real value, just a place holder.
167 */
168struct Id : public BaseItem<Id> {
Adam Lesinski393b5f02015-12-17 13:03:11 -0800169 Id() { mWeak = true; }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700170 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700171 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700172 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800173};
174
175/**
176 * A raw, unprocessed string. This may contain quotations,
177 * escape sequences, and whitespace. This shall *NOT*
178 * end up in the final resource table.
179 */
180struct RawString : public BaseItem<RawString> {
181 StringPool::Ref value;
182
183 RawString(const StringPool::Ref& ref);
184
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700185 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700186 RawString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700187 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800188};
189
190struct String : public BaseItem<String> {
191 StringPool::Ref value;
192
193 String(const StringPool::Ref& ref);
194
Adam Lesinski393b5f02015-12-17 13:03:11 -0800195 // Whether the string is marked as translateable. This does not persist when flattened.
196 // It is only used during compilation phase.
197 void setTranslateable(bool val);
198 bool isTranslateable() const;
199
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700200 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700201 String* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700202 void print(std::ostream* out) const override;
Adam Lesinski393b5f02015-12-17 13:03:11 -0800203
204private:
205 bool mTranslateable;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800206};
207
208struct StyledString : public BaseItem<StyledString> {
209 StringPool::StyleRef value;
210
211 StyledString(const StringPool::StyleRef& ref);
212
Adam Lesinski393b5f02015-12-17 13:03:11 -0800213 // Whether the string is marked as translateable. This does not persist when flattened.
214 // It is only used during compilation phase.
215 void setTranslateable(bool val);
216 bool isTranslateable() const;
217
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700218 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700219 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700220 void print(std::ostream* out) const override;
Adam Lesinski393b5f02015-12-17 13:03:11 -0800221
222private:
223 bool mTranslateable;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800224};
225
226struct FileReference : public BaseItem<FileReference> {
227 StringPool::Ref path;
228
229 FileReference() = default;
230 FileReference(const StringPool::Ref& path);
231
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700232 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700233 FileReference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700234 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800235};
236
237/**
238 * Represents any other android::Res_value.
239 */
240struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
241 android::Res_value value;
242
243 BinaryPrimitive() = default;
244 BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700245 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800246
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700247 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700248 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700249 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800250};
251
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800252struct Attribute : public BaseValue<Attribute> {
253 struct Symbol {
254 Reference symbol;
255 uint32_t value;
256 };
257
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800258 uint32_t typeMask;
Adam Lesinskia5870652015-11-20 15:32:30 -0800259 int32_t minInt;
260 int32_t maxInt;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800261 std::vector<Symbol> symbols;
262
263 Attribute(bool w, uint32_t t = 0u);
264
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700265 Attribute* clone(StringPool* newPool) const override;
266 void printMask(std::ostream* out) const;
267 void print(std::ostream* out) const override;
Adam Lesinskia5870652015-11-20 15:32:30 -0800268 bool matches(const Item* item, DiagMessage* outMsg) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800269};
270
271struct Style : public BaseValue<Style> {
272 struct Entry {
273 Reference key;
274 std::unique_ptr<Item> value;
275 };
276
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700277 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700278
279 /**
280 * If set to true, the parent was auto inferred from the
281 * style's name.
282 */
283 bool parentInferred = false;
284
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800285 std::vector<Entry> entries;
286
Adam Lesinski769de982015-04-10 19:43:55 -0700287 Style* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700288 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800289};
290
291struct Array : public BaseValue<Array> {
292 std::vector<std::unique_ptr<Item>> items;
293
Adam Lesinski769de982015-04-10 19:43:55 -0700294 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700295 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800296};
297
298struct Plural : public BaseValue<Plural> {
299 enum {
300 Zero = 0,
301 One,
302 Two,
303 Few,
304 Many,
305 Other,
306 Count
307 };
308
309 std::array<std::unique_ptr<Item>, Count> values;
310
Adam Lesinski769de982015-04-10 19:43:55 -0700311 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700312 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800313};
314
315struct Styleable : public BaseValue<Styleable> {
316 std::vector<Reference> entries;
317
Adam Lesinski769de982015-04-10 19:43:55 -0700318 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700319 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800320};
321
322/**
323 * Stream operator for printing Value objects.
324 */
325inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700326 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800327 return out;
328}
329
Adam Lesinski330edcd2015-05-04 17:40:56 -0700330inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700331 if (s.symbol.name) {
332 out << s.symbol.name.value().entry;
333 } else {
334 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800335 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700336 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800337}
338
339} // namespace aapt
340
341#endif // AAPT_RESOURCE_VALUES_H