11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/* 21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License. 61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at 71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software 111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and 141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License. 151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#ifndef AAPT_VALUE_VISITOR_H 181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#define AAPT_VALUE_VISITOR_H 191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2059e04c6f92da584b322c87072f18e6cab4de4c60Adam Lesinski#include "ResourceTable.h" 21cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#include "ResourceValues.h" 221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt { 241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 26cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Visits a value and invokes the appropriate method based on its type. Does not 27ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski * traverse into compound types. Use ValueVisitor for that. 281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct RawValueVisitor { 30cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski virtual ~RawValueVisitor() = default; 31cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 32ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski virtual void VisitAny(Value* value) {} 33ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski virtual void VisitItem(Item* value) { VisitAny(value); } 34ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(Reference* value) { VisitItem(value); } 35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(RawString* value) { VisitItem(value); } 36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(String* value) { VisitItem(value); } 37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(StyledString* value) { VisitItem(value); } 38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(FileReference* value) { VisitItem(value); } 39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(Id* value) { VisitItem(value); } 40ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(BinaryPrimitive* value) { VisitItem(value); } 41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 42ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski virtual void Visit(Attribute* value) { VisitAny(value); } 43ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski virtual void Visit(Style* value) { VisitAny(value); } 44ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski virtual void Visit(Array* value) { VisitAny(value); } 45ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski virtual void Visit(Plural* value) { VisitAny(value); } 46ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski virtual void Visit(Styleable* value) { VisitAny(value); } 471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 49470f8fcb5c0c59b28b5f73ee011a797b05085da7Chih-Hung Hsieh// NOLINT, do not add parentheses around T. 50ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#define DECL_VISIT_COMPOUND_VALUE(T) \ 51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(T* value) override { /* NOLINT */ \ 52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski VisitSubValues(value); \ 53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Visits values, and if they are compound values, visits the components as 57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * well. 581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct ValueVisitor : public RawValueVisitor { 60cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // The compiler will think we're hiding an overload, when we actually intend 61cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // to call into RawValueVisitor. This will expose the visit methods in the 62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // super class so the compiler knows we are trying to call them. 63ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski using RawValueVisitor::Visit; 64cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 65ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void VisitSubValues(Attribute* attribute) { 66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (Attribute::Symbol& symbol : attribute->symbols) { 67ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Visit(&symbol.symbol); 681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 69cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 71ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void VisitSubValues(Style* style) { 72cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (style->parent) { 73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Visit(&style->parent.value()); 74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 76cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (Style::Entry& entry : style->entries) { 77ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Visit(&entry.key); 78ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski entry.value->Accept(this); 791ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 82ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void VisitSubValues(Array* array) { 83cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (std::unique_ptr<Item>& item : array->items) { 84ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski item->Accept(this); 851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 871ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 88ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void VisitSubValues(Plural* plural) { 89cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (std::unique_ptr<Item>& item : plural->values) { 90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (item) { 91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski item->Accept(this); 92cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 931ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 94cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 951ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 96ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void VisitSubValues(Styleable* styleable) { 97cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (Reference& reference : styleable->entries) { 98ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Visit(&reference); 991ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 100cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 1011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 102cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski DECL_VISIT_COMPOUND_VALUE(Attribute); 103cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski DECL_VISIT_COMPOUND_VALUE(Style); 104cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski DECL_VISIT_COMPOUND_VALUE(Array); 105cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski DECL_VISIT_COMPOUND_VALUE(Plural); 106cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski DECL_VISIT_COMPOUND_VALUE(Styleable); 1071ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 1081ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1091ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 1101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Do not use directly. Helper struct for dyn_cast. 1111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 1131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct DynCastVisitor : public RawValueVisitor { 114cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski T* value = nullptr; 1151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 116ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void Visit(T* v) override { value = v; } 1171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 1181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 120e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski * Specialization that checks if the value is an Item. 121e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski */ 122e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinskitemplate <> 123e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinskistruct DynCastVisitor<Item> : public RawValueVisitor { 124cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski Item* value = nullptr; 125e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski 126ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void VisitItem(Item* item) override { value = item; } 127e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski}; 128e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski 129458b877488c12ea4336d8fc00a95d9c0298bd6d0Adam Lesinskitemplate <typename T> 130ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst T* ValueCast(const Value* value) { 131ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return ValueCast<T>(const_cast<Value*>(value)); 132458b877488c12ea4336d8fc00a95d9c0298bd6d0Adam Lesinski} 133458b877488c12ea4336d8fc00a95d9c0298bd6d0Adam Lesinski 134e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski/** 1351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Returns a valid pointer to T if the Value is of subtype T. 1361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Otherwise, returns nullptr. 1371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 139ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiT* ValueCast(Value* value) { 140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (!value) { 141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return nullptr; 142cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 143cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski DynCastVisitor<T> visitor; 144ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski value->Accept(&visitor); 145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return visitor.value; 1461ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} 1471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 148ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline void VisitAllValuesInPackage(ResourceTablePackage* pkg, 149cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski RawValueVisitor* visitor) { 150cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (auto& type : pkg->types) { 151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (auto& entry : type->entries) { 152ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (auto& config_value : entry->values) { 153ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski config_value->value->Accept(visitor); 154cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 15559e04c6f92da584b322c87072f18e6cab4de4c60Adam Lesinski } 156cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 15759e04c6f92da584b322c87072f18e6cab4de4c60Adam Lesinski} 15859e04c6f92da584b322c87072f18e6cab4de4c60Adam Lesinski 159ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline void VisitAllValuesInTable(ResourceTable* table, 160cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski RawValueVisitor* visitor) { 161cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (auto& pkg : table->packages) { 162ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski VisitAllValuesInPackage(pkg.get(), visitor); 163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 16459e04c6f92da584b322c87072f18e6cab4de4c60Adam Lesinski} 16559e04c6f92da584b322c87072f18e6cab4de4c60Adam Lesinski 166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 1671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 168cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif // AAPT_VALUE_VISITOR_H 169