1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker #ifndef AAPT_RESOURCE_VALUES_H 18*d57664e9SAndroid Build Coastguard Worker #define AAPT_RESOURCE_VALUES_H 19*d57664e9SAndroid Build Coastguard Worker 20*d57664e9SAndroid Build Coastguard Worker #include <array> 21*d57664e9SAndroid Build Coastguard Worker #include <limits> 22*d57664e9SAndroid Build Coastguard Worker #include <ostream> 23*d57664e9SAndroid Build Coastguard Worker #include <vector> 24*d57664e9SAndroid Build Coastguard Worker 25*d57664e9SAndroid Build Coastguard Worker #include "Resource.h" 26*d57664e9SAndroid Build Coastguard Worker #include "ValueTransformer.h" 27*d57664e9SAndroid Build Coastguard Worker #include "androidfw/IDiagnostics.h" 28*d57664e9SAndroid Build Coastguard Worker #include "androidfw/ResourceTypes.h" 29*d57664e9SAndroid Build Coastguard Worker #include "androidfw/StringPiece.h" 30*d57664e9SAndroid Build Coastguard Worker #include "androidfw/StringPool.h" 31*d57664e9SAndroid Build Coastguard Worker #include "io/File.h" 32*d57664e9SAndroid Build Coastguard Worker #include "text/Printer.h" 33*d57664e9SAndroid Build Coastguard Worker 34*d57664e9SAndroid Build Coastguard Worker namespace aapt { 35*d57664e9SAndroid Build Coastguard Worker 36*d57664e9SAndroid Build Coastguard Worker class ValueVisitor; 37*d57664e9SAndroid Build Coastguard Worker class ConstValueVisitor; 38*d57664e9SAndroid Build Coastguard Worker 39*d57664e9SAndroid Build Coastguard Worker // A resource value. This is an all-encompassing representation 40*d57664e9SAndroid Build Coastguard Worker // of Item and Map and their subclasses. The way to do 41*d57664e9SAndroid Build Coastguard Worker // type specific operations is to check the Value's type() and 42*d57664e9SAndroid Build Coastguard Worker // cast it to the appropriate subclass. This isn't super clean, 43*d57664e9SAndroid Build Coastguard Worker // but it is the simplest strategy. 44*d57664e9SAndroid Build Coastguard Worker class Value { 45*d57664e9SAndroid Build Coastguard Worker public: 46*d57664e9SAndroid Build Coastguard Worker virtual ~Value() = default; 47*d57664e9SAndroid Build Coastguard Worker 48*d57664e9SAndroid Build Coastguard Worker // Whether this value is weak and can be overridden without warning or error. Default is false. IsWeak()49*d57664e9SAndroid Build Coastguard Worker bool IsWeak() const { 50*d57664e9SAndroid Build Coastguard Worker return weak_; 51*d57664e9SAndroid Build Coastguard Worker } 52*d57664e9SAndroid Build Coastguard Worker SetWeak(bool val)53*d57664e9SAndroid Build Coastguard Worker void SetWeak(bool val) { 54*d57664e9SAndroid Build Coastguard Worker weak_ = val; 55*d57664e9SAndroid Build Coastguard Worker } 56*d57664e9SAndroid Build Coastguard Worker 57*d57664e9SAndroid Build Coastguard Worker // Whether the value is marked as translatable. This does not persist when flattened to binary. 58*d57664e9SAndroid Build Coastguard Worker // It is only used during compilation phase. SetTranslatable(bool val)59*d57664e9SAndroid Build Coastguard Worker void SetTranslatable(bool val) { 60*d57664e9SAndroid Build Coastguard Worker translatable_ = val; 61*d57664e9SAndroid Build Coastguard Worker } 62*d57664e9SAndroid Build Coastguard Worker 63*d57664e9SAndroid Build Coastguard Worker // Default true. IsTranslatable()64*d57664e9SAndroid Build Coastguard Worker bool IsTranslatable() const { 65*d57664e9SAndroid Build Coastguard Worker return translatable_; 66*d57664e9SAndroid Build Coastguard Worker } 67*d57664e9SAndroid Build Coastguard Worker SetFlag(std::optional<FeatureFlagAttribute> val)68*d57664e9SAndroid Build Coastguard Worker void SetFlag(std::optional<FeatureFlagAttribute> val) { 69*d57664e9SAndroid Build Coastguard Worker flag_ = val; 70*d57664e9SAndroid Build Coastguard Worker } 71*d57664e9SAndroid Build Coastguard Worker GetFlag()72*d57664e9SAndroid Build Coastguard Worker std::optional<FeatureFlagAttribute> GetFlag() const { 73*d57664e9SAndroid Build Coastguard Worker return flag_; 74*d57664e9SAndroid Build Coastguard Worker } 75*d57664e9SAndroid Build Coastguard Worker SetFlagStatus(FlagStatus val)76*d57664e9SAndroid Build Coastguard Worker void SetFlagStatus(FlagStatus val) { 77*d57664e9SAndroid Build Coastguard Worker flag_status_ = val; 78*d57664e9SAndroid Build Coastguard Worker } 79*d57664e9SAndroid Build Coastguard Worker 80*d57664e9SAndroid Build Coastguard Worker // If the value is behind a flag this returns whether that flag was enabled when the value was 81*d57664e9SAndroid Build Coastguard Worker // parsed by comparing it to the flags passed on the command line to aapt2 (taking into account 82*d57664e9SAndroid Build Coastguard Worker // negation if necessary). If there was no flag, FlagStatus::NoFlag is returned instead. GetFlagStatus()83*d57664e9SAndroid Build Coastguard Worker FlagStatus GetFlagStatus() const { 84*d57664e9SAndroid Build Coastguard Worker return flag_status_; 85*d57664e9SAndroid Build Coastguard Worker } 86*d57664e9SAndroid Build Coastguard Worker 87*d57664e9SAndroid Build Coastguard Worker // Returns the source where this value was defined. GetSource()88*d57664e9SAndroid Build Coastguard Worker const android::Source& GetSource() const { 89*d57664e9SAndroid Build Coastguard Worker return source_; 90*d57664e9SAndroid Build Coastguard Worker } 91*d57664e9SAndroid Build Coastguard Worker SetSource(const android::Source & source)92*d57664e9SAndroid Build Coastguard Worker void SetSource(const android::Source& source) { 93*d57664e9SAndroid Build Coastguard Worker source_ = source; 94*d57664e9SAndroid Build Coastguard Worker } 95*d57664e9SAndroid Build Coastguard Worker SetSource(android::Source && source)96*d57664e9SAndroid Build Coastguard Worker void SetSource(android::Source&& source) { 97*d57664e9SAndroid Build Coastguard Worker source_ = std::move(source); 98*d57664e9SAndroid Build Coastguard Worker } 99*d57664e9SAndroid Build Coastguard Worker 100*d57664e9SAndroid Build Coastguard Worker // Returns the comment that was associated with this resource. GetComment()101*d57664e9SAndroid Build Coastguard Worker const std::string& GetComment() const { 102*d57664e9SAndroid Build Coastguard Worker return comment_; 103*d57664e9SAndroid Build Coastguard Worker } 104*d57664e9SAndroid Build Coastguard Worker SetComment(android::StringPiece str)105*d57664e9SAndroid Build Coastguard Worker void SetComment(android::StringPiece str) { 106*d57664e9SAndroid Build Coastguard Worker comment_.assign(str); 107*d57664e9SAndroid Build Coastguard Worker } 108*d57664e9SAndroid Build Coastguard Worker SetComment(std::string && str)109*d57664e9SAndroid Build Coastguard Worker void SetComment(std::string&& str) { 110*d57664e9SAndroid Build Coastguard Worker comment_ = std::move(str); 111*d57664e9SAndroid Build Coastguard Worker } 112*d57664e9SAndroid Build Coastguard Worker 113*d57664e9SAndroid Build Coastguard Worker virtual bool Equals(const Value* value) const = 0; 114*d57664e9SAndroid Build Coastguard Worker 115*d57664e9SAndroid Build Coastguard Worker // Calls the appropriate overload of ValueVisitor. 116*d57664e9SAndroid Build Coastguard Worker virtual void Accept(ValueVisitor* visitor) = 0; 117*d57664e9SAndroid Build Coastguard Worker 118*d57664e9SAndroid Build Coastguard Worker // Calls the appropriate overload of ConstValueVisitor. 119*d57664e9SAndroid Build Coastguard Worker virtual void Accept(ConstValueVisitor* visitor) const = 0; 120*d57664e9SAndroid Build Coastguard Worker 121*d57664e9SAndroid Build Coastguard Worker // Transform this Value into another Value using the transformer. 122*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Value> Transform(ValueTransformer& transformer) const; 123*d57664e9SAndroid Build Coastguard Worker 124*d57664e9SAndroid Build Coastguard Worker // Human readable printout of this value. 125*d57664e9SAndroid Build Coastguard Worker virtual void Print(std::ostream* out) const = 0; 126*d57664e9SAndroid Build Coastguard Worker 127*d57664e9SAndroid Build Coastguard Worker // Human readable printout of this value that may omit some information for the sake 128*d57664e9SAndroid Build Coastguard Worker // of brevity and readability. Default implementation just calls Print(). 129*d57664e9SAndroid Build Coastguard Worker virtual void PrettyPrint(text::Printer* printer) const; 130*d57664e9SAndroid Build Coastguard Worker 131*d57664e9SAndroid Build Coastguard Worker // Removes any part of the value that is beind a disabled flag. RemoveFlagDisabledElements()132*d57664e9SAndroid Build Coastguard Worker virtual void RemoveFlagDisabledElements() { 133*d57664e9SAndroid Build Coastguard Worker } 134*d57664e9SAndroid Build Coastguard Worker 135*d57664e9SAndroid Build Coastguard Worker friend std::ostream& operator<<(std::ostream& out, const Value& value); 136*d57664e9SAndroid Build Coastguard Worker 137*d57664e9SAndroid Build Coastguard Worker protected: 138*d57664e9SAndroid Build Coastguard Worker android::Source source_; 139*d57664e9SAndroid Build Coastguard Worker std::string comment_; 140*d57664e9SAndroid Build Coastguard Worker bool weak_ = false; 141*d57664e9SAndroid Build Coastguard Worker bool translatable_ = true; 142*d57664e9SAndroid Build Coastguard Worker std::optional<FeatureFlagAttribute> flag_; 143*d57664e9SAndroid Build Coastguard Worker FlagStatus flag_status_ = FlagStatus::NoFlag; 144*d57664e9SAndroid Build Coastguard Worker 145*d57664e9SAndroid Build Coastguard Worker private: 146*d57664e9SAndroid Build Coastguard Worker virtual Value* TransformValueImpl(ValueTransformer& transformer) const = 0; 147*d57664e9SAndroid Build Coastguard Worker }; 148*d57664e9SAndroid Build Coastguard Worker 149*d57664e9SAndroid Build Coastguard Worker // Inherit from this to get visitor accepting implementations for free. 150*d57664e9SAndroid Build Coastguard Worker template <typename Derived> 151*d57664e9SAndroid Build Coastguard Worker struct BaseValue : public Value { 152*d57664e9SAndroid Build Coastguard Worker void Accept(ValueVisitor* visitor) override; 153*d57664e9SAndroid Build Coastguard Worker void Accept(ConstValueVisitor* visitor) const override; 154*d57664e9SAndroid Build Coastguard Worker }; 155*d57664e9SAndroid Build Coastguard Worker 156*d57664e9SAndroid Build Coastguard Worker // A resource item with a single value. This maps to android::ResTable_entry. 157*d57664e9SAndroid Build Coastguard Worker struct Item : public Value { 158*d57664e9SAndroid Build Coastguard Worker // Fills in an android::Res_value structure with this Item's binary representation. 159*d57664e9SAndroid Build Coastguard Worker // Returns false if an error occurred. 160*d57664e9SAndroid Build Coastguard Worker virtual bool Flatten(android::Res_value* out_value) const = 0; 161*d57664e9SAndroid Build Coastguard Worker 162*d57664e9SAndroid Build Coastguard Worker // Transform this Item into another Item using the transformer. 163*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Item> Transform(ValueTransformer& transformer) const; 164*d57664e9SAndroid Build Coastguard Worker 165*d57664e9SAndroid Build Coastguard Worker private: 166*d57664e9SAndroid Build Coastguard Worker virtual Item* TransformItemImpl(ValueTransformer& transformer) const = 0; 167*d57664e9SAndroid Build Coastguard Worker }; 168*d57664e9SAndroid Build Coastguard Worker 169*d57664e9SAndroid Build Coastguard Worker // Inherit from this to get visitor accepting implementations for free. 170*d57664e9SAndroid Build Coastguard Worker template <typename Derived> 171*d57664e9SAndroid Build Coastguard Worker struct BaseItem : public Item { 172*d57664e9SAndroid Build Coastguard Worker void Accept(ValueVisitor* visitor) override; 173*d57664e9SAndroid Build Coastguard Worker void Accept(ConstValueVisitor* visitor) const override; 174*d57664e9SAndroid Build Coastguard Worker }; 175*d57664e9SAndroid Build Coastguard Worker 176*d57664e9SAndroid Build Coastguard Worker // A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE. 177*d57664e9SAndroid Build Coastguard Worker // A reference can be symbolic (with the name set to a valid resource name) or be 178*d57664e9SAndroid Build Coastguard Worker // numeric (the id is set to a valid resource ID). 179*d57664e9SAndroid Build Coastguard Worker struct Reference : public TransformableItem<Reference, BaseItem<Reference>> { 180*d57664e9SAndroid Build Coastguard Worker enum class Type : uint8_t { 181*d57664e9SAndroid Build Coastguard Worker kResource, 182*d57664e9SAndroid Build Coastguard Worker kAttribute, 183*d57664e9SAndroid Build Coastguard Worker }; 184*d57664e9SAndroid Build Coastguard Worker 185*d57664e9SAndroid Build Coastguard Worker std::optional<ResourceName> name; 186*d57664e9SAndroid Build Coastguard Worker std::optional<ResourceId> id; 187*d57664e9SAndroid Build Coastguard Worker std::optional<uint32_t> type_flags; 188*d57664e9SAndroid Build Coastguard Worker Reference::Type reference_type; 189*d57664e9SAndroid Build Coastguard Worker bool private_reference = false; 190*d57664e9SAndroid Build Coastguard Worker bool is_dynamic = false; 191*d57664e9SAndroid Build Coastguard Worker bool allow_raw = false; 192*d57664e9SAndroid Build Coastguard Worker 193*d57664e9SAndroid Build Coastguard Worker Reference(); 194*d57664e9SAndroid Build Coastguard Worker explicit Reference(const ResourceNameRef& n, Type type = Type::kResource); 195*d57664e9SAndroid Build Coastguard Worker explicit Reference(const ResourceId& i, Type type = Type::kResource); 196*d57664e9SAndroid Build Coastguard Worker Reference(const ResourceNameRef& n, const ResourceId& i); 197*d57664e9SAndroid Build Coastguard Worker 198*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 199*d57664e9SAndroid Build Coastguard Worker bool Flatten(android::Res_value* out_value) const override; 200*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 201*d57664e9SAndroid Build Coastguard Worker void PrettyPrint(text::Printer* printer) const override; 202*d57664e9SAndroid Build Coastguard Worker 203*d57664e9SAndroid Build Coastguard Worker // Prints the reference without a package name if the package name matches the one given. 204*d57664e9SAndroid Build Coastguard Worker void PrettyPrint(android::StringPiece package, text::Printer* printer) const; 205*d57664e9SAndroid Build Coastguard Worker }; 206*d57664e9SAndroid Build Coastguard Worker 207*d57664e9SAndroid Build Coastguard Worker bool operator<(const Reference&, const Reference&); 208*d57664e9SAndroid Build Coastguard Worker bool operator==(const Reference&, const Reference&); 209*d57664e9SAndroid Build Coastguard Worker 210*d57664e9SAndroid Build Coastguard Worker // An ID resource. Has no real value, just a place holder. 211*d57664e9SAndroid Build Coastguard Worker struct Id : public TransformableItem<Id, BaseItem<Id>> { IdId212*d57664e9SAndroid Build Coastguard Worker Id() { 213*d57664e9SAndroid Build Coastguard Worker weak_ = true; 214*d57664e9SAndroid Build Coastguard Worker } 215*d57664e9SAndroid Build Coastguard Worker 216*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 217*d57664e9SAndroid Build Coastguard Worker bool Flatten(android::Res_value* out) const override; 218*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 219*d57664e9SAndroid Build Coastguard Worker }; 220*d57664e9SAndroid Build Coastguard Worker 221*d57664e9SAndroid Build Coastguard Worker // A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace. 222*d57664e9SAndroid Build Coastguard Worker // This shall *NOT* end up in the final resource table. 223*d57664e9SAndroid Build Coastguard Worker struct RawString : public TransformableItem<RawString, BaseItem<RawString>> { 224*d57664e9SAndroid Build Coastguard Worker android::StringPool::Ref value; 225*d57664e9SAndroid Build Coastguard Worker 226*d57664e9SAndroid Build Coastguard Worker explicit RawString(const android::StringPool::Ref& ref); 227*d57664e9SAndroid Build Coastguard Worker 228*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 229*d57664e9SAndroid Build Coastguard Worker bool Flatten(android::Res_value* out_value) const override; 230*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 231*d57664e9SAndroid Build Coastguard Worker }; 232*d57664e9SAndroid Build Coastguard Worker 233*d57664e9SAndroid Build Coastguard Worker // Identifies a range of characters in a string that are untranslatable. 234*d57664e9SAndroid Build Coastguard Worker // These should not be pseudolocalized. The start and end indices are measured in bytes. 235*d57664e9SAndroid Build Coastguard Worker struct UntranslatableSection { 236*d57664e9SAndroid Build Coastguard Worker // Start offset inclusive. 237*d57664e9SAndroid Build Coastguard Worker size_t start; 238*d57664e9SAndroid Build Coastguard Worker 239*d57664e9SAndroid Build Coastguard Worker // End offset exclusive. 240*d57664e9SAndroid Build Coastguard Worker size_t end; 241*d57664e9SAndroid Build Coastguard Worker }; 242*d57664e9SAndroid Build Coastguard Worker 243*d57664e9SAndroid Build Coastguard Worker inline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) { 244*d57664e9SAndroid Build Coastguard Worker return a.start == b.start && a.end == b.end; 245*d57664e9SAndroid Build Coastguard Worker } 246*d57664e9SAndroid Build Coastguard Worker 247*d57664e9SAndroid Build Coastguard Worker inline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) { 248*d57664e9SAndroid Build Coastguard Worker return a.start != b.start || a.end != b.end; 249*d57664e9SAndroid Build Coastguard Worker } 250*d57664e9SAndroid Build Coastguard Worker 251*d57664e9SAndroid Build Coastguard Worker struct String : public TransformableItem<String, BaseItem<String>> { 252*d57664e9SAndroid Build Coastguard Worker android::StringPool::Ref value; 253*d57664e9SAndroid Build Coastguard Worker 254*d57664e9SAndroid Build Coastguard Worker // Sections of the string to NOT translate. Mainly used 255*d57664e9SAndroid Build Coastguard Worker // for pseudolocalization. This data is NOT persisted 256*d57664e9SAndroid Build Coastguard Worker // in any format. 257*d57664e9SAndroid Build Coastguard Worker std::vector<UntranslatableSection> untranslatable_sections; 258*d57664e9SAndroid Build Coastguard Worker 259*d57664e9SAndroid Build Coastguard Worker explicit String(const android::StringPool::Ref& ref); 260*d57664e9SAndroid Build Coastguard Worker 261*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 262*d57664e9SAndroid Build Coastguard Worker bool Flatten(android::Res_value* out_value) const override; 263*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 264*d57664e9SAndroid Build Coastguard Worker void PrettyPrint(text::Printer* printer) const override; 265*d57664e9SAndroid Build Coastguard Worker }; 266*d57664e9SAndroid Build Coastguard Worker 267*d57664e9SAndroid Build Coastguard Worker struct StyledString : public TransformableItem<StyledString, BaseItem<StyledString>> { 268*d57664e9SAndroid Build Coastguard Worker android::StringPool::StyleRef value; 269*d57664e9SAndroid Build Coastguard Worker 270*d57664e9SAndroid Build Coastguard Worker // Sections of the string to NOT translate. Mainly used 271*d57664e9SAndroid Build Coastguard Worker // for pseudolocalization. This data is NOT persisted 272*d57664e9SAndroid Build Coastguard Worker // in any format. 273*d57664e9SAndroid Build Coastguard Worker std::vector<UntranslatableSection> untranslatable_sections; 274*d57664e9SAndroid Build Coastguard Worker 275*d57664e9SAndroid Build Coastguard Worker explicit StyledString(const android::StringPool::StyleRef& ref); 276*d57664e9SAndroid Build Coastguard Worker 277*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 278*d57664e9SAndroid Build Coastguard Worker bool Flatten(android::Res_value* out_value) const override; 279*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 280*d57664e9SAndroid Build Coastguard Worker }; 281*d57664e9SAndroid Build Coastguard Worker 282*d57664e9SAndroid Build Coastguard Worker struct FileReference : public TransformableItem<FileReference, BaseItem<FileReference>> { 283*d57664e9SAndroid Build Coastguard Worker android::StringPool::Ref path; 284*d57664e9SAndroid Build Coastguard Worker 285*d57664e9SAndroid Build Coastguard Worker // A handle to the file object from which this file can be read. 286*d57664e9SAndroid Build Coastguard Worker // This field is NOT persisted in any format. It is transient. 287*d57664e9SAndroid Build Coastguard Worker io::IFile* file = nullptr; 288*d57664e9SAndroid Build Coastguard Worker 289*d57664e9SAndroid Build Coastguard Worker // FileType of the file pointed to by `file`. This is used to know how to inflate the file, 290*d57664e9SAndroid Build Coastguard Worker // or if to inflate at all (just copy). 291*d57664e9SAndroid Build Coastguard Worker ResourceFile::Type type = ResourceFile::Type::kUnknown; 292*d57664e9SAndroid Build Coastguard Worker 293*d57664e9SAndroid Build Coastguard Worker FileReference() = default; 294*d57664e9SAndroid Build Coastguard Worker explicit FileReference(const android::StringPool::Ref& path); 295*d57664e9SAndroid Build Coastguard Worker 296*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 297*d57664e9SAndroid Build Coastguard Worker bool Flatten(android::Res_value* out_value) const override; 298*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 299*d57664e9SAndroid Build Coastguard Worker }; 300*d57664e9SAndroid Build Coastguard Worker 301*d57664e9SAndroid Build Coastguard Worker // Represents any other android::Res_value. 302*d57664e9SAndroid Build Coastguard Worker struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<BinaryPrimitive>> { 303*d57664e9SAndroid Build Coastguard Worker android::Res_value value; 304*d57664e9SAndroid Build Coastguard Worker 305*d57664e9SAndroid Build Coastguard Worker BinaryPrimitive() = default; 306*d57664e9SAndroid Build Coastguard Worker explicit BinaryPrimitive(const android::Res_value& val); 307*d57664e9SAndroid Build Coastguard Worker BinaryPrimitive(uint8_t dataType, uint32_t data); 308*d57664e9SAndroid Build Coastguard Worker 309*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 310*d57664e9SAndroid Build Coastguard Worker bool Flatten(android::Res_value* out_value) const override; 311*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 312*d57664e9SAndroid Build Coastguard Worker static const char* DecideFormat(float f); 313*d57664e9SAndroid Build Coastguard Worker void PrettyPrint(text::Printer* printer) const override; 314*d57664e9SAndroid Build Coastguard Worker }; 315*d57664e9SAndroid Build Coastguard Worker 316*d57664e9SAndroid Build Coastguard Worker struct Attribute : public TransformableValue<Attribute, BaseValue<Attribute>> { 317*d57664e9SAndroid Build Coastguard Worker struct Symbol { 318*d57664e9SAndroid Build Coastguard Worker Reference symbol; 319*d57664e9SAndroid Build Coastguard Worker uint32_t value; 320*d57664e9SAndroid Build Coastguard Worker uint8_t type; 321*d57664e9SAndroid Build Coastguard Worker 322*d57664e9SAndroid Build Coastguard Worker friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol); 323*d57664e9SAndroid Build Coastguard Worker }; 324*d57664e9SAndroid Build Coastguard Worker 325*d57664e9SAndroid Build Coastguard Worker uint32_t type_mask; 326*d57664e9SAndroid Build Coastguard Worker int32_t min_int; 327*d57664e9SAndroid Build Coastguard Worker int32_t max_int; 328*d57664e9SAndroid Build Coastguard Worker std::vector<Symbol> symbols; 329*d57664e9SAndroid Build Coastguard Worker 330*d57664e9SAndroid Build Coastguard Worker explicit Attribute(uint32_t t = 0u); 331*d57664e9SAndroid Build Coastguard Worker 332*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 333*d57664e9SAndroid Build Coastguard Worker 334*d57664e9SAndroid Build Coastguard Worker // Returns true if this Attribute's format is compatible with the given Attribute. The basic 335*d57664e9SAndroid Build Coastguard Worker // rule is that TYPE_REFERENCE can be ignored for both of the Attributes, and TYPE_FLAGS and 336*d57664e9SAndroid Build Coastguard Worker // TYPE_ENUMS are never compatible. 337*d57664e9SAndroid Build Coastguard Worker bool IsCompatibleWith(const Attribute& attr) const; 338*d57664e9SAndroid Build Coastguard Worker 339*d57664e9SAndroid Build Coastguard Worker std::string MaskString() const; 340*d57664e9SAndroid Build Coastguard Worker static std::string MaskString(uint32_t type_mask); 341*d57664e9SAndroid Build Coastguard Worker 342*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 343*d57664e9SAndroid Build Coastguard Worker bool Matches(const Item& item, android::DiagMessage* out_msg = nullptr) const; 344*d57664e9SAndroid Build Coastguard Worker }; 345*d57664e9SAndroid Build Coastguard Worker 346*d57664e9SAndroid Build Coastguard Worker struct Style : public TransformableValue<Style, BaseValue<Style>> { 347*d57664e9SAndroid Build Coastguard Worker struct Entry { 348*d57664e9SAndroid Build Coastguard Worker Reference key; 349*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Item> value; 350*d57664e9SAndroid Build Coastguard Worker 351*d57664e9SAndroid Build Coastguard Worker friend std::ostream& operator<<(std::ostream& out, const Entry& entry); 352*d57664e9SAndroid Build Coastguard Worker }; 353*d57664e9SAndroid Build Coastguard Worker 354*d57664e9SAndroid Build Coastguard Worker std::optional<Reference> parent; 355*d57664e9SAndroid Build Coastguard Worker 356*d57664e9SAndroid Build Coastguard Worker // If set to true, the parent was auto inferred from the style's name. 357*d57664e9SAndroid Build Coastguard Worker bool parent_inferred = false; 358*d57664e9SAndroid Build Coastguard Worker 359*d57664e9SAndroid Build Coastguard Worker std::vector<Entry> entries; 360*d57664e9SAndroid Build Coastguard Worker 361*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 362*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 363*d57664e9SAndroid Build Coastguard Worker 364*d57664e9SAndroid Build Coastguard Worker // Merges `style` into this Style. All identical attributes of `style` take precedence, including 365*d57664e9SAndroid Build Coastguard Worker // the parent, if there is one. 366*d57664e9SAndroid Build Coastguard Worker void MergeWith(Style* style, android::StringPool* pool); 367*d57664e9SAndroid Build Coastguard Worker }; 368*d57664e9SAndroid Build Coastguard Worker 369*d57664e9SAndroid Build Coastguard Worker struct Array : public TransformableValue<Array, BaseValue<Array>> { 370*d57664e9SAndroid Build Coastguard Worker std::vector<std::unique_ptr<Item>> elements; 371*d57664e9SAndroid Build Coastguard Worker 372*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 373*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 374*d57664e9SAndroid Build Coastguard Worker void RemoveFlagDisabledElements() override; 375*d57664e9SAndroid Build Coastguard Worker }; 376*d57664e9SAndroid Build Coastguard Worker 377*d57664e9SAndroid Build Coastguard Worker struct Plural : public TransformableValue<Plural, BaseValue<Plural>> { 378*d57664e9SAndroid Build Coastguard Worker enum { Zero = 0, One, Two, Few, Many, Other, Count }; 379*d57664e9SAndroid Build Coastguard Worker 380*d57664e9SAndroid Build Coastguard Worker std::array<std::unique_ptr<Item>, Count> values; 381*d57664e9SAndroid Build Coastguard Worker 382*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 383*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 384*d57664e9SAndroid Build Coastguard Worker }; 385*d57664e9SAndroid Build Coastguard Worker 386*d57664e9SAndroid Build Coastguard Worker struct Styleable : public TransformableValue<Styleable, BaseValue<Styleable>> { 387*d57664e9SAndroid Build Coastguard Worker std::vector<Reference> entries; 388*d57664e9SAndroid Build Coastguard Worker 389*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 390*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 391*d57664e9SAndroid Build Coastguard Worker void MergeWith(Styleable* styleable); 392*d57664e9SAndroid Build Coastguard Worker }; 393*d57664e9SAndroid Build Coastguard Worker 394*d57664e9SAndroid Build Coastguard Worker struct Macro : public TransformableValue<Macro, BaseValue<Macro>> { 395*d57664e9SAndroid Build Coastguard Worker std::string raw_value; 396*d57664e9SAndroid Build Coastguard Worker android::StyleString style_string; 397*d57664e9SAndroid Build Coastguard Worker std::vector<UntranslatableSection> untranslatable_sections; 398*d57664e9SAndroid Build Coastguard Worker 399*d57664e9SAndroid Build Coastguard Worker struct Namespace { 400*d57664e9SAndroid Build Coastguard Worker std::string alias; 401*d57664e9SAndroid Build Coastguard Worker std::string package_name; 402*d57664e9SAndroid Build Coastguard Worker bool is_private; 403*d57664e9SAndroid Build Coastguard Worker 404*d57664e9SAndroid Build Coastguard Worker bool operator==(const Namespace& right) const { 405*d57664e9SAndroid Build Coastguard Worker return alias == right.alias && package_name == right.package_name && 406*d57664e9SAndroid Build Coastguard Worker is_private == right.is_private; 407*d57664e9SAndroid Build Coastguard Worker } 408*d57664e9SAndroid Build Coastguard Worker }; 409*d57664e9SAndroid Build Coastguard Worker 410*d57664e9SAndroid Build Coastguard Worker std::vector<Namespace> alias_namespaces; 411*d57664e9SAndroid Build Coastguard Worker 412*d57664e9SAndroid Build Coastguard Worker bool Equals(const Value* value) const override; 413*d57664e9SAndroid Build Coastguard Worker void Print(std::ostream* out) const override; 414*d57664e9SAndroid Build Coastguard Worker }; 415*d57664e9SAndroid Build Coastguard Worker 416*d57664e9SAndroid Build Coastguard Worker template <typename T> 417*d57664e9SAndroid Build Coastguard Worker typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<( 418*d57664e9SAndroid Build Coastguard Worker std::ostream& out, const std::unique_ptr<T>& value) { 419*d57664e9SAndroid Build Coastguard Worker if (value == nullptr) { 420*d57664e9SAndroid Build Coastguard Worker out << "NULL"; 421*d57664e9SAndroid Build Coastguard Worker } else { 422*d57664e9SAndroid Build Coastguard Worker value->Print(&out); 423*d57664e9SAndroid Build Coastguard Worker } 424*d57664e9SAndroid Build Coastguard Worker return out; 425*d57664e9SAndroid Build Coastguard Worker } 426*d57664e9SAndroid Build Coastguard Worker 427*d57664e9SAndroid Build Coastguard Worker struct CloningValueTransformer : public ValueTransformer { 428*d57664e9SAndroid Build Coastguard Worker explicit CloningValueTransformer(android::StringPool* new_pool); 429*d57664e9SAndroid Build Coastguard Worker 430*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Reference> TransformDerived(const Reference* value) override; 431*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Id> TransformDerived(const Id* value) override; 432*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<RawString> TransformDerived(const RawString* value) override; 433*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<String> TransformDerived(const String* value) override; 434*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<StyledString> TransformDerived(const StyledString* value) override; 435*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<FileReference> TransformDerived(const FileReference* value) override; 436*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<BinaryPrimitive> TransformDerived(const BinaryPrimitive* value) override; 437*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Attribute> TransformDerived(const Attribute* value) override; 438*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> TransformDerived(const Style* value) override; 439*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Array> TransformDerived(const Array* value) override; 440*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Plural> TransformDerived(const Plural* value) override; 441*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Styleable> TransformDerived(const Styleable* value) override; 442*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Macro> TransformDerived(const Macro* value) override; 443*d57664e9SAndroid Build Coastguard Worker }; 444*d57664e9SAndroid Build Coastguard Worker 445*d57664e9SAndroid Build Coastguard Worker } // namespace aapt 446*d57664e9SAndroid Build Coastguard Worker 447*d57664e9SAndroid Build Coastguard Worker #endif // AAPT_RESOURCE_VALUES_H 448