1 /*
2  * Copyright (C) 2015, The Android Open Source Project *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <set>
19 #include <string>
20 #include <vector>
21 
22 #include "diagnostics.h"
23 
24 namespace android {
25 namespace aidl {
26 
27 using std::set;
28 using std::string;
29 using std::vector;
30 
31 // A simple wrapper around ostringstream. This is just to make Options class
32 // copiable by the implicit copy constructor. If ostingstream is not wrapped,
33 // the implcit copy constructor is not generated because ostringstream isn't
34 // copiable. This class makes the field copiable by having a copy constructor
35 // that does not copy the underlying stream.
36 class ErrorMessage {
37  public:
38   ErrorMessage() = default;
ErrorMessage(const ErrorMessage &)39   ErrorMessage(const ErrorMessage&) {}
40   std::ostringstream stream_;
41 
42   template <typename T>
43   ErrorMessage& operator<<(T& t) {
44     stream_ << t;
45     return *this;
46   }
47 
48   template <typename T>
49   ErrorMessage& operator<<(const T& t) {
50     stream_ << t;
51     return *this;
52   }
53 
54   // for "<< endl"
55   ErrorMessage& operator<<(std::ostream& (*f)(std::ostream&)) {
56     f(stream_);
57     return *this;
58   }
59 };
60 
61 // Handles warning-related options (e.g. -W, -w, ...)
62 class WarningOptions {
63  public:
64   std::vector<const char*> Parse(int argc, const char* const argv[], ErrorMessage& error_message);
65   DiagnosticMapping GetDiagnosticMapping() const;
66 
67  private:
68   bool as_errors_ = false;           // -Werror
69   bool enable_all_ = false;          // -Weverything
70   bool disable_all_ = false;         // -w
71   std::set<std::string> enabled_;    // -Wfoo
72   std::set<std::string> disabled_;   // -Wno-foo
73   std::set<std::string> no_errors_;  // -Wno-error=foo
74 };
75 
76 class Options final {
77  public:
78   enum class Language { UNSPECIFIED, JAVA, CPP, NDK, RUST };
79 
80   enum class Task { UNSPECIFIED, COMPILE, PREPROCESS, DUMP_API, CHECK_API, DUMP_MAPPINGS };
81 
82   enum class CheckApiLevel { COMPATIBLE, EQUAL };
83 
84   enum class Stability { UNSPECIFIED, VINTF };
85   bool StabilityFromString(const std::string& stability, Stability* out_stability);
86 
87   Options(int argc, const char* const argv[], Language default_lang = Language::UNSPECIFIED);
88 
89   static Options From(const string& cmdline);
90 
91   static Options From(const vector<string>& args);
92 
93   // Contain no references to unstructured data types (such as a parcelable that is
94   // implemented in Java). These interfaces aren't inherently stable but they have the
95   // capacity to be stabilized.
IsStructured()96   bool IsStructured() const { return structured_; }
97 
GetStability()98   Stability GetStability() const { return stability_; }
99 
TargetLanguage()100   Language TargetLanguage() const { return language_; }
IsCppOutput()101   bool IsCppOutput() const { return language_ == Language::CPP || language_ == Language::NDK; }
102 
GetTask()103   Task GetTask() const { return task_; }
104 
GetCheckApiLevel()105   CheckApiLevel GetCheckApiLevel() const { return check_api_level_; }
106 
ImportDirs()107   const set<string>& ImportDirs() const { return import_dirs_; }
108 
ImportFiles()109   const set<string>& ImportFiles() const { return import_files_; }
110 
PreprocessedFiles()111   const vector<string>& PreprocessedFiles() const { return preprocessed_files_; }
112 
DependencyFile()113   string DependencyFile() const {
114     return dependency_file_;
115   }
116 
AutoDepFile()117   bool AutoDepFile() const { return auto_dep_file_; }
118 
GenTraces()119   bool GenTraces() const { return gen_traces_; }
120 
GenTransactionNames()121   bool GenTransactionNames() const { return gen_transaction_names_; }
122 
DependencyFileNinja()123   bool DependencyFileNinja() const { return dependency_file_ninja_; }
124 
InputFiles()125   const vector<string>& InputFiles() const { return input_files_; }
126 
127   // Path to the output file. This is used only when there is only one
128   // output file for the invocation. When there are multiple outputs
129   // (e.g. compile multiple AIDL files), output files are created under
130   // OutputDir().
OutputFile()131   const string& OutputFile() const { return output_file_; }
132 
133   // Path to the directory where output file(s) will be generated under.
OutputDir()134   const string& OutputDir() const { return output_dir_; }
135 
136   // Path to the directory where header file(s) will be generated under.
137   // Only used when TargetLanguage() == Language::CPP
OutputHeaderDir()138   const string& OutputHeaderDir() const { return output_header_dir_; }
139 
FailOnParcelable()140   bool FailOnParcelable() const { return fail_on_parcelable_; }
141 
Version()142   int Version() const { return version_; }
143 
Hash()144   string Hash() const { return hash_; }
145 
GenLog()146   bool GenLog() const { return gen_log_; }
147 
DumpNoLicense()148   bool DumpNoLicense() const { return dump_no_license_; }
149 
Ok()150   bool Ok() const { return error_message_.stream_.str().empty(); }
151 
GetErrorMessage()152   string GetErrorMessage() const { return error_message_.stream_.str(); }
153 
154   string GetUsage() const;
155 
GenApiMapping()156   bool GenApiMapping() const { return task_ == Task::DUMP_MAPPINGS; }
157 
GetDiagnosticMapping()158   DiagnosticMapping GetDiagnosticMapping() const { return warning_options_.GetDiagnosticMapping(); }
159 
160   // The following are for testability, but cannot be influenced on the command line.
161   // Threshold of interface methods to enable outlining of onTransact cases.
162   size_t onTransact_outline_threshold_{275u};
163   // Number of cases to _not_ outline, if outlining is enabled.
164   size_t onTransact_non_outline_count_{275u};
165 
166  private:
167   Options() = default;
168 
169   const string myname_;
170   Language language_ = Language::UNSPECIFIED;
171   Task task_ = Task::COMPILE;
172   CheckApiLevel check_api_level_ = CheckApiLevel::COMPATIBLE;
173   set<string> import_dirs_;
174   set<string> import_files_;
175   vector<string> preprocessed_files_;
176   string dependency_file_;
177   bool gen_traces_ = false;
178   bool gen_transaction_names_ = false;
179   bool dependency_file_ninja_ = false;
180   bool structured_ = false;
181   Stability stability_ = Stability::UNSPECIFIED;
182   string output_dir_;
183   string output_header_dir_;
184   bool fail_on_parcelable_ = false;
185   bool auto_dep_file_ = false;
186   vector<string> input_files_;
187   string output_file_;
188   int version_ = 0;
189   string hash_ = "";
190   bool gen_log_ = false;
191   bool dump_no_license_ = false;
192   ErrorMessage error_message_;
193   WarningOptions warning_options_;
194 };
195 
196 std::string to_string(Options::Language language);
197 
198 }  // namespace aidl
199 }  // namespace android
200