|  | /* | 
|  | * Copyright (C) 2016 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #include "java/ClassDefinition.h" | 
|  |  | 
|  | #include "androidfw/StringPiece.h" | 
|  |  | 
|  | using ::aapt::text::Printer; | 
|  | using ::android::StringPiece; | 
|  |  | 
|  | namespace aapt { | 
|  |  | 
|  | void ClassMember::Print(bool /*final*/, Printer* printer, bool strip_api_annotations) const { | 
|  | processor_.Print(printer, strip_api_annotations); | 
|  | } | 
|  |  | 
|  | void MethodDefinition::AppendStatement(const StringPiece& statement) { | 
|  | statements_.push_back(statement.to_string()); | 
|  | } | 
|  |  | 
|  | void MethodDefinition::Print(bool final, Printer* printer, bool) const { | 
|  | printer->Print(signature_).Println(" {"); | 
|  | printer->Indent(); | 
|  | for (const auto& statement : statements_) { | 
|  | printer->Println(statement); | 
|  | } | 
|  | printer->Undent(); | 
|  | printer->Print("}"); | 
|  | } | 
|  |  | 
|  | ClassDefinition::Result ClassDefinition::AddMember(std::unique_ptr<ClassMember> member) { | 
|  | Result result = Result::kAdded; | 
|  | auto iter = indexed_members_.find(member->GetName()); | 
|  | if (iter != indexed_members_.end()) { | 
|  | // Overwrite the entry. Be careful, as the key in indexed_members_ is actually memory owned | 
|  | // by the value at ordered_members_[index]. Since overwriting a value for a key doesn't replace | 
|  | // the key (the initial key inserted into the unordered_map is kept), we must erase and then | 
|  | // insert a new key, whose memory is being kept around. We do all this to avoid using more | 
|  | // memory for each key. | 
|  | size_t index = iter->second; | 
|  |  | 
|  | // Erase the key + value from the map. | 
|  | indexed_members_.erase(iter); | 
|  |  | 
|  | // Now clear the memory that was backing the key (now erased). | 
|  | ordered_members_[index].reset(); | 
|  | result = Result::kOverridden; | 
|  | } | 
|  |  | 
|  | indexed_members_[member->GetName()] = ordered_members_.size(); | 
|  | ordered_members_.push_back(std::move(member)); | 
|  | return result; | 
|  | } | 
|  |  | 
|  | bool ClassDefinition::empty() const { | 
|  | for (const std::unique_ptr<ClassMember>& member : ordered_members_) { | 
|  | if (member != nullptr && !member->empty()) { | 
|  | return false; | 
|  | } | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void ClassDefinition::Print(bool final, Printer* printer, bool strip_api_annotations) const { | 
|  | if (empty() && !create_if_empty_) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | ClassMember::Print(final,  printer, strip_api_annotations); | 
|  |  | 
|  | printer->Print("public "); | 
|  | if (qualifier_ == ClassQualifier::kStatic) { | 
|  | printer->Print("static "); | 
|  | } | 
|  | printer->Print("final class ").Print(name_).Println(" {"); | 
|  | printer->Indent(); | 
|  |  | 
|  | for (const std::unique_ptr<ClassMember>& member : ordered_members_) { | 
|  | // There can be nullptr members when a member is added to the ClassDefinition | 
|  | // and takes precedence over a previous member with the same name. The overridden member is | 
|  | // set to nullptr. | 
|  | if (member != nullptr) { | 
|  | member->Print(final, printer, strip_api_annotations); | 
|  | printer->Println(); | 
|  | } | 
|  | } | 
|  |  | 
|  | printer->Undent(); | 
|  | printer->Print("}"); | 
|  | } | 
|  |  | 
|  | constexpr static const char* sWarningHeader = | 
|  | "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n" | 
|  | " *\n" | 
|  | " * This class was automatically generated by the\n" | 
|  | " * aapt tool from the resource data it found. It\n" | 
|  | " * should not be modified by hand.\n" | 
|  | " */\n\n"; | 
|  |  | 
|  | void ClassDefinition::WriteJavaFile(const ClassDefinition* def, const StringPiece& package, | 
|  | bool final, bool strip_api_annotations, io::OutputStream* out) { | 
|  | Printer printer(out); | 
|  | printer.Print(sWarningHeader).Print("package ").Print(package).Println(";"); | 
|  | printer.Println(); | 
|  | def->Print(final, &printer, strip_api_annotations); | 
|  | } | 
|  |  | 
|  | }  // namespace aapt |