Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 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 | #ifndef AAPT_JAVA_CLASSDEFINITION_H |
| 18 | #define AAPT_JAVA_CLASSDEFINITION_H |
| 19 | |
| 20 | #include "Resource.h" |
| 21 | #include "java/AnnotationProcessor.h" |
| 22 | #include "util/StringPiece.h" |
| 23 | #include "util/Util.h" |
| 24 | |
| 25 | #include <android-base/macros.h> |
| 26 | #include <sstream> |
| 27 | #include <string> |
| 28 | |
| 29 | namespace aapt { |
| 30 | |
| 31 | // The number of attributes to emit per line in a Styleable array. |
| 32 | constexpr static size_t kAttribsPerLine = 4; |
| 33 | constexpr static const char* kIndent = " "; |
| 34 | |
| 35 | class ClassMember { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 36 | public: |
| 37 | virtual ~ClassMember() = default; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 38 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 39 | AnnotationProcessor* getCommentBuilder() { return &mProcessor; } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 40 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 41 | virtual bool empty() const = 0; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 42 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 43 | virtual void writeToStream(const StringPiece& prefix, bool final, |
| 44 | std::ostream* out) const { |
| 45 | mProcessor.writeToStream(out, prefix); |
| 46 | } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 47 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 48 | private: |
| 49 | AnnotationProcessor mProcessor; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 50 | }; |
| 51 | |
| 52 | template <typename T> |
| 53 | class PrimitiveMember : public ClassMember { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 54 | public: |
| 55 | PrimitiveMember(const StringPiece& name, const T& val) |
| 56 | : mName(name.toString()), mVal(val) {} |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 57 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 58 | bool empty() const override { return false; } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 59 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 60 | void writeToStream(const StringPiece& prefix, bool final, |
| 61 | std::ostream* out) const override { |
| 62 | ClassMember::writeToStream(prefix, final, out); |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 63 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 64 | *out << prefix << "public static " << (final ? "final " : "") << "int " |
| 65 | << mName << "=" << mVal << ";"; |
| 66 | } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 67 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 68 | private: |
| 69 | std::string mName; |
| 70 | T mVal; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 71 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 72 | DISALLOW_COPY_AND_ASSIGN(PrimitiveMember); |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 73 | }; |
| 74 | |
| 75 | /** |
| 76 | * Specialization for strings so they get the right type and are quoted with "". |
| 77 | */ |
| 78 | template <> |
| 79 | class PrimitiveMember<std::string> : public ClassMember { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 80 | public: |
| 81 | PrimitiveMember(const StringPiece& name, const std::string& val) |
| 82 | : mName(name.toString()), mVal(val) {} |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 83 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 84 | bool empty() const override { return false; } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 85 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 86 | void writeToStream(const StringPiece& prefix, bool final, |
| 87 | std::ostream* out) const override { |
| 88 | ClassMember::writeToStream(prefix, final, out); |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 89 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 90 | *out << prefix << "public static " << (final ? "final " : "") << "String " |
| 91 | << mName << "=\"" << mVal << "\";"; |
| 92 | } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 93 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 94 | private: |
| 95 | std::string mName; |
| 96 | std::string mVal; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 97 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 98 | DISALLOW_COPY_AND_ASSIGN(PrimitiveMember); |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 99 | }; |
| 100 | |
| 101 | using IntMember = PrimitiveMember<uint32_t>; |
| 102 | using ResourceMember = PrimitiveMember<ResourceId>; |
| 103 | using StringMember = PrimitiveMember<std::string>; |
| 104 | |
| 105 | template <typename T> |
| 106 | class PrimitiveArrayMember : public ClassMember { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 107 | public: |
| 108 | explicit PrimitiveArrayMember(const StringPiece& name) |
| 109 | : mName(name.toString()) {} |
| 110 | |
| 111 | void addElement(const T& val) { mElements.push_back(val); } |
| 112 | |
| 113 | bool empty() const override { return false; } |
| 114 | |
| 115 | void writeToStream(const StringPiece& prefix, bool final, |
| 116 | std::ostream* out) const override { |
| 117 | ClassMember::writeToStream(prefix, final, out); |
| 118 | |
| 119 | *out << prefix << "public static final int[] " << mName << "={"; |
| 120 | |
| 121 | const auto begin = mElements.begin(); |
| 122 | const auto end = mElements.end(); |
| 123 | for (auto current = begin; current != end; ++current) { |
| 124 | if (std::distance(begin, current) % kAttribsPerLine == 0) { |
| 125 | *out << "\n" << prefix << kIndent << kIndent; |
| 126 | } |
| 127 | |
| 128 | *out << *current; |
| 129 | if (std::distance(current, end) > 1) { |
| 130 | *out << ", "; |
| 131 | } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 132 | } |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 133 | *out << "\n" << prefix << kIndent << "};"; |
| 134 | } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 135 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 136 | private: |
| 137 | std::string mName; |
| 138 | std::vector<T> mElements; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 139 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 140 | DISALLOW_COPY_AND_ASSIGN(PrimitiveArrayMember); |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 141 | }; |
| 142 | |
| 143 | using ResourceArrayMember = PrimitiveArrayMember<ResourceId>; |
| 144 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 145 | enum class ClassQualifier { None, Static }; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 146 | |
| 147 | class ClassDefinition : public ClassMember { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 148 | public: |
| 149 | static bool writeJavaFile(const ClassDefinition* def, |
| 150 | const StringPiece& package, bool final, |
| 151 | std::ostream* out); |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 152 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 153 | ClassDefinition(const StringPiece& name, ClassQualifier qualifier, |
| 154 | bool createIfEmpty) |
| 155 | : mName(name.toString()), |
| 156 | mQualifier(qualifier), |
| 157 | mCreateIfEmpty(createIfEmpty) {} |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 158 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 159 | void addMember(std::unique_ptr<ClassMember> member) { |
| 160 | mMembers.push_back(std::move(member)); |
| 161 | } |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 162 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 163 | bool empty() const override; |
| 164 | void writeToStream(const StringPiece& prefix, bool final, |
| 165 | std::ostream* out) const override; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 166 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 167 | private: |
| 168 | std::string mName; |
| 169 | ClassQualifier mQualifier; |
| 170 | bool mCreateIfEmpty; |
| 171 | std::vector<std::unique_ptr<ClassMember>> mMembers; |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 172 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 173 | DISALLOW_COPY_AND_ASSIGN(ClassDefinition); |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 174 | }; |
| 175 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame^] | 176 | } // namespace aapt |
Adam Lesinski | 6cbfb1d | 2016-03-31 13:33:02 -0700 | [diff] [blame] | 177 | |
| 178 | #endif /* AAPT_JAVA_CLASSDEFINITION_H */ |