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