blob: aa1b550bdf092afb4672cc6a694c0c261d6da4fe [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
Adam Lesinski458b8772016-04-25 14:20:21 -070057 // 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
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080069 /**
Adam Lesinskie78fd612015-10-22 12:48:43 -070070 * 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
Adam Lesinski458b8772016-04-25 14:20:21 -070099 virtual bool equals(const Value* value) const = 0;
100
Adam Lesinskie78fd612015-10-22 12:48:43 -0700101 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800102 * Calls the appropriate overload of ValueVisitor.
103 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700104 virtual void accept(RawValueVisitor* visitor) = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800105
106 /**
107 * Clone the value.
108 */
Adam Lesinski769de982015-04-10 19:43:55 -0700109 virtual Value* clone(StringPool* newPool) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800110
111 /**
112 * Human readable printout of this value.
113 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700114 virtual void print(std::ostream* out) const = 0;
Adam Lesinskie78fd612015-10-22 12:48:43 -0700115
Adam Lesinskib274e352015-11-06 15:14:35 -0800116protected:
Adam Lesinskie78fd612015-10-22 12:48:43 -0700117 Source mSource;
118 std::u16string mComment;
Adam Lesinski393b5f02015-12-17 13:03:11 -0800119 bool mWeak = false;
Adam Lesinski458b8772016-04-25 14:20:21 -0700120 bool mTranslateable = true;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800121};
122
123/**
124 * Inherit from this to get visitor accepting implementations for free.
125 */
126template <typename Derived>
127struct BaseValue : public Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700128 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800129};
130
131/**
132 * A resource item with a single value. This maps to android::ResTable_entry.
133 */
134struct Item : public Value {
135 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800136 * Clone the Item.
137 */
Adam Lesinski769de982015-04-10 19:43:55 -0700138 virtual Item* clone(StringPool* newPool) const override = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800139
140 /**
141 * Fills in an android::Res_value structure with this Item's binary representation.
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700142 * Returns false if an error occurred.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800143 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700144 virtual bool flatten(android::Res_value* outValue) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800145};
146
147/**
148 * Inherit from this to get visitor accepting implementations for free.
149 */
150template <typename Derived>
151struct BaseItem : public Item {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700152 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800153};
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 */
161struct Reference : public BaseItem<Reference> {
162 enum class Type {
163 kResource,
164 kAttribute,
165 };
166
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700167 Maybe<ResourceName> name;
168 Maybe<ResourceId> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800169 Reference::Type referenceType;
170 bool privateReference = false;
171
172 Reference();
Adam Lesinski59e04c62016-02-04 15:59:23 -0800173 explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
174 explicit Reference(const ResourceId& i, Type type = Type::kResource);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800175
Adam Lesinski458b8772016-04-25 14:20:21 -0700176 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700177 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700178 Reference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700179 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800180};
181
182/**
183 * An ID resource. Has no real value, just a place holder.
184 */
185struct Id : public BaseItem<Id> {
Adam Lesinski393b5f02015-12-17 13:03:11 -0800186 Id() { mWeak = true; }
Adam Lesinski458b8772016-04-25 14:20:21 -0700187 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700188 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700189 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700190 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800191};
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 */
198struct RawString : public BaseItem<RawString> {
199 StringPool::Ref value;
200
201 RawString(const StringPool::Ref& ref);
202
Adam Lesinski458b8772016-04-25 14:20:21 -0700203 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700204 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700205 RawString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700206 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800207};
208
209struct String : public BaseItem<String> {
210 StringPool::Ref value;
211
212 String(const StringPool::Ref& ref);
213
Adam Lesinski458b8772016-04-25 14:20:21 -0700214 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700215 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700216 String* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700217 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800218};
219
220struct StyledString : public BaseItem<StyledString> {
221 StringPool::StyleRef value;
222
223 StyledString(const StringPool::StyleRef& ref);
224
Adam Lesinski458b8772016-04-25 14:20:21 -0700225 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700226 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700227 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700228 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800229};
230
231struct FileReference : public BaseItem<FileReference> {
232 StringPool::Ref path;
233
Adam Lesinski355f2852016-02-13 20:26:45 -0800234 /**
235 * A handle to the file object from which this file can be read.
236 */
237 io::IFile* file = nullptr;
238
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800239 FileReference() = default;
240 FileReference(const StringPool::Ref& path);
241
Adam Lesinski458b8772016-04-25 14:20:21 -0700242 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700243 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700244 FileReference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700245 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800246};
247
248/**
249 * Represents any other android::Res_value.
250 */
251struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
252 android::Res_value value;
253
254 BinaryPrimitive() = default;
255 BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700256 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800257
Adam Lesinski458b8772016-04-25 14:20:21 -0700258 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700259 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700260 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700261 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800262};
263
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800264struct Attribute : public BaseValue<Attribute> {
265 struct Symbol {
266 Reference symbol;
267 uint32_t value;
268 };
269
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800270 uint32_t typeMask;
Adam Lesinskia5870652015-11-20 15:32:30 -0800271 int32_t minInt;
272 int32_t maxInt;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800273 std::vector<Symbol> symbols;
274
275 Attribute(bool w, uint32_t t = 0u);
276
Adam Lesinski458b8772016-04-25 14:20:21 -0700277 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700278 Attribute* clone(StringPool* newPool) const override;
279 void printMask(std::ostream* out) const;
280 void print(std::ostream* out) const override;
Adam Lesinskia5870652015-11-20 15:32:30 -0800281 bool matches(const Item* item, DiagMessage* outMsg) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800282};
283
284struct Style : public BaseValue<Style> {
285 struct Entry {
286 Reference key;
287 std::unique_ptr<Item> value;
288 };
289
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700290 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700291
292 /**
293 * If set to true, the parent was auto inferred from the
294 * style's name.
295 */
296 bool parentInferred = false;
297
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800298 std::vector<Entry> entries;
299
Adam Lesinski458b8772016-04-25 14:20:21 -0700300 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700301 Style* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700302 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800303};
304
305struct Array : public BaseValue<Array> {
306 std::vector<std::unique_ptr<Item>> items;
307
Adam Lesinski458b8772016-04-25 14:20:21 -0700308 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700309 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700310 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800311};
312
313struct 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
Adam Lesinski458b8772016-04-25 14:20:21 -0700326 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700327 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700328 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800329};
330
331struct Styleable : public BaseValue<Styleable> {
332 std::vector<Reference> entries;
333
Adam Lesinski458b8772016-04-25 14:20:21 -0700334 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700335 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700336 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800337};
338
339/**
340 * Stream operator for printing Value objects.
341 */
342inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700343 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800344 return out;
345}
346
Adam Lesinski330edcd2015-05-04 17:40:56 -0700347inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700348 if (s.symbol.name) {
349 out << s.symbol.name.value().entry;
350 } else {
351 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800352 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700353 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800354}
355
356} // namespace aapt
357
358#endif // AAPT_RESOURCE_VALUES_H