blob: eb7559a1a964e2cebfc16c21e8291dcab685f850 [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 */
Adam Lesinskid0f116b2016-07-08 15:00:32 -070087 const std::string& getComment() const {
Adam Lesinskie78fd612015-10-22 12:48:43 -070088 return mComment;
89 }
90
Adam Lesinskid0f116b2016-07-08 15:00:32 -070091 void setComment(const StringPiece& str) {
Adam Lesinskie78fd612015-10-22 12:48:43 -070092 mComment = str.toString();
93 }
94
Adam Lesinskid0f116b2016-07-08 15:00:32 -070095 void setComment(std::string&& str) {
Adam Lesinskie78fd612015-10-22 12:48:43 -070096 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;
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700118 std::string 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
Adam Lesinski8197cc462016-08-19 12:16:49 -0700182bool operator<(const Reference&, const Reference&);
183bool operator==(const Reference&, const Reference&);
184
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800185/**
186 * An ID resource. Has no real value, just a place holder.
187 */
188struct Id : public BaseItem<Id> {
Adam Lesinski393b5f02015-12-17 13:03:11 -0800189 Id() { mWeak = true; }
Adam Lesinski458b8772016-04-25 14:20:21 -0700190 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700191 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700192 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700193 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800194};
195
196/**
197 * A raw, unprocessed string. This may contain quotations,
198 * escape sequences, and whitespace. This shall *NOT*
199 * end up in the final resource table.
200 */
201struct RawString : public BaseItem<RawString> {
202 StringPool::Ref value;
203
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700204 explicit RawString(const StringPool::Ref& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800205
Adam Lesinski458b8772016-04-25 14:20:21 -0700206 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700207 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700208 RawString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700209 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800210};
211
212struct String : public BaseItem<String> {
213 StringPool::Ref value;
214
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700215 explicit String(const StringPool::Ref& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800216
Adam Lesinski458b8772016-04-25 14:20:21 -0700217 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700218 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700219 String* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700220 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800221};
222
223struct StyledString : public BaseItem<StyledString> {
224 StringPool::StyleRef value;
225
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700226 explicit StyledString(const StringPool::StyleRef& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800227
Adam Lesinski458b8772016-04-25 14:20:21 -0700228 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700229 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700230 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700231 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800232};
233
234struct FileReference : public BaseItem<FileReference> {
235 StringPool::Ref path;
236
Adam Lesinski355f2852016-02-13 20:26:45 -0800237 /**
238 * A handle to the file object from which this file can be read.
239 */
240 io::IFile* file = nullptr;
241
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800242 FileReference() = default;
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700243 explicit FileReference(const StringPool::Ref& path);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800244
Adam Lesinski458b8772016-04-25 14:20:21 -0700245 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700246 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700247 FileReference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700248 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800249};
250
251/**
252 * Represents any other android::Res_value.
253 */
254struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
255 android::Res_value value;
256
257 BinaryPrimitive() = default;
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700258 explicit BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700259 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800260
Adam Lesinski458b8772016-04-25 14:20:21 -0700261 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700262 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700263 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700264 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800265};
266
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800267struct Attribute : public BaseValue<Attribute> {
268 struct Symbol {
269 Reference symbol;
270 uint32_t value;
271 };
272
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800273 uint32_t typeMask;
Adam Lesinskia5870652015-11-20 15:32:30 -0800274 int32_t minInt;
275 int32_t maxInt;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800276 std::vector<Symbol> symbols;
277
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700278 explicit Attribute(bool w, uint32_t t = 0u);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800279
Adam Lesinski458b8772016-04-25 14:20:21 -0700280 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700281 Attribute* clone(StringPool* newPool) const override;
282 void printMask(std::ostream* out) const;
283 void print(std::ostream* out) const override;
Adam Lesinskia5870652015-11-20 15:32:30 -0800284 bool matches(const Item* item, DiagMessage* outMsg) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800285};
286
287struct Style : public BaseValue<Style> {
288 struct Entry {
289 Reference key;
290 std::unique_ptr<Item> value;
291 };
292
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700293 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700294
295 /**
296 * If set to true, the parent was auto inferred from the
297 * style's name.
298 */
299 bool parentInferred = false;
300
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800301 std::vector<Entry> entries;
302
Adam Lesinski458b8772016-04-25 14:20:21 -0700303 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700304 Style* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700305 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800306};
307
308struct Array : public BaseValue<Array> {
309 std::vector<std::unique_ptr<Item>> items;
310
Adam Lesinski458b8772016-04-25 14:20:21 -0700311 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700312 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700313 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800314};
315
316struct Plural : public BaseValue<Plural> {
317 enum {
318 Zero = 0,
319 One,
320 Two,
321 Few,
322 Many,
323 Other,
324 Count
325 };
326
327 std::array<std::unique_ptr<Item>, Count> values;
328
Adam Lesinski458b8772016-04-25 14:20:21 -0700329 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700330 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700331 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800332};
333
334struct Styleable : public BaseValue<Styleable> {
335 std::vector<Reference> entries;
336
Adam Lesinski458b8772016-04-25 14:20:21 -0700337 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700338 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700339 void print(std::ostream* out) const override;
Adam Lesinski8197cc462016-08-19 12:16:49 -0700340 void mergeWith(Styleable* styleable);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800341};
342
343/**
344 * Stream operator for printing Value objects.
345 */
346inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700347 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800348 return out;
349}
350
Adam Lesinski330edcd2015-05-04 17:40:56 -0700351inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700352 if (s.symbol.name) {
353 out << s.symbol.name.value().entry;
354 } else {
355 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800356 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700357 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800358}
359
360} // namespace aapt
361
362#endif // AAPT_RESOURCE_VALUES_H