ValueVisitor.h revision e78fd617ec60139a973a01925fa7adad31febb39
1/* 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 20#include "ResourceValues.h" 21 22namespace aapt { 23 24/** 25 * Visits a value and invokes the appropriate method based on its type. Does not traverse 26 * into compound types. Use ValueVisitor for that. 27 */ 28struct RawValueVisitor { 29 virtual ~RawValueVisitor() = default; 30 31 virtual void visitItem(Item* value) {} 32 virtual void visit(Reference* value) { visitItem(value); } 33 virtual void visit(RawString* value) { visitItem(value); } 34 virtual void visit(String* value) { visitItem(value); } 35 virtual void visit(StyledString* value) { visitItem(value); } 36 virtual void visit(FileReference* value) { visitItem(value); } 37 virtual void visit(Id* value) { visitItem(value); } 38 virtual void visit(BinaryPrimitive* value) { visitItem(value); } 39 40 virtual void visit(Attribute* value) {} 41 virtual void visit(Style* value) {} 42 virtual void visit(Array* value) {} 43 virtual void visit(Plural* value) {} 44 virtual void visit(Styleable* value) {} 45}; 46 47#define DECL_VISIT_COMPOUND_VALUE(T) \ 48 virtual void visit(T* value) { \ 49 visitSubValues(value); \ 50 } 51 52/** 53 * Visits values, and if they are compound values, visits the components as well. 54 */ 55struct ValueVisitor : public RawValueVisitor { 56 // The compiler will think we're hiding an overload, when we actually intend 57 // to call into RawValueVisitor. This will expose the visit methods in the super 58 // class so the compiler knows we are trying to call them. 59 using RawValueVisitor::visit; 60 61 void visitSubValues(Attribute* attribute) { 62 for (Attribute::Symbol& symbol : attribute->symbols) { 63 visit(&symbol.symbol); 64 } 65 } 66 67 void visitSubValues(Style* style) { 68 if (style->parent) { 69 visit(&style->parent.value()); 70 } 71 72 for (Style::Entry& entry : style->entries) { 73 visit(&entry.key); 74 entry.value->accept(this); 75 } 76 } 77 78 void visitSubValues(Array* array) { 79 for (std::unique_ptr<Item>& item : array->items) { 80 item->accept(this); 81 } 82 } 83 84 void visitSubValues(Plural* plural) { 85 for (std::unique_ptr<Item>& item : plural->values) { 86 if (item) { 87 item->accept(this); 88 } 89 } 90 } 91 92 void visitSubValues(Styleable* styleable) { 93 for (Reference& reference : styleable->entries) { 94 visit(&reference); 95 } 96 } 97 98 DECL_VISIT_COMPOUND_VALUE(Attribute); 99 DECL_VISIT_COMPOUND_VALUE(Style); 100 DECL_VISIT_COMPOUND_VALUE(Array); 101 DECL_VISIT_COMPOUND_VALUE(Plural); 102 DECL_VISIT_COMPOUND_VALUE(Styleable); 103}; 104 105/** 106 * Do not use directly. Helper struct for dyn_cast. 107 */ 108template <typename T> 109struct DynCastVisitor : public RawValueVisitor { 110 T* value = nullptr; 111 112 void visit(T* v) override { 113 value = v; 114 } 115}; 116 117/** 118 * Specialization that checks if the value is an Item. 119 */ 120template <> 121struct DynCastVisitor<Item> : public RawValueVisitor { 122 Item* value = nullptr; 123 124 void visitItem(Item* item) override { 125 value = item; 126 } 127}; 128 129/** 130 * Returns a valid pointer to T if the Value is of subtype T. 131 * Otherwise, returns nullptr. 132 */ 133template <typename T> 134T* valueCast(Value* value) { 135 if (!value) { 136 return nullptr; 137 } 138 DynCastVisitor<T> visitor; 139 value->accept(&visitor); 140 return visitor.value; 141} 142 143} // namespace aapt 144 145#endif // AAPT_VALUE_VISITOR_H 146