blob: 5e5d1f3dd6aa2b6a03ea4b65bc44e4609a5675f7 [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 Lesinski5c3464c2016-08-24 16:03:48 -0700175 explicit Reference(const ResourceNameRef& n, const ResourceId& i);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800176
Adam Lesinski458b8772016-04-25 14:20:21 -0700177 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700178 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700179 Reference* 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
Adam Lesinski8197cc462016-08-19 12:16:49 -0700183bool operator<(const Reference&, const Reference&);
184bool operator==(const Reference&, const Reference&);
185
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800186/**
187 * An ID resource. Has no real value, just a place holder.
188 */
189struct Id : public BaseItem<Id> {
Adam Lesinski393b5f02015-12-17 13:03:11 -0800190 Id() { mWeak = true; }
Adam Lesinski458b8772016-04-25 14:20:21 -0700191 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700192 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700193 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700194 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800195};
196
197/**
198 * A raw, unprocessed string. This may contain quotations,
199 * escape sequences, and whitespace. This shall *NOT*
200 * end up in the final resource table.
201 */
202struct RawString : public BaseItem<RawString> {
203 StringPool::Ref value;
204
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700205 explicit RawString(const StringPool::Ref& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800206
Adam Lesinski458b8772016-04-25 14:20:21 -0700207 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700208 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700209 RawString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700210 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800211};
212
213struct String : public BaseItem<String> {
214 StringPool::Ref value;
215
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700216 explicit String(const StringPool::Ref& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800217
Adam Lesinski458b8772016-04-25 14:20:21 -0700218 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700219 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700220 String* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700221 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800222};
223
224struct StyledString : public BaseItem<StyledString> {
225 StringPool::StyleRef value;
226
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700227 explicit StyledString(const StringPool::StyleRef& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800228
Adam Lesinski458b8772016-04-25 14:20:21 -0700229 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700230 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700231 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700232 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800233};
234
235struct FileReference : public BaseItem<FileReference> {
236 StringPool::Ref path;
237
Adam Lesinski355f2852016-02-13 20:26:45 -0800238 /**
239 * A handle to the file object from which this file can be read.
240 */
241 io::IFile* file = nullptr;
242
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800243 FileReference() = default;
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700244 explicit FileReference(const StringPool::Ref& path);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800245
Adam Lesinski458b8772016-04-25 14:20:21 -0700246 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700247 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700248 FileReference* 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
252/**
253 * Represents any other android::Res_value.
254 */
255struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
256 android::Res_value value;
257
258 BinaryPrimitive() = default;
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700259 explicit BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700260 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800261
Adam Lesinski458b8772016-04-25 14:20:21 -0700262 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700263 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700264 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700265 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800266};
267
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800268struct Attribute : public BaseValue<Attribute> {
269 struct Symbol {
270 Reference symbol;
271 uint32_t value;
272 };
273
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800274 uint32_t typeMask;
Adam Lesinskia5870652015-11-20 15:32:30 -0800275 int32_t minInt;
276 int32_t maxInt;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800277 std::vector<Symbol> symbols;
278
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700279 explicit Attribute(bool w, uint32_t t = 0u);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800280
Adam Lesinski458b8772016-04-25 14:20:21 -0700281 bool equals(const Value* value) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700282 Attribute* clone(StringPool* newPool) const override;
283 void printMask(std::ostream* out) const;
284 void print(std::ostream* out) const override;
Adam Lesinskia5870652015-11-20 15:32:30 -0800285 bool matches(const Item* item, DiagMessage* outMsg) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800286};
287
288struct Style : public BaseValue<Style> {
289 struct Entry {
290 Reference key;
291 std::unique_ptr<Item> value;
292 };
293
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700294 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700295
296 /**
297 * If set to true, the parent was auto inferred from the
298 * style's name.
299 */
300 bool parentInferred = false;
301
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800302 std::vector<Entry> entries;
303
Adam Lesinski458b8772016-04-25 14:20:21 -0700304 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700305 Style* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700306 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800307};
308
309struct Array : public BaseValue<Array> {
310 std::vector<std::unique_ptr<Item>> items;
311
Adam Lesinski458b8772016-04-25 14:20:21 -0700312 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700313 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700314 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800315};
316
317struct Plural : public BaseValue<Plural> {
318 enum {
319 Zero = 0,
320 One,
321 Two,
322 Few,
323 Many,
324 Other,
325 Count
326 };
327
328 std::array<std::unique_ptr<Item>, Count> values;
329
Adam Lesinski458b8772016-04-25 14:20:21 -0700330 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700331 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700332 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800333};
334
335struct Styleable : public BaseValue<Styleable> {
336 std::vector<Reference> entries;
337
Adam Lesinski458b8772016-04-25 14:20:21 -0700338 bool equals(const Value* value) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700339 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700340 void print(std::ostream* out) const override;
Adam Lesinski8197cc462016-08-19 12:16:49 -0700341 void mergeWith(Styleable* styleable);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800342};
343
344/**
345 * Stream operator for printing Value objects.
346 */
347inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700348 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800349 return out;
350}
351
Adam Lesinski330edcd2015-05-04 17:40:56 -0700352inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700353 if (s.symbol.name) {
354 out << s.symbol.name.value().entry;
355 } else {
356 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800357 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700358 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800359}
360
361} // namespace aapt
362
363#endif // AAPT_RESOURCE_VALUES_H