blob: a28ffe5aff0f68c7585c264796569553eebb4779 [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
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080026#include <androidfw/ResourceTypes.h>
Adam Lesinskicacb28f2016-10-19 12:18:14 -070027#include <array>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080028#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 Lesinskicacb28f2016-10-19 12:18:14 -070043 virtual ~Value() = default;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070044
Adam Lesinskicacb28f2016-10-19 12:18:14 -070045 /**
46 * Whether this value is weak and can be overridden without
47 * warning or error. Default is false.
48 */
49 bool isWeak() const { return mWeak; }
Adam Lesinski393b5f02015-12-17 13:03:11 -080050
Adam Lesinskicacb28f2016-10-19 12:18:14 -070051 void setWeak(bool val) { mWeak = val; }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080052
Adam Lesinskicacb28f2016-10-19 12:18:14 -070053 // Whether the value is marked as translateable.
54 // This does not persist when flattened.
55 // It is only used during compilation phase.
56 void setTranslateable(bool val) { mTranslateable = val; }
Adam Lesinski458b8772016-04-25 14:20:21 -070057
Adam Lesinskicacb28f2016-10-19 12:18:14 -070058 // Default true.
59 bool isTranslateable() const { return mTranslateable; }
Adam Lesinski458b8772016-04-25 14:20:21 -070060
Adam Lesinskicacb28f2016-10-19 12:18:14 -070061 /**
62 * Returns the source where this value was defined.
63 */
64 const Source& getSource() const { return mSource; }
Adam Lesinskie78fd612015-10-22 12:48:43 -070065
Adam Lesinskicacb28f2016-10-19 12:18:14 -070066 void setSource(const Source& source) { mSource = source; }
Adam Lesinskie78fd612015-10-22 12:48:43 -070067
Adam Lesinskicacb28f2016-10-19 12:18:14 -070068 void setSource(Source&& source) { mSource = std::move(source); }
Adam Lesinskie78fd612015-10-22 12:48:43 -070069
Adam Lesinskicacb28f2016-10-19 12:18:14 -070070 /**
71 * Returns the comment that was associated with this resource.
72 */
73 const std::string& getComment() const { return mComment; }
Adam Lesinskie78fd612015-10-22 12:48:43 -070074
Adam Lesinskicacb28f2016-10-19 12:18:14 -070075 void setComment(const StringPiece& str) { mComment = str.toString(); }
Adam Lesinskie78fd612015-10-22 12:48:43 -070076
Adam Lesinskicacb28f2016-10-19 12:18:14 -070077 void setComment(std::string&& str) { mComment = std::move(str); }
Adam Lesinskie78fd612015-10-22 12:48:43 -070078
Adam Lesinskicacb28f2016-10-19 12:18:14 -070079 virtual bool equals(const Value* value) const = 0;
Adam Lesinski458b8772016-04-25 14:20:21 -070080
Adam Lesinskicacb28f2016-10-19 12:18:14 -070081 /**
82 * Calls the appropriate overload of ValueVisitor.
83 */
84 virtual void accept(RawValueVisitor* visitor) = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080085
Adam Lesinskicacb28f2016-10-19 12:18:14 -070086 /**
87 * Clone the value.
88 */
89 virtual Value* clone(StringPool* newPool) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080090
Adam Lesinskicacb28f2016-10-19 12:18:14 -070091 /**
92 * Human readable printout of this value.
93 */
94 virtual void print(std::ostream* out) const = 0;
Adam Lesinskie78fd612015-10-22 12:48:43 -070095
Adam Lesinskicacb28f2016-10-19 12:18:14 -070096 protected:
97 Source mSource;
98 std::string mComment;
99 bool mWeak = false;
100 bool mTranslateable = true;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800101};
102
103/**
104 * Inherit from this to get visitor accepting implementations for free.
105 */
106template <typename Derived>
107struct BaseValue : public Value {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700108 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800109};
110
111/**
112 * A resource item with a single value. This maps to android::ResTable_entry.
113 */
114struct Item : public Value {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700115 /**
116 * Clone the Item.
117 */
118 virtual Item* clone(StringPool* newPool) const override = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800119
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700120 /**
121 * Fills in an android::Res_value structure with this Item's binary
122 * representation.
123 * Returns false if an error occurred.
124 */
125 virtual bool flatten(android::Res_value* outValue) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800126};
127
128/**
129 * Inherit from this to get visitor accepting implementations for free.
130 */
131template <typename Derived>
132struct BaseItem : public Item {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700133 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800134};
135
136/**
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700137 * A reference to another resource. This maps to
138 * android::Res_value::TYPE_REFERENCE.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800139 *
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700140 * A reference can be symbolic (with the name set to a valid resource name) or
141 * be
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800142 * numeric (the id is set to a valid resource ID).
143 */
144struct Reference : public BaseItem<Reference> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 enum class Type {
146 kResource,
147 kAttribute,
148 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800149
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700150 Maybe<ResourceName> name;
151 Maybe<ResourceId> id;
152 Reference::Type referenceType;
153 bool privateReference = false;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800154
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700155 Reference();
156 explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
157 explicit Reference(const ResourceId& i, Type type = Type::kResource);
158 explicit Reference(const ResourceNameRef& n, const ResourceId& i);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800159
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700160 bool equals(const Value* value) const override;
161 bool flatten(android::Res_value* outValue) const override;
162 Reference* clone(StringPool* newPool) const override;
163 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800164};
165
Adam Lesinski8197cc462016-08-19 12:16:49 -0700166bool operator<(const Reference&, const Reference&);
167bool operator==(const Reference&, const Reference&);
168
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800169/**
170 * An ID resource. Has no real value, just a place holder.
171 */
172struct Id : public BaseItem<Id> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700173 Id() { mWeak = true; }
174 bool equals(const Value* value) const override;
175 bool flatten(android::Res_value* out) const override;
176 Id* clone(StringPool* newPool) const override;
177 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800178};
179
180/**
181 * A raw, unprocessed string. This may contain quotations,
182 * escape sequences, and whitespace. This shall *NOT*
183 * end up in the final resource table.
184 */
185struct RawString : public BaseItem<RawString> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700186 StringPool::Ref value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800187
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700188 explicit RawString(const StringPool::Ref& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800189
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700190 bool equals(const Value* value) const override;
191 bool flatten(android::Res_value* outValue) const override;
192 RawString* clone(StringPool* newPool) const override;
193 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800194};
195
196struct String : public BaseItem<String> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700197 StringPool::Ref value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800198
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700199 explicit String(const StringPool::Ref& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800200
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700201 bool equals(const Value* value) const override;
202 bool flatten(android::Res_value* outValue) const override;
203 String* clone(StringPool* newPool) const override;
204 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800205};
206
207struct StyledString : public BaseItem<StyledString> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700208 StringPool::StyleRef value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800209
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700210 explicit StyledString(const StringPool::StyleRef& ref);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800211
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700212 bool equals(const Value* value) const override;
213 bool flatten(android::Res_value* outValue) const override;
214 StyledString* clone(StringPool* newPool) const override;
215 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800216};
217
218struct FileReference : public BaseItem<FileReference> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700219 StringPool::Ref path;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800220
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700221 /**
222 * A handle to the file object from which this file can be read.
223 */
224 io::IFile* file = nullptr;
Adam Lesinski355f2852016-02-13 20:26:45 -0800225
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700226 FileReference() = default;
227 explicit FileReference(const StringPool::Ref& path);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800228
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700229 bool equals(const Value* value) const override;
230 bool flatten(android::Res_value* outValue) const override;
231 FileReference* clone(StringPool* newPool) const override;
232 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800233};
234
235/**
236 * Represents any other android::Res_value.
237 */
238struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700239 android::Res_value value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800240
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700241 BinaryPrimitive() = default;
242 explicit BinaryPrimitive(const android::Res_value& val);
243 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800244
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700245 bool equals(const Value* value) const override;
246 bool flatten(android::Res_value* outValue) const override;
247 BinaryPrimitive* clone(StringPool* newPool) const override;
248 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800249};
250
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800251struct Attribute : public BaseValue<Attribute> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700252 struct Symbol {
253 Reference symbol;
254 uint32_t value;
255 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800256
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700257 uint32_t typeMask;
258 int32_t minInt;
259 int32_t maxInt;
260 std::vector<Symbol> symbols;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800261
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700262 explicit Attribute(bool w, uint32_t t = 0u);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800263
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700264 bool equals(const Value* value) const override;
265 Attribute* clone(StringPool* newPool) const override;
266 void printMask(std::ostream* out) const;
267 void print(std::ostream* out) const override;
268 bool matches(const Item* item, DiagMessage* outMsg) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800269};
270
271struct Style : public BaseValue<Style> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700272 struct Entry {
273 Reference key;
274 std::unique_ptr<Item> value;
275 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800276
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700277 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700278
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700279 /**
280 * If set to true, the parent was auto inferred from the
281 * style's name.
282 */
283 bool parentInferred = false;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700284
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700285 std::vector<Entry> entries;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800286
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700287 bool equals(const Value* value) const override;
288 Style* clone(StringPool* newPool) const override;
289 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800290};
291
292struct Array : public BaseValue<Array> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700293 std::vector<std::unique_ptr<Item>> items;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800294
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700295 bool equals(const Value* value) const override;
296 Array* clone(StringPool* newPool) const override;
297 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800298};
299
300struct Plural : public BaseValue<Plural> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700301 enum { Zero = 0, One, Two, Few, Many, Other, Count };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800302
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700303 std::array<std::unique_ptr<Item>, Count> values;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800304
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700305 bool equals(const Value* value) const override;
306 Plural* clone(StringPool* newPool) const override;
307 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800308};
309
310struct Styleable : public BaseValue<Styleable> {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700311 std::vector<Reference> entries;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800312
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700313 bool equals(const Value* value) const override;
314 Styleable* clone(StringPool* newPool) const override;
315 void print(std::ostream* out) const override;
316 void mergeWith(Styleable* styleable);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800317};
318
319/**
320 * Stream operator for printing Value objects.
321 */
322inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700323 value.print(&out);
324 return out;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800325}
326
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700327inline ::std::ostream& operator<<(::std::ostream& out,
328 const Attribute::Symbol& s) {
329 if (s.symbol.name) {
330 out << s.symbol.name.value().entry;
331 } else {
332 out << "???";
333 }
334 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800335}
336
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700337} // namespace aapt
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800338
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700339#endif // AAPT_RESOURCE_VALUES_H