xref: /aosp_15_r20/frameworks/base/tools/aapt2/java/ClassDefinition.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1  /*
2   * Copyright (C) 2016 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  #include "java/ClassDefinition.h"
18  
19  #include "androidfw/StringPiece.h"
20  
21  using ::aapt::text::Printer;
22  using ::android::StringPiece;
23  
24  namespace aapt {
25  
Print(bool,Printer * printer,bool strip_api_annotations) const26  void ClassMember::Print(bool /*final*/, Printer* printer, bool strip_api_annotations) const {
27    processor_.Print(printer, strip_api_annotations);
28  }
29  
AppendStatement(StringPiece statement)30  void MethodDefinition::AppendStatement(StringPiece statement) {
31    statements_.emplace_back(statement);
32  }
33  
Print(bool final,Printer * printer,bool) const34  void MethodDefinition::Print(bool final, Printer* printer, bool) const {
35    printer->Print(signature_).Println(" {");
36    printer->Indent();
37    for (const auto& statement : statements_) {
38      printer->Println(statement);
39    }
40    printer->Undent();
41    printer->Print("}");
42  }
43  
AddMember(std::unique_ptr<ClassMember> member)44  ClassDefinition::Result ClassDefinition::AddMember(std::unique_ptr<ClassMember> member) {
45    Result result = Result::kAdded;
46    auto iter = indexed_members_.find(member->GetName());
47    if (iter != indexed_members_.end()) {
48      // Overwrite the entry. Be careful, as the key in indexed_members_ is actually memory owned
49      // by the value at ordered_members_[index]. Since overwriting a value for a key doesn't replace
50      // the key (the initial key inserted into the unordered_map is kept), we must erase and then
51      // insert a new key, whose memory is being kept around. We do all this to avoid using more
52      // memory for each key.
53      size_t index = iter->second;
54  
55      // Erase the key + value from the map.
56      indexed_members_.erase(iter);
57  
58      // Now clear the memory that was backing the key (now erased).
59      ordered_members_[index].reset();
60      result = Result::kOverridden;
61    }
62  
63    indexed_members_[member->GetName()] = ordered_members_.size();
64    ordered_members_.push_back(std::move(member));
65    return result;
66  }
67  
empty() const68  bool ClassDefinition::empty() const {
69    for (const std::unique_ptr<ClassMember>& member : ordered_members_) {
70      if (member != nullptr && !member->empty()) {
71        return false;
72      }
73    }
74    return true;
75  }
76  
Print(bool final,Printer * printer,bool strip_api_annotations) const77  void ClassDefinition::Print(bool final, Printer* printer, bool strip_api_annotations) const {
78    if (empty() && !create_if_empty_) {
79      return;
80    }
81  
82    ClassMember::Print(final,  printer, strip_api_annotations);
83  
84    printer->Print("public ");
85    if (qualifier_ == ClassQualifier::kStatic) {
86      printer->Print("static ");
87    }
88    printer->Print("final class ").Print(name_).Println(" {");
89    printer->Indent();
90  
91    for (const std::unique_ptr<ClassMember>& member : ordered_members_) {
92      // There can be nullptr members when a member is added to the ClassDefinition
93      // and takes precedence over a previous member with the same name. The overridden member is
94      // set to nullptr.
95      if (member != nullptr) {
96        member->Print(final, printer, strip_api_annotations);
97        printer->Println();
98      }
99    }
100  
101    printer->Undent();
102    printer->Print("}");
103  }
104  
105  constexpr static const char* sWarningHeader =
106      "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n"
107      " *\n"
108      " * This class was automatically generated by the\n"
109      " * aapt tool from the resource data it found. It\n"
110      " * should not be modified by hand.\n"
111      " */\n\n";
112  
WriteJavaFile(const ClassDefinition * def,StringPiece package,bool final,bool strip_api_annotations,android::OutputStream * out)113  void ClassDefinition::WriteJavaFile(const ClassDefinition* def, StringPiece package, bool final,
114                                      bool strip_api_annotations, android::OutputStream* out) {
115    Printer printer(out);
116    printer.Print(sWarningHeader).Print("package ").Print(package).Println(";");
117    printer.Println();
118    def->Print(final, &printer, strip_api_annotations);
119  }
120  
121  }  // namespace aapt
122