blob: a03828206c91c082df5ac56dccc9ead5f626fd05 [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 Lesinski6f6ceb72014-11-14 14:48:12 -080046 * warning or error. Default for base class is false.
47 */
48 virtual bool isWeak() const;
49
50 /**
Adam Lesinskie78fd612015-10-22 12:48:43 -070051 * Returns the source where this value was defined.
52 */
53 const Source& getSource() const {
54 return mSource;
55 }
56
57 void setSource(const Source& source) {
58 mSource = source;
59 }
60
61 void setSource(Source&& source) {
62 mSource = std::move(source);
63 }
64
65 /**
66 * Returns the comment that was associated with this resource.
67 */
68 StringPiece16 getComment() const {
69 return mComment;
70 }
71
72 void setComment(const StringPiece16& str) {
73 mComment = str.toString();
74 }
75
76 void setComment(std::u16string&& str) {
77 mComment = std::move(str);
78 }
79
80 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080081 * Calls the appropriate overload of ValueVisitor.
82 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070083 virtual void accept(RawValueVisitor* visitor) = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080084
85 /**
86 * Clone the value.
87 */
Adam Lesinski769de982015-04-10 19:43:55 -070088 virtual Value* clone(StringPool* newPool) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080089
90 /**
91 * Human readable printout of this value.
92 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070093 virtual void print(std::ostream* out) const = 0;
Adam Lesinskie78fd612015-10-22 12:48:43 -070094
Adam Lesinskib274e352015-11-06 15:14:35 -080095protected:
Adam Lesinskie78fd612015-10-22 12:48:43 -070096 Source mSource;
97 std::u16string mComment;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080098};
99
100/**
101 * Inherit from this to get visitor accepting implementations for free.
102 */
103template <typename Derived>
104struct BaseValue : public Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700105 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800106};
107
108/**
109 * A resource item with a single value. This maps to android::ResTable_entry.
110 */
111struct Item : public Value {
112 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800113 * Clone the Item.
114 */
Adam Lesinski769de982015-04-10 19:43:55 -0700115 virtual Item* clone(StringPool* newPool) const override = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800116
117 /**
118 * Fills in an android::Res_value structure with this Item's binary representation.
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700119 * Returns false if an error occurred.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800120 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700121 virtual bool flatten(android::Res_value* outValue) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800122};
123
124/**
125 * Inherit from this to get visitor accepting implementations for free.
126 */
127template <typename Derived>
128struct BaseItem : public Item {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700129 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800130};
131
132/**
133 * A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
134 *
135 * A reference can be symbolic (with the name set to a valid resource name) or be
136 * numeric (the id is set to a valid resource ID).
137 */
138struct Reference : public BaseItem<Reference> {
139 enum class Type {
140 kResource,
141 kAttribute,
142 };
143
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700144 Maybe<ResourceName> name;
145 Maybe<ResourceId> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800146 Reference::Type referenceType;
147 bool privateReference = false;
148
149 Reference();
150 Reference(const ResourceNameRef& n, Type type = Type::kResource);
151 Reference(const ResourceId& i, Type type = Type::kResource);
152
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700153 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700154 Reference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700155 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800156};
157
158/**
159 * An ID resource. Has no real value, just a place holder.
160 */
161struct Id : public BaseItem<Id> {
162 bool isWeak() const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700163 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700164 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700165 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800166};
167
168/**
169 * A raw, unprocessed string. This may contain quotations,
170 * escape sequences, and whitespace. This shall *NOT*
171 * end up in the final resource table.
172 */
173struct RawString : public BaseItem<RawString> {
174 StringPool::Ref value;
175
176 RawString(const StringPool::Ref& ref);
177
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700178 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700179 RawString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700180 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800181};
182
183struct String : public BaseItem<String> {
184 StringPool::Ref value;
185
186 String(const StringPool::Ref& ref);
187
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700188 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700189 String* 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
193struct StyledString : public BaseItem<StyledString> {
194 StringPool::StyleRef value;
195
196 StyledString(const StringPool::StyleRef& ref);
197
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700198 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700199 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700200 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800201};
202
203struct FileReference : public BaseItem<FileReference> {
204 StringPool::Ref path;
205
206 FileReference() = default;
207 FileReference(const StringPool::Ref& path);
208
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700209 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700210 FileReference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700211 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800212};
213
214/**
215 * Represents any other android::Res_value.
216 */
217struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
218 android::Res_value value;
219
220 BinaryPrimitive() = default;
221 BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700222 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800223
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700224 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700225 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700226 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800227};
228
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800229struct Attribute : public BaseValue<Attribute> {
230 struct Symbol {
231 Reference symbol;
232 uint32_t value;
233 };
234
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700235 bool weak;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800236 uint32_t typeMask;
Adam Lesinskia5870652015-11-20 15:32:30 -0800237 int32_t minInt;
238 int32_t maxInt;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800239 std::vector<Symbol> symbols;
240
241 Attribute(bool w, uint32_t t = 0u);
242
243 bool isWeak() const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700244 Attribute* clone(StringPool* newPool) const override;
245 void printMask(std::ostream* out) const;
246 void print(std::ostream* out) const override;
Adam Lesinskia5870652015-11-20 15:32:30 -0800247 bool matches(const Item* item, DiagMessage* outMsg) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800248};
249
250struct Style : public BaseValue<Style> {
251 struct Entry {
252 Reference key;
253 std::unique_ptr<Item> value;
254 };
255
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700256 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700257
258 /**
259 * If set to true, the parent was auto inferred from the
260 * style's name.
261 */
262 bool parentInferred = false;
263
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800264 std::vector<Entry> entries;
265
Adam Lesinski769de982015-04-10 19:43:55 -0700266 Style* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700267 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800268};
269
270struct Array : public BaseValue<Array> {
271 std::vector<std::unique_ptr<Item>> items;
272
Adam Lesinski769de982015-04-10 19:43:55 -0700273 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700274 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800275};
276
277struct Plural : public BaseValue<Plural> {
278 enum {
279 Zero = 0,
280 One,
281 Two,
282 Few,
283 Many,
284 Other,
285 Count
286 };
287
288 std::array<std::unique_ptr<Item>, Count> values;
289
Adam Lesinski769de982015-04-10 19:43:55 -0700290 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700291 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800292};
293
294struct Styleable : public BaseValue<Styleable> {
295 std::vector<Reference> entries;
296
Adam Lesinski769de982015-04-10 19:43:55 -0700297 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700298 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800299};
300
301/**
302 * Stream operator for printing Value objects.
303 */
304inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700305 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800306 return out;
307}
308
Adam Lesinski330edcd2015-05-04 17:40:56 -0700309inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700310 if (s.symbol.name) {
311 out << s.symbol.name.value().entry;
312 } else {
313 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800314 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700315 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800316}
317
318} // namespace aapt
319
320#endif // AAPT_RESOURCE_VALUES_H