blob: 609bcf377b4660917b2bb6612088cd0613c35a91 [file] [log] [blame]
Eric Holkc4239ac2018-09-05 10:43:31 -07001/*
2 * Copyright (C) 2018 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 "gflags/gflags.h"
18
Eric Holkdbc36e22018-09-20 12:03:10 -070019#include "dex_builder.h"
Eric Holkc4239ac2018-09-05 10:43:31 -070020#include "java_lang_builder.h"
Eric Holk3cbf1762018-12-13 16:04:56 -080021#include "tinyxml_layout_parser.h"
Eric Holkc4239ac2018-09-05 10:43:31 -070022#include "util.h"
23
24#include "tinyxml2.h"
25
26#include <fstream>
27#include <iostream>
28#include <sstream>
29#include <string>
30#include <vector>
31
Eric Holkdbc36e22018-09-20 12:03:10 -070032namespace {
33
Eric Holkc4239ac2018-09-05 10:43:31 -070034using namespace tinyxml2;
Eric Holkddc89902018-12-13 13:23:43 -080035using namespace startop::util;
Eric Holkc4239ac2018-09-05 10:43:31 -070036using std::string;
37
38constexpr char kStdoutFilename[]{"stdout"};
39
Eric Holkdbc36e22018-09-20 12:03:10 -070040DEFINE_bool(dex, false, "Generate a DEX file instead of Java");
Eric Holkc4239ac2018-09-05 10:43:31 -070041DEFINE_string(out, kStdoutFilename, "Where to write the generated class");
Eric Holkdbc36e22018-09-20 12:03:10 -070042DEFINE_string(package, "", "The package name for the generated class (required)");
Eric Holkc4239ac2018-09-05 10:43:31 -070043
Eric Holkc4239ac2018-09-05 10:43:31 -070044class ViewCompilerXmlVisitor : public XMLVisitor {
45 public:
Chih-Hung Hsieh81aff0f2018-12-20 13:53:28 -080046 explicit ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
Eric Holkc4239ac2018-09-05 10:43:31 -070047
48 bool VisitEnter(const XMLDocument& /*doc*/) override {
49 builder_->Start();
50 return true;
51 }
52
53 bool VisitExit(const XMLDocument& /*doc*/) override {
54 builder_->Finish();
55 return true;
56 }
57
58 bool VisitEnter(const XMLElement& element, const XMLAttribute* /*firstAttribute*/) override {
59 builder_->StartView(element.Name());
60 return true;
61 }
62
63 bool VisitExit(const XMLElement& /*element*/) override {
64 builder_->FinishView();
65 return true;
66 }
67
68 private:
69 JavaLangViewBuilder* builder_;
70};
Eric Holkdbc36e22018-09-20 12:03:10 -070071
Eric Holkc4239ac2018-09-05 10:43:31 -070072} // end namespace
73
74int main(int argc, char** argv) {
75 constexpr size_t kProgramName = 0;
76 constexpr size_t kFileNameParam = 1;
77 constexpr size_t kNumRequiredArgs = 2;
78
79 gflags::SetUsageMessage(
80 "Compile XML layout files into equivalent Java language code\n"
81 "\n"
82 " example usage: viewcompiler layout.xml --package com.example.androidapp");
83 gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags*/ true);
84
85 gflags::CommandLineFlagInfo cmd = gflags::GetCommandLineFlagInfoOrDie("package");
86 if (argc != kNumRequiredArgs || cmd.is_default) {
87 gflags::ShowUsageWithFlags(argv[kProgramName]);
88 return 1;
89 }
90
Eric Holkdbc36e22018-09-20 12:03:10 -070091 if (FLAGS_dex) {
92 startop::dex::WriteTestDexFile("test.dex");
93 return 0;
94 }
95
Eric Holkc4239ac2018-09-05 10:43:31 -070096 const char* const filename = argv[kFileNameParam];
97 const string layout_name = FindLayoutNameFromFilename(filename);
98
99 // We want to generate Java language code to inflate exactly this layout. This means
100 // generating code to walk the resource XML too.
101
102 XMLDocument xml;
103 xml.LoadFile(filename);
104
Eric Holk3cbf1762018-12-13 16:04:56 -0800105 string message{};
106 if (!startop::CanCompileLayout(xml, &message)) {
107 LOG(ERROR) << "Layout not supported: " << message;
108 return 1;
109 }
110
Eric Holkc4239ac2018-09-05 10:43:31 -0700111 std::ofstream outfile;
112 if (FLAGS_out != kStdoutFilename) {
113 outfile.open(FLAGS_out);
114 }
115 JavaLangViewBuilder builder{
116 FLAGS_package, layout_name, FLAGS_out == kStdoutFilename ? std::cout : outfile};
117
118 ViewCompilerXmlVisitor visitor{&builder};
119 xml.Accept(&visitor);
120
121 return 0;
Eric Holkdbc36e22018-09-20 12:03:10 -0700122}