16cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski/*
26cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski *
46cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * you may not use this file except in compliance with the License.
66cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * You may obtain a copy of the License at
76cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski *
86cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski *
106cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * See the License for the specific language governing permissions and
146cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * limitations under the License.
156cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski */
166cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
176cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#ifndef AAPT_JAVA_CLASSDEFINITION_H
186cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#define AAPT_JAVA_CLASSDEFINITION_H
196cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
206cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#include "Resource.h"
216cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#include "java/AnnotationProcessor.h"
226cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#include "util/StringPiece.h"
236cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#include "util/Util.h"
246cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
256cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#include <android-base/macros.h>
266cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#include <sstream>
276cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#include <string>
286cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
296cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskinamespace aapt {
306cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
316cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski// The number of attributes to emit per line in a Styleable array.
326cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiconstexpr static size_t kAttribsPerLine = 4;
336cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiconstexpr static const char* kIndent = "  ";
346cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
356cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiclass ClassMember {
366cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskipublic:
376cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    virtual ~ClassMember() = default;
386cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
396cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    AnnotationProcessor* getCommentBuilder() {
406cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        return &mProcessor;
416cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
426cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
436cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    virtual bool empty() const = 0;
446cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
456cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    virtual void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const {
466cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        mProcessor.writeToStream(out, prefix);
476cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
486cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
496cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiprivate:
506cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    AnnotationProcessor mProcessor;
516cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski};
526cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
536cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskitemplate <typename T>
546cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiclass PrimitiveMember : public ClassMember {
556cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskipublic:
566cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    PrimitiveMember(const StringPiece& name, const T& val) :
576cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            mName(name.toString()), mVal(val) {
586cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
596cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
606cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    bool empty() const override {
616cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        return false;
626cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
636cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
646cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override {
656cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        ClassMember::writeToStream(prefix, final, out);
666cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
676cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        *out << prefix << "public static " << (final ? "final " : "")
686cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski             << "int " << mName << "=" << mVal << ";";
696cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
706cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
716cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiprivate:
726cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::string mName;
736cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    T mVal;
746cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
756cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);
766cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski};
776cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
786cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski/**
796cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski * Specialization for strings so they get the right type and are quoted with "".
806cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski */
816cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskitemplate <>
826cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiclass PrimitiveMember<std::string> : public ClassMember {
836cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskipublic:
846cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    PrimitiveMember(const StringPiece& name, const std::string& val) :
856cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            mName(name.toString()), mVal(val) {
866cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
876cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
886cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    bool empty() const override {
896cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        return false;
906cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
916cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
926cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override {
936cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        ClassMember::writeToStream(prefix, final, out);
946cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
956cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        *out << prefix << "public static " << (final ? "final " : "")
966cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski             << "String " << mName << "=\"" << mVal << "\";";
976cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
986cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
996cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiprivate:
1006cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::string mName;
1016cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::string mVal;
1026cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1036cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);
1046cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski};
1056cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1066cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiusing IntMember = PrimitiveMember<uint32_t>;
1076cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiusing ResourceMember = PrimitiveMember<ResourceId>;
1086cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiusing StringMember = PrimitiveMember<std::string>;
1096cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1106cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskitemplate <typename T>
1116cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiclass PrimitiveArrayMember : public ClassMember {
1126cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskipublic:
1136cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    PrimitiveArrayMember(const StringPiece& name) :
1146cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            mName(name.toString()) {
1156cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
1166cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1176cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    void addElement(const T& val) {
1186cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        mElements.push_back(val);
1196cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
1206cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1216cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    bool empty() const override {
1226cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        return false;
1236cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
1246cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1256cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override {
1266cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        ClassMember::writeToStream(prefix, final, out);
1276cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
128626b3dbf74f02ae630ae0089632f5962340694dcAdam Lesinski        *out << prefix << "public static final int[] " << mName << "={";
1296cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1306cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        const auto begin = mElements.begin();
1316cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        const auto end = mElements.end();
1326cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        for (auto current = begin; current != end; ++current) {
1336cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            if (std::distance(begin, current) % kAttribsPerLine == 0) {
1346cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski                *out << "\n" << prefix << kIndent << kIndent;
1356cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            }
1366cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1376cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            *out << *current;
1386cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            if (std::distance(current, end) > 1) {
1396cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski                *out << ", ";
1406cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            }
1416cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        }
1426cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        *out << "\n" << prefix << kIndent <<"};";
1436cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
1446cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1456cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiprivate:
1466cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::string mName;
1476cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::vector<T> mElements;
1486cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1496cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    DISALLOW_COPY_AND_ASSIGN(PrimitiveArrayMember);
1506cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski};
1516cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1526cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiusing ResourceArrayMember = PrimitiveArrayMember<ResourceId>;
1536cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1546cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskienum class ClassQualifier {
1556cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    None,
1566cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    Static
1576cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski};
1586cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1596cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiclass ClassDefinition : public ClassMember {
1606cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskipublic:
1616cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    static bool writeJavaFile(const ClassDefinition* def,
1626cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski                              const StringPiece& package,
1636cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski                              bool final,
1646cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski                              std::ostream* out);
1656cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1666cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    ClassDefinition(const StringPiece& name, ClassQualifier qualifier, bool createIfEmpty) :
1676cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            mName(name.toString()), mQualifier(qualifier), mCreateIfEmpty(createIfEmpty) {
1686cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
1696cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1706cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    void addMember(std::unique_ptr<ClassMember> member) {
1716cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        mMembers.push_back(std::move(member));
1726cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
1736cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1746cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    bool empty() const override;
1756cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override;
1766cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1776cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskiprivate:
1786cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::string mName;
1796cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    ClassQualifier mQualifier;
1806cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    bool mCreateIfEmpty;
1816cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::vector<std::unique_ptr<ClassMember>> mMembers;
1826cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1836cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    DISALLOW_COPY_AND_ASSIGN(ClassDefinition);
1846cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski};
1856cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1866cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski} // namespace aapt
1876cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
1886cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski#endif /* AAPT_JAVA_CLASSDEFINITION_H */
189