16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License.
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License.
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#ifndef AAPT_RESOURCE_VALUES_H
186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#define AAPT_RESOURCE_VALUES_H
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <array>
21c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski#include <limits>
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <ostream>
23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <vector>
24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
25ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "androidfw/ResourceTypes.h"
26d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h"
27ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
28a587065721053ad54e34f484868142407d59512dAdam Lesinski#include "Diagnostics.h"
296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "Resource.h"
306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "StringPool.h"
31355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski#include "io/File.h"
3293190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski#include "text/Printer.h"
33a587065721053ad54e34f484868142407d59512dAdam Lesinski#include "util/Maybe.h"
346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
37d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinskiclass ValueVisitor;
38d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinskiclass ConstValueVisitor;
396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
407542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// A resource value. This is an all-encompassing representation
417542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// of Item and Map and their subclasses. The way to do
427542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// type specific operations is to check the Value's type() and
437542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// cast it to the appropriate subclass. This isn't super clean,
447542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// but it is the simplest strategy.
455924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinskiclass Value {
465924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski public:
47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  virtual ~Value() = default;
48cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
497542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Whether this value is weak and can be overridden without warning or error. Default is false.
50d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  bool IsWeak() const {
51d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    return weak_;
52d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
54d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void SetWeak(bool val) {
55d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    weak_ = val;
56d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
58d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  // Whether the value is marked as translatable. This does not persist when flattened to binary.
59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // It is only used during compilation phase.
60d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void SetTranslatable(bool val) {
61d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    translatable_ = val;
62d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
64cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Default true.
65d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  bool IsTranslatable() const {
66d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    return translatable_;
67d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
68cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
697542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Returns the source where this value was defined.
70d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  const Source& GetSource() const {
71d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    return source_;
72d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
73cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
74d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void SetSource(const Source& source) {
75d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    source_ = source;
76d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
77cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
78d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void SetSource(Source&& source) {
79d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    source_ = std::move(source);
80d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
81cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
827542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Returns the comment that was associated with this resource.
83d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  const std::string& GetComment() const {
84d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    return comment_;
85d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
87d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void SetComment(const android::StringPiece& str) {
88d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    comment_ = str.to_string();
89d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
91d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void SetComment(std::string&& str) {
92d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    comment_ = std::move(str);
93d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
94cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
95ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  virtual bool Equals(const Value* value) const = 0;
96cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
977542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Calls the appropriate overload of ValueVisitor.
98d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual void Accept(ValueVisitor* visitor) = 0;
99d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
100d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  // Calls the appropriate overload of ConstValueVisitor.
101d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual void Accept(ConstValueVisitor* visitor) const = 0;
102cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
1037542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Clone the value. `new_pool` is the new StringPool that
1047542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // any resources with strings should use when copying their string.
105ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  virtual Value* Clone(StringPool* new_pool) const = 0;
106cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
1077542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Human readable printout of this value.
108ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  virtual void Print(std::ostream* out) const = 0;
109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
11093190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  // Human readable printout of this value that may omit some information for the sake
11193190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  // of brevity and readability. Default implementation just calls Print().
11293190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  virtual void PrettyPrint(text::Printer* printer) const;
11393190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski
1145924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski  friend std::ostream& operator<<(std::ostream& out, const Value& value);
1155924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski
116cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski protected:
117ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Source source_;
118ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::string comment_;
119ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool weak_ = false;
1207542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  bool translatable_ = true;
1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1237542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// Inherit from this to get visitor accepting implementations for free.
1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Derived>
1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct BaseValue : public Value {
126d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Accept(ValueVisitor* visitor) override;
127d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Accept(ConstValueVisitor* visitor) const override;
1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1307542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// A resource item with a single value. This maps to android::ResTable_entry.
1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Item : public Value {
1327542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Clone the Item.
133ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  virtual Item* Clone(StringPool* new_pool) const override = 0;
134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
1357542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Fills in an android::Res_value structure with this Item's binary representation.
1367542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Returns false if an error occurred.
137ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  virtual bool Flatten(android::Res_value* out_value) const = 0;
1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1407542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// Inherit from this to get visitor accepting implementations for free.
1416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Derived>
1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct BaseItem : public Item {
143d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Accept(ValueVisitor* visitor) override;
144d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Accept(ConstValueVisitor* visitor) const override;
1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1477542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
1487542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// A reference can be symbolic (with the name set to a valid resource name) or be
1497542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// numeric (the id is set to a valid resource ID).
1506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Reference : public BaseItem<Reference> {
151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  enum class Type {
152cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    kResource,
153cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    kAttribute,
154cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  };
155cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
156cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Maybe<ResourceName> name;
157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Maybe<ResourceId> id;
158ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Reference::Type reference_type;
159ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool private_reference = false;
160325129964e5b0a9794cf5bb63a2d2d8774ea6a1bTodd Kennedy  bool is_dynamic = false;
161cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
162cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Reference();
163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
164cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  explicit Reference(const ResourceId& i, Type type = Type::kResource);
165ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Reference(const ResourceNameRef& n, const ResourceId& i);
166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
167ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
168ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Flatten(android::Res_value* out_value) const override;
169ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Reference* Clone(StringPool* new_pool) const override;
170ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
17193190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  void PrettyPrint(text::Printer* printer) const override;
17293190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski
17393190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  // Prints the reference without a package name if the package name matches the one given.
17493190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  void PrettyPrint(const android::StringPiece& package, text::Printer* printer) const;
1756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1778197cc460e02c6445434eace435e3d38ebe475c6Adam Lesinskibool operator<(const Reference&, const Reference&);
1788197cc460e02c6445434eace435e3d38ebe475c6Adam Lesinskibool operator==(const Reference&, const Reference&);
1798197cc460e02c6445434eace435e3d38ebe475c6Adam Lesinski
1807542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// An ID resource. Has no real value, just a place holder.
1816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Id : public BaseItem<Id> {
182d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  Id() {
183d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    weak_ = true;
184d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
185d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
186ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
187ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Flatten(android::Res_value* out) const override;
188ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Id* Clone(StringPool* new_pool) const override;
189ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
1906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1927542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace.
1937542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// This shall *NOT* end up in the final resource table.
1946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct RawString : public BaseItem<RawString> {
195cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  StringPool::Ref value;
1966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
197cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  explicit RawString(const StringPool::Ref& ref);
1986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
199ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
200ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Flatten(android::Res_value* out_value) const override;
201ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  RawString* Clone(StringPool* new_pool) const override;
202ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
2036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
2046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2057542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// Identifies a range of characters in a string that are untranslatable.
2067542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// These should not be pseudolocalized. The start and end indices are measured in bytes.
2077542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskistruct UntranslatableSection {
2087542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Start offset inclusive.
2097542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  size_t start;
2107542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2117542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // End offset exclusive.
2127542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  size_t end;
2137542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski};
2147542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2157542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskiinline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) {
2167542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  return a.start == b.start && a.end == b.end;
2177542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski}
2187542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2197542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskiinline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) {
2207542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  return a.start != b.start || a.end != b.end;
2217542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski}
2227542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct String : public BaseItem<String> {
224cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  StringPool::Ref value;
2256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2267542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Sections of the string to NOT translate. Mainly used
2277542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // for pseudolocalization. This data is NOT persisted
2287542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // in any format.
2297542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  std::vector<UntranslatableSection> untranslatable_sections;
2307542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
231cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  explicit String(const StringPool::Ref& ref);
2326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
233ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
234ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Flatten(android::Res_value* out_value) const override;
235ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  String* Clone(StringPool* new_pool) const override;
236ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
23793190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  void PrettyPrint(text::Printer* printer) const override;
2386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
2396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct StyledString : public BaseItem<StyledString> {
241cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  StringPool::StyleRef value;
2426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2437542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // Sections of the string to NOT translate. Mainly used
2447542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // for pseudolocalization. This data is NOT persisted
2457542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // in any format.
2467542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  std::vector<UntranslatableSection> untranslatable_sections;
2477542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
248cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  explicit StyledString(const StringPool::StyleRef& ref);
2496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
250ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
251ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Flatten(android::Res_value* out_value) const override;
252ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  StyledString* Clone(StringPool* new_pool) const override;
253ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
2546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
2556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct FileReference : public BaseItem<FileReference> {
257cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  StringPool::Ref path;
2586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2597542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // A handle to the file object from which this file can be read.
2607542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // This field is NOT persisted in any format. It is transient.
261cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  io::IFile* file = nullptr;
262355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski
263004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  // FileType of the file pointed to by `file`. This is used to know how to inflate the file,
264004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  // or if to inflate at all (just copy).
265004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ResourceFile::Type type = ResourceFile::Type::kUnknown;
266004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
267cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  FileReference() = default;
268cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  explicit FileReference(const StringPool::Ref& path);
2696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
270ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
271ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Flatten(android::Res_value* out_value) const override;
272ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  FileReference* Clone(StringPool* new_pool) const override;
273ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
2746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
2756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2767542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski// Represents any other android::Res_value.
2776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
278cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  android::Res_value value;
2796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
280cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  BinaryPrimitive() = default;
281cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  explicit BinaryPrimitive(const android::Res_value& val);
282cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  BinaryPrimitive(uint8_t dataType, uint32_t data);
2836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
284ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
285ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Flatten(android::Res_value* out_value) const override;
286ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  BinaryPrimitive* Clone(StringPool* new_pool) const override;
287ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
28893190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  void PrettyPrint(text::Printer* printer) const override;
2896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
2906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Attribute : public BaseValue<Attribute> {
292cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  struct Symbol {
293cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    Reference symbol;
294cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    uint32_t value;
2955924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski
2965924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski    friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol);
297cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  };
298cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
299ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  uint32_t type_mask;
300ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  int32_t min_int;
301ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  int32_t max_int;
302cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<Symbol> symbols;
303cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
30473bff1e8519bb73f17a801f45977d41b69b5b0d0Adam Lesinski  explicit Attribute(uint32_t t = 0u);
305cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
306ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
30773bff1e8519bb73f17a801f45977d41b69b5b0d0Adam Lesinski
30873bff1e8519bb73f17a801f45977d41b69b5b0d0Adam Lesinski  // Returns true if this Attribute's format is compatible with the given Attribute. The basic
30973bff1e8519bb73f17a801f45977d41b69b5b0d0Adam Lesinski  // rule is that TYPE_REFERENCE can be ignored for both of the Attributes, and TYPE_FLAGS and
31073bff1e8519bb73f17a801f45977d41b69b5b0d0Adam Lesinski  // TYPE_ENUMS are never compatible.
31173bff1e8519bb73f17a801f45977d41b69b5b0d0Adam Lesinski  bool IsCompatibleWith(const Attribute& attr) const;
31273bff1e8519bb73f17a801f45977d41b69b5b0d0Adam Lesinski
313ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Attribute* Clone(StringPool* new_pool) const override;
31493190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  std::string MaskString() const;
315ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
3163124e7ca0f582c8d54a9b4cf560c25dfef77ac2aAdam Lesinski  bool Matches(const Item& item, DiagMessage* out_msg = nullptr) const;
3176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
3186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Style : public BaseValue<Style> {
320cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  struct Entry {
321cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    Reference key;
322cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    std::unique_ptr<Item> value;
3235924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski
3245924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski    friend std::ostream& operator<<(std::ostream& out, const Entry& entry);
325cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  };
3266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
327cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Maybe<Reference> parent;
328bdaa092a193d8ddccbd9ad8434be97878e6ded59Adam Lesinski
3297542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // If set to true, the parent was auto inferred from the style's name.
330ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool parent_inferred = false;
331bdaa092a193d8ddccbd9ad8434be97878e6ded59Adam Lesinski
332cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<Entry> entries;
3336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
334ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
335ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Style* Clone(StringPool* new_pool) const override;
336ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
3375924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski
3385924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski  // Merges `style` into this Style. All identical attributes of `style` take precedence, including
3395924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski  // the parent, if there is one.
3405924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski  void MergeWith(Style* style, StringPool* pool);
3416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
3426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Array : public BaseValue<Array> {
3444ffea040641d3b74ab04b6d2d3e78280bc893d5fAdam Lesinski  std::vector<std::unique_ptr<Item>> elements;
3456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
346ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
347ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Array* Clone(StringPool* new_pool) const override;
348ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
3496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
3506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Plural : public BaseValue<Plural> {
352cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  enum { Zero = 0, One, Two, Few, Many, Other, Count };
353cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
354cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::array<std::unique_ptr<Item>, Count> values;
355cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
356ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
357ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Plural* Clone(StringPool* new_pool) const override;
358ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
3596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
3606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Styleable : public BaseValue<Styleable> {
362cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<Reference> entries;
3636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
364ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Equals(const Value* value) const override;
365ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Styleable* Clone(StringPool* newPool) const override;
366ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Print(std::ostream* out) const override;
367ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void MergeWith(Styleable* styleable);
3686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
3696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3705924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinskitemplate <typename T>
3715924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinskitypename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<(
3725924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski    std::ostream& out, const std::unique_ptr<T>& value) {
3735924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski  if (value == nullptr) {
3745924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski    out << "NULL";
375cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else {
3765924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski    value->Print(&out);
377cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3785924d8c9ab7bd8614e8bd99864903ce9d50f3bf7Adam Lesinski  return out;
3796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
381cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
3826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
383cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif  // AAPT_RESOURCE_VALUES_H
384