blob: 4e74ec366dabc33592a2caff96e7d2b22d9f6133 [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
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_VALUE_VISITOR_H
18#define AAPT_VALUE_VISITOR_H
19
Adam Lesinski59e04c62016-02-04 15:59:23 -080020#include "ResourceTable.h"
Adam Lesinskicacb28f2016-10-19 12:18:14 -070021#include "ResourceValues.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070022
23namespace aapt {
24
Adam Lesinskid3ffa8442017-09-28 13:34:35 -070025// Visits a value and invokes the appropriate method based on its type.
26// Does not traverse into compound types. Use ValueVisitor for that.
27class ValueVisitor {
28 public:
29 virtual ~ValueVisitor() = default;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070030
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080031 virtual void VisitAny(Value* value) {}
32 virtual void VisitItem(Item* value) { VisitAny(value); }
Adam Lesinskice5e56e2016-10-21 17:56:45 -070033 virtual void Visit(Reference* value) { VisitItem(value); }
34 virtual void Visit(RawString* value) { VisitItem(value); }
35 virtual void Visit(String* value) { VisitItem(value); }
36 virtual void Visit(StyledString* value) { VisitItem(value); }
37 virtual void Visit(FileReference* value) { VisitItem(value); }
38 virtual void Visit(Id* value) { VisitItem(value); }
39 virtual void Visit(BinaryPrimitive* value) { VisitItem(value); }
Adam Lesinski1ab598f2015-08-14 14:26:04 -070040
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080041 virtual void Visit(Attribute* value) { VisitAny(value); }
42 virtual void Visit(Style* value) { VisitAny(value); }
43 virtual void Visit(Array* value) { VisitAny(value); }
44 virtual void Visit(Plural* value) { VisitAny(value); }
45 virtual void Visit(Styleable* value) { VisitAny(value); }
Adam Lesinski1ab598f2015-08-14 14:26:04 -070046};
47
Adam Lesinskid3ffa8442017-09-28 13:34:35 -070048// Const version of ValueVisitor.
49class ConstValueVisitor {
50 public:
51 virtual ~ConstValueVisitor() = default;
52
53 virtual void VisitAny(const Value* value) {
54 }
55 virtual void VisitItem(const Item* value) {
56 VisitAny(value);
57 }
58 virtual void Visit(const Reference* value) {
59 VisitItem(value);
60 }
61 virtual void Visit(const RawString* value) {
62 VisitItem(value);
63 }
64 virtual void Visit(const String* value) {
65 VisitItem(value);
66 }
67 virtual void Visit(const StyledString* value) {
68 VisitItem(value);
69 }
70 virtual void Visit(const FileReference* value) {
71 VisitItem(value);
72 }
73 virtual void Visit(const Id* value) {
74 VisitItem(value);
75 }
76 virtual void Visit(const BinaryPrimitive* value) {
77 VisitItem(value);
78 }
79
80 virtual void Visit(const Attribute* value) {
81 VisitAny(value);
82 }
83 virtual void Visit(const Style* value) {
84 VisitAny(value);
85 }
86 virtual void Visit(const Array* value) {
87 VisitAny(value);
88 }
89 virtual void Visit(const Plural* value) {
90 VisitAny(value);
91 }
92 virtual void Visit(const Styleable* value) {
93 VisitAny(value);
94 }
95};
96
Chih-Hung Hsieh470f8fc2016-08-15 12:32:51 -070097// NOLINT, do not add parentheses around T.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070098#define DECL_VISIT_COMPOUND_VALUE(T) \
99 virtual void Visit(T* value) override { /* NOLINT */ \
100 VisitSubValues(value); \
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700101 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700102
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700103// Visits values, and if they are compound values, descends into their components as well.
104struct DescendingValueVisitor : public ValueVisitor {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700105 // The compiler will think we're hiding an overload, when we actually intend
106 // to call into RawValueVisitor. This will expose the visit methods in the
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700107 // super class so the compiler knows we are trying to call them.
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700108 using ValueVisitor::Visit;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700109
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700110 void VisitSubValues(Attribute* attribute) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700111 for (Attribute::Symbol& symbol : attribute->symbols) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700112 Visit(&symbol.symbol);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700113 }
114 }
115
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700116 void VisitSubValues(Style* style) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700117 if (style->parent) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700118 Visit(&style->parent.value());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700119 }
120
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700121 for (Style::Entry& entry : style->entries) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700122 Visit(&entry.key);
123 entry.value->Accept(this);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700124 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700125 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700126
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700127 void VisitSubValues(Array* array) {
Adam Lesinski4ffea042017-08-10 15:37:28 -0700128 for (std::unique_ptr<Item>& item : array->elements) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700129 item->Accept(this);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700130 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700131 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700132
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700133 void VisitSubValues(Plural* plural) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700134 for (std::unique_ptr<Item>& item : plural->values) {
135 if (item) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700136 item->Accept(this);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700137 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700138 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700139 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700140
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700141 void VisitSubValues(Styleable* styleable) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700142 for (Reference& reference : styleable->entries) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700143 Visit(&reference);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700144 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700146
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700147 DECL_VISIT_COMPOUND_VALUE(Attribute);
148 DECL_VISIT_COMPOUND_VALUE(Style);
149 DECL_VISIT_COMPOUND_VALUE(Array);
150 DECL_VISIT_COMPOUND_VALUE(Plural);
151 DECL_VISIT_COMPOUND_VALUE(Styleable);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700152};
153
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700154// Do not use directly. Helper struct for dyn_cast.
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700155template <typename T>
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700156struct DynCastVisitor : public ConstValueVisitor {
157 const T* value = nullptr;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700158
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700159 void Visit(const T* v) override {
160 value = v;
161 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700162};
163
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700164// Specialization that checks if the value is an Item.
Adam Lesinskie78fd612015-10-22 12:48:43 -0700165template <>
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700166struct DynCastVisitor<Item> : public ConstValueVisitor {
167 const Item* value = nullptr;
Adam Lesinskie78fd612015-10-22 12:48:43 -0700168
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700169 void VisitItem(const Item* item) override {
170 value = item;
171 }
Adam Lesinskie78fd612015-10-22 12:48:43 -0700172};
173
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700174// Returns a valid pointer to T if the value is an instance of T. Returns nullptr if value is
175// nullptr of if value is not an instance of T.
Adam Lesinski458b8772016-04-25 14:20:21 -0700176template <typename T>
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700177const T* ValueCast(const Value* value) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700178 if (!value) {
179 return nullptr;
180 }
181 DynCastVisitor<T> visitor;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700182 value->Accept(&visitor);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700183 return visitor.value;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700184}
185
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700186// Non-const version of ValueCast.
187template <typename T>
188T* ValueCast(Value* value) {
189 return const_cast<T*>(ValueCast<T>(static_cast<const Value*>(value)));
190}
191
192inline void VisitAllValuesInPackage(ResourceTablePackage* pkg, ValueVisitor* visitor) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700193 for (auto& type : pkg->types) {
194 for (auto& entry : type->entries) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700195 for (auto& config_value : entry->values) {
196 config_value->value->Accept(visitor);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700197 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800198 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700199 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800200}
201
Adam Lesinskid3ffa8442017-09-28 13:34:35 -0700202inline void VisitAllValuesInTable(ResourceTable* table, ValueVisitor* visitor) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700203 for (auto& pkg : table->packages) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700204 VisitAllValuesInPackage(pkg.get(), visitor);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700205 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800206}
207
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700208} // namespace aapt
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700209
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700210#endif // AAPT_VALUE_VISITOR_H