blob: 26291536ae80f14c4e5ca4815bc43b84c581e86c [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 Lesinski1ab598f2015-08-14 14:26:04 -070020#include "util/Maybe.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080021#include "Resource.h"
22#include "StringPool.h"
23
24#include <array>
25#include <androidfw/ResourceTypes.h>
26#include <ostream>
27#include <vector>
28
29namespace aapt {
30
Adam Lesinski1ab598f2015-08-14 14:26:04 -070031struct RawValueVisitor;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080032
33/**
34 * A resource value. This is an all-encompassing representation
35 * of Item and Map and their subclasses. The way to do
36 * type specific operations is to check the Value's type() and
37 * cast it to the appropriate subclass. This isn't super clean,
38 * but it is the simplest strategy.
39 */
40struct Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -070041 virtual ~Value() = default;
42
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080043 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -070044 * Whether this value is weak and can be overridden without
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080045 * warning or error. Default for base class is false.
46 */
47 virtual bool isWeak() const;
48
49 /**
Adam Lesinskie78fd612015-10-22 12:48:43 -070050 * Returns the source where this value was defined.
51 */
52 const Source& getSource() const {
53 return mSource;
54 }
55
56 void setSource(const Source& source) {
57 mSource = source;
58 }
59
60 void setSource(Source&& source) {
61 mSource = std::move(source);
62 }
63
64 /**
65 * Returns the comment that was associated with this resource.
66 */
67 StringPiece16 getComment() const {
68 return mComment;
69 }
70
71 void setComment(const StringPiece16& str) {
72 mComment = str.toString();
73 }
74
75 void setComment(std::u16string&& str) {
76 mComment = std::move(str);
77 }
78
79 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080080 * Calls the appropriate overload of ValueVisitor.
81 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070082 virtual void accept(RawValueVisitor* visitor) = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080083
84 /**
85 * Clone the value.
86 */
Adam Lesinski769de982015-04-10 19:43:55 -070087 virtual Value* clone(StringPool* newPool) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080088
89 /**
90 * Human readable printout of this value.
91 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070092 virtual void print(std::ostream* out) const = 0;
Adam Lesinskie78fd612015-10-22 12:48:43 -070093
94private:
95 Source mSource;
96 std::u16string mComment;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080097};
98
99/**
100 * Inherit from this to get visitor accepting implementations for free.
101 */
102template <typename Derived>
103struct BaseValue : public Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700104 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800105};
106
107/**
108 * A resource item with a single value. This maps to android::ResTable_entry.
109 */
110struct Item : public Value {
111 /**
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800112 * Clone the Item.
113 */
Adam Lesinski769de982015-04-10 19:43:55 -0700114 virtual Item* clone(StringPool* newPool) const override = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800115
116 /**
117 * Fills in an android::Res_value structure with this Item's binary representation.
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700118 * Returns false if an error occurred.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800119 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700120 virtual bool flatten(android::Res_value* outValue) const = 0;
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 BaseItem : public Item {
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 reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
133 *
134 * A reference can be symbolic (with the name set to a valid resource name) or be
135 * numeric (the id is set to a valid resource ID).
136 */
137struct Reference : public BaseItem<Reference> {
138 enum class Type {
139 kResource,
140 kAttribute,
141 };
142
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700143 Maybe<ResourceName> name;
144 Maybe<ResourceId> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800145 Reference::Type referenceType;
146 bool privateReference = false;
147
148 Reference();
149 Reference(const ResourceNameRef& n, Type type = Type::kResource);
150 Reference(const ResourceId& i, Type type = Type::kResource);
151
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700152 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700153 Reference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700154 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800155};
156
157/**
158 * An ID resource. Has no real value, just a place holder.
159 */
160struct Id : public BaseItem<Id> {
161 bool isWeak() const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700162 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700163 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700164 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800165};
166
167/**
168 * A raw, unprocessed string. This may contain quotations,
169 * escape sequences, and whitespace. This shall *NOT*
170 * end up in the final resource table.
171 */
172struct RawString : public BaseItem<RawString> {
173 StringPool::Ref value;
174
175 RawString(const StringPool::Ref& ref);
176
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700177 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700178 RawString* 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
182struct String : public BaseItem<String> {
183 StringPool::Ref value;
184
185 String(const StringPool::Ref& ref);
186
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700187 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700188 String* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700189 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800190};
191
192struct StyledString : public BaseItem<StyledString> {
193 StringPool::StyleRef value;
194
195 StyledString(const StringPool::StyleRef& ref);
196
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700197 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700198 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700199 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800200};
201
202struct FileReference : public BaseItem<FileReference> {
203 StringPool::Ref path;
204
205 FileReference() = default;
206 FileReference(const StringPool::Ref& path);
207
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700208 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700209 FileReference* 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
213/**
214 * Represents any other android::Res_value.
215 */
216struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
217 android::Res_value value;
218
219 BinaryPrimitive() = default;
220 BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700221 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800222
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700223 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700224 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700225 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800226};
227
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800228struct Attribute : public BaseValue<Attribute> {
229 struct Symbol {
230 Reference symbol;
231 uint32_t value;
232 };
233
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700234 bool weak;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800235 uint32_t typeMask;
236 uint32_t minInt;
237 uint32_t maxInt;
238 std::vector<Symbol> symbols;
239
240 Attribute(bool w, uint32_t t = 0u);
241
242 bool isWeak() const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700243 Attribute* clone(StringPool* newPool) const override;
244 void printMask(std::ostream* out) const;
245 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800246};
247
248struct Style : public BaseValue<Style> {
249 struct Entry {
250 Reference key;
251 std::unique_ptr<Item> value;
252 };
253
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700254 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700255
256 /**
257 * If set to true, the parent was auto inferred from the
258 * style's name.
259 */
260 bool parentInferred = false;
261
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800262 std::vector<Entry> entries;
263
Adam Lesinski769de982015-04-10 19:43:55 -0700264 Style* 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
268struct Array : public BaseValue<Array> {
269 std::vector<std::unique_ptr<Item>> items;
270
Adam Lesinski769de982015-04-10 19:43:55 -0700271 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700272 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800273};
274
275struct Plural : public BaseValue<Plural> {
276 enum {
277 Zero = 0,
278 One,
279 Two,
280 Few,
281 Many,
282 Other,
283 Count
284 };
285
286 std::array<std::unique_ptr<Item>, Count> values;
287
Adam Lesinski769de982015-04-10 19:43:55 -0700288 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700289 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800290};
291
292struct Styleable : public BaseValue<Styleable> {
293 std::vector<Reference> entries;
294
Adam Lesinski769de982015-04-10 19:43:55 -0700295 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700296 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800297};
298
299/**
300 * Stream operator for printing Value objects.
301 */
302inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700303 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800304 return out;
305}
306
Adam Lesinski330edcd2015-05-04 17:40:56 -0700307inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700308 if (s.symbol.name) {
309 out << s.symbol.name.value().entry;
310 } else {
311 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800312 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700313 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800314}
315
316} // namespace aapt
317
318#endif // AAPT_RESOURCE_VALUES_H