blob: cf92c9aa6f89eacf6e9e3972ee47c45f23bf42a6 [file] [log] [blame]
Adam Lesinskib274e352015-11-06 15:14:35 -08001/*
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
Adam Lesinski467f1712015-11-16 17:35:44 -080020#include "Resource.h"
Adam Lesinskib274e352015-11-06 15:14:35 -080021#include "java/AnnotationProcessor.h"
22#include "util/StringPiece.h"
23#include "util/Util.h"
24
25#include <sstream>
26#include <string>
27
28namespace aapt {
29
30struct ClassDefinitionWriterOptions {
31 bool useFinalQualifier = false;
32 bool forceCreationIfEmpty = false;
33};
34
35/**
36 * Writes a class for use in R.java or Manifest.java.
37 */
38class ClassDefinitionWriter {
39public:
40 ClassDefinitionWriter(const StringPiece& name, const ClassDefinitionWriterOptions& options) :
41 mName(name.toString()), mOptions(options), mStarted(false) {
42 }
43
44 ClassDefinitionWriter(const StringPiece16& name, const ClassDefinitionWriterOptions& options) :
45 mName(util::utf16ToUtf8(name)), mOptions(options), mStarted(false) {
46 }
47
48 void addIntMember(const StringPiece& name, AnnotationProcessor* processor,
49 const uint32_t val) {
50 ensureClassDeclaration();
51 if (processor) {
52 processor->writeToStream(&mOut, kIndent);
53 }
54 mOut << kIndent << "public static " << (mOptions.useFinalQualifier ? "final " : "")
55 << "int " << name << "=" << val << ";\n";
56 }
57
58 void addStringMember(const StringPiece16& name, AnnotationProcessor* processor,
59 const StringPiece16& val) {
60 ensureClassDeclaration();
61 if (processor) {
62 processor->writeToStream(&mOut, kIndent);
63 }
64 mOut << kIndent << "public static " << (mOptions.useFinalQualifier ? "final " : "")
65 << "String " << name << "=\"" << val << "\";\n";
66 }
67
Adam Lesinski74605cd2016-03-03 15:39:50 -080068 void addResourceMember(const StringPiece& name, AnnotationProcessor* processor,
Adam Lesinskib274e352015-11-06 15:14:35 -080069 const ResourceId id) {
70 ensureClassDeclaration();
71 if (processor) {
72 processor->writeToStream(&mOut, kIndent);
73 }
74 mOut << kIndent << "public static " << (mOptions.useFinalQualifier ? "final " : "")
75 << "int " << name << "=" << id <<";\n";
76 }
77
78 template <typename Iterator, typename FieldAccessorFunc>
Adam Lesinski74605cd2016-03-03 15:39:50 -080079 void addArrayMember(const StringPiece& name, AnnotationProcessor* processor,
Adam Lesinskib274e352015-11-06 15:14:35 -080080 const Iterator begin, const Iterator end, FieldAccessorFunc f) {
81 ensureClassDeclaration();
82 if (processor) {
83 processor->writeToStream(&mOut, kIndent);
84 }
85 mOut << kIndent << "public static final int[] " << name << "={";
86
87 for (Iterator current = begin; current != end; ++current) {
88 if (std::distance(begin, current) % kAttribsPerLine == 0) {
89 mOut << "\n" << kIndent << kIndent;
90 }
91
92 mOut << f(*current);
93 if (std::distance(current, end) > 1) {
94 mOut << ", ";
95 }
96 }
97 mOut << "\n" << kIndent <<"};\n";
98 }
99
100 void writeToStream(std::ostream* out, const StringPiece& prefix,
101 AnnotationProcessor* processor=nullptr) {
102 if (mOptions.forceCreationIfEmpty) {
103 ensureClassDeclaration();
104 }
105
106 if (!mStarted) {
107 return;
108 }
109
110 if (processor) {
111 processor->writeToStream(out, prefix);
112 }
113
114 std::string result = mOut.str();
115 for (StringPiece line : util::tokenize<char>(result, '\n')) {
116 *out << prefix << line << "\n";
117 }
118 *out << prefix << "}\n";
119 }
120
121private:
122 constexpr static const char* kIndent = " ";
123
124 // The number of attributes to emit per line in a Styleable array.
125 constexpr static size_t kAttribsPerLine = 4;
126
127 void ensureClassDeclaration() {
128 if (!mStarted) {
129 mStarted = true;
130 mOut << "public static final class " << mName << " {\n";
131 }
132 }
133
134 std::stringstream mOut;
135 std::string mName;
136 ClassDefinitionWriterOptions mOptions;
137 bool mStarted;
138};
139
140} // namespace aapt
141
142#endif /* AAPT_JAVA_CLASSDEFINITION_H */