blob: 7d791c229a98adda660fc14cc70b991c5c1acb89 [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"
21#include "util.h"
22
23#include "tinyxml2.h"
24
25#include <fstream>
26#include <iostream>
27#include <sstream>
28#include <string>
29#include <vector>
30
Eric Holkdbc36e22018-09-20 12:03:10 -070031namespace {
32
Eric Holkc4239ac2018-09-05 10:43:31 -070033using namespace tinyxml2;
34using std::string;
35
36constexpr char kStdoutFilename[]{"stdout"};
37
Eric Holkdbc36e22018-09-20 12:03:10 -070038DEFINE_bool(dex, false, "Generate a DEX file instead of Java");
Eric Holkc4239ac2018-09-05 10:43:31 -070039DEFINE_string(out, kStdoutFilename, "Where to write the generated class");
Eric Holkdbc36e22018-09-20 12:03:10 -070040DEFINE_string(package, "", "The package name for the generated class (required)");
Eric Holkc4239ac2018-09-05 10:43:31 -070041
Eric Holkc4239ac2018-09-05 10:43:31 -070042class ViewCompilerXmlVisitor : public XMLVisitor {
43 public:
44 ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
45
46 bool VisitEnter(const XMLDocument& /*doc*/) override {
47 builder_->Start();
48 return true;
49 }
50
51 bool VisitExit(const XMLDocument& /*doc*/) override {
52 builder_->Finish();
53 return true;
54 }
55
56 bool VisitEnter(const XMLElement& element, const XMLAttribute* /*firstAttribute*/) override {
57 builder_->StartView(element.Name());
58 return true;
59 }
60
61 bool VisitExit(const XMLElement& /*element*/) override {
62 builder_->FinishView();
63 return true;
64 }
65
66 private:
67 JavaLangViewBuilder* builder_;
68};
Eric Holkdbc36e22018-09-20 12:03:10 -070069
Eric Holkc4239ac2018-09-05 10:43:31 -070070} // end namespace
71
72int main(int argc, char** argv) {
73 constexpr size_t kProgramName = 0;
74 constexpr size_t kFileNameParam = 1;
75 constexpr size_t kNumRequiredArgs = 2;
76
77 gflags::SetUsageMessage(
78 "Compile XML layout files into equivalent Java language code\n"
79 "\n"
80 " example usage: viewcompiler layout.xml --package com.example.androidapp");
81 gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags*/ true);
82
83 gflags::CommandLineFlagInfo cmd = gflags::GetCommandLineFlagInfoOrDie("package");
84 if (argc != kNumRequiredArgs || cmd.is_default) {
85 gflags::ShowUsageWithFlags(argv[kProgramName]);
86 return 1;
87 }
88
Eric Holkdbc36e22018-09-20 12:03:10 -070089 if (FLAGS_dex) {
90 startop::dex::WriteTestDexFile("test.dex");
91 return 0;
92 }
93
Eric Holkc4239ac2018-09-05 10:43:31 -070094 const char* const filename = argv[kFileNameParam];
95 const string layout_name = FindLayoutNameFromFilename(filename);
96
97 // We want to generate Java language code to inflate exactly this layout. This means
98 // generating code to walk the resource XML too.
99
100 XMLDocument xml;
101 xml.LoadFile(filename);
102
103 std::ofstream outfile;
104 if (FLAGS_out != kStdoutFilename) {
105 outfile.open(FLAGS_out);
106 }
107 JavaLangViewBuilder builder{
108 FLAGS_package, layout_name, FLAGS_out == kStdoutFilename ? std::cout : outfile};
109
110 ViewCompilerXmlVisitor visitor{&builder};
111 xml.Accept(&visitor);
112
113 return 0;
Eric Holkdbc36e22018-09-20 12:03:10 -0700114}