/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef AAPT_VALUE_TRANSFORMER_H #define AAPT_VALUE_TRANSFORMER_H #include #include "androidfw/StringPool.h" namespace aapt { class Value; struct Item; struct Reference; struct Id; struct RawString; struct String; struct StyledString; struct FileReference; struct BinaryPrimitive; struct Attribute; struct Style; struct Array; struct Plural; struct Styleable; struct Macro; #define AAPT_TRANSFORM_VALUE(T) \ virtual std::unique_ptr TransformDerived(const T* value) = 0; \ virtual std::unique_ptr TransformValue(const T* value); #define AAPT_TRANSFORM_ITEM(T) \ virtual std::unique_ptr TransformItem(const T* value); \ AAPT_TRANSFORM_VALUE(T) /** * An interface for consuming a Value type and transforming it into another Value. * * The interface defines 2 methods for each type (T) that inherits from TransformableValue: * std::unique_ptr TransformDerived(const T*) * std::unique_ptr TransformValue(const T*) * * The interface defines 3 method for each type (T) that inherits from TransformableItem: * std::unique_ptr TransformDerived(const T*) * std::unique_ptr TransformItem(const T*) * std::unique_ptr TransformValue(const T*) * * TransformDerived is invoked when Transform is invoked on the derived type T. * TransformItem is invoked when Transform is invoked on an Item type. * TransformValue is invoked when Transform is invoked on a Value type. * * ValueTransformerImpl transformer(&string_pool); * T* derived = ...; * std::unique_ptr new_type = derived->Transform(transformer); // Invokes TransformDerived * * Item* item = derived; * std::unique_ptr new_item = item->TransformItem(transformer); // Invokes TransformItem * * Value* value = item; * std::unique_ptr new_value = value->TransformValue(transformer); // Invokes TransformValue * * For types that inherit from AbstractTransformableItem, the default implementation of * TransformValue invokes TransformItem which invokes TransformDerived. * * For types that inherit from AbstractTransformableValue, the default implementation of * TransformValue invokes TransformDerived. */ struct ValueTransformer { // `new_pool` is the new StringPool that newly created Values should use for string storing string // values. explicit ValueTransformer(android::StringPool* new_pool); virtual ~ValueTransformer() = default; AAPT_TRANSFORM_ITEM(Id); AAPT_TRANSFORM_ITEM(Reference); AAPT_TRANSFORM_ITEM(RawString); AAPT_TRANSFORM_ITEM(String); AAPT_TRANSFORM_ITEM(StyledString); AAPT_TRANSFORM_ITEM(FileReference); AAPT_TRANSFORM_ITEM(BinaryPrimitive); AAPT_TRANSFORM_VALUE(Attribute); AAPT_TRANSFORM_VALUE(Style); AAPT_TRANSFORM_VALUE(Array); AAPT_TRANSFORM_VALUE(Plural); AAPT_TRANSFORM_VALUE(Styleable); AAPT_TRANSFORM_VALUE(Macro); protected: android::StringPool* const pool_; }; #undef AAPT_TRANSFORM_VALUE #undef AAPT_TRANSFORM_ITEM template struct TransformableValue : public Base { // Transform this Derived into another Derived using the transformer. std::unique_ptr Transform(ValueTransformer& transformer) const; private: Value* TransformValueImpl(ValueTransformer& transformer) const override; }; template struct TransformableItem : public TransformableValue { private: Item* TransformItemImpl(ValueTransformer& transformer) const override; }; } // namespace aapt // Implementation #include "ValueTransformer_inline.h" #endif // AAPT_VALUE_TRANSFORMER_H