175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/*
275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Copyright (C) 2015 The Android Open Source Project
375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *
475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * you may not use this file except in compliance with the License.
675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * You may obtain a copy of the License at
775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *
875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *
1075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Unless required by applicable law or agreed to in writing, software
1175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
1275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * See the License for the specific language governing permissions and
1475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * limitations under the License.
1575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
1675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
1775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#ifndef AAPT_XML_DOM_H
1875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#define AAPT_XML_DOM_H
1975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <memory>
21ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <string>
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <vector>
23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
24d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h"
25d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski
261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Diagnostics.h"
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Resource.h"
281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ResourceValues.h"
29efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski#include "io/Io.h"
301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h"
31467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlUtil.h"
3275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
3375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace aapt {
3475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace xml {
3575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
36c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinskiclass Element;
376b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskiclass Visitor;
38d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinskiclass ConstVisitor;
39c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski
40efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// Base class for all XML nodes.
415eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Node {
42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  virtual ~Node() = default;
44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
456b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  Element* parent = nullptr;
466b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  size_t line_number = 0u;
476b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  size_t column_number = 0u;
486b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::string comment;
496b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
506b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  virtual void Accept(Visitor* visitor) = 0;
51d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual void Accept(ConstVisitor* visitor) const = 0;
52c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski
53c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  using ElementCloneFunc = std::function<void(const Element&, Element*)>;
54c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski
55c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  // Clones the Node subtree, using the given function to decide how to clone an Element.
566b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  virtual std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const = 0;
5775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
5875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
596b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski// A namespace declaration (xmlns:prefix="uri").
606b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskistruct NamespaceDecl {
616b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::string prefix;
626b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::string uri;
636b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  size_t line_number = 0u;
646b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  size_t column_number = 0u;
651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
6675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct AaptAttribute {
68c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  explicit AaptAttribute(const ::aapt::Attribute& attr, const Maybe<ResourceId>& resid = {})
69c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski      : attribute(attr), id(resid) {
70c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  }
71c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski
72cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  aapt::Attribute attribute;
73c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  Maybe<ResourceId> id;
7475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
7575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
76efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// An XML attribute.
7775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Attribute {
78ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::string namespace_uri;
79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string name;
80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string value;
811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
82ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Maybe<AaptAttribute> compiled_attribute;
83ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::unique_ptr<Item> compiled_value;
8475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
8575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
86efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// An Element XML node.
876b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskiclass Element : public Node {
88cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
896b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  // Ordered namespace prefix declarations.
906b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::vector<NamespaceDecl> namespace_decls;
916b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
92ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::string namespace_uri;
93cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string name;
94cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<Attribute> attributes;
956b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::vector<std::unique_ptr<Node>> children;
966b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
976b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  void AppendChild(std::unique_ptr<Node> child);
986b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  void InsertChild(size_t index, std::unique_ptr<Node> child);
99cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
100d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  Attribute* FindAttribute(const android::StringPiece& ns, const android::StringPiece& name);
101c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  const Attribute* FindAttribute(const android::StringPiece& ns,
102c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski                                 const android::StringPiece& name) const;
103c6284379a5dde6bc5927409eff292db2f0add578Adam Lesinski  Attribute* FindOrCreateAttribute(const android::StringPiece& ns,
104c6284379a5dde6bc5927409eff292db2f0add578Adam Lesinski                                   const android::StringPiece& name);
1058780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski
1066b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name);
1078780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski  const Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name) const;
1088780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski
1096b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  Element* FindChildWithAttribute(const android::StringPiece& ns, const android::StringPiece& name,
1106b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski                                  const android::StringPiece& attr_ns,
1116b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski                                  const android::StringPiece& attr_name,
1126b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski                                  const android::StringPiece& attr_value);
1138780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski
1148780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski  const Element* FindChildWithAttribute(const android::StringPiece& ns,
1158780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski                                        const android::StringPiece& name,
1168780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski                                        const android::StringPiece& attr_ns,
1178780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski                                        const android::StringPiece& attr_name,
1188780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski                                        const android::StringPiece& attr_value) const;
1198780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski
1206b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::vector<Element*> GetChildElements();
1216b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
1226b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  // Due to overriding of subtypes not working with unique_ptr, define a convenience Clone method
1236b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  // that knows cloning an element returns an element.
1246b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::unique_ptr<Element> CloneElement(const ElementCloneFunc& el_cloner) const;
1256b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
1266b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override;
1276b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
1286b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  void Accept(Visitor* visitor) override;
129d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Accept(ConstVisitor* visitor) const override;
13075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
13175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
132efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// A Text (CDATA) XML node. Can not have any children.
1336b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskiclass Text : public Node {
134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
135cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string text;
1365eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski
1376b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override;
1386b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
1396b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  void Accept(Visitor* visitor) override;
140d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Accept(ConstVisitor* visitor) const override;
14175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
14275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
143efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// An XML resource with a source, name, and XML tree.
1445eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass XmlResource {
145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
146cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceFile file;
147ea134e08d70d156bdd17714d5f9ab9c44c91d4faAdam Lesinski
148ea134e08d70d156bdd17714d5f9ab9c44c91d4faAdam Lesinski  // StringPool must come before the xml::Node. Destructors are called in reverse order, and
149ea134e08d70d156bdd17714d5f9ab9c44c91d4faAdam Lesinski  // the xml::Node may have StringPool references that need to be destroyed before the StringPool
150ea134e08d70d156bdd17714d5f9ab9c44c91d4faAdam Lesinski  // is destroyed.
151d0f492db038c6210c1138865d816bfb134376538Adam Lesinski  StringPool string_pool;
152ea134e08d70d156bdd17714d5f9ab9c44c91d4faAdam Lesinski
1536b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::unique_ptr<xml::Element> root;
1548780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski
1558780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski  std::unique_ptr<XmlResource> Clone() const;
156467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski};
157467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski
158efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// Inflates an XML DOM from an InputStream, logging errors to the logger.
159efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinskistd::unique_ptr<XmlResource> Inflate(io::InputStream* in, IDiagnostics* diag, const Source& source);
16075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
1618780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski// Inflates an XML DOM from a binary ResXMLTree.
1628780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinskistd::unique_ptr<XmlResource> Inflate(const void* data, size_t len,
1638780eb6e4918ae24fb1ae74d631042c32e41dc3dAdam Lesinski                                     std::string* out_error = nullptr);
1641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
165ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiElement* FindRootElement(Node* node);
166ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
167efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// Visitor whose default implementation visits the children nodes of any node.
1686b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskiclass Visitor {
169cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
1706b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  virtual ~Visitor() = default;
1711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1726b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  virtual void Visit(Element* el) {
1736b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski    VisitChildren(el);
174efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  }
1751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1766b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  virtual void Visit(Text* text) {
177efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  }
1781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1796b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski protected:
1806b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  Visitor() = default;
1811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1826b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  void VisitChildren(Element* el) {
1836b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski    for (auto& child : el->children) {
184ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      child->Accept(this);
1851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
186cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
1876b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
1886b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  virtual void BeforeVisitElement(Element* el) {
1896b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  }
1906b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  virtual void AfterVisitElement(Element* el) {
1916b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  }
1926b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
1936b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski private:
1946b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  DISALLOW_COPY_AND_ASSIGN(Visitor);
1956b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
1966b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  friend class Element;
1971ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
19875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
199d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinskiclass ConstVisitor {
200d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski public:
201d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual ~ConstVisitor() = default;
202d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
203d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual void Visit(const Element* el) {
204d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    VisitChildren(el);
205d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
206d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
207d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual void Visit(const Text* text) {
208d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
209d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
210d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski protected:
211d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  ConstVisitor() = default;
212d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
213d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void VisitChildren(const Element* el) {
214d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    for (const auto& child : el->children) {
215d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski      child->Accept(this);
216d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski    }
217d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
218d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
219d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual void BeforeVisitElement(const Element* el) {
220d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
221d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
222d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  virtual void AfterVisitElement(const Element* el) {
223d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  }
224d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
225d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski private:
226d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  DISALLOW_COPY_AND_ASSIGN(ConstVisitor);
227d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
228d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  friend class Element;
229d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski};
230d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
231efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski// An XML DOM visitor that will record the package name for a namespace prefix.
2321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass PackageAwareVisitor : public Visitor, public IPackageDeclStack {
233cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
234ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  using Visitor::Visit;
2355eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski
2361ef0fa9d7242b1926543bc49e35905d1be02a781Adam Lesinski  Maybe<ExtractedPackage> TransformPackageAlias(const android::StringPiece& alias) const override;
2375eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski
2386b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski protected:
2396b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  PackageAwareVisitor() = default;
2406b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
2416b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  void BeforeVisitElement(Element* el) override;
2426b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  void AfterVisitElement(Element* el) override;
2436b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
244cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private:
2456b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  DISALLOW_COPY_AND_ASSIGN(PackageAwareVisitor);
2466b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
247cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  struct PackageDecl {
248cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    std::string prefix;
249cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    ExtractedPackage package;
250cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  };
2511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
2526b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  std::vector<std::vector<PackageDecl>> package_decls_;
25375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
25475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
2556b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskinamespace internal {
25675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
2576b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski// Base class that overrides the default behaviour and does not descend into child nodes.
258d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinskiclass NodeCastBase : public ConstVisitor {
2596b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski public:
260d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Visit(const Element* el) override {
2616b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  }
262d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Visit(const Text* el) override {
2636b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  }
2646b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
2656b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski protected:
2666b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  NodeCastBase() = default;
2676b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
268d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void BeforeVisitElement(const Element* el) override {
2696b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  }
270d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void AfterVisitElement(const Element* el) override {
2716b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  }
2726b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
2736b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski private:
2746b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  DISALLOW_COPY_AND_ASSIGN(NodeCastBase);
2756b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski};
27675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
2771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T>
2786b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskiclass NodeCastImpl : public NodeCastBase {
279cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
2806b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  using NodeCastBase::Visit;
2816b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
2826b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  NodeCastImpl() = default;
2831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
284d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  const T* value = nullptr;
2851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
286d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  void Visit(const T* v) override {
287efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski    value = v;
288efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  }
2896b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
2906b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski private:
2916b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  DISALLOW_COPY_AND_ASSIGN(NodeCastImpl);
2921ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
2931ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
2946b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski}  // namespace internal
2956b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski
2961ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T>
297d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinskiconst T* NodeCast(const Node* node) {
2986b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinski  internal::NodeCastImpl<T> visitor;
299ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  node->Accept(&visitor);
300cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return visitor.value;
30175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}
30275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
303d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinskitemplate <typename T>
304d3ffa844f5a07756009f019e13806e253d1bb119Adam LesinskiT* NodeCast(Node* node) {
305d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski  return const_cast<T*>(NodeCast<T>(static_cast<const T*>(node)));
306d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski}
307d3ffa844f5a07756009f019e13806e253d1bb119Adam Lesinski
308cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace xml
309cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
31075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
311cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif  // AAPT_XML_DOM_H
312