11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/*
21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License.
61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at
71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software
111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and
141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License.
151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
17cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#include "compile/XmlIdCollector.h"
181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <algorithm>
201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <vector>
211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "ResourceUtils.h"
23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "ResourceValues.h"
24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "xml/XmlDom.h"
25ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt {
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace {
291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
30ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskistatic bool cmp_name(const SourcedResourceName& a, const ResourceNameRef& b) {
31cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return a.name < b;
321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
331ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct IdCollector : public xml::Visitor {
35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public:
36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  using xml::Visitor::Visit;
371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  explicit IdCollector(std::vector<SourcedResourceName>* out_symbols)
39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      : out_symbols_(out_symbols) {}
401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Visit(xml::Element* element) override {
42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    for (xml::Attribute& attr : element->attributes) {
43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      ResourceNameRef name;
44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      bool create = false;
45ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      if (ResourceUtils::ParseReference(attr.value, &name, &create, nullptr)) {
46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski        if (create && name.type == ResourceType::kId) {
47ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          auto iter = std::lower_bound(out_symbols_->begin(),
48ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                       out_symbols_->end(), name, cmp_name);
49ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          if (iter == out_symbols_->end() || iter->name != name) {
50ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            out_symbols_->insert(iter,
51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                 SourcedResourceName{name.ToResourceName(),
52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                                     element->line_number});
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          }
541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        }
55cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      }
561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
58ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    xml::Visitor::Visit(element);
59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
61ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private:
62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::vector<SourcedResourceName>* out_symbols_;
631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace
661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
67ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool XmlIdCollector::Consume(IAaptContext* context, xml::XmlResource* xmlRes) {
68ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  xmlRes->file.exported_symbols.clear();
69ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  IdCollector collector(&xmlRes->file.exported_symbols);
70ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  xmlRes->root->Accept(&collector);
71cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
75