xref: /aosp_15_r20/frameworks/base/tools/aapt2/ResourceValues.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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