blob: 43354acf1d0b1bed942f5d3f82a15d7cbb1efdc6 [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 Lesinski355f2852016-02-13 20:26:45 -080023#include "io/File.h"
Adam Lesinskia5870652015-11-20 15:32:30 -080024#include "util/Maybe.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080025
26#include <array>
27#include <androidfw/ResourceTypes.h>
28#include <ostream>
29#include <vector>
30
31namespace aapt {
32
Adam Lesinski1ab598f2015-08-14 14:26:04 -070033struct RawValueVisitor;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080034
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 */
42struct Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -070043 virtual ~Value() = default;
44
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080045 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -070046 * Whether this value is weak and can be overridden without
Adam Lesinski393b5f02015-12-17 13:03:11 -080047 * warning or error. Default is false.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080048 */
Adam Lesinski393b5f02015-12-17 13:03:11 -080049 bool isWeak() const {
50 return mWeak;
51 }
52
53 void setWeak(bool val) {
54 mWeak = val;
55 }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080056
57 /**
Adam Lesinskie78fd612015-10-22 12:48:43 -070058 * 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 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080088 * Calls the appropriate overload of ValueVisitor.
89 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070090 virtual void accept(RawValueVisitor* visitor) = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080091
92 /**
93 * Clone the value.
94 */
Adam Lesinski769de982015-04-10 19:43:55 -070095 virtual Value* clone(StringPool* newPool) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080096
97 /**
98 * Human readable printout of this value.
99 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700100 virtual void print(std::ostream* out) const = 0;
Adam Lesinskie78fd612015-10-22 12:48:43 -0700101
Adam Lesinskib274e352015-11-06 15:14:35 -0800102protected:
Adam Lesinskie78fd612015-10-22 12:48:43 -0700103 Source mSource;
104 std::u16string mComment;
Adam Lesinski393b5f02015-12-17 13:03:11 -0800105 bool mWeak = false;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800106};
107
108/**
109 * Inherit from this to get visitor accepting implementations for free.
110 */
111template <typename Derived>
112struct BaseValue : public Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700113 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800114};
115
116/**
117 * A resource item with a single value. This maps to android::ResTable_entry.
118 */
119struct Item : public Value {
120 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800121 * Clone the Item.
122 */
Adam Lesinski769de982015-04-10 19:43:55 -0700123 virtual Item* clone(StringPool* newPool) const override = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800124
125 /**
126 * Fills in an android::Res_value structure with this Item's binary representation.
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700127 * Returns false if an error occurred.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800128 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700129 virtual bool flatten(android::Res_value* outValue) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800130};
131
132/**
133 * Inherit from this to get visitor accepting implementations for free.
134 */
135template <typename Derived>
136struct BaseItem : public Item {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700137 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800138};
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 */
146struct Reference : public BaseItem<Reference> {
147 enum class Type {
148 kResource,
149 kAttribute,
150 };
151
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700152 Maybe<ResourceName> name;
153 Maybe<ResourceId> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800154 Reference::Type referenceType;
155 bool privateReference = false;
156
157 Reference();
Adam Lesinski59e04c62016-02-04 15:59:23 -0800158 explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
159 explicit Reference(const ResourceId& i, Type type = Type::kResource);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800160
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700161 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700162 Reference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700163 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800164};
165
166/**
167 * An ID resource. Has no real value, just a place holder.
168 */
169struct Id : public BaseItem<Id> {
Adam Lesinski393b5f02015-12-17 13:03:11 -0800170 Id() { mWeak = true; }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700171 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700172 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700173 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800174};
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 */
181struct RawString : public BaseItem<RawString> {
182 StringPool::Ref value;
183
184 RawString(const StringPool::Ref& ref);
185
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700186 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700187 RawString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700188 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800189};
190
191struct String : public BaseItem<String> {
192 StringPool::Ref value;
193
194 String(const StringPool::Ref& ref);
195
Adam Lesinski393b5f02015-12-17 13:03:11 -0800196 // 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
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700201 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700202 String* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700203 void print(std::ostream* out) const override;
Adam Lesinski393b5f02015-12-17 13:03:11 -0800204
205private:
206 bool mTranslateable;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800207};
208
209struct StyledString : public BaseItem<StyledString> {
210 StringPool::StyleRef value;
211
212 StyledString(const StringPool::StyleRef& ref);
213
Adam Lesinski393b5f02015-12-17 13:03:11 -0800214 // 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
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700219 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700220 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700221 void print(std::ostream* out) const override;
Adam Lesinski393b5f02015-12-17 13:03:11 -0800222
223private:
224 bool mTranslateable;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800225};
226
227struct FileReference : public BaseItem<FileReference> {
228 StringPool::Ref path;
229
Adam Lesinski355f2852016-02-13 20:26:45 -0800230 /**
231 * A handle to the file object from which this file can be read.
232 */
233 io::IFile* file = nullptr;
234
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800235 FileReference() = default;
236 FileReference(const StringPool::Ref& path);
237
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700238 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700239 FileReference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700240 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800241};
242
243/**
244 * Represents any other android::Res_value.
245 */
246struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
247 android::Res_value value;
248
249 BinaryPrimitive() = default;
250 BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700251 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800252
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700253 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700254 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700255 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800256};
257
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800258struct Attribute : public BaseValue<Attribute> {
259 struct Symbol {
260 Reference symbol;
261 uint32_t value;
262 };
263
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800264 uint32_t typeMask;
Adam Lesinskia5870652015-11-20 15:32:30 -0800265 int32_t minInt;
266 int32_t maxInt;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800267 std::vector<Symbol> symbols;
268
269 Attribute(bool w, uint32_t t = 0u);
270
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700271 Attribute* clone(StringPool* newPool) const override;
272 void printMask(std::ostream* out) const;
273 void print(std::ostream* out) const override;
Adam Lesinskia5870652015-11-20 15:32:30 -0800274 bool matches(const Item* item, DiagMessage* outMsg) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800275};
276
277struct Style : public BaseValue<Style> {
278 struct Entry {
279 Reference key;
280 std::unique_ptr<Item> value;
281 };
282
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700283 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700284
285 /**
286 * If set to true, the parent was auto inferred from the
287 * style's name.
288 */
289 bool parentInferred = false;
290
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800291 std::vector<Entry> entries;
292
Adam Lesinski769de982015-04-10 19:43:55 -0700293 Style* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700294 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800295};
296
297struct Array : public BaseValue<Array> {
298 std::vector<std::unique_ptr<Item>> items;
299
Adam Lesinski769de982015-04-10 19:43:55 -0700300 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700301 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800302};
303
304struct 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
Adam Lesinski769de982015-04-10 19:43:55 -0700317 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700318 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800319};
320
321struct Styleable : public BaseValue<Styleable> {
322 std::vector<Reference> entries;
323
Adam Lesinski769de982015-04-10 19:43:55 -0700324 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700325 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800326};
327
328/**
329 * Stream operator for printing Value objects.
330 */
331inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700332 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800333 return out;
334}
335
Adam Lesinski330edcd2015-05-04 17:40:56 -0700336inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700337 if (s.symbol.name) {
338 out << s.symbol.name.value().entry;
339 } else {
340 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800341 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700342 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800343}
344
345} // namespace aapt
346
347#endif // AAPT_RESOURCE_VALUES_H